Delphi Posição DBGrid

08/03/2017

35

Bom dia Pessoa..

Tenho um grid em meu formulário onde quando clico no Title ele ordena os registros contidos em uma query...

Ex:
qry.close;
qry.sql.clear;
qry.sql.add(sql);
qry.Open;


O problema é que ao abrir é que ao abrir e fechar a query, a barra de rolagem do dbgrid não fica posicionada no mesmo lugar antes de clicar, sendo assim, ele vai para a primeira coluna novamente ao abrir a query...

Até setei o index do dbgrid novamente após abrir a query, ele volta para o mesmo lugar sim, porém na tela não fica no mesmo lugar....

Até fiz um vídeo para demonstrar, vejam que ao clicar no titulo a coluna se move, justamente pelo fato de abrir e fechar a query novamente, que é necessária para realizar outro order by nos dados...

https://www.youtube.com/watch?v=D20uw-XyO50

Muito Obrigado desde já..
Responder

Post mais votado

08/03/2017

Use um ClientDataSet com o Provider pontando pra sua Query; o DataSource do DBGrid apontando pro ClientDataSet.

No lugar de fazer Open e Close da Query, você passa o Column.FieldName pro IndexFieldNames do ClientDataSet; ele vai ordenar em memória.
Responder

Mais Posts

08/03/2017

Jones Granatyr

Olá! Uma vez precisei fazer algo parecido e resolvi da seguinte maneira

* Cria uma variável para armazenar o registro selecionado
* Antes de fazer a ordenação, essa variável global recebe o ID do registro selecionado
* Depois de ordenar, você faz um Locate no DataSet para posicionar onde estava clicado
Responder

08/03/2017

Alberto

Tente usar a propriedade indexfieldnames no click do titulo
Desse modo vc não precisa fechar e abrir a query toda vez.
Responder
Olá! Uma vez precisei fazer algo parecido e resolvi da seguinte maneira

* Cria uma variável para armazenar o registro selecionado
* Antes de fazer a ordenação, essa variável global recebe o ID do registro selecionado
* Depois de ordenar, você faz um Locate no DataSet para posicionar onde estava clicado


Então, não é bem isso que preciso localizar a linha, preciso é localizar a coluna... Você viu o vídeo? Já consegui localizar a coluna também pegando o selectedIndex do dbgrid antes de fechar a query, porém a barra de rolagem não para no mesmo lugar....
Responder
Use um ClientDataSet com o Provider pontando pra sua Query; o DataSource do DBGrid apontando pro ClientDataSet.

No lugar de fazer Open e Close da Query, você passa o Column.FieldName pro IndexFieldNames do ClientDataSet; ele vai ordenar em memória.


Raylan, você diz substituir o ClientDataSet pela query? Acho que não entendi... como ficara feita a ligação...
Responder
Use um ClientDataSet com o Provider pontando pra sua Query; o DataSource do DBGrid apontando pro ClientDataSet.

No lugar de fazer Open e Close da Query, você passa o Column.FieldName pro IndexFieldNames do ClientDataSet; ele vai ordenar em memória.


Raylan, você diz substituir o ClientDataSet pela query? Acho que não entendi... como ficara feita a ligação...

Como apontar o ClientDataSet para a query??
Responder

08/03/2017

Raylan Zibel

o Provider pontando pra sua Query
Responder
E o clienteDataSet, ligo ele onde?
Responder

09/03/2017

P2

Como assim ? ligo ele aonde?
Responder

09/03/2017

P2

Dê uma olha no exemplo :Link do Exemplo
Responder
Como assim ? ligo ele aonde?


Entendo sua explicação, acredito que irá funcionar, porém terei que fazer uma modificação bastante grande no meu projeto. Pois hoje ele trabalha o.o, tenho somente um formulário pai padrão, quando chamo a tela de clientes, fornecedores, estoque, etc, informo somente o sql e o resto fica tudo pronto.... dessa forma que você disse terei que criar um clientdataset para cada quero certo?
Responder

