Progresso com PACK e COPY FIELDS

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

carlos_dornelas
Usuário Nível 3
Usuário Nível 3
Mensagens: 400
Registrado em: 25 Ago 2004 21:54

Progresso com PACK e COPY FIELDS

Mensagem por carlos_dornelas »

Pessoal, é possível implementar uma barra de progressão quando da utilização dos comandos PACK e COPY FIELDS?

Antonio Carlos
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

Não. Mas o ideal é não usar PACK. O melhor seria reaproveitar os registros, pra economizar tempo.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Mensagem por Eolo »

Código: Selecionar todos

use arquivo.dbf
arq=0
totalrec=lastrec()
conta=0
x_arecop()
quit

Código: Selecionar todos

FUNCTION X_ARECOP
dbeval( {|| x_arecop2() } )
retu

Código: Selecionar todos

FUNCTION X_ARECOP2
conta=conta+iif((totalrec/30)<30,30,int(totalrec/30))
conta=iif(conta>totalrec,totalrec,conta)
?tran(conta/totalrec*100,"@E 999.9%") // -> mostra evolução
arq=arq+1
c="lixo"+strzero(arq,2,0)
copy to &c next iif((totalrec/30)<30,30,int(totalrec/30))
retu
Antonio Carlos, eu tb procurei muito por isso e não achei. Acabei montando essa função meio capenga aí em cima... Funciona, mas de repente alguém melhora ela... O que eu faço é copiar os registros não deletados para 30 arquivos temporários, depois trago-os de volta com uma outra função semelhante.

Maligno, isso de reaproveitar registros não pode tornar (em determinados casos) o arquivo "fragmentado"?
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Mensagem por Eolo »

Ah, um detalhe importante: meus arquivos são normalmente "pequenos", porque eu mando informação antiga pro arquivo morto... Então essa operação de "pack" não toma muito tempo.
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

isso de reaproveitar registros não pode tornar (em determinados casos) o arquivo "fragmentado"?
Claro. Isso é bem possível de acontecer. Mas é realmente em uma pequena parte dos casos. Pra maioria, reaproveitar é uma opção muito melhor que o PACK.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

GasPro - Barra rolagem

Mensagem por clodoaldomonteiro »

Carlos!
Vai ai um exemplo da LIB do GASpro.
Hoje o GAS DOS é gratuito, então voce deve pegar a LIB dela no site da GAS informática.
Eu postei um exemplo ha uns dois dias atrás que tem um link com a lib do GASpro, voce pode baixar se quiser.

Código: Selecionar todos

// PROGRAMA EXEMPLO PARA MOSTRAR BARRA DE ROLAGEM NA TELA QUANDO ESTIVER
// COPIANDO, INDEXANDO OU QUALQUER OUTRA OPERAۂO EM ARQUIVO
// PROGRAMADOR: CLODOALDO MONTEIRO
// DIREITOS...: GAS INFORMATICA
// LIB........: GASP52PM.LIB
// FUNۂO.....: POE_GAUGE(MENSAGEM,TITULO1,TITULO2)
//              A FUNۂO PODE MOSTRAR UMA BARRA DE ROLAGEM OU UM CONTADOR DE REGISTROS

#include "INKEY.CH"

drvmenucen=.f.                            // vari vel para a funcao DBOX
drvcorpad="W+/RB"  ; drvcorbox="W+/B"     // cores default
drvcormsg="W+/N*"  ; drvcorenf="W+/R"
drvcorget="W+/BG"  ; drvcortel="W+/B"
drvcorhlp="GR+/G"  ; drvcortna="GR/N"
drvtitpad="GR+/RB" ; drvtitbox="GR+/B"    // cores dos titulos default
drvtitmsg="GR+/N*" ; drvtitenf="GR+/R"
drvtitget="GR+/BG" ; drvtittel="GR+/B"
drvtithlp="W+/G"   ; drvtittna="W/N"

use EMP new excl                          // ABRE O ARQUIVO EMP PARA TESTAR OS COMANDOS COM A FUNۂO POE_GAUGE

// indexando registros
clea
POE_GAUGE("Criando ¡ndices.",,,13,30)              // MOSTRA UM BOX NA TELA COM UMA MENSSAGEM
INDE ON EMP_COD TO EMP1 EVAL POE_GAUGE() EVERY (LASTREC()/20)     // indexando...
     // emp_cod ‚ um campo do arquivo EMP

// logalizando registros
clea
go top
POE_GAUGE("Pesquisando...|ESC interrompe","AGUARDE...","Processados:",16,28)
LOCA FOR emp_nomecr='xxmaria' WHIL INKEY()!=K_ESC .AND. POE_GAUGE() // tenta localizar registro desejado
      // emp_nomecr ‚ um campo do arquivo EMP
      // Depois do comando WHIL vocˆ pode colocar qualquer fun‡Æo e pode
      // at‚ mostrar um box com uma menssagem e esperando que o usu rio
      // fa‡a alguma a‡Æo.

// copiando arquivos
CLEA
POE_GAUGE("Compactando o arquivo EMP.DBF","AGUARDE!","Registros feitos:",15,28)      // msg de gauge
GO TOP                                             // inicio do dbf
COPY TO tmp WHILE POE_GAUGE()                      // copia reg nao excluido para tmp

RETU                                               //FIM DO PROGRAMA PRINCIPAL

FUNC POE_GAUGE(msg_,tit_,tit_reg,m_l,m_c)          // coloca gauge(BARRA DE ROLAGEM) na tela
STATIC l_g, c_g, ct_g:=0, so_conta                 // linha e coluna do inicio gauge
LOCAL x, defa_dev, i
IF msg_!=NIL                              // mensagem da dbox
   so_conta=(tit_reg!=NIL)                // vai contar ou colocar %
   ct_g=0                                 // contador de registro ja processados
   IF so_conta                            // se vai contar concatena msg que
      msg_+="|*|"+tit_reg+"       0"      // vamos mostrar qtde de reg processados
   ELSE                                   // processo em todo o arq
      msg_+="|*|"+REPL("°",20)            // concatena gauge no final
   ENDI
   x=DBOX(msg_,10,,,.f.,tit_)             // coloca msg na tela
   SETCOLOR(drvtitbox)                    // cor do titulo para gauge
   l_g = m_l                              // linha e
   c_g = m_c                              // coluna de inicio do gauge
   IF so_conta                            // vai contar registro
      c_g+=LEN(tit_reg)+1                 // posiciona cursor apos msg de proc
   ENDI
ELSE                                      // coloca o gauge
   ct_g++                                 // conta quantos ja foi feito
   IF so_conta                            // gauge em contador
      IF INT(ct_g/30)=ct_g/30             // mostra em 30 em 30
         x=RIGHT(SPACE(8)+STR(ct_g),8)    // coloca qtde na tela sem
         FOR i=1 TO 8                     // usar o SAY (pode estar imprimindo)
            POKE(-18432,(l_g*160)+((c_g+i)*2),ASC(SUBS(x,i+1,1)))
         NEXT
      ENDI
   ELSE                                   // gauge com percentual
      @ l_g,c_g SAY REPL("Û",MIN(ct_g,20))     // coloca na msg
   END IF
ENDI
RETURN .t.                              // sempre retorna verdadeiro
Espero ter ajudado, até mais.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Mensagem por clodoaldomonteiro »

Nesse link tem a lib do GAS DOS.

Link de sistema gerado em GAS usando o NODISIMP.
http://suportegas.com.br/portal/downloa ... ST_USB.ZIP
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Mensagem por Eolo »

(RETIFICADO)

Clodoaldo, interessante o uso do WHILE... Não tinha pensado nisso. Testei com o COPY e funciona legal. Só não entendi por que é necessária a LIB do GAS, se o que manda é o WHILE. Resumindo o que vc postou:

Código: Selecionar todos

use arquivo.dbf
priv conta:=0
priv tudo:=lastrec()
go top
copy to temp while copia()
quit

function copia
conta++
@10,10 say conta/tudo*100 //-> mostra %
retu .t.
Só um problema: tentei rodar o PACK e não consegui. Você conseguiu com o código que vc postou?
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

poe_gauge

Mensagem por clodoaldomonteiro »

Eolo!
É que eu montei um sistema para o Carlos ver, conforme o link acima, e nesse exemplo uso a função poe_gauge() para montar uma barra de rolagem e a função dbox(), para montar vários box.
Depois, é claro, o Carlos vai mundar o uso desse exemplo para ficar de acordo com o gosto dele.

Espero que eu tenha me explicado.[/b]
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Mensagem por Eolo »

a) Ok, eu entendi. Só quis ressaltar que o que manda é o WHILE, dá pra fazer sem o GAS... :-))

b) Vc não respondeu sobre o PACK. Você conseguiu, afinal? Eu, não.


Aliás, tem um 'complicômetro' nesse jeito de trabalhar com o COPY: o percentual de evolução não fecha... Seguinte: pra mostrar esse percentual, tem que comparar um contador com o total de registros - obtido com LASTREC(), certo? Só que o LASTREC() traz o TOTAL de registros (deletados ou não), então, dependendo do número de deletados, dá um resultado sem sentido.

Exemplo: DBF com 1.000 registros, sendo 100 deletados. LASTREC() retorna 1.000. Como vc está com o SET DELETED ON (pra pegar só os não deletados), a conta vai de 1/1000 até 900/1000, ou seja, pula os deletados e o percentual pára nos 90%... Dá pra fazer COUNT TO CONTADOR FOR !DELETED(), mas isso toma muito tempo e é ruim de usar com arquivos muito grandes.

No caso do INDEX isto não acontece porque todos os registros (deletados ou não) são indexados.
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Mensagem por sygecom »

Boa, essa do COPY, uso muito isso no MSYQL para DBF eu não tinha nd desse tipo...legal.

Abraços
Leonardo Machado
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Mensagem por clodoaldomonteiro »

Eolo!
Eu não uso muito o lastrec() e sim o comando COUNT, que acho que é a mesma coisa e fiz um teste no FOX com um DBF qualquer e deu certo, mais ou menos assim:

Código: Selecionar todos

USE ARQ
SET DELE ON         //seleciona só os registros ativos
COUNT TO M_VAR //cria uma variável com o total de registros ativos
Eu usei o COUNT para jogar na variável M_VAR somente os registros ativos com o comando SET DELE ON.
Acho que com o LASTREC() dá certo também o comando chave aqui é o SET DELE ON.

Você pode substituir o PACK pela sequencia de comandos a seguir:

Código: Selecionar todos

USE ARQ         //abre o seu arquivo
SET DELE ON   //seleciona somente os registros ativos
GO TOP           //vai para o início do arquivo
COPY TO TEMP WHILE COPIA()  //copia para um arquivo temporário usando uma função para mostrar a progressão dos registros
CLOSE ALL      //fecha todos os arquivos
ERASE ARQ.DBF      //apaga arquivo com registros deletados
RENAME TEMP.DBF TO ARQ.DBF   //renomeia arquivo temporário
... depois você deve reconstruir os índices novamente.
Não testei a rorina acima, mais o GAS gera assim e sempre dá certo, salvo algum erro não percebido por mim.

Espero ter ajudado, até mais.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

Eu não uso muito o lastrec() e sim o comando COUNT, que acho que é a mesma coisa
O comando COUNT é traduzido para uma expressão complexa utilizando DBEval() pra realizar uma contagem filtrada, enquanto que o LastRec() é uma função que só retorna a quantidade de registros.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Mensagem por clodoaldomonteiro »

Então quer dizer que a LASTREC() sempre dá a quantidade total de registros, mesmo usando o SET DELE ON?
Vou dá uma revisa nos meus fontes.
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

LastRec() fornece a quantidade de registros físicos do DBF, independentemente do estado do SET DELETED ou SET FILTER.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Responder