Página 1 de 1
Trocando NTX para CDX
Enviado: 25 Set 2006 13:46
por Jarbas
Pessoal, boa tarde, troquei um sistema de NTX para CDX, e estou com o seguinte problema :
- Esta mostrando o mesmo nr. de venda em dois terminais diferentes.
No programa de vendas (balção) , qdo o usuario vai realizar uma venda eu vou no ultimo registro do arquivo , pego o proximo numero , gravo um registro em branco e faço o dbcommit . Isso eu faço já no inicio do programa, depois eu pego todos os dados e no final gravo nesse registro já travado no começo .
Vejam :
dbselectarea("Ven1")
dbgobottom()
lN_Numero:=numero
lN_Numero++
adireg(0) \\Funcao para fazer o append blank e já travar o registro.
field->numero:=lN_Numero
dbunlock()
dbcommit()
O problema é q as vezes aparece o mesmo numero de Venda em dois terminais diferente, qdo eu trabalhava com NTX não tinha esse problema .
Desde já mto obrigado.
Abs
Jarbas
Enviado: 25 Set 2006 14:05
por gvc
Após o dbgobottom(), tente bloquear o registro antes de incluir um novo.
O seu sistema pode estar lendo o ultimo registro para uma máquina e antes de incluir e gravar o próximo registro, outra máquina esta lendo o "ultimo" novamente.
Essa lógica irá provocar problemas quando muitos usuários estiverem entrando com dados.
Veja neste sitio como trabalhar com semaforo.
Boa sorte.
Enviado: 28 Set 2006 11:47
por Eliane
Verifique o seguinte: o index do CDX é CUMULATIVO. Antes de usar o INDEX ON para criar os índices, verifique se o arq.existe:
IF FILE('TESTE.CDX')
DELETE FILE TESTE.CDX
IF FILE('TESTE.CDX')
Mensagem(... O arq. não pode ser deletado ... Verifique...)
ENDIF
ENDIF
Isto para todos os CDX que vc criar. No NTX não precisava disto !
Enviado: 29 Set 2006 10:30
por Eliane
Jarbas, outra coisa que pode causar erro é vc pegar o No do último registro DO BANCO DE DADOS e somar 1. Se o indíce estiver corrompido ou desatualizado, ou problemas de gravação simultânea, poderá duplicar dados. Neste site encontrei uma saída segura:
- Crie um arquivo TXT com o No do último registro, ex: CLIENTES.NUM
- Se fosse um sistema seu conteúdo seria: 0000000000
- No seu programa vc irá ler este arquivo, somar 1 e gravar. Assim não haverá maneira de os usuários pegarem o mesmo número. Dê então o ADIREG somente se o usuário confirmar a inserção. Não fique deletando registros em branco. Já fiz isso e não é uma boa saída.
Ex do código :
PROGRAMA CLIENTE
....
....
*** pega ultimo numero de arq.DOS ***
l_utlcod := FNOVOCOD('CLIENTE.NUM')
...
...
*************************************************************
* PROGRAMA : EXPBAIXO
* OBJETIVO : Cadastro em arquivo DOS do numero do ultimo reg.para rede
* - Este arquivo ter apenas o ultimo codigo gravado
* PARAMETROS : pa_arquivo ==> nome do arquivo
* pa_tam ==> tamanho do codigo a ser lido (numerico)
* RETORNO : ultimo codigo ou ZERO se algum erro
******************************************************************************
# include "fileio.ch"
****************************************
FUNCTION FNOVOCOD(pa_arquivo,pa_tam)
****************************************
LOCAL l_handle ,; // handle do arquivo DOS
l_cod ,; // codigo
l_retorno := 0 ,; // 0 se erro ou o codigo lido
l_write ,; // flag de gravacao
l_mensagem ,; // mensagem de erro
l_continua ,; // flag permite continuar mesmo com problemas
l_tela // savescreen
SAVE SCREEN TO l_tela
**** Verifica se arquivo existe
IF ! FILE(pa_arquivo)
l_mensagem := 'Arquivo '+ pa_arquivo + ' nÆo encontrado ! Imposs¡vel inserir ' +;
'registro. Este arquivo cont‚m o No do £ltimo registro !'
l_continua := FRETORNO(l_mensagem)
IF ! l_continua
RESTORE SCREEN FROM l_tela
RETURN(l_retorno)
ENDIF
ENDIF
**** Abre o arquivo ****
l_handle := FOPEN(pa_arquivo,FO_READWRITE+FO_SHARED)
IF FERROR() != 0
l_mensagem := 'Arquivo '+ pa_arquivo + ' nÆo pode ser aberto ! Imposs¡vel inserir ' +;
'registro. Este arquivo cont‚m o No do £ltimo registro !' + ;
'Erro ' + ALLTRIM(STR( FERROR() )) + '.'
l_continua := FRETORNO(l_mensagem)
IF ! l_continua
RESTORE SCREEN FROM l_tela
RETURN(l_retorno)
ENDIF
ENDIF
**** Le codigo/atualiza ****
l_cod := VAL( FREADSTR(l_handle,pa_tam) ) // lˆ o ultimo codigo
l_cod++ // soma 1 ao ultimo codigo
Fseek(l_handle,0) // posiciona comeco do arq.
l_write := Fwrite(l_handle,STRZERO(l_cod,pa_tam), pa_tam )
// l_write retorna o numero de bytes gravados. Se for o mesmo de
// pa_tam porque gravou corretamente
IF l_write <> pa_tam
l_mensagem := 'Erro ' + ALLTRIM(STR( FERROR() )) +' .Problemas na grava‡Æo do No '+;
'do £ltimo registro no arq.' + pa_arquivo + ;
'. NÇO INCLUA NENHUM REGISTRO !!! Reinicie o sistema e verifique ' + ;
'se a numera‡Æo est correta ... '
l_continua := FRETORNO(l_mensagem)
IF ! l_continua
FCLOSE(l_handle)
RESTORE SCREEN FROM l_tela
RETURN(l_retorno)
ENDIF
ENDIF
l_retorno := l_cod // operacao correta
**** Fecha arquivo ****
FCLOSE(l_handle)
// Testa FCLOSE se gravou corretamente, mas mesmo que dˆ erro em fclose
// libera o ultimo numero mas d mensagem ao usuario.
IF FERROR() != 0
NewALERT('Erro ' + ALLTRIM(STR( FERROR() )) + ': Arquivo nÆo pode ser fechado ' +;
'corretamente. NÇO INCLUA REGISTROS. Reinicie o sistema ...' , { 'Retornar'})
ENDIF
RESTORE SCREEN FROM l_tela
RETURN(l_retorno)
*****************************************************************************
* FUNCAO : FRETORNO
* OBJETIVO : Quando acontece um erro com o Arquivo d a chance de
* continuar com senha
* PARAMETROS : pa_mensagem ==> mensagem a exibir
* RETORNO : .f. ou .t.
* --> retorno .t. como entrou com a senha permitir continuar
* --> para tentar arrumar o problema com o arquivo
******************************************************************************
STATIC FUNCTION FRETORNO(pa_mensagem)
*****************************************
LOCAL l_botao ,; // No do botao escolhido em newalert
l_senha ,; // senha
l_resp := .f. // retorno .t. se continua mesmo com erro
l_botao := NEWALERT(pa_mensagem,{ ' Retornar ' , ' SENHA ' })
IF l_botao = 2
NEWMENSA(' Entre com a Senha de DOS-Dbf ou <ENTER> para Sair : ')
@ 13,22 SAY "SENHA .......: "
l_senha := DIG_SEN(13,37,0)
IF l_senha = "DOS_EXP"
l_resp := .t.
ENDIF
ENDIF
RETURN(l_resp)
Pergunta: Gostaria de mandar o código com identação (tabulação) para ficar mais fácil de compreender. Não sei mexer direito neste editor do fórum. Poderia me explicar ?
Enviado: 29 Set 2006 10:58
por rochinha
Amiguinho
Faça uso da função de uso geral que coloquei na sessão
código fonte.
Com ela será praticamente impossivel voce obter um contador duplicado para qualquer arquivo controlado.
https://pctoledo.org/forum/viewto ... =5952#5952
@braços :?)