Jump to content
Fivewin Brasil

Às vezes, não grava no 2003


mkyx

Recommended Posts

olá, pessoal,

Será que alguém poderia me esclarecer, pois estou ficando de cabelo em pé.

Acontece de maneira intermitente, não é sempre.

O sistema operacional dos terminais é w7 e w8 e o servidor é 2003server.

No módulo do caixa, eu tenho os seguintes arquivos: CAIXA.DBF, PEDIDOS.DBF, PRODUTOS.DBF CORRENTE.DBF, CHEQUES.DBF, CARTOES.DBF, SELLER.DBF, e outros de segundas necessidades.

Todos os produtos que passam pela caixa, são gravados imediatamente no arquivo PRODUTOS.DBF,

depois que finaliza a venda, grava nos demais.

É aí que acontece o inexplicável, os itens que já foram gravados no produtos.dbf,

grava o recebimento no arquivo CAIXA.DBF, mas NÃO GRAVA NO ARQUIVOS PEDIDOS.DBF, e grava no corrente.dbf ou no cheques.dbf

Às vezes, além de não gravar no pedidos.dbf, tb não grava no caixa.dbf. (varia de vez em quando, esse erro!)

O exemplo abaixo, é como eu gravo no produtos.dbf e sigo a mesma sintaxe para gravar nos demais arquivos.

= acrescento o registro em branco -> bloqueio o registro -> gravo os dados -> libero a memória -> desbloqueio o registro

dbappend dbrlock replace dbcommit dbunlock

.

.

.

select arq_prod
arq_prod->(dbsetorder(1))
do while .t.
arq_prod->(dbappend())
if !arq_prod->(NetErr())
exit
endif
enddo
IF REGLOCK(100)
replace arq_prod->data_mov with data_cx,arq_prod->hora_mov with time(),arq_prod->cod_venda with str(nume,13),arq_prod->operador with user000,arq_prod->saldo_atua with sda,arq_prod->custo with pcu0,arq_prod->terminal with str(t_maq,3)
replace arq_prod->estado with esta00,arq_prod->codigo with cod,arq_prod->quantidade with qtd,arq_prod->unitario with pru,arq_prod->val_total with pt,ARQ_prod->UNIDADE WITH UNID,arq_prod->cliente with strzero(val(C_CODCLI),6)
replace arq_prod->comis_av with cav,arq_prod->comis_ap with cap,arq_prod->vendedor with strZERO(codve,6),ARQ_PROD->CAIXA WITH COD_CX,ARQ_PROD->PERIODO WITH COD_PERI,arq_prod->n_item with str(c_item,3),ARQ_PROD->OBSERVACAO WITH "BALCAO"
REPLACE ARQ_PROD->CLA_FISCAL WITH CACA01,ARQ_PROD->SIT_TRIBUT WITH CACA02,ARQ_PROD->POR_ICMS WITH CACA03,ARQ_PROD->POR_IPI WITH CACA04,ARQ_PROD->REDUCAO WITH CACA05,ARQ_PROD->IVA_MVA WITH CACA06,ARQ_PROD->ICMS_SUBS WITH CACA07
REPLACE ARQ_PROD->POR_PIS WITH CACA08,ARQ_PROD->POR_COFINS WITH CACA09,arq_prod->retorno with ret_ent,arq_prod->desc_indiv with des_inv
REPLACE ARQ_PROD->RETORNO WITH RET_ENT
n_reg:=arq_prod->(recno())
IF ESTA00="D"
QT_DEV:=QT_DEV+1
ELSE
QT_LEVA:=QT_LEVA+1
ENDIF
do while .t.
ARQ_PROD->(dbcommit())
if !arq_prod->(NetErr())
exit
endif
enddo
do while .t.
ARQ_PROD->(dbunlock())
if !arq_prod->(NetErr())
exit
endif
enddo

.

.

.

return .t.

********************

FUNCTION REGLOCK(TEMPO) // FUNÇÃO BLOQUEADORA DE REGISTROS PARA GRAVAR, ALTERA OU EXCLUIR
LOCAL A:=1
_dbf:=dbf()
DO WHILE A=1
IF (_dbf)->(dbrlock((_dbf)->(RECNO())))
A:=0
LOOP
ENDIF
tempo:=10000
DO WHILE TEMPO>0
IF (_dbf)->(DBRLOCK((_dbf)->(RECNO())))
TEMPO=-10
ENDIF
SYSWAIT(0.3)
TEMPO=TEMPO-1
ENDDO
A:=0
IF TEMPO>=0
IF MSGYESNO("NÃO CONSEGUI BLOQUEIAR O REGISTRO PARA GRAVAR OS DADOS, TENTA NOVAMENTE?","ATENÇÃO: PROBLEMA NO ARQUIVO!")
A:=1
ELSE
A:=1000
ENDIF
ENDIF
ENDDO
IF A=1000
MSGINFO("DADOS NÃO FORAM GRAVADOS!","PERDA DAS INFORMAÇÃES:")
RETURN .F.
ENDIF
RETURN(.T.)

AGORA ALTEREI A FUNÇÃO BLOQUEADORA DE REGISTRO POR ESTA: ( VAMOS VER O QUE VAI DAR...)

FUNCTION REGLOCK(TPO)
LOCAL tempo:=0
_dbf:=dbf()
DO WHILE .t.
IF (_dbf)->(dbrlock((_dbf)->(RECNO())))
exit
ENDIF
SYSWAIT(0.3)
TEMPO=TEMPO+1
IF TEMPO>100000
TEMPO:=0
MSGINFO("TEM ALGUMA COISA ERRADA COM ESTE ARQUIVO!"+CHR(13)+CHR(13)+"JÁ PASSOU DE 100.000, O NÚMERO DE TENTATIVAS"+CHR(13)+"PARA BLOQUEAR O ARQUIVOS.","ATENÇÃO:")
ENDIF
ENDDO
RETURN(.T.)

OBRIGADO A TODOS QUE PUDEREM ME AJUDAR.

FWH 8.02 COMPILADOR Xharbour



Link to comment
Share on other sites

EXEMPLO:



IF INCLUSAO
ADICIONE(0)
ELSE // ALTERACAO
TRAVEREG(0)
ENDIF

REPLACES...

DESTRAVA(0)


//---------------------------------------------------------------------------//
FUNCTION TRAVEREG(TEMPO) // trava o registro.

DO WHILE .NOT. REGLOCK(TEMPO)

SYSREFRESH()

MSGWAIT("AGUARDE ACESSO ARQUIVO","Bloqueando o registro...Aguarde",01)

ENDDO

RETURN(0)

FUNCTION REGLOCK(TEMPO)

* TENTA TRAVAR O REGISTRO ATUAL
* PAR: 1 - NUMERICO - TEMPO ESPERA

LOCAL SEMPRE, TELA

IF RLOCK()

RETURN(.T.) && BLOQUEADO

ENDIF

SEMPRE = (TEMPO = 0 )

DO WHILE (SEMPRE .OR. TEMPO > 0 ) .AND. INKEY() <> 27

SYSREFRESH()

IF RLOCK()
RETURN(.T.) && BLOQUEADO
ENDIF

SYSWAIT( .5 )

TEMPO = TEMPO-.5

ENDDO

RETURN( .F. ) && NAO BLOQUEADO

FUNCTION ADICIONE(TEMPO) // adicione um registro

DO WHILE .NOT. ADIREG(TEMPO)

SYSREFRESH()

MSGWAIT("AGUARDE ACESSO ARQUIVO","Adição de novo registro...Aguarde",01)

ENDDO

RETURN(0)

FUNCTION ADIREG(TEMPO)

* RETORNA VERDADEIRA SE O REGISTRO FOI APENDADO.O NOVO REG.PASSA A SER O REG.ATUAL BLOQUEADO
* PAR: 1-NUMERICO-TEMPO DE ESPERA

LOCAL SEMPRE, TELA

APPEND BLANK

IF .NOT. NETERR()
TRAVEREG(0)
RETURN(.T.)
ENDIF

SEMPRE = ( TEMPO = 0 )

DO WHILE( SEMPRE .OR. TEMPO > 0 ) .AND. INKEY() <> 27

SYSREFRESH()

APPEND BLANK

IF .NOT. NETERR()
TRAVEREG(0)
RETURN(.T.)
ENDIF

SYSWAIT(.5)

TEMPO = TEMPO - .5

ENDDO

RETURN( .F. ) && NAO BLOQUEADO

FUNCTION DESTRAVA() // destrava o registro.

COMMIT
UNLOCK

RETURN(NIL)


Link to comment
Share on other sites

Olá...

Além das dicas do amigos acima, faça algumas alterações na sua forma de programar :

- Dentro do "While" sempre coloque uma "Sysrefresh()", isso irá aliviar o processamento numa rede.

- Nunca coloque o "DbCommit()" dentro do "While", isso força a gravação a cada registro inserido e "pode" estar causando lentidão e perda de pacotes em sua rede.

- Deixe para colocar o "DbCoomit()" após o "EndDo"

As vezes já ocorreu comigo um bug do RddCdx, que não grava as informações após estar usando um arquivo (.Dbf) por muito tempo. Pelo menos é isso que imagino. Para resolver isso, passei a fechar e reabrir os mesmo arquivo durante algumas situações.

Um abraço

Link to comment
Share on other sites

Não entendi o funcionamento do sysrefresh() em rede. Por favor, explique melhor esse comando.

Obrigado,

SysRefresh()
Atualiza todas as mensagens(operações) pendentes.
Sintaxe
SysRefresh ( ) --> lRet
Retorno
lRet(logico)
Retorna verdadeiro (.T.), se o processo for realizado com sucesso; caso contrário, falso (.F.).
Exemplos
SysRefresh()
Link to comment
Share on other sites

Parece que o objetivo é fazer com que o Windows não dê a impressão de que está congelado enquanto se executa um processamento longo.

Apenas não entendi como isso pode aliviar o processamento em rede.

Refresh do sistema

Ao realizar processos que ocupem uma grande quantidade de tempo, como por exemplo rastrear uma informação em uma grande base de dados, devemos levar em conta que o Windows não poderá atualizar todo o sistema até que o processo termine. Por exemplo, se existisse um relógio no vídeo, este ficaria completamente parado até que a busca terminasse.

Para resolver este problema, o FiveWin incorpora uma função “SysRefresh()” que pode ser chamada tantas vezes quantas forem necessárias e que permitirá atualizar o sistema ao executar processos longos:

DO WHILE !Eof()

....

SysRefresh()

...

SKIP

ENDDO

Link to comment
Share on other sites

Não vi nada demais nem de errado no código dele, apesar de eu não fazer desta forma

Valdir, o DBCOMMIT dele está dentro de um while, mas se NETERR não retornar "erro", é feito um EXIT, ou seja, isso não está pesando nada, além de achar desnecessário colocar isso dentro do WHILE, já q teoricamente só será executado uma única vez, digo o mesmo referente ao UNLOCK.....

sei lá, acho q o erro não está aí ^^

Link to comment
Share on other sites

Olá...

Além das dicas do amigos acima, faça algumas alterações na sua forma de programar :

- Dentro do "While" sempre coloque uma "Sysrefresh()", isso irá aliviar o processamento numa rede.

- Nunca coloque o "DbCommit()" dentro do "While", isso força a gravação a cada registro inserido e "pode" estar causando lentidão e perda de pacotes em sua rede.

- Deixe para colocar o "DbCoomit()" após o "EndDo"

As vezes já ocorreu comigo um bug do RddCdx, que não grava as informações após estar usando um arquivo (.Dbf) por muito tempo. Pelo menos é isso que imagino. Para resolver isso, passei a fechar e reabrir os mesmo arquivo durante algumas situações.

Um abraço

Mkyx,

Não vou opinar sobre o problema citado, pq todas as informações citadas pelos companheiros no sentido de esclarecer tal questão estão corretas, contudo, o Valdir tem razão quando destaca a descarga do BUFFER em disco a cada registro gravado.

É contra-producente o tempo que vc perde descarregando um registro por vez em disco, mesmo que o tempo seja ínfimo, ainda assim na soma geral do tempo executado registro a registro vc acaba perdendo, pq com certeza em algum momento vc estará concorrendo com outros aplicativos da rede, então o melhor é descarregar em blocos

Vc pode criar uma função que faça esta gravação a cada X registros, seria a mesma coisa que o sistema faz quando BUFFER está cheio no processo de SWAP ou então coloque o COMMIT fora do WHILE como citou o Valdir para que seja executado após o final total do processamento do arquivo envolvido.

[]s,

Link to comment
Share on other sites

Parece que o objetivo é fazer com que o Windows não dê a impressão de que está congelado enquanto se executa um processamento longo.

Apenas não entendi como isso pode aliviar o processamento em rede.

Refresh do sistema

Ao realizar processos que ocupem uma grande quantidade de tempo, como por exemplo rastrear uma informação em uma grande base de dados, devemos levar em conta que o Windows não poderá atualizar todo o sistema até que o processo termine. Por exemplo, se existisse um relógio no vídeo, este ficaria completamente parado até que a busca terminasse.

Para resolver este problema, o FiveWin incorpora uma função “SysRefresh()” que pode ser chamada tantas vezes quantas forem necessárias e que permitirá atualizar o sistema ao executar processos longos:

DO WHILE !Eof()

....

SysRefresh()

...

SKIP

ENDDO

Olá Oscar... Blz ?

Como você mesmo postou acima, a Fivewin utiliza o comando Sysrefresh() para descarregar o buffer durante um processamento. Essa é uma caracteristica do Windows.

Tive problemas com isso num cliente. No Servidor estevam instalados além do meu Sistema, alguns aplicativos e o Autocad

Dai meu caro... como dizia meu amigo Kapiaba... é o cão chupando manga.

Passei a usar o Sysrefresh() fora do while e a perda de pacotes cessaram.

Para resolver de uma vez, foi necessário instalar o meu Sistema em outro Servidor.

abração.

Não vi nada demais nem de errado no código dele, apesar de eu não fazer desta forma

Valdir, o DBCOMMIT dele está dentro de um while, mas se NETERR não retornar "erro", é feito um EXIT, ou seja, isso não está pesando nada, além de achar desnecessário colocar isso dentro do WHILE, já q teoricamente só será executado uma única vez, digo o mesmo referente ao UNLOCK.....

sei lá, acho q o erro não está aí ^^

Olá Erciley... Blz ?

Faça um teste... cronometre a gravação de 10.000 registros através do while sem e depois com o o refresh()... isso numa rede..oK ?

Veja a diferença de performance.

abração.

Link to comment
Share on other sites

Olá Erciley... Blz ?

Faça um teste... cronometre a gravação de 10.000 registros através do while sem e depois com o o refresh()... isso numa rede..oK ?

Veja a diferença de performance.

abração.

Olá Valdir, bem e você? ^^

Bom, em nenhum momento eu disse que este procedimento que você acabou de citar, não deixe o processo lento,

o que eu disse, é que o processamento postado pelo mkyx no "post nº1" NÃO faz isso que você citou, por isso não vejo problemas no código dele em relação ao DBCOMMIT e ao DBUNLOCK (leia atentamente o código dele, o DBCOMMIT só será executado uma única vez, apesar de ele ter deixado esse DBCOMMIT em um WHILE).

É claro que nessa situação que você descreveu, tenha uma diferença enorme de performance, já constatei isso, mas não é o caso do mkyx.

Leia o código dele "identado"

select arq_prod
 
arq_prod->(dbsetorder(1))
do while .t.
    arq_prod->(dbappend())
    if !arq_prod->(NetErr())
       exit
    endif
enddo
 
//BLOQUEOU O REGISTRO
 
IF REGLOCK(100)
 
   replace arq_prod->data_mov with data_cx
   REPLACE arq_prod->hora_mov with time()
   REPLACE arq_prod->cod_venda with str(nume,13)
   REPLACE arq_prod->operador with user000
   REPLACE arq_prod->saldo_atua with sda
   REPLACE arq_prod->custo with pcu0
   REPLACE arq_prod->terminal with str(t_maq,3)
   
   replace arq_prod->estado with esta00
   REPLACE arq_prod->codigo with cod
   REPLACE arq_prod->quantidade with qtd
   REPLACE arq_prod->unitario with pru
   REPLACE arq_prod->val_total with pt
   REPLACE ARQ_prod->UNIDADE WITH UNID
   REPLACE arq_prod->cliente with strzero(val(C_CODCLI),6)
   
   replace arq_prod->comis_av with cav
   REPLACE arq_prod->comis_ap with cap
   REPLACE arq_prod->vendedor with strZERO(codve,6)
   REPLACE ARQ_PROD->CAIXA WITH COD_CX
   REPLACE ARQ_PROD->PERIODO WITH COD_PERI
   REPLACE arq_prod->n_item with str(c_item,3)
   REPLACE ARQ_PROD->OBSERVACAO WITH "BALCAO"
   
   REPLACE ARQ_PROD->CLA_FISCAL WITH CACA01
   REPLACE ARQ_PROD->SIT_TRIBUT WITH CACA02
   REPLACE ARQ_PROD->POR_ICMS WITH CACA03
   REPLACE ARQ_PROD->POR_IPI WITH CACA04
   REPLACE ARQ_PROD->REDUCAO WITH CACA05
   REPLACE ARQ_PROD->IVA_MVA WITH CACA06
   REPLACE ARQ_PROD->ICMS_SUBS WITH CACA07
   
   REPLACE ARQ_PROD->POR_PIS WITH CACA08
   REPLACE ARQ_PROD->POR_COFINS WITH CACA09
   REPLACE arq_prod->retorno with ret_ent
   REPLACE arq_prod->desc_indiv with des_inv
   REPLACE ARQ_PROD->RETORNO WITH RET_ENT
 
   n_reg:=arq_prod->(recno())
 
   IF ESTA00="D"
      QT_DEV:=QT_DEV+1
   ELSE
      QT_LEVA:=QT_LEVA+1
   ENDIF
 
   do while .t.
      //SE NÃO RETORNAR ERRO = NETERR FALSE, EXECUTE "EXIT"
      
      //QUAL A NECESSIDADE DISSO ESTAR EM UM WHILE? -----> NENHUMA AO MEU VER
 
      ARQ_PROD->(dbcommit())
      if !arq_prod->(NetErr())
         exit      
      endif
      
   enddo
 
   do while .t.      
      //SE NÃO RETORNAR ERRO = NETERR FALSE, EXECUTE "EXIT"
      
      //QUAL A NECESSIDADE DISSO ESTAR EM UM WHILE? -----> NENHUMA AO MEU VER
   
      ARQ_PROD->(dbunlock())
      if !arq_prod->(NetErr())
         exit
      endif
   enddo
 
ENDIF
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...