Jump to content

Recommended Posts

Posted

Boa Tarde a todos

Agradeço ajuda a fim de perceber a razão do que apresento.

Tenho uma aplicação para uso pessoal feita por mim em VB.

Quando executo a rotina para apresentar resultados entre datas (Ex. DataInicial  2025-01-01 e DataFinal 2025-09-03) só me apresenta  1 Registo, 

se eu mudar o ano da DataInicial para 2024-01-01

a consulta apresenta os registos todos correspondentes. ao Ano 2025

Segue o código da rotina

NOTA: 1 Tenho o mesmo programa no portatil e funciona bem com a mesma rotina

            2 Base Dados Access 

Dim DataInicio = Format(DateTimePicker1.Value, "yyyy-MM-dd")     

   Dim DataFim = Format(DateTimePicker2.Value, "yyyy-MM-dd")                     

 Dim ConnectionString As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Users\Justino\Documents\DespesasCaseiras\DespesasPessoaisFamiliares.mdb;")    

    Dim Query As String = "SELECT Id,Data,Designacao,Despesa,Categoria,SubCategoria,Familiar FROM DadosActuais Where Data BETWEEN '" & DataInicio & "' AND '" & DataFim & "' AND Categoria Like '" & Trim(TextBox1.Text.ToString) & "%' AND SubCategoria Like '" & Trim(TextBox2.Text.ToString) & "%' AND Familiar Like '" & Trim(TextBox3.Text.ToString) & "%' Order By Id"      

  Dim DataAdapter As New OleDbDataAdapter(Query, ConnectionString)      

 Dim MyData As New DataSet      

  DataAdapter.Fill(MyData, "DadosActuais")      

  ' Neste caso utilizei uma datagridview para visualizar os dados      

  Me.DataGridView1.DataSource = MyData.Tables("DadosActuais")        

'Conta as linhas da Grid e coloca na Label      

  Label1.Text = Nothing       

 Label1.Text = "Este Filtro encontrou - " & Me.DataGridView1.RowCount - 1 & " Registos"     

   Button2.Enabled = True       

      ConnectionString.Close()       

 Call ControlaGrid()      

  Call SomarColunas()
Posted

Não sei se ajuda, terá de experimentar... usei o chatgpt (que também se engana...) e obtive, de uma forma resumida, esta resposta:

Access não entende o formato yyyy-MM-dd (esse é formato ISO, usado no SQL Server ou MySQL).

No Access, as datas devem ser no formato americano MM/dd/yyyy.

Além disso, devem estar delimitadas por # em vez de '.

Exemplo correto:

SELECT * FROM Tabela WHERE Data BETWEEN #01/01/2025# AND #09/03/2025#

O facto de no portátil funcionar pode ser porque lá o regional settings do Windows aceitam o formato de data que você está a gerar, mas no outro PC não.

Como você está a concatenar a string SQL, está a passar as datas entre aspas ' em vez de #, e ainda por cima no formato yyyy-MM-dd, que pode ser interpretado errado no Access, daí só aparecer 1 registo.

Dim DataInicio As String = "#" & Format(DateTimePicker1.Value, "MM/dd/yyyy") & "#"
Dim DataFim As String = "#" & Format(DateTimePicker2.Value, "MM/dd/yyyy") & "#"


Dim Query As String = "SELECT Id, Data, Designacao, Despesa, Categoria, SubCategoria, Familiar " &
                      "FROM DadosActuais " &
                      "WHERE Data BETWEEN ? AND ? " &
                      "AND Categoria Like ? " &
                      "AND SubCategoria Like ? " &
                      "AND Familiar Like ? " &
                      "ORDER BY Id"

Dim cmd As New OleDbCommand(Query, ConnectionString)
cmd.Parameters.AddWithValue("?", DateTimePicker1.Value.Date)
cmd.Parameters.AddWithValue("?", DateTimePicker2.Value.Date)
cmd.Parameters.AddWithValue("?", Trim(TextBox1.Text) & "%")
cmd.Parameters.AddWithValue("?", Trim(TextBox2.Text) & "%")
cmd.Parameters.AddWithValue("?", Trim(TextBox3.Text) & "%")

Dim DataAdapter As New OleDbDataAdapter(cmd)

 

Assim não depende de formato nenhum.

Posted

Obrigado desde já pela atenção Fausto Luís

Tentei com os dados por si apresentados e não funcionou

Retornei aos dados que tinha, e constato que com ao recuar  com a DataInicial para o ano 2023 ou 2022 funciona, não funciona com 2024 e 2025

Estou a dar em maluco

Posted

O que parece estranho é funcionar no portátil.

De qualquer forma, a sugestão de usar parâmetros no seu query, parece-me a mais indicada, O '#' antes e depois de uma data, também é usada, por norma, no Access.
O que posso sugerir mais:

1. Coloque um break-point  em'Dim DataAdapter As New OleDbDataAdapter(Query, ConnectionString)'; verifique qual o conteúdo de 'Query' e copie o seu conteúdo
2. No Access, crie um novo query e cole. Execute e vá alterando os valores para as datas, para ver se descobre onde possa estar o problema; assim, escusa de estar sempre a alterar o código, compilar, executar, ...
3. Uma vez que o programa corre sem problemas no portátil, parece que  problema possa estar no formato (cultura) das datas que tem definidas nesse pc

Outra coisa que não entendo bem, é o porquê de tantos 'AND' no seu query, mas não conheço a aplicação; se só quer o intervalo entre datas...; ou seja o problema poderá estar nos dados em si, que não são datas, mas que estão no query;

Usei o Access muito tempo, mas apenas para criar protótipos rápidos; se só o usa para armazenar dados, sugiro que experimente outros motores de dados; como o seu programa é para uso pessoal, se não processar muitos registos, o SQLite (por exemplo) ajusta-se perfeitamente.

Foram os meus 5 cêntimos

Posted (edited)

Bom dia Fausto

Uma pergunta faço eu. Será por ter muitos registos na BD Access (12697).

Faço uma busca a partir de 2009 até 2025, e só aparecem registos até 2023 (estou a usar a sua rotina)

Edited by Chamuanza
Acrescentar dados
Posted

Questiono se não haverá alguma parametrização que esteja a limitar a extração de registos, à semelhança do TOP no SQL Server ou do LIMIT no MySQL.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Posted

O mais problemático, a meu ver, é que o programa funciona no portátil... no query apresentado, não existe 'TOP' ou qualquer outra coisa pareceida... por isso apontei alternativas, como debug e execução do query em Access;, sem esquecer o uso de '#' nas datas... 

De 2009 a 20023 tudo parece ok, certo? quando faz o query em Access de 01/01/2024 até 31/12/2025, não tem qualquer registo? Experimente com a data.fim 12/31/2026; tem erro? Com o mesmo MDB no portátil mostra tudo o que esperava? Estranho...  lembre-se, as datas no Access usam o prefixo e sufixo '#; veja na documentação.

12697registos? em todas as tabelas, ou o programa só usa uma? tem relacionamentos, chaves estrangeiras para relacionar outras tabelas, etc? Tudo isso ocupa espaço no MDB... Se o MDB ficar grande (> 100 MB), por exemplo, pense em alternaticas; a migração será pacífica.

