Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Renanbg

Identificar registros selecionados

Recommended Posts

Bom dia pessoal.

Estou fazendo um pequeno sistema de compras em delphi + firebird.

 

A ideia é a seguinte:

 

Tenho a tabela de compras e itens_compras. Na itens_compras, os usuarios vão inserindo suas requisições de compras. Então quando acesso essa tela, uma sql lista todas os itens cujo status seja pendente.

 

O proximo passo é selecionar os itens que se deseja comprar, clicar num botão que vai abrir uma nova janela onde vou escolher um fornecedor e um prazo de entrega. Para isso bolei essa rotina:

//Insere os dados na tabela de compras
  frmdm.qrCompras.Append;

  frmdm.qrComprasFORNECEDOR_COD.AsInteger:= StrToInt(Edit1.Text);
  frmdm.qrComprasDATA_COMPRA.AsDateTime:= Date;
  frmdm.qrComprasPREV_RECEBIMENTO.AsDateTime:= DateTimePickerEntrega.Date;

  frmdm.spCompras.ParamByName('TABELA').AsString := 'COMPRAS';
  frmdm.spCompras.ExecProc;
  frmdm.qrComprasCODIGO.AsInteger := frmdm.spCompras.ParamByName('RESULT').AsInteger;
  frmdm.qrCompras.Post;
  frmdm.trCompras.CommitRetaining;

  //atualiza itens com os dados da compra
  qrSelecionados.Close;
  qrSelecionados.SQL.Clear;
  qrSelecionados.SQL.Add('Update ITENS_COMPRAS set NUM_PEDIDO = :CODCOMPRA, STATUS = "COMPRADO"');
  qrSelecionados.SQL.Add('Where SELECIONADO = 1');
  qrSelecionados.parambyname('CODCOMPRA').AsInteger:= frmdm.spCompras.ParamByName('RESULT').AsInteger;
  qrSelecionados.ExecSQL;

  //marca os selecionados para 0 pra evitar que sejam atualizados na proxima compra
  qrSelecionados.Close;
  qrSelecionados.SQL.Clear;
  qrSelecionados.SQL.Add('Update ITENS_COMPRAS set SELECIONADO = 0');
  qrSelecionados.SQL.Add('Where SELECIONADO = 1');
  qrSelecionados.ExecSQL;

  Mensagem:= 'Compra realizada com sucesso.';
  Application.MessageBox(Pchar(Mensagem),'Gestão de Compras RM',mb_ok+MB_ICONINFORMATION); 

Até funciona bem, mas o grande problema está nesse update pois se, durante o fechamento da compra, outro usuario selecionar um registro, esse update vai acabar marcando como comprando um item que não devia.

qrSelecionados.SQL.Add('Where SELECIONADO = 1');

Alguma sugestão de como melhorar isso?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo bom dia.

 

Eu vejo duas possíveis soluções.

 

1- Você trabalhar os dados em memória (usando o clientdataset) e no final realizar a gravação na sua tabela em seu banco de dados.

 

2- Você manter da forma que está, e acrescentar o usuário como parte da condição na hora de atualizar sua tabela. Dessa maneira, por mais que outro usuário mexa, você trata pra somente o que fez o lançamento dos itens é que atualize o registro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Jeferson.

 

Não estou usando clientdataset, então pensei no seguinte:

 

Como eu poderia armazenar numa variavel o CODIGO de todos os registros que estiverem com o campo SELECIONADO = 1 ?

 

Dessa forma eu daria o update nos codigos dos itens e evitaria atualizar algum item que pudesse ser marcado durante essa ação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo!

 

Então, eu acredito que o mais viável no seu caso seria você incluir uma coluna com o código do usuário que está fazendo o lançamento, mas pq?

 

Por que no momento de alterar o valor da coluna selecionado, ou fazer qualquer outra operação, as mudanças serão aplicadas ao usuário que as fez, sem afetar os outros registros que consequentemente outros usuários lançaram/alteraram.

 

Exemplo:

 

Imagine que o usuário Jeferson cujo código de cadastro é o 13 lançou um item cujo código é 100. Na hora de alterar a coluna selecionado, sua instrução seria semelhante a isso:

update [ TABELA ]
set selecionado = 1
where usuario = 13
  and codigo  = 100
 

Da forma como você fez, ele vai aplicar o valor 1 para todos os registros da sua tabela, cujo valor seja Zero, ou seja, não tem um critério para ser obedecido somente para aquela situação.

 

Da forma acima que exemplifiquei, acredito que você consiga resolver seu problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Na verdade da forma que eu tenho hoje, eu seleciono um item por vez, usando esse codigo. Apertando o botão novamente remove a seleção.

Isso já está perfeito.

 

Só preciso de uma rotina pra atualizar o campo STATUS dos itens selecionados para "COMPRADO".

Não tem uam forma de passar os selecionados, e armazenar os codigos de cada um numa variavel e depois dar o update um a um colocando o CODIGO na clausula WHERE?

  frmdm.qrItensCompras.Edit;
  frmdm.qrItensCompras.FieldByName('SELECIONADO').AsInteger := IfThen(frmdm.qrItensCompras.FieldByName('SELECIONADO').AsInteger = 1, 0, 1);
  frmdm.qrItensCompras.Post;

Complementando a ideia, achei uma dica que ao inves de atualizar, deleta os itens selecionados. Só precisaria adaptar para que ao inves de pegar os registros pelo selectrows, pegaria os que tem o campo selecionado = 1

 

Consegue me ajudar a modificar ela?

var sCodigos:String;
      qryAux : TQuery;
begin
if Application.MessageBox('Deseja realizar a exclusão destes registros?' , 'Aviso' ,Mb_OkCancel) = IDOk then
     begin
       sCodigos := '';
        for cont := 0 to Pred(dbGrid1.SelectedRows.Count) do
           sCodigos := sCodigos + QUERY.FieldByName('CODIGO').asstring+',';
        sCodigos := Copy(sCodigos,1,Length(Trim(sCodigos))-1);
       //Vc terá algo do tipo sCodigos = 1,3,9,10
       qryAux : TQuery.Create(Self);
       with qryAux do
       begin
          databasename := "Nome_do_seu_Alias";
          with SQL do
          begin
              Clear;
              Add('delete FROM TABELA WHERE CODIGO IN ('+sCodigo+');
              ExecSQL;
          end;
       end;
     end;
end

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo!

 

Se eu entendi, os itens que foram comprados ficam com a coluna selecionado = 1, certo?

 

Se estiver certo, você poderia fazer o seguinte:

update [ TABELA ]
set status = "SEU STATUS"
where selecionado = 1
  and codigo = [ Aqui teria que ser o código "mestre" da tabela, que diferencia os registros, por exemplo o código da compra ]

Não sei se você compreendeu a idéia?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Os itens comprados ficam com o campo STATUS = COMPRADO. O campo SELECIONADO volta a ficar "zero".

 

O problema está bem na ultima linha que você colocou, preciso de um codigo mestre para essas linhas selecionadas, mas não estão achando um meio. Por isso postei aquele codigo acima que vai pegar a ID de cada registro.

 

Porem aquele codigo é usado pra pegar as linhas selecionadas atraves do comando SelectedRows do dbgrid e eu preciso muda-lo pra pegar o campo selecionado = 1.

 

consegue me ajudar a adaptar?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo!

 

Eu entendi a sua necessidade, só não "aceito" a forma de resolver por visualizar uma solução de certa forma mais simples para o seu problema, eu acho que você não entendeu a idéia que eu te passei, então vamos por partes:

 

Você possuí duas tabelas, sendo elas:

compras - Grava o cabeçalho do registro;
itens_compras - Grava os itens que serão comprados.

 

Quando você pressiona o botão para incluir uma nova "compra", eu imagino que você gere um código de controle que seja único e utilizado para identificar os registros em sua tabela de compras. Sendo assim, quando você preenche o "Cabeçalho", você vai para a parte dos "Itens". Quando você pressiona o botão para lançar os itens, a tabela itens_compras deve ter um campo cuja informação seja a mesma que foi gerada para o código da tabela compras. Essa informação é a "chave" para identificar os itens ao cabeçalho.

 

Exemplificando:

 

Ao iniciar um novo lançamento, imagine que o campo código que foi gerado seja 11.

 

Ao iniciar o lançamento/seleção dos itens, imagine que pra cada item, exista também o mesmo código, nesse caso 11.

 

Seguindo desse princípio, você conseguiria atualizar sua tabela dessa maneira:

 

update itens_compras
set status = "COMPRADO",

selecionado = 0
where selecionado = 1
and codigo = 11

Entendeu?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ola Jeferson.

 

Entendi sim sua colocação, mas o problema é que o processo de incluir pedido aqui é diferente. Vou te citar o passo a passo pra você entender.

 

Na tabela itens_compras estão listadas as "necessidades de compras" da empresa. Como funciona?

Cada vez que o estoque de um item está baixo, um usuario vai lá e lança esses dados

descrição item
quantidade
prioridade(normal, urgente..etc)
Status(pendente ou comprado) esse campo o sistema automaticamente coloca como pendente sem a intervenção do usuario

O comprador acessa essa tela e visualiza somente as compras com STATUS = PENDENTE.

 

Em seguida ele marca as que vai comprar atualizando o campo SELECIONADO para 1 atraves desse codigo

  frmdm.qrItensCompras.Edit;
  frmdm.qrItensCompras.FieldByName('SELECIONADO').AsInteger := IfThen(frmdm.qrItensCompras.FieldByName('SELECIONADO').AsInteger = 1, 0, 1);
  frmdm.qrItensCompras.Post;

Daí ele clica num botão que executa essa SQL. Onde vai abrir uma nova janela mostrando somente os selecionados e dando a opção de escolher o fornecedor onde vai fechar o pedido e definir o prazo de entrega


  //Lista todos os itens que foram marcados
  Application.CreateForm(TFrmFinalizaPedido, FrmFinalizaPedido);
  FrmFinalizaPedido.qrSelecionados.Close;
  FrmFinalizaPedido.qrSelecionados.SQL.Clear;
  FrmFinalizaPedido.qrSelecionados.SQL.Add('SELECT * FROM ITENS_COMPRAS WHERE SELECIONADO = 1 and STATUS = "PENDENTE"');
  FrmFinalizaPedido.qrSelecionados.Prepare;
  FrmFinalizaPedido.qrSelecionados.Open;

  if FrmFinalizaPedido.qrSelecionados.RecordCount > 0 then
     FrmFinalizaPedido.ShowModal
  else
     Application.MessageBox(PWideChar('Não existem produtos selecionados.'), 'Gestão de Compras RM', MB_ICONWARNING + MB_OK);

Por fim, neste mesmo formulario, por meio de um botão chamado finalizar pedido, é executrado esse codigo para gravar o cabeçalho da venda e atualizar a tabela itens_compras

  frmdm.qrCompras.Append;

  frmdm.qrComprasFORNECEDOR_COD.AsInteger:= StrToInt(Edit1.Text);
  frmdm.qrComprasDATA_COMPRA.AsDateTime:= Date;
  frmdm.qrComprasPREV_RECEBIMENTO.AsDateTime:= DateTimePickerEntrega.Date;

  frmdm.spCompras.ParamByName('TABELA').AsString := 'COMPRAS';
  frmdm.spCompras.ExecProc;
  frmdm.qrComprasCODIGO.AsInteger := frmdm.spCompras.ParamByName('RESULT').AsInteger;
  frmdm.qrCompras.Post;
  frmdm.trCompras.CommitRetaining;

  //atualiza itens com os dados da compra
  qrSelecionados.Close;
  qrSelecionados.SQL.Clear;
  qrSelecionados.SQL.Add('Update ITENS_COMPRAS set NUM_PEDIDO = :CODCOMPRA, STATUS = "COMPRADO"');
  qrSelecionados.SQL.Add('Where SELECIONADO = 1');
  qrSelecionados.parambyname('CODCOMPRA').AsInteger:= frmdm.spCompras.ParamByName('RESULT').AsInteger;
  qrSelecionados.ExecSQL;

  //marca os selecionados para 0 pra evitar que sejam atualizados na proxima compra
  qrSelecionados.Close;
  qrSelecionados.SQL.Clear;
  qrSelecionados.SQL.Add('Update ITENS_COMPRAS set SELECIONADO = 0');
  qrSelecionados.SQL.Add('Where SELECIONADO = 1');
  qrSelecionados.ExecSQL;

Como você pode ver, o processo aqui é meio que inverso. Eu não incluo itens no pedido, mas seleciono os que estão na lista de compras e gravo tanto o cabeçalho como os itens no final.

 

Por isso precisaria obter o codigo dos selecionados para usar no update da itens_compras

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo!

 

Compreendi o processo. A única forma que vejo para você resolver isso seria o seguinte:

 

Quando o comprador click no item que ele precisa comprar, você teria um flag na tabela itens_compras que faria esse item não ser "exibido" para outras pessoas que fossem acessar a mesma tela que você. Se você desmarcar o item, ai ele voltaria a ser exibido. Dessa maneira, como o item não é exibido quando estiver marcado por quem estiver manipulando, você conseguiria fazer a atualização que precisa.

 

A única obs é que você teria que ter o código do usuário que marcou o item, e fazer com que mesmo ele estando marcado, só seja exibido para a pessoa que o marcou.

 

Conseguiu entender?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Jeferson.

Entendi sua colocação.

Hoje já tenho um flag, que marca o campo SELECIONADO = 1 ou 0.

Eu poderia ao mesmo tempo tornar o registro invisivel, porém isso não resolve o problema do meu update.

 

Veja que meu update leva em conta o seguinte

where selecionado = 1

Logo, se alguem marcar outro registro, meu update vai atualizar um item que não desejo. Por isso eu acredito que a unica forma é capturar a ID dos registros que selecionei. Assim não tem como errar.

 

Você conhece uma forma de capturar a ID dos registros cujo campo SELECIONADO = 1 ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa noite amigo.

 

Não consegui enxergar o problema que você menciona, no entanto acredito que o código abaixo corresponde a sua pergunta:

 

Você conhece uma forma de capturar a ID dos registros cujo campo SELECIONADO = 1 ?

 

update itens_compras
set selecionado = 0
where id = ( select id 
             from itens_compras 
             where selecionado = 1 )

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá. Acho que não estamos nos entendendo ,,hehehe

 

Vamos lá... Meu problema está nesse update. Preciso atualizar o status para comprado e o num_pedido com o numero da compra. Do jeito que está ja funciona, mas como voce pode ver, eu dou esse update me baseando somente nos registros selecionados = 1

  qrSelecionados.Close;
  qrSelecionados.SQL.Clear;
  qrSelecionados.SQL.Add('Update ITENS_COMPRAS set NUM_PEDIDO = :CODCOMPRA, STATUS = "COMPRADO"');
  qrSelecionados.SQL.Add('Where SELECIONADO = 1');
  qrSelecionados.parambyname('CODCOMPRA').AsInteger:= frmdm.spCompras.ParamByName('RESULT').AsInteger;
  qrSelecionados.ExecSQL;

Para que esse comando seja eficaz eu preciso colocar na clausula where que atualize alem do selecionado = 1 and codigo = codigo do item selecionado.

 

Mas porque?

 

Imagine que eu selecionei 3 registros.

Mas nesse meio tempo um outro usuario selecionou 2 registros.

Quando eu deu o update, vou aplicar as alterações em 5 registros, quando devia ser em 3

 

Aí se eu conseguir incluir o codigo do item no "where" desse update, certamente vou atualizar somente os meus 3 registros.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá amigo!

 

Sinceramente, não sei como posso de ajudar. Confesso que já li e reli várias vezes desde o início, e confesso que tenho como resolver seu problema dentre as formas que te passei, mas você diz que não dá.

 

Se tiver interesse, me mande uma mensagem em privado e te passo um contato.

 

:thumbsup:

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.