10/03/2017

Raylan Zibel

O ClienteDataset seria apenas pra visualizar/manusear os dados em memoria. Teoricamente a mudança seria de algumas linhas, apontar um DataSource, adicionar os Fields. Mas depende muito de como você escreveu até agora..

Pra continuar apenas com a Query e manter o foco no mesmo registro depois de fazer o Close Open pra ordenar, você precisaria guardar o ID do registro atual, reordenar, e fazer um Locate na Query pra focar novamente nele... O que pode não ser possível, dependendo do componente Query que está trabalhando.

Fechar e Abrir Query pra reordenar consome recurso desnecessariamente. Mas vê aí o que acha melhor.
Responder
O ClienteDataset seria apenas pra visualizar/manusear os dados em memoria. Teoricamente a mudança seria de algumas linhas, apontar um DataSource, adicionar os Fields. Mas depende muito de como você escreveu até agora..

Pra continuar apenas com a Query e manter o foco no mesmo registro depois de fazer o Close Open pra ordenar, você precisaria guardar o ID do registro atual, reordenar, e fazer um Locate na Query pra focar novamente nele... O que pode não ser possível, dependendo do componente Query que está trabalhando.

Fechar e Abrir Query pra reordenar consome recurso desnecessariamente. Mas vê aí o que acha melhor.


Entendido.. Geralmente qual estrutura de conexões você usa...

Estou usando o firebird,,

Pra cada tabela estou usando uma query com clientDataSet, Provider e DataSource para connsulta de dados e para inserção e update de dados uso um ibtable...

Existe uma forma alternativa mais eficiente e que use menos componentes??
Responder

10/03/2017

Raylan Zibel

O ibdataset tem Locate. Daria pra usar.

Se está começando um projeto, eu não recomendaria usar os componentes Interbase e sim DBExpress. Se for um Delphi mais novo, estude FireDac.

O problema não é a quantidade de componentes, mais a limitação deles. O quanto você vai ter que quebrar a cabeça pra fazer algo que já está disponível de outra forma. Nem sempre o caminho mais rápido é o mais fácil.
Responder
O ibdataset tem Locate. Daria pra usar.

Se está começando um projeto, eu não recomendaria usar os componentes Interbase e sim DBExpress. Se for um Delphi mais novo, estude FireDac.

O problema não é a quantidade de componentes, mais a limitação deles. O quanto você vai ter que quebrar a cabeça pra fazer algo que já está disponível de outra forma. Nem sempre o caminho mais rápido é o mais fácil.


Entendi.. O locate não resolve meu problema.. Ele é muito lento quando a tabela tem muito registro e fica limitado, uso um filtro bem complexo.... Ex tabela de cliente... Filtrar clientes com nome contendo sousa, que mora no bairro centro, com idade de 18 a 40 anos, com data de ultima compra inferior a uma determinada data.....

estou usando o delphi 10 seatle...

Agora outra duvida...

Estoque...
Suponhamos que 3 computadores funcinoando fazenda vendas ao mesmo tempo...

O produto de codigo 1, tem 3 unidades em estoque...

Suponhamos que um dos vendedores adicione as 3 unidades para vender em seu sistema e ao mesmo tempo no outro computador outro vendedor consulte o estoque e adicione mais 1, total de 4 unidades a serem vendidas sendo que meu estoque tem apenas 3...

Como tratar essa situaçao???

Pensei em dar um comiit no banco cada vez que o vendedor adicionar o produto, dessa forma quando o outro vendedor consultar o estoque estaria disponível somente o que realmente estaria disponível para vender.... porém dando um comiit a cada produto adicionado eu poderia gerar o seguinte problema ( E se no meio da venda o cliente desistir de comprar, eu teria que cancelar a emissão do pedido, dessa forma teria que executar update retornando as unidades para o estoque..) deu pra entender?
Responder

10/03/2017

Raylan Zibel

Eu faria a saída usando uma stored procedure. Se o cliente cancela, precisa ter função de estorno.
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar