... Pague apenas R$67,00 uma única vez e tenha acesso por 1 ano aos vídeos e arquivos exemplos do site ...

Clique aqui e obtenha mais detalhes.


Movimento Bancário - Saldo, linha a linha, em um formulário

Front-end desacoplado

Muitos dos programadores em Access têm sido instruídos a desenvolver seus aplicativos desacoplados da base de dados, ou seja, sem fazer uso das tabelas vinculadas, com a alegação de que estará ganhando no desempenho do aplicativo ao se trabalhar em rede. 

Considero trabalhar com o aplicativos desacoplados, para a maioria dos projetos, uma decisão equivocada que está sendo tomada, principalmente se você é novato na programação com Access. 

Entenda que o Access foi desenvolvido para se trabalhar com tabelas vinculadas e isso será, sem dúvida nenhuma, o seu maior trunfo, quando estiver competindo no mercado de trabalho com programadores de outras plataformas.  Tudo no Access se consegue desenvolver pela metade ou até mesmo pela quarta parte do tempo, em relação aos nossos rivais de outras plataformas. 

Ao tomar a decisão de não usar as tabelas vinculadas, você perde a vantagem que tinha, que era a do fator produtividade. Assim, como o seu tempo de programação irá crescer substancialmente, terá que formar preços mais altos e indicar prazos mais longos para conclusão do projeto.

Desempenho baixo do Access em Rede

Muitos Aplicativos feitos em Access, de fato, rodam com baixíssimo desempenho, deixando seus criadores sem dormir direito.  Afirmo que na maioria esmagadora das vezes, a culpa recai sobre os seus próprios criadores, que fazem uso de uma programação equivocada.   Se soubessem que a regra de ouro  é acessar às tabelas, somente o necessário, já dariam um salto quântico nos seus projetos.

Um exemplo clássico, ao desrespeito a regra de ouro citada acima

Acesse um fórum de Access qualquer e peça uma ajuda para montar uma programação que lhe forneça o saldo linha a linha de um movimento bancário.  É certo que lhe oferecerão a seguinte consulta:

SELECT IdMovimento, DataMovimento, Credito, Debito, 
DSum("[Credito] - [Debito]","tblMovimento","idMovimento <= " & [idMovimento]) AS Saldo
FROM [tblMovimento];

Sabe o slogan "Se beber, não dirija!"? O Slogan para esta consulta é: "Se programar, não use esta consulta!".  Além desta função ter uma pegadinha, faltando uma informação de data, no critério de filtragem.

A função Dsum() faz uma viagem até a tabela e realiza a soma do crédito menos o débito de todos os registros existentes menores ou iguais ao número exclusivo idMovimento.  Só que esta viagem é executada para cada registro que a consulta retorna.  Se a consulta retornar 1000 registros, serão realizadas 1000 viagens à tabela para o Dsum() trazer os cálculos.  Tente imaginar o tráfego na rede que irá gerar esta consulta, forçando 1000 viagens adicionais à tabela .  Fala sério! Isto vai totalmente contra as regras do bom senso de programação quando estamos programando em Access.

O Maestro

Preocupado com esta situação, resolvi inserir no aplicativo exemplo Maestro, uma técnica de programação, usando tabelas temporárias criadas em tempo de execução, que visa reduzir a necessidade de viagens às tabelas.

Veja aqui as novidades do Maestro.

Ofereço também 9 dicas para melhorar o desempenho do seu aplicativo em rede.  Observe que chamei a atenção neste artigo sobre o uso errado da função DLookup(), que desrespeita a regra de ouro aqui apresentada.

Veja aqui as 9 dicas sobre desempenho.

Movimento Bancário - Saldo, linha a linha, em um formulário

Estou disponibilizando um aplicativo exemplo de controle de movimento bancário para demonstrar uma forma bem eficiente de apresentar o saldo, linha a linha.  Uso a técnica de criar tabela temporária, com o objetivo não só de montar o saldo, linha a linha, como também de realizar filtragens sobre a tabela temporária local e não sobre a tabela de origem. 

Usando Access - Movimento bancário

O relatório usa, também, como origem a tabela temporária, desafogando ainda mais a necessidade de acessos à tabela no back-end.

Usando Access - Relatório Movimento bancárioSaldo anterior

Esta é outra situação desastrosa, no tocante ao desempenho, pois na prática vejo muitos programadores somando os campos (crédito - débito) desde a primeira linha de registro. 

