DUVIDAS SOBRE SISTEMA MULTI USUARIO

USUARIO.EXCLUIDOS 15/04/2007 13:29:52
#211967
Gostaria de um exemplo feito no DAO... pois nunca tive tempo de migra os meus sistemas pra ADO...
USUARIO.EXCLUIDOS 15/04/2007 14:10:51
#211972
Cara, Você esta mexendo na maior ferida de desenvolvimento vb."Minha Opinião"
Não encontrei até hoje nemhum artigo eficiente quanto a isso.
Utilizando .execute"Update tabela", não da certo pois o jet não bloqueia um unico registro e sim a pagina e isso depende do tamanho dos registros.
Selecionando antes o registro e utilizando rs.Update eu consegui, segue exemplo.

Agora Fox, Esse metodo você não é o primeiro que eu vejo aqui recomendando
criar campo booleano e gravar sim quando estiver editando.
Funciona muito bem sem utilizar begintrans, mas utilizando, não funcionou.
e sem controle de transações eu não recomendo.

Se eu estiver errado por favor aguém entre e colabore com o tópico.

Bom, essa foi a forma que consegui.

If MsgBox("Confirma alterar """ & txtRazaoSocial & """", vbQuestion + vbYesNo, "Confirmação de Edição") = vbYes Then
ReplaceTel 'Formata os telefones sem () e -
Me.Enabled = False
Me.MousePointer = 13
Conexao.BeginTrans
RSClientes.Open "Select *From TabClientes Where Codigo=" & lblCodigo & ";", Conexao, adOpenKeyset, adLockOptimistic
On Error Resume Next
lblProcesso = "Sistema em Processamento, aguarde..."
'*******Função que Edita os registros
RSClientes!RazaoSocial = Trim(txtRazaoSocial)
RSClientes!NomeFantasia = Trim(txtNomeFantasia)
RSClientes.Update
If Err Then
Select Case Err.Number
Case -2147217887 'Estão editando o reg ao mesmo tempo
'MsgBox Err.Number & Err.Description
doevents
Err.Clear
Me.MousePointer = 0
Me.Enabled = True
lblProcesso = ""
RSClientes.Close
Set RSClientes = Nothing
Conexao.RollbackTrans
MsgBox "O Registro esta sendo ditado por outro Usuário ao mesmo tempo, Tente Novamente", vbCritical, "Aviso"
Exit Sub
Case Else
DoEvents
Me.MousePointer = 0
Me.Enabled=True
lblProcesso = ""
RSClientes.Close
Set RSClientes = Nothing
Conexao.RollbackTrans
MsgBox "erro", vbCritical, "Aviso"
Exit Sub
End Select
End If
USUARIO.EXCLUIDOS 15/04/2007 16:34:42
#211988
Alguem nao tem nenhum exemplo pratico em DAO não?
LCSD 16/04/2007 09:49:17
#212050
Citação:

NIL escreveu:

Agora Fox, Esse metodo você não é o primeiro que eu vejo aqui recomendando
criar campo booleano e gravar sim quando estiver editando.
Funciona muito bem sem utilizar begintrans, mas utilizando, não funcionou.
e sem controle de transações eu não recomendo.

Se eu estiver errado por favor aguém entre e colabore com o tópico.



Nil, pode citar um exemplo com relação ao não funcionamento dos trans no caso em questão ?

' BeginTrans - Dá inicio ao processamento

'CommitTrans - Conclui a transacção

'RollBack - Repõe a situação anterior, ou melhor, não executa a transacção.


[c]Sub begintrans()


bd.BeginTrans

' Aqui abro a tabela, edito, altero enfim, manipulo todos os dados.

If MsgBox("Confirma Alterações ?", vbYesNo) = vbYes Then
[b]bd.CommitTrans
' aki confirmo as alterações/edições.

Else
bd.Rollback
End If

End Sub

[/c]
USUARIO.EXCLUIDOS 16/04/2007 18:00:57
#212152
Ola Fox,
Seguinte: Onde vc coloca o código que altera o campo ex:Editando=True ?


LCSD 17/04/2007 09:50:41
#212230
NIl

Seguite.

Cada programador utiliza uma lógica pessoal. No meu caso veja bem :

Para o usuário editar um registro é necessario desbloquear o form.

Para desbloquear o form eu verifico se tem alguém editando.

  
[c]Private Sub cmdAlterar_Click()

On Error GoTo SAIFUNC

cmdGravar.Enabled = False
cmdUltimo.Enabled = False
cmdAnterior.Enabled = False
cmdPrimeiro.Enabled = False
cmdProximo.Enabled = False
cmdSair.Enabled = False

bd.BeginTrans ' atente-se a este momento, onde inicio a transação

Set rsProdutos = New ADODB.Recordset
rsProdutos.Open "select * from produtos WHERE CODBARRAS='" & txt.Item(2).Text & "' order by codproduto", bd, adOpenStatic, adLockOptimistic
LerRegistroAtual ' aki leio o registro atual

Select Case rsProdutos.Fields("AlteradoPor") 'o campo que define se pode ou naum ser editado é o 'mesmo campo que registra quem editou.

Case Is <> 1 ' caso o "alteradopor" for diferente de 1 (ou seja o nome de quem alterou pela ultima vez)

rsProdutos.Fields("AlteradoPor") = 1 ' aki defino que esta sendo editado
rsProdutos.Update ' atualizo o campo
Dim I As Integer
For I = 0 To 20
If txt(I).Locked = True Then: txt(I).Locked = False
If txt(I).Enabled = False Then: txt(I).Enabled = True
Next I
txtUnidade.Enabled = True
Check3.Enabled = True
chkATIVO.Enabled = True
chkPromocional.Enabled = True
cmdSalvar.Enabled = True
cmdAdicionar.Enabled = False
cmdAlterar.Enabled = False
cmdCancelar.Enabled = True
Case Is = 1 ' agora caso o campo seja = a 1
MsgBox "Este registro não poderá ser editado." & vbCrLf & "Tente novamente mais tarde !!!!", vbInformation, "Edição de registro"
cmdExcluir.Enabled = False
cmdSair.Enabled = True
End Select
SAIFUNC:
Select Case Err.Number
Case 0
'faz nada
Case -2147168237
MsgBox "Na última tentativa não foi possível alterar este registro, " & Chr(10) & "Verifique se já não estão editando!"
bd.RollbackTrans ' aki dou um rollback soh para finalizar a transação, pois se o usuário clicar 'novamente no botão alterar , naum dara o erro

Err.Clear

Case -2147217864
MsgBox Err.Description
End Select
Err.Clear
End Sub

[/c]

Não sei se vc observou , mas em nem um momento vc viu o committrans na rotina acima, ou seja se nada der errado vou para o segundo passo do procediemtno.

Agora a questão esta no botão Salvar, é nele que se o usuário conseguiu desbloquear o form dara inicio nas alterações.




  Private Sub cmdSalvar_Click()

On Error GoTo TRATAERRO

cmdUltimo.Enabled = True
cmdAnterior.Enabled = True
cmdPrimeiro.Enabled = True
cmdProximo.Enabled = True

rsProdutos.Fields("Lista") = Check3.Value
rsProdutos.Fields("CODPRODUTO") = txt.Item(2).Text
rsProdutos.Fields("CODBARRAS") = txt.Item(2).Text
rsProdutos.Fields("NOMEPRODUTO") = txt.Item(3).Text
rsProdutos.Fields("PRECOCUSTO") = CCur(txt.Item(4).Text)
BLA
BLA
BLA
BLA
BLA
BLA
BLA
BLA
BLA

rsProdutos.Fields("ALTERADOPOR") = txt.Item(13).Text ' OBSERVE QUE NESTE MOMENTO ESTOU ALTERANDO A CONDIÇÃO 1 DO CAMPO Q DEFINE SE PODE OU NÃO SER ALTERADO.
cmdCancelar.Enabled = False
rsProdutos.Update
bd.CommitTrans ' OLHA A CONFIRAMÇÃO DO BEGINTRANS AKI.....PORTANTO VC NAUM VIU NESTE PROCEDIMENTO A 'CHAMADA PARA O BEGINTRANS, QUE JÁ FOI FEITA LÁ NO BOTÃO ALTERAR.


TRATAERRO:

Select Case Err.Number
Case 0
BlockRegistro (I)
cmdAdicionar.Enabled = True
cmdAlterar.Enabled = True
cmdSalvar.Enabled = False
cmdSair.Enabled = True
Case -2147217864
MsgBox "Houve um erro na transação e todas as alterações serão descartadas" & Chr(10) & Err.Description
bd.RollbackTrans
End Select
End Sub


Bem comigo ta funcionando legal, ainda não tive nem um problema


USUARIO.EXCLUIDOS 17/04/2007 22:45:41
#212431
Fox,
Então é como eu disse acima ,
Citação:

Utilizando .execute"Update tabela", não da certo pois o jet não bloqueia um unico registro e sim a pagina e isso depende do tamanho dos registros.
Selecionando antes o registro e utilizando rs.Update eu consegui, segue exemplo.

. Selecionando o registro asim como voê fez:
Citação:

rsProdutos.Open "select * from produtos WHERE CODBARRAS='" & txt.Item(2).Text & "' order by

, e sem utilizar instruçoçes sql "db.Execute Update", eu consegui , mas nem precisou criar campo para isso , o proprio Jet ja se encarregou de bloquear e gerar a mensagem de erro que foi tratada.

O que eu disse é que se você tentar fazer via ".execute, não é possivel."

beleza ?

WEBER 17/04/2007 23:04:04
#212433
Citação:

NIL escreveu:
Fox,
Então é como eu disse acima , Utilizando .execute Update tabela , não da certo pois o jet não bloqueia um unico registro e sim a pagina e isso depende do tamanho dos registros.
Selecionando antes o registro e utilizando rs.Update eu consegui, segue exemplo. . Selecionando o registro asim como voê fez:
rsProdutos.Open select * from produtos WHERE CODBARRAS=[ÃÂ'] & txt.Item(2).Text & [ÃÂ'] order by , e sem utilizar instruçoçes sql db.Execute Update , eu consegui , mas nem precisou criar campo para isso , o proprio Jet ja se encarregou de bloquear e gerar a mensagem de erro que foi tratada.

O que eu disse é que se você tentar fazer via .execute, não é possivel.

beleza ?



KinGX, o foxman, criou algumas rotinas como ele mesmo comentou cada programador age do jeito q lhe melhor convir, mas concordo com o nil num ponto que se vc estiver usando o DAO, e dois usuarios acessarem a mesma tabela e tentarem alterar o dao irá retornar um erro q vc pode inclusive tratalo muito facilmente ou com mensagens ou simplesmente cancelando a operação, enfim, o dao lhe retorna informações q tu pode ou nao usa-las.

Oq o foxman fez é algo q funciona com certeza, mas eu pergunto o seguinte, é tão necessario toda essa frescura vamos colocar a seguinte situação

cadastro de cliente
nao sei qnto a vcs mas eu geralmente tenho um botao chamado atualizar ou gravar q o recordset esta desconectado para o usuario ele mexe tranquilamente nos campos e se quiser realizar alguma alteração ai sim ele clica no botao "atualizar" ai no momento do click o processo q eu faço

abre recordset
sub de gravação
fecho novamente

cara é milionesimos de segundos, mas funciona e se alguem vier me dizer q sistemas maiores e bla, bla eu discordo pq eu clientes q tem ate 100 maquinas logadas no sistema, e nunca tive problemas claro q em determinadas situações como pedidos, caixas e bla, bla eu uso alguns artificios como trazer registros pelo id do usuario logado, ou pelo ip da mauqina enfim...

Mas sinceramente eu nunca usei committrans ou begin... e olha q o meu sistema é preparado pra trabalhar com firebird, access e mysql, ou seja a interface aceita qualquer um deles, claro dependendo da situação do cliente.
mas ate hoje nao tive necessidade vai ver tb devo ter tido muita sorte pq muitos aqui reclamam de access corrompendo nao sei se é a minha tecnica ou sorte mas tb nunca passei por issso.

Pra finalizar, eu acredito q todas as ideias sao validas algumas com mais processos outras com menos, umas com mais "controles para evitar isso e aquilo e outras com menos" mas no final das contas o interessante é tu aprender com os proprios erros, se é o primeiro sistema multi q tu ta desenvolvendo pode ter certeza q depois dele pronto se vc olhar daqui 6 meses tu vai falar q porcaria vou reescrever tudo denovo e assim vai, ache o seu metodo q lhe de segurança e agilidade pra vc.
WEBER 17/04/2007 23:09:52
#212434
equanto ao codigo em dao é simples, faz tempo q nao uso mais dao mas ...
é so vc mesmo criar o seu proprio uma maneira bem simples é
pegue o seu projeto compile e ai coloque pra rodar o exe.

ai no seu projeto rode junto e faça os testes como se fosse dois usuarios acessando os mesmo registros vc vera as mensagens de erro que o dao lhe retornará e pode simplesmente trata-las ou fazer como os amigos e criar um simples campo Texto de tamanho 1 ou um booleano (é q o fire nao tem boleano, por isso tenho q me adaptar) e qndo o cara clicar em alterar tu abre o recordset e coloca um A de alterando, e depois q fizer as alterações tu coloca um L de livre e ai é so tu colocar um simples If then antes de executar qualquer coisa pra ler esse campo se tiver A avisa o teu usuario pra esperar e ter paciencia pq tem algum mané alterando o registro e poderá levar horas e as vezes ate meses pra q um usuario consiga digitar algo, heheheheheh geralmente a cada 50 caracteres digitados 40 sao o bakespace

huahuahuahuah
LCSD 18/04/2007 09:22:13
#212472
Weber...blza....

Bem, vamos lá.....

Podem navegar simultaneamente pelos registros, quantos usuários quiserem....portanto, como descrevi no código assim, utilizo dois botões, um alterar (bloqueio apenas o registro em questão) e o salvar.



As firulas ou frescuras (rsrsrsrsrs), no meu caso achei necessária, e de certa forma, naum vi nada além do básico, em um botão ALTERAR e em um botão Salvar, com exceção de 3 linhas de transações dividida entre ambos.

Qual é o seu procedimento utilizado, em caso de dois usuários abrirem o mesmo cadastro no mesmo tempo ? e olha isso acontece.

Como vc trata essa possibilidade ?

A minha forma está resumida em dois botões.
Página 2 de 3 [25 registro(s)]
Tópico encerrado , respostas não são mais permitidas