No limite, envie o mdb em formato zip, com algus registos (reais com datas anteriores a 2024 e alguns com datas posteriores;; talvez assim consiga uma melhor análise

Posted (edited)

Após criar a tabela em Access, inseri alguns registos com dados fictícios:
 

ID    Data    Designacao    Despesa    Categoria    SubCategoria    Familiar
1    21/01/2023    Designacao 2023    1000    Categoria 1    Sub categoria 1 da categoria 1    Familiar 1
2    21/04/2025    Designacao 2025    250    Categoria 1    Sub categoria 2 da categoria 1    Familiar 1
3    05/01/2009    Designacao 2025    350    Categoria 2009    Sub categoria 1 da categoria 2009    Familiar 2
4    01/06/2024    Designacao 2024    125    Categoria 2024    Sub categoria 1 da categoria 2024    Familiar 3

Query: todos os registos:
 

Citação

 

SELECT DadosGerais.Id, DadosGerais.Data, DadosGerais.Designacao, DadosGerais.Despesa, DadosGerais.Categoria, DadosGerais.SubCategoria, DadosGerais.Familiar
FROM DadosGerais
WHERE Data Between #01-01-2009# and #31-12-2025#

 

Resutado:

Id    Data    Designacao    Despesa    Categoria    SubCategoria    Familiar
1    21/01/2023    Designacao 2023    1000    Categoria 1    Sub categoria 1 da categoria 1    Familiar 1
2    21/04/2025    Designacao 2025    250    Categoria 1    Sub categoria 2 da categoria 1    Familiar 1
3    05/01/2009    Designacao 2025    350    Categoria 2009    Sub categoria 1 da categoria 2009    Familiar 2
4    01/06/2024    Designacao 2024    125    Categoria 2024    Sub categoria 1 da categoria 2024    Familiar 3



Query para datas de 2024 a 2025:
 

Citação

SELECT DadosGerais.Id, DadosGerais.Data, DadosGerais.Designacao, DadosGerais.Despesa, DadosGerais.Categoria, DadosGerais.SubCategoria, DadosGerais.Familiar
FROM DadosGerais
WHERE Data Between #01-01-2024# and #31-12-2025#

Resultado:

Id    Data    Designacao    Despesa    Categoria    SubCategoria    Familiar
2    21/04/2025    Designacao 2025    250    Categoria 1    Sub categoria 2 da categoria 1    Familiar 1
4    01/06/2024    Designacao 2024    125    Categoria 2024    Sub categoria 1 da categoria 2024    Familiar 3

Tudo feito dentro do Access... parece funcionar

Ou o problema poderá na configuração standard que tem para datas no seu sistema, ou o seu programa tem algum bug na formatação das datas; confirma que o mesmo programa funciona bem num outro dispositivo? Já comparou  configuração de cada um deles (nomeadamente o formato das datas?

 

 

Edited by Fausto Luís
typos
Posted

As limitações não necessitam de ser explicitas na query, podem ser implicitas. Por exemplo, o MySQL Workbench, não dizendo nada, só retorna X linhas.
A configuração do sistema, ou da connection string, pode levar a um corte. Um exemplo simples de compreender é o valor de timeout, que pode ser controlado em vários locais e de várias formas.

Há uma forma simples para ajudar a despistar o problema.
Em vez de se executar um select * executa-se um select count para compreender quantos registos são efetivamente selecionados.
Recordo que as datas, devido aos seus inumeros formatos, pode causar alguns dissabores. Podemos ter 01/12/2025 e enquanto um português lê 1 de dezembro de 2025, o sistema informático pode ler 12 de janeiro de 2025. Os formatos é outro parametro que pode ser manipulado em vários locais.

10 REM Generation 48K!
20 INPUT "URL:", A$
30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50
40 PRINT "404 Not Found"
50 PRINT "./M6 @ Portugal a Programar."

 

Posted

Um bem aja Fausto

Já dei conta do problema

1º Tive que alterar na tabela do Access a coluna da Data para Data estava como Texto

2º Fiz o Select conforme o código

 Dim Query As String = "SELECT Id,Data,Designacao,Despesa,Categoria,SubCategoria,Familiar FROM DadosActuais Where Data BETWEEN #" & DataInicio.ToString("yyyy-MM-dd") & "# AND #" & DataFim.ToString("yyyy-MM-dd") & "# And Categoria Like '" & Trim(TextBox1.Text.ToString) & "%' AND SubCategoria Like '" & Trim(TextBox2.Text.ToString) & "%' AND Familiar Like '" & Trim(TextBox3.Text.ToString) & "%' Order By Id"

Obrigado pela atenção, não tendo a certeza acho que possa ter havido alteração em alguma actualização do Windows

Posted (edited)

Ainda bem. que resolveu. Uma última sugestão: nos seus queries com "WHERE" use sempre parâmetros como boa prática (tem exemplos nas respostas anteriores):

. Impede que entradas maliciosas alterem a lógica da query
. Ao usar parâmetros, o plano de execução da query pode ser reutilizado pelo banco de dados, porque a estrutura da consulta não muda.
          Raw queries com strings diferentes em cada execução podem gerar múltiplos planos desnecessários.
          Consultas parametrizadas mantêm a mesma estrutura, apenas mudando os valores.

Usar parâmetros poupa o trabalho de 'escapar' aspas, barras, e outros caracteres especiais, que podem causar erros ou vulnerabilidades

Além disso, o seu query parece-me de difícil leitura;, demasiado longo, o que não facilita a sua manutenção..  Experimente usar o StringBuilder.

Abraço

 

Edited by Fausto Luís

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.