Será que os programadores que trabalham para os bancos fazem desta forma; ou seja, programam para pegar o dia do primeiro movimento de uma conta corrente e ir somando até os dias atuais?  Então, se o correntista tiver uma conta há 20 anos, a rotina criada somará  todas as linhas do  movimento de sua conta.  Isso tem lógica, meu amigo programador ?   Esta questão, se não bem tratada no Access, é um desastre anunciado para o seu aplicativo.

E outro problema que poderia ocorrer é alguém inadvertidamente alterar um valor de registro bem antigo, o que acarretaria em um saldo acumulado errôneo.

Neste projeto que forneço é usada uma tabela para armazenar o saldo acumulado até um determinado período.  Assim, a rotina criada pega este saldo acumulado da tabela e o soma ao saldo calculado de um período mais recente, obtendo o saldo atual bem mais rápido.

Leia com atenção os comentários, da função que regula o acúmulo do saldo na tabela tblConfig:

Private Sub fncAcumularSaldo()
Dim DataLimite As Date
Dim strFiltro As String
Dim SaldoAcumulado As Double
Dim DataMaxSaldoAcumulado As Date
'-------------------------------------------------------------------------
'Data limite para acumular o saldo. Estou aqui estipulando que acumule o 
'saldo a partir do centésimo dia, em relação ao último lançamento
'-------------------------------------------------------------------------
DataLimite = DMax("DataMovimento", "tmp_tblMovimento") - 100
'-------------------------------------------------------------------------
'Calcula o saldo até o centésimo dia,apenas dos campos que não receberam 
'o status de "fechado"
'-------------------------------------------------------------------------
strFiltro = "Fechado = 0 And cdbl([dataMovimento]) <= " & CDbl(DataLimite)
SaldoAcumulado = Nz(DSum("[valorCredito]-[valorDebito]", "tblMovimento", strFiltro), 0)
'--------------------------------------------------------------------
'Se não tiver saldo acumulado, para ser armazenado na tabela auxiliar 
'tblConfig, encerra.
'--------------------------------------------------------------------
If SaldoAcumulado = 0 Then Exit Sub

DataMaxSaldoAcumulado = DMax("dataMovimento", "tblMovimento", strFiltro)
'----------------------------------------------------------------------------
'Toda transação que envolver mais de uma tabela sendo atualizada, devemos 
'colocar dentro da estrutura Begin <==> Commit
'Se não utilizar esta estrutura e uma das duas atualizações falhar, as contas 
'ficarão desequilibradas.
'A realização dessas alterações, dentro da estrutura begin <==> Commit, 
'garante que todas as alterações ocorram, ou nenhuma delas.
'-----------------------------------------------------------------------------
On Error GoTo trataerro
BeginTrans
  CurrentDb.Execute "UPDATE tblConfig SET DataSaldo ='" & DataMaxSaldoAcumulado & _
  "', Saldocaixa = Saldocaixa + val('" & SaldoAcumulado & "');"
  CurrentDb.Execute "UPDATE tblMovimento SET fechado = -1 WHERE " & strFiltro & ";"
CommitTrans

sair:
Exit Sub
trataerro:
Rollback
Resume sair
End Sub				

Arquivo Exemplo

Segue o arquivo exemplo para você baixar: 

Descompacte os arquivos na pasta "c:\MovimentoConta" para não perder os vínculos das tabelas

Erros cometidos na prática, que comprometem o desempenho

Leia os diversos tópicos abaixo, aonde tento chamar a atenção dos participantes sobre as falhas cometidas e que prejudicam o desempenho.  Para isso, será necessário se registrar no fórum.

Bom estudo!


 

 


36 comentários

Raimundo Bacabal   23/07/2013 14:14:15

Olá Avelino,
Parabéns por mais esta contribuição.

Abs,

Raimundo Bacabal
Secom/PR

Welson Zeferino de Oliveira Junior   23/07/2013 14:18:05

Avelino, simplesmente fantástico.

Edson Junho   24/07/2013 09:18:17

Mestre Avelino,

Não consegui encontrar como foi arquitetada a função =fncMontaSaldo()
Onde fica o código?
Um abraço.

Avelino Sampaio   24/07/2013 09:27:55

Edson,

está no VBA do formulário frmMovimentoCaixa. É logo uma das primeiras funções da lista do VBA.

Sucesso!

Edson Junho   24/07/2013 11:03:43

Mestre, encontrei a função mas onde ficam os critérios para 3 dias, 7 dias... do salmo do último movimento. A montagem da função. o Call.

Sergio Nishimura   24/07/2013 11:37:02

Faz tempo que eu tenho esse problema, já estava até pensando em pedir uma dica sobre isso ao mestre Avelino, e de repente, puff! Já está aí a solução!

Walter Florêncio   24/07/2013 11:59:42

Parabéns Avelino. Suas dicas são fundamentais para nosso aprendizado.

Edson   25/07/2013 08:52:25

Mestre,

Encontrei, mas não consegui destrinchar o uso do filtro do grupo de opções para 3 dias, 15 dias....
Se puder....

Julio G.S.   25/07/2013 10:48:30

Avelino, Meus parabéns e obrigado pela AULA que nós dá em seus códigos, são limpos e maravilhosos, uma arquitetura, perfeita, dá gosto de estudá-la. Obrigado!

Caio - Tbls temporárias   26/07/2013 10:09:40

Avelino, bom dia!
Estou lendo vários artigos seus, inclusive em outros sites. Sobre o uso de tabelas temporárias, faço uso desta vantagem a muito tempo. Só que deixo uma tabela já criada no front-end com 10 campos textos, 19 campos de números, 10 de datas, etc. Não crio varias tabelas e sim apenas esta temporária.

Assim, em cada formulário que for usar dados provenientes dela, acrescento a consulta exclusão padrão e uma outra para adicionar novos dados a tbl (de acordo com cada forms). Neste caso, o campo texto1 de minha tabela pode equivaler a "Nome do cliente" em um forms e ao mesmo tempo a "Cidade do cliente" em outro forms. Foi uma forma que achei útil por ter conhecimento limitadíssimo em ADO.

Em termos de performance, você acha que isso é produtivo ou me aconselha a partir para ADO mesmo?

OBS: todas as demais tabelas são vinculadas, estão em rede e são usadas por diversos usuários.

Sucesso!

Diogo Gomes   29/08/2013 00:48:14

Boa noite Avelino gostaria de saber se vc poderia me ajudar com um problema, eu estou tentando fazer um extrato Bancario em uma impressora nao fiscal e nao to conseguindo gostaria de saber se vc poderia distrinchar isso pra mim, ou ate mesmo se vc pudexe implementar tudinho ai e me falasse qnto era q eu ate pagava vc.
De ja agradeço.
Diogo Gomes
email: topgun-000@hotmail.com
Aguardo retorno parceiro.

Anibal Assis   19/10/2013 08:12:44

Avelino
Neste seu exemplo só dá para movimentar um (1) Banco.
Como fazer para movimentar + que 1 Banco ?
Obrigado



Avelino Sampaio   21/10/2013 06:18:40

Anibal,

observe que na tabela tblMovimento existe o campo IdCaixa. Altere o valor deste campo, que é de 24 para 1
Crie uma tabela chamada de tblCaixas ou tblBancos. Chame o campo Autonumeração desta tabeça de idCaixa
Abra esta tabela tblCaixas e acrescente um banco
E por fim crie o relacionamente de UM PARA MUITOS entre as duas tabelas
No formulário crie uma Combobox com a lista de bancos, origem na tabela tblCaixas
A ListBox deve ser filtrada de acordo com o caixa selecionado na combobox

Sucesso!

Armando   13/11/2013 14:26:37

Avelino,
Entendo muito pouco de acess mas preciso de uma consulta que crie uma tabela de saldos (ano, mes, saldo) a partir de uma tabela que tem : ano, mes, credito, debito. É sensato isso? O fato é que imaginei que tendo saldo de "ano, mes" fica fácil trabalhar.
Muito obrigado!

Jorge Luís Pontes   19/11/2013 14:37:03

Excelente iniciativa!

Antonio de Padua e Silva   07/12/2013 19:37:35

Avelino, boa tarde,

Como funciona na tabela o controle de contas bancárias? (saldo+depósitos)-(cheques+despesas). Essas informações constam naquela 1a. fase do curso que o senhor me mandou?

Obrigado

Tico   25/02/2014 15:45:39

Boa Tarde!!! Caro Avelino tenho a seguinte necessidade:

no Excel tenho a tabela;

linha 1: coluna A coluna B
linha 2: carro 1
linha 3: carro 2
linha 4: moto 2

se a linha posterior repetir na coluna A e Coluna B = 2 para ter uma resposta basta eu colocara a seguinte fórmula: =SE(E(A3=A2;B2=2);1;"") com base em uma tabela do mesmo tipo é possível fazer uma consulta no ACCESS 2007 com esta expressão?

Ralph Kanya   21/05/2014 00:26:54

Avelino,
Gostaria de sua ajuda no sentido de que seu programa MOvimentoConta, se eu lanco um movimento futuro (depois da data de hoje) ele soma no saldo atual, como faco para nao aparecer no historico e nao somar no saldo

grato pela compreensao

Ralph kanya

Avelino Sampaio   21/05/2014 04:09:50

Ralph,

sugiro acrecentar um campo do tipo sim/não. Realize a soma somente dos registros que tiverem o campo marcado como SIM(TRUE).

Sucesso!

Carlos Roberto   15/10/2014 04:11:25

Avelino!
Em 21/10 respondeste ao Anibal este assunto...
==============================================================
observe que na tabela tblMovimento existe o campo IdCaixa. Altere o valor deste campo, que é de 24 para 1
Crie uma tabela chamada de tblCaixas ou tblBancos. Chame o campo Autonumeração desta tabeça de idCaixa
Abra esta tabela tblCaixas e acrescente um banco
E por fim crie o relacionamente de UM PARA MUITOS entre as duas tabelas
No formulário crie uma Combobox com a lista de bancos, origem na tabela tblCaixas
A ListBox deve ser filtrada de acordo com o caixa selecionado na combobox
================================================
Não seria melhor criar uma tabela de Contas. Conta Bancos e Conta Caixa, coloco desta forma pois o saldo em linha, poderia também ser usado em uma conta de Caixa certo?

Evanildo Conceição   21/11/2014 17:04:01

Um dia com fé em Deus eu chego lá. Parabéns!

Mauricio Mendes   01/12/2014 11:23:28

Amigo Avelino,

Você tem um modelo de um aplicativo semelhante a esse para controle de caixa, com relatórios mensais.
tenho pouca experiência em Access tou tentado montar e ainda não conseguir.
Esses exemplo me ajudou muito, mas ainda não consegui construir.

Paulo Cruz   25/02/2015 17:38:41

Amigo Avelino, parabéns por todos os teus trabalhos, brother sobre esse saldo linha a linha eu quero saber como que eu faço pra ter o saldo de varias pessoas no mesmo aplicativo, abraço, Deus abençoe

Avelino Sampaio   26/02/2015 07:32:13

Paulo,

observe que na tabela tblMovimento existe o campo IdCaixa. Altere o valor deste campo, que é de 24 para 1
Crie uma tabela chamada de tblCaixas ou tblBancos. Chame o campo Autonumeração desta tabeça de idCaixa
Abra esta tabela tblCaixas e acrescente um banco
E por fim crie o relacionamente de UM PARA MUITOS entre as duas tabelas
No formulário crie uma Combobox com a lista de bancos, origem na tabela tblCaixas
A ListBox deve ser filtrada de acordo com o caixa selecionado na combobox

Sucesso!

Marcelo Pontes   06/04/2015 10:15:13

E se tivéssemos que entrar no mérito do IdCaixa, se ele assumisse diversos valores, como ficaria o critério em sua consulta.

Entendo que isto é fundamental pois e comum existir diversas contas.

Não consegui estabelecer um critério neste sentido.

Marcelo Pontes   07/04/2015 09:48:23

Complementando meu comentário anterior, na verdade onde consigo um tutorial para aprender quando usar aspas duplas, aspa simples, &., [] ;e outros comandos que não tem para mim um significado lógico mas são fundamentais para definição de um critério !!!!

É possível modificar o critério de sua formula abaixo de forma a atender esta necessidade !!!!

saldo: Nz(DSoma("[valorCredito]-[valorDebito]";"tblMovimento";"idmovimento <=" & [idMovimento]);[valorCredito]-[valorDebito])

Marcelo Pontess   22/04/2015 17:05:39

Em 06/04 enviei comentário e até 22 04 não obtive o menor retorno, com isto a credibilidade de apoio conforme prometido em sua propaganda se vê abalada.
Estava disposto em aproveitar sua promoção mas passei a reavaliar considerando o presente fato.
Os meus comentários anteriores podem não ter o menor sentido mas acho que merecem atenção, conforme prometido.

Avelino Sampaio   23/04/2015 07:21:13

Marcelo

peço desculpas pela falta de retorno. Tem momentos que a demanda no pedido de ajuda é muito grande e acabo tendo que priorizar as pessoas que compraram meu material. Pelo que entendi neste seu caso, basta acrescentar na filtragem o campo idcaixa. Exemplo:

saldo: Nz(DSoma("[valorCredito]-[valorDebito]";"tblMovimento";"idcaixa = " & [idcaixa] & " AND idmovimento <=" & [idMovimento]);[valorCredito]-[valorDebito])

Quanto ao tutorial, peço que veja este meu:

"Referenciar objetos Forms e Reports e às suas propriedades"

Quanto ao uso dos colchetes "[]" na consulta são para identificar os campos da própria consulta.

Sucesso!

Marcelo Pontes   08/05/2015 19:44:42

Avelino e se tivermos a necessidade de entrar no mérito da data da movimentação para apurarmos o saldo ao final de cada dia.

Tentei desta forma " saldo: Nz(DSoma("[valorCredito]-[valorDebito]";"tblMovimento";"idcaixa = " & [idcaixa] & "AND DataMovimento <=" & [DataMovimento] & " AND idmovimento <=" & [idMovimento]);[valorCredito]-[valorDebito]) mas não deu certo. Onde errei !!! É considerando as características de um campo Data !!!"
Tive o cuidado de ordenar a consulta em função da data e observei que os idMovimento não mantem ordem lógica.

Giovanni Paiva   26/05/2015 12:45:18

Boa tarde Avelino!

Esse exemplo facilitou eu muito o meu projeto, porém estou com uma dificuldade que com certeza para você é muito facil.

Preciso que no formulário /relatório tenha um cabeçalho com os dados idcaixa, nomebanco, nragencia, nr conta. Já incluí os campos na tabela tblmovimento e criei uma rotina para atualizar essa tabela de acordo com o banco selecionado, criei no formulário um campo com o nome lista2 mas não estou conseguindo fazer com que os dados idcaixa, nomebanco,nragencia e nrconta apareçam nesse campo.

Desde já obrigado pela ajuda.

Marcelo Pontes   01/06/2015 11:05:23

Ratifico meu comentário de 08/05/2015 que até o momento não foi possível sua atenção.

Com os meus comentários acho que já ficou claro as minhas dificuldades e pergunto onde no material do seu site conseguirei uma evolução.

Marcelo Pontes 08/05/2015 19:44:42

Avelino e se tivermos a necessidade de entrar no mérito da data da movimentação para apurarmos o saldo ao final de cada dia.

Tentei desta forma " saldo: Nz(DSoma("[valorCredito]-[valorDebito]";"tblMovimento";"idcaixa = " & [idcaixa] & "AND DataMovimento <=" & [DataMovimento] & " AND idmovimento <=" & [idMovimento]);[valorCredito]-[valorDebito]) mas não deu certo. Onde errei !!! É considerando as características de um campo Data !!!"
Tive o cuidado de ordenar a consulta em função da data e observei que os idMovimento não mantem ordem lógica.

Antonio Izzo Junior   16/09/2016 12:26:02

Bom Dia!!!

Achei muito bom esse tutorial, porque veio de interesse no sistema que estou desenvolvendo, "contabilidade descomplicada", e estava justamente com certa dificuldade em fazer os relatórios das contas, no modo sistema bancário. Vou aproveitar e depois envio meu comentário.
Mas me interessou também receber o Download do site, depois entro em contato para saber com fazer.

Abraço

Regina   27/10/2016 14:17:25

Necessito ajuda:
Duas tabelas: Empenho (valor) e Pagamento (valor em R$) com campo chave Doc.

1º empenho - 1ºpagamento = saldo 1 publicar o saldo 1
(saldo1 + 2º empenho) - 2ºpagamento = saldo 2 publicar o saldo 2
(saldo2 + 3º empenho) - 3ºpagamento = saldo 3 publicar o saldo 3

Pode ter linhas sem empenho ou pagamento.
Isso vai gerar um display e um relatório.

Regina Cely

tem novo empenho? 2º empenho +saldo 2 - 3º pagamento

Avelino Sampaio   27/10/2016 14:37:36

Regina,

traga a questão para o nosso fórum.

http://www.redeaccess.com.br

Procure um Bd exemplo, para que possamos te ajudar mais rápido.

Aguardamos

Regina   03/11/2016 18:04:17

Avelino, levei para o fórum. Meu banco de dados não é muito simples mas dentro dele tem essas duas tabelas: Empenho e Pagamento.

Empenho contém: cod; número, valor e data.
Pagamento contém: entre outras:cod; nº empenho valor em r$ e dt pg.

Além do trabalho de registro fazemos um display da situação do pagamento. Se tem empenho pra tudo etc?

Tenho uma consulta e relatório que calculam pelo nº de empenho, mas fura, empenho -pagamento pode não se ter empenho e só se ter o saldo anterior.

Teofilo   24/01/2017 00:25:28

Avelino
Estou a criar uma folha de caixa em access, com três opções de movimento: por caixa, pelo banco e por TPA. Queria que na opção do movimento por caixa, quando o saldo de caixa for insuficiente para o movimento a débito o cancelasse com a respectiva msg: Saldo insuficiente.
Como não tenho conhecimentos para isso, agradecia a sua ajuda.
Obrigado


Envie seu comentário: