Ir para conteúdo
Fórum Script Brasil
  • 0

Autocompletar Fotmulario


Carlos Rocha

Pergunta

Ola pessoal, estou usando Delphi 7, MySql Server e Zeos.

Estou com um formulario onde coloquei um ZConnection.

Coloquei uma Ztable e conectei bem a tabela.

Puxei os itens da tabela pro formulario e puz um DBControl pra as operações mais comuns(postar, alterar).

Agora quero fazer o seguinte:

Uma vez que já foram cadastrados "n" clientes na tabela, queria que quando abrisse o formulario acotecessem 2 coisas:

1) O formulario viesse vazio e não com os campos do ultimo cadastro preenchido e após cadastrar desse uma mensagem de "Cadastro OK" e depois voltasse o form vazio de novo.

2) Gostaria de, usando os DBEdits colocados o form fazer um sistema de busca.

- Por exemplo: são os campos, nome, endereço, cpf...etc...

Como fazer para, ao começar digitar o nome de uma pessoa ele autocompletasse o resto do nome e tambem autocompletasse os outros dados que estão na tabela tipo nome, endereço, cpf...etc...

Porem, gostaria de fazer isso de forma tal que por exemplo:

Ao escrever:

Carl

Completa o restante do nome carlos ou carla mas tambem quando tivesse completasse carlos e eu tirasse o "os" carl, ele apagasse os dados do carlos pois não existe o cliente "carl" e, apos colocasse "Carla", ele completasse os dados da carla.

Me ajudem nessa aí pessoal.

Muito Obrigado.

Link para o comentário
Compartilhar em outros sites

18 respostass a esta questão

Posts Recomendados

  • 0
...

Puxei os itens da tabela pro formulario e puz um DBControl pra as operações mais comuns(postar, alterar).

Agora quero fazer o seguinte:

Uma vez que já foram cadastrados "n" clientes na tabela, queria que quando abrisse o formulario acotecessem 2 coisas:

1) O formulario viesse vazio e não com os campos do ultimo cadastro preenchido e após cadastrar desse uma mensagem de "Cadastro OK" e depois voltasse o form vazio de novo.

Utilizando componentes dataware, você não irá ter os campos vazios - eles só ficam neste estado quando você utiliza Insert ou Append (isso sem atribuição de valores padrão). Mesmo que você utilize uma função para limpar os DBEdit's, tipo DBEdit1.Text := '', quando você mover o foco para dentro do componente o texto correspondente ao campo ao qual ele está vinculado será apresentado.

A mensagem você consegue acrescentando no evento AfterPost da sua ZTable um: ShowMessage('Cadastro OK');

2) Gostaria de, usando os DBEdits colocados o form fazer um sistema de busca.

- Por exemplo: são os campos, nome, endereço, cpf...etc...

Como fazer para, ao começar digitar o nome de uma pessoa ele autocompletasse o resto do nome e tambem autocompletasse os outros dados que estão na tabela tipo nome, endereço, cpf...etc...

Porem, gostaria de fazer isso de forma tal que por exemplo:

Ao escrever:

Carl

Completa o restante do nome carlos ou carla mas tambem quando tivesse completasse carlos e eu tirasse o "os" carl, ele apagasse os dados do carlos pois não existe o cliente "carl" e, apos colocasse "Carla", ele completasse os dados da carla.

A princípio (vai que alguém já conseguiu - eu não), não daria para implementar isto num DBEdit. Ainda que utilizando Edit's, o que você quer não é impossível, mas é meio chato de gerenciar, já que:

- digitanto "para a frente", ao digitar "carl" você quer posicionar no primeiro nome similar (p.e. "carlos") e auto-completar os outros dados, mas;

- digitanto "para trás" (back-space), ao apagar "os" e ficando novamente com "carl", você quer que ele apague os dados auto-completados (o oposto da primeira situação).

Para fazer o que você quer, eu acredito que a melhor opção seria utilizar TEdit's.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Veja só:

O código abaixo faz com que a comboboxCli retorne os nomes dos clientes da tabela de clientes.

À medida que vou digitando cada letra(tipo C, Ca, Car, Carl, Carlo, Carlos) dos nomes dos clientes, a combobox completa o resto dos nome do cliente.

Até aí tudo bem!

procedure TFormCotacoes.ComboBoxCliChange(Sender: TObject);
begin
   if (ZTableCotacoes.State in [dsInsert,dsEdit]) then //Verifica se a tabela esta em estado de edição ou inserção
   begin
   ZqryClientes.Close;
   ZqryClientes.ParamByName('Nome').Value:=ZTableCotacoesNomeCli.Value;
   ZqryClientes.Open;
   ZqryClientes.Refresh;
   ZqryClientes.First;
     //Verifica se encontrou
    while not ZqryClientes.EOF do
    begin
    ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));
    ZqryClientes.Next;
    end;
   end
end;

Agora eu preciso fazer o seguinte:

A medida que eu troco o cliente na ComboboxCli, de Carlos para Antonio, os campos CPF, CI, Telefone, etc... mudem tambem de cliente para cliente

Link para o comentário
Compartilhar em outros sites

  • 0

Carlos Rocha, este código está funcionando como esperado?

você não colocou o conteúdo de sua query, mas parece-me que você está procurando na tabela clientes, os dados do cliente cadastrado na tabela cotações:

   ZqryClientes.Close;
   ZqryClientes.ParamByName('Nome').Value:=ZTableCotacoesNomeCli.Value;
   ZqryClientes.Open;
e desta forma, se você encontra terá possivelmente apenas um registro como resultado. Do contrário, não terá nenhum. Assim sendo, esta outra parte do código faria com que o combobox1 tivesse apenas um registro ou nenhum:
   ZqryClientes.Refresh; // *** não é necessário, você acabou de abrir a consulta 
   ZqryClientes.First;
    //Verifica se encontrou
   while not ZqryClientes.EOF do
   begin
     ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));
     ZqryClientes.Next;
   end;

aliás, se for encontrado um cliente este será adicionado ao ComboBox e a lista irá crescer a cada cliente encontrado, já que apenas ao encontrar você adiciona o cliente a lista do combo.

Como você colocou este procedimento dentro do evento OnChange do ComboBox1, a cada vez que o texto no combobox for alterado (por digitação ou seleção da lista) ele executará exatamente a mesma coisa.

Entendi errado?

Dê uma conferida, porque não tenho certeza no momento, mas deve existir um método AsString no componente field da query da Zeos lib. Neste caso, você poderia substituir a linha:

ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));

por

ComboBoxCli.Items.Add(ZqryClientesNome.AsString);

Agora eu preciso fazer o seguinte:

A medida que eu troco o cliente na ComboboxCli, de Carlos para Antonio, os campos CPF, CI, Telefone, etc... mudem tambem de cliente para cliente

para fazer isso, primeiramente você deverá ter incluído estes campos na sua query aonde você busca os dados de um determinado cliente (imagino que seja ZqryClientes). Com isto, após posicionar corretamente o cliente (imagino que você quizesse fazeri isso no procedimento acima), bastaria mover os campos para os edit's desejados.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Micheus!

Obrigado pela dica.

O Conteudo da query é:

Select * from clientes order by Nome;
E tem um parametro "Nome" O código que estou usando completo é o seguinte
procedure TFormCotacoes.ComboBoxCliChange(Sender: TObject);
begin
   if (ZTableCotacoes.State in [dsInsert,dsEdit]) then //Verifica se a tabela esta em estado de edição ou inserção
   begin
   ZqryClientes.Close;
   ZqryClientes.ParamByName('Nome').Value:=ZTableCotacoesNomeCli.Value;
   ZqryClientes.Open;
   ZqryClientes.First;
     //Verifica se encontrou
    while not ZqryClientes.EOF do
    begin
    ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));
    ZqryClientes.Next;
    end;
     if not ZqryClientes.IsEmpty then
       begin
         ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
         ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
         ZTableCotacoesLocal_Cobranca.Value:=ZqryClientesEndereco.Value;
         ZTableCotacoesCPF.Value:=ZqryClientesCpf.Value;
         ZTableCotacoesCNPJ.Value:=ZqryClientesCNPJ.Value; 
       end
     else
       begin
         ZTableCotacoesCodigo_Cliente.AsString:='';
         ZTableCotacoesLocal_Cobranca.AsString:='';
         ZTableCotacoesCPF.AsString:='';
         ZTableCotacoesCNPJ.AsString:='';
       end
   end
end;

essa parte nova é que faz preencher os outros campos(CPF,Tel,Endereço, etc...)

Porem, qualquer que seja o Cliente escolhido, só esta dando os dados do 1° cliente cadastrado.

E agora????????????

Link para o comentário
Compartilhar em outros sites

  • 0
O Conteudo da query é:

Select * from clientes order by Nome;
E tem um parametro "Nome"
desculpe-me, mas acho que falta a declaração do parâmetro neste SQL:
Select * 
from clientes 
where Nome like :Nome 
order by Nome;
e daí para filtrar apenas o segmento digitado e popular uma lista com tudo o que começa com o que foi digitado, você adicionaria o '%' ao final da string procurada quando utilizar o ParamByName.
O código que estou usando completo é o seguinte
procedure TFormCotacoes.ComboBoxCliChange(Sender: TObject);
begin
   if (ZTableCotacoes.State in [dsInsert,dsEdit]) then //Verifica se a tabela esta em estado de edição ou inserção
   begin
     ZqryClientes.Close;
     ZqryClientes.ParamByName('Nome').Value:=ZTableCotacoesNomeCli.Value;
     ZqryClientes.Open;
     ZqryClientes.First;
   //Verifica se encontrou
     while not ZqryClientes.EOF do
     begin
       ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));
       ZqryClientes.Next;
     end;
     if not ZqryClientes.IsEmpty then
     begin
       ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
       ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
       ZTableCotacoesLocal_Cobranca.Value:=ZqryClientesEndereco.Value;
       ZTableCotacoesCPF.Value:=ZqryClientesCpf.Value;
       ZTableCotacoesCNPJ.Value:=ZqryClientesCNPJ.Value; 
     end
     else
     begin
       ZTableCotacoesCodigo_Cliente.AsString:='';
       ZTableCotacoesLocal_Cobranca.AsString:='';
       ZTableCotacoesCPF.AsString:='';
       ZTableCotacoesCNPJ.AsString:='';
     end;
   end;
end;
essa parte nova é que faz preencher os outros campos(CPF,Tel,Endereço, etc...)
Exclareça-me: 1) que informações você pretende adicionar a ComboBox1? Seria uma lista de pessoas que comecem com o nome informado em CotacoesNomeCli? Se for vale o primeiro comentário que fiz. 2) você realmente tem e mantém as informações do cliente duplicadas nas duas tabelas Clientes e Cotações? 3) como você buscaria os dados corretos do cliente, desta forma, se por acaso puderem haver clientes homônimos? você sempre estará posicionando no primeiro que encontrar. lembre-se, se você está obtendo uma possível lista de clientes para popular sua ComboBox1, é de imaginar que se realmente foi digitado o nome parcial e você quer atualizar os demais campos para o primeiro cliente da lista, você terá que após chegar ao fim da lista no while..do, novamente mover o apontador do dataset para a primeira linha:
...
     while not ZqryClientes.EOF do
     begin
       ComboBoxCli.Items.Add(VarToStr(ZqryClientesNome.Value));
       ZqryClientes.Next;
     end;
     ZqryClientes.First;  // *** <=== Posiciona no primeiro cliente compatível
     if not ZqryClientes.IsEmpty then
...

Porem, qualquer que seja o Cliente escolhido, só esta dando os dados do 1° cliente cadastrado.

E agora????????????

será que isto não estaria associado ao primeito comentário?

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

O que eu quero é popular a combobox com os clientes cadastrados na Tabela Clientes do Banco de Dados.

A medida que escolho(troco) o cliente na combobox, os outros campos que tenho que preencher da tabela Cotacoes, sejam automaticamente preenchidos com os dados particulares de cada Cliente escolhido na combobox.

Com respeito ao autocompletamento do combobox, é o seguinte:

Preciso fazer uma consulta na tabela de clientes de forma tal que, se eu começar a digitar o nome de um cliente cadastrado, ele se auto-complete.

Link para o comentário
Compartilhar em outros sites

  • 0
O que eu quero é popular a combobox com os clientes cadastrados na Tabela Clientes do Banco de Dados.
para isto, supondo a declaração do parâmetro na SQL da sua ZqryClientes (conforme propus no post anterior), você faz algo como: criar um procedimento para popular sua lista:

procedure TFormCotacoes.PopulaComboBox;
begin
  ComboBoxCli.Items.Clear;
  ZqryClientes.Close;
 // com o % vamos buscar todos os clientes
  ZqryClientes.ParamByName('Nome').Value := '%'; 
  ZqryClientes.Open;
  while not ZqryClientes.EOF do
  begin
    ComboBoxCli.Items.Add(ZqryClientesNome.AsString);
    ZqryClientes.Next;
  end;
end;
Não esqueça de alterar a propriedade Sorted=True no seu ComboBoxCli.
A medida que escolho(troco) o cliente na combobox, os outros campos que tenho que preencher da tabela Cotacoes, sejam automaticamente preenchidos com os dados particulares de cada Cliente escolhido na combobox.
como o conteúdo que você digita é o desejado de ser procurado, no evento OnChange que ocorre quando você digita na caixa de texto do combobox ou seleciona um item dela, é que iremos posicionar o item da tabela cliente:
procedure TFormCotacoes.ComboBoxCliChange(Sender: TObject);
begin
  //Verifica se a tabela esta em estado de edição ou inserção
  if (ZTableCotacoes.State in [dsInsert,dsEdit]) then
  begin
    ZqryClientes.Close;
   // copiamos o texto na caixa da combobox so início até a posição do cursor
   // se você está digitando, será o sub-string digitado; se for uma seleção será todo o texto
    ZqryClientes.ParamByName('Nome').AsString := Copy(ComboBoxCli.Text, 1, ComboBoxCli.SelStart +'%');
    ZqryClientes.Open;
    if not ZqryClientes.EOF then
    begin
      ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
      ZTableCotacoesCodigo_Cliente.Value:=ZqryClientesId.Value;
      ZTableCotacoesLocal_Cobranca.Value:=ZqryClientesEndereco.Value;
      ZTableCotacoesCPF.Value:=ZqryClientesCpf.Value;
      ZTableCotacoesCNPJ.Value:=ZqryClientesCNPJ.Value;
    end
    else
    begin
      ZTableCotacoesCodigo_Cliente.AsString:='';
      ZTableCotacoesLocal_Cobranca.AsString:='';
      ZTableCotacoesCPF.AsString:='';
      ZTableCotacoesCNPJ.AsString:='';
    end;
  end;
end;
Com respeito ao autocompletamento do combobox, é o seguinte: Preciso fazer uma consulta na tabela de clientes de forma tal que, se eu começar a digitar o nome de um cliente cadastrado, ele se auto-complete.
Acho que é o que você vai conseguir com a sugestão acima. Dê uma conferida. Importante: a sua combobox deve ser populada a cada inclusão ou edição, porque podem ocorrer inclusões na sua tabela Clientes por outro usuário. No momento em que você coloca a tabela em edição ou inserção, você deve chamar o procedimento que popula a lista (PopulaComboBox). No caso específico decolocar no modo edição, você tem que posicionar seu ComboBox no cliente correto. Então, teria que executar algo como:
begin
  ...
  PopulaComboBox;
  ComboBoxCli.ItemIndex := ComboBoxCli.Items.IndexOf(NomeCliente_em_cotacoes);
end;

Me diga se captou a idéia. Observei que você mudou alguns campos. você não tem mais o campo nome na tabela de cotações? Porque se agora tem apenas o código, teremos que fazer alguns ajustes no exemplo que coloquei acima, já que precisará olhar o codigo.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Micheus!

Quero te agradecer pelo esforço em me ajudar mais o que estou querendo, parece-me ser dar um passo maior que minhas pernas.

Sou novo em Delphi e só queria fazer um programinha de cotrole de pedidos que tivesse:

1) Formulario de Cadastro de Clientes;

2) Formulario de Cadastro de Fornecedores;

3) Formulario de Cadastro de Produtos;

4) Formulario de Cadastro de Pedidos;

5) Formulario de Impressao dos Pedidos;

Nos Formularios de Cadastro de Clientes e Fornecedores, eu gostaria de fazer aquele squema que ao começar digitar o nome do novo Cliente, autocomplete os dados do cliente já cadastrado para servir de alerta pro Digitadornão correr o risco de cadastrar "Joao José" sendo que "João José" já esta cadastrado.

No Formulario de Cadastro de Pedidos, eu queria fazer igual aqueles programinhas de cadastro feito em DOS que a medida que voce digita o nome do produto e da enter, os outros campos, Preço, Descrição são auto preenchidos.

Usando Zeos Lib no Delphi 7 com MySql.

Tentei muito mas num deu.

Mesmo assim quero agradecer pelo boa vontade em ajudar.

Caso você teha algum fonte que te ajudou nos teus estudos e possa me passar.......Eu agradeço.

Valeu.

Carlos Rocha

E-mail: carcleo@oi.com.br

MSN: carcleo1999@hotmail.com

Link para o comentário
Compartilhar em outros sites

  • 0

Rapaz, depois de muito mexer acabei decobrindo outro erro que não estou conseguindo descobrir.

Quando mando gravar um novo registro no "V" do DBNavigator, a operação não é realizada, em da erro.

Porem, se tiver algum registro na tabela para alterar, ele altera normalmente.

E agora?

Link para o comentário
Compartilhar em outros sites

  • 0
Rapaz, depois de muito mexer acabei decobrindo outro erro que não estou conseguindo descobrir.

Quando mando gravar um novo registro no "V" do DBNavigator, a operação não é realizada, em da erro.

Porem, se tiver algum registro na tabela para alterar, ele altera normalmente.

Que erro seria esse? Qual a mensagem? Não teria relação com uma chave não inicilizada - campo nulo?

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Michael.

Num da erro nenhum. Só não grava.

vê mais essa então pra min por favor:(Vou acabar conseguindo)

To testando um código que encotrei:

procedure TCPedidos.RecalculaPedido;
var
  TmpTable:TTable;
    TmpTable := TTable.Create(Application);
  Total:Currency; // armazena valores do tipo moeda
begin
    // cria um objeto Table via codificação
    TmpTable := TTable.Create(Application);
    try
        // define DatabaseName e TableName via codificação
        TmpTable.DatabaseName := TableItens.DatabaseName;
        TmpTable.TableName := TableItens.TableName;
        TmpTable.Open;
        TmpTable.FindKey([TablePedidosCodigoPedido.AsInteger]);
        Total := 0; // inicializa a variavel totalizadora
        while (not TmpTable.Eof) and
           (TmpTable.FieldByName('NumeroPedido').AsInteger = TablePedidosNumeroPedido.AsInteger) do
         begin
             // Acumula o Total da linha
             Total := Total + (TmpTable.FieldByName('preço').AsCurrency * TmpTable.FieldByName('Quantidade').AsFloat);
             TmpTable.Next; // próximo registro
         end;
     finally
         TmpTable.Close; // fecha a tabela
         TmpTable.Free; // libera objeto da memória
     end;
     StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total);
 end;
Mas está danda os seguintes erros:
Build
  [Error] CadPedidos.pas(160): ',' or ':' expected but ':=' found
  [Error] CadPedidos.pas(160): ',' or ':' expected but '(' found
  [Error] CadPedidos.pas(164): Record, object or class type required
  [Error] CadPedidos.pas(164): Statement expected, but expression of type 'Enumeration' found
  [Error] CadPedidos.pas(167): Record, object or class type required
  [Error] CadPedidos.pas(167): Undeclared identifier: 'DatabaseName'
  [Error] CadPedidos.pas(168): Record, object or class type required
  [Error] CadPedidos.pas(169): Record, object or class type required
  [Error] CadPedidos.pas(170): Record, object or class type required
  [Error] CadPedidos.pas(172): Record, object or class type required
  [Error] CadPedidos.pas(176): Record, object or class type required
  [Error] CadPedidos.pas(176): Missing operator or semicolon
  [Error] CadPedidos.pas(176): Record, object or class type required
  [Error] CadPedidos.pas(176): Missing operator or semicolon
  [Error] CadPedidos.pas(178): EXCEPT or FINALLY expected
  [Error] CadPedidos.pas(179): 'END' expected but 'FINALLY' found
  [Error] CadPedidos.pas(183): Declaration expected but identifier 'StaticTextTotal' found
  [Error] CadPedidos.pas(184): '.' expected but ';' found
  [Error] CadPedidos.pas(257): Undeclared identifier: 'FindKey'
  [Error] CadPedidos.pas(338): Undeclared identifier: 'FindKey'
  [Fatal Error] SaneRio.dpr(15): Could not compile used unit 'CadPedidos.pas'
Eis o codigo todo, onde sera que esta o erro:
unit CadPedidos;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, DBCtrls, Grids, DBGrids, ExtCtrls, DB,
  ZAbstractRODataset, ZAbstractDataset, ZAbstractTable, ZDataset, Mask;

type
  TCPedidos = class(TForm)
    PanelDados: TPanel;
    PanelBotoes: TPanel;
    DBGridItens: TDBGrid;
    DBNavigatorPedidos: TDBNavigator;
    SpdBtnAlterar: TSpeedButton;
    SpdBtnIncluir: TSpeedButton;
    SpdBtnProcurar: TSpeedButton;
    SpdBtnCancelar: TSpeedButton;
    SpdBtnGravar: TSpeedButton;
    SpdBtnExcluir: TSpeedButton;
    BitBtnFechar: TBitBtn;
    TablePedidos: TZTable;
    TableItens: TZTable;
    TableClientes: TZTable;
    TableProdutos: TZTable;
    DSPedidos: TDataSource;
    DSItens: TDataSource;
    TablePedidosCodigoPedido: TIntegerField;
    TablePedidosCondicaoPgto: TStringField;
    TablePedidosCodigoCliente: TIntegerField;
    TablePedidosNomeCli: TStringField;
    TablePedidosLocalFatura: TStringField;
    TablePedidosLocalCobranca: TStringField;
    TablePedidosLocalEntrega: TStringField;
    TablePedidosCPF_CNPJ: TStringField;
    TablePedidosCEP: TStringField;
    TablePedidosDataCadastro: TDateField;
    TableClientesCodigoCliente: TIntegerField;
    TableClientesNome: TStringField;
    TableClientesTipo: TStringField;
    TableClientesEndereco: TStringField;
    TableClientesEmail: TStringField;
    TableClientesBairro: TStringField;
    TableClientesCidade: TStringField;
    TableClientesEstado: TStringField;
    TableClientesTelefone: TStringField;
    TableClientesCPF_CNPJ: TStringField;
    TableClientesDataCadastro: TDateField;
    TablePedidosNomeCliente: TStringField;
    TableProdutosCodigoProduto: TIntegerField;
    TableProdutosDescricao: TStringField;
    TableProdutosPrecoUni: TIntegerField;
    TableItensItem: TIntegerField;
    TableItensCodigoProduto: TIntegerField;
    TableItensQuantidade: TIntegerField;
    TableItensPrecoUni: TIntegerField;
    TableItensDescricao: TStringField;
    TableItensTotal: TCurrencyField;
    TableItensNumeroPedido: TIntegerField;
    LabelCodigoPedido: TLabel;
    DBEditCodigoPedido: TDBEdit;
    LabelCondicaoPagamento: TLabel;
    DBEditCondicaoPagamento: TDBEdit;
    LabelCodigoCliente: TLabel;
    DBEditCodigoCliente: TDBEdit;
    LabelNomeCliente: TLabel;
    DBLookupComboBoxNomeCliente: TDBLookupComboBox;
    LabelLocalFatura: TLabel;
    DBEditLocalFatura: TDBEdit;
    LabelLocalCobranca: TLabel;
    DBEditLocalCobranca: TDBEdit;
    LabelLocalEntrega: TLabel;
    DBEditLocalEntrega: TDBEdit;
    LabelCPF_CNPJ: TLabel;
    DBEditCPF_CNPJ: TDBEdit;
    LabelCEP: TLabel;
    DBEditCEP: TDBEdit;
    LabelDataCadastro: TLabel;
    DBEditDataCadastro: TDBEdit;
    LabelTotalPedido: TLabel;
    StaticTextTotal: TStaticText;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TablePedidosNewRecord(DataSet: TDataSet);
    procedure TableItensCalcFields(DataSet: TDataSet);
    procedure TableItensNewRecord(DataSet: TDataSet);
    procedure TableItensBeforeInsert(DataSet: TDataSet);
    procedure TableItensBeforePost(DataSet: TDataSet);
    procedure DBGridItensKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure TableItensCodigoProdutoValidate(Sender: TField);
    procedure TablePedidosDataCadastroSetText(Sender: TField;
      const Text: String);
    procedure SpdBtnIncluirClick(Sender: TObject);
    procedure SpdBtnAlterarClick(Sender: TObject);
    procedure SpdBtnExcluirClick(Sender: TObject);
    procedure SpdBtnGravarClick(Sender: TObject);
    procedure SpdBtnCancelarClick(Sender: TObject);
  private
    procedure AtivarControles(Ativar: Boolean);
    procedure RecalculaPedido;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  CPedidos: TCPedidos;

implementation

{$R *.dfm}

procedure TCPedidos.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree; // remove o form da memória
CPedidos := NIL; // informa que foi destruído (não criado
end;

procedure TCPedidos.FormCreate(Sender: TObject);
begin
TableProdutos.Open;
TableClientes.Open;
TablePedidos.Open;
TableItens.Open;
end;

procedure TCPedidos.FormDestroy(Sender: TObject);
begin
TableProdutos.Close;
TableClientes.Close;
TablePedidos.Close;
TableItens.Close;
end;

procedure TCPedidos.TablePedidosNewRecord(DataSet: TDataSet);
begin
TablePedidosDataCadastro.AsDateTime := Date; //inicia com a data atual
end;

procedure TCPedidos.AtivarControles(Ativar: Boolean);
begin
    PanelDados.Enabled := Ativar;
    DBNavigatorPedidos.Enabled := (not Ativar);
    DBGridItens.ReadOnly := (not Ativar);
    SpdBtnIncluir.Enabled := (not Ativar);
    SpdBtnAlterar.Enabled := (not Ativar);
    SpdBtnExcluir.Enabled := (not Ativar);
    SpdBtnGravar.Enabled := Ativar;
    SpdBtnCancelar.Enabled := Ativar;
    SpdBtnProcurar.Enabled := (not Ativar);
end;


procedure TCPedidos.RecalculaPedido;
var
  TmpTable:TTable;
    TmpTable := TTable.Create(Application);
  Total:Currency; // armazena valores do tipo moeda
begin
    // cria um objeto Table via codificação
    TmpTable := TTable.Create(Application);
    try
        // define DatabaseName e TableName via codificação
        TmpTable.DatabaseName := TableItens.DatabaseName;
        TmpTable.TableName := TableItens.TableName;
        TmpTable.Open;
        TmpTable.FindKey([TablePedidosCodigoPedido.AsInteger]);
        Total := 0; // inicializa a variavel totalizadora
        while (not TmpTable.Eof) and
           (TmpTable.FieldByName('NumeroPedido').AsInteger = TablePedidosNumeroPedido.AsInteger) do
         begin
             // Acumula o Total da linha
             Total := Total + (TmpTable.FieldByName('preço').AsCurrency * TmpTable.FieldByName('Quantidade').AsFloat);
             TmpTable.Next; // próximo registro
         end;
     finally
         TmpTable.Close; // fecha a tabela
         TmpTable.Free; // libera objeto da memória
     end;
     StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total);
 end;

procedure TCPedidos.TableItensCalcFields(DataSet: TDataSet);
begin
if (TableItensQuantidade.AsFloat > 0) and
        (TableItensPrecoUni.AsCurrency > 0) then
        TableItensTotal.AsCurrency := TableItensPrecoUni.AsCurrency * TableItensQuantidade.AsFloat;
        RecalculaPedido; // recalcula e exibe novamente
end;

procedure TCPedidos.TableItensNewRecord(DataSet: TDataSet);
begin
TableItensQuantidade.AsFloat := 1;
DBGridItens.SelectedIndex := 0; //código
end;

procedure TCPedidos.TableItensBeforeInsert(DataSet: TDataSet);
begin
if TablePedidosCodigoPedido.AsString = '' then
    begin
        if TablePedidos.State = dsInsert then
        begin
            // grava para salvar o número do pedido na tabela pai
            TablePedidos.Post;
            // ativa a alteração novamente
            TablePedidos.Edit;
        end;
    end;
end;

procedure TCPedidos.TableItensBeforePost(DataSet: TDataSet);
begin
 if TableItensNumeroPedido.AsString = '' then
        TableItensNumeroPedido.AsInteger := TablePedidosCodigoPedido.AsInteger;
    if TableItensCodigoProduto.AsString = '' then
    begin
        DBGridItens.SelectedIndex := 0; // seleciona a coluna código
        ShowMessage('Código do produto deve ser informado!');
        Abort; // interrompe a gravação
    end;
    if TableItensQuantidade.AsFloat <= 0 then
    begin
        DBGridItens.SelectedIndex := 2; // seleciona coluna quantidade
        ShowMessage('Código do produto deve ser informado!');
        Abort; // interrompe a gravação
    end;
end;

procedure TCPedidos.DBGridItensKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
// muda para a próxima coluna se pressionar Enter
if Key = VK_RETURN then // pressionou ENTER
begin
    case DBGridItens.SelectedIndex of
        0: DBGridItens.SelectedIndex := 2; //quantidade
        1: DBGridItens.SelectedIndex := 2; //quantidade
        2: DBGridItens.SelectedIndex := 3; //preço
    else
        DBGridItens.SelectedIndex := 0; //código
        TableItens.Next;
        if TableItens.Eof then
            TableItens.Append;
    end;
end;


end;

procedure TCPedidos.TableItensCodigoProdutoValidate(Sender: TField);
begin
if TableItensCodigoProduto.AsString <> '' then
begin
    if TableProdutos.FindKey([TableItensCodigoProduto.AsInteger]) then
    TableItensPrecoUni.AsCurrency := TableProdutos.FieldByName('PrecoUni').AsCurrency
    else
    begin
        ShowMessage('Código inválido');
        Abort;
    end;
end;
end;

procedure TCPedidos.TablePedidosDataCadastroSetText(Sender: TField;
  const Text: String);
begin
if Text = '  /  /    ' then
        Sender.Clear // apaga o campo data
    else
        // atribui a data digitada ao campo
        try
            Sender.AsString := Text;
        except
            ShowMessage('Data inválida!');
        end;
end;

procedure TCPedidos.SpdBtnIncluirClick(Sender: TObject);
begin
    AtivarControles(True); // ativa os controles para digitação
    TablePedidos.Append; // inclui um novo registro na tabela
    DBEditDataCadastro.SetFocus;
end;

procedure TCPedidos.SpdBtnAlterarClick(Sender: TObject);
begin
  if TablePedidos.IsEmpty then
    begin
        // a tabela está vazia, então devemos incluir
        SpdBtnIncluir.Click; // executa o click no botão
        Exit; // retorna
    end;
    AtivarControles(True); // ativa os controles para digitação
    TablePedidos.Edit; // permite alterar os dados
    DBEditDataCadastro.SetFocus;
end;

procedure TCPedidos.SpdBtnExcluirClick(Sender: TObject);
begin
if Application.MessageBox('Deseja excluir este pedido?','Confirme',
        MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = IDNO then
        Exit; // retorna (sem fazer nada)
    // devemos excluir os itens primeiro, para não termos
    // registros órfãos
    try
        TableItens.First; // posiciona no primeiro item
        while not TableItens.Eof do // executa até o fim do arquivo
        begin
            TableItens.Delete; // exclui o item
            TableItens.First;
        end;
        TablePedidos.Delete; // exclui o pedido
    except
        ShowMessage('Ocorreu um erro durante a exclusão do pedido');
    end;
end;

procedure TCPedidos.SpdBtnGravarClick(Sender: TObject);
begin
if TablePedidosCodigoPedido.AsInteger <= 0 then
    begin
        ShowMessage('Digite o número do pedido!');
        DBEditCodigoPedido.SetFocus;
        Exit;
    end;
    if TablePedidosDataCadastro.IsNull then
    begin
        ShowMessage('Digite a data do pedido!');
        DBEditDataCadastro.SetFocus;
        Exit;
    end;
    if TablePedidosNomeCliente.AsInteger > 0 then
    begin
        // procura pelo cliente usando o código
        if not TableClientes.FindKey([TablePedidosNomeCli.AsInteger]) then
        begin
            ShowMessage('Código de cliente inválido!');
            DBEditCodigoCliente.SetFocus;
            Exit;
        end;
    end
    else
    begin
        ShowMessage('Digite o código do cliente!');
        DBEditCodigoCliente.SetFocus;
        Exit;
    end;
    TablePedidos.Post;
    if TableItens.State in [dsInsert,dsEdit] then
        TableItens.Post;
    AtivarControles(False); // desativa os controles
end;

procedure TCPedidos.SpdBtnCancelarClick(Sender: TObject);
begin
 TablePedidos.Cancel; // cancela inclusão/alteração
    AtivarControles(False); // desativa os controles
end;

end.

onde sera que esta o erro:

Editado por Carlos Rocha
Link para o comentário
Compartilhar em outros sites

  • 0

Carlos Rocha, vamos por partes então.

Comece corrigindo duas coisas que não estão legais no código da procedure abaixo (veja comentário com "// *** COMPARE"):

procedure TCPedidos.RecalculaPedido;
var
  TmpTable:TTable;
  TmpTable :TTable;   // *** COMPARE
  Total:Currency; // armazena valores do tipo moeda
begin
    // cria um objeto Table via codificação
    TmpTable := TTable.Create(Self);   // *** COMPARE
    try
        // define DatabaseName e TableName via codificação
        TmpTable.DatabaseName := TableItens.DatabaseName;
        TmpTable.TableName := TableItens.TableName;
        TmpTable.Open;
        TmpTable.FindKey([TablePedidosCodigoPedido.AsInteger]);
        Total := 0; // inicializa a variavel totalizadora
        while (not TmpTable.Eof) and
           (TmpTable.FieldByName('NumeroPedido').AsInteger = TablePedidosNumeroPedido.AsInteger) do
         begin
             // Acumula o Total da linha
             Total := Total + (TmpTable.FieldByName('preço').AsCurrency * TmpTable.FieldByName('Quantidade').AsFloat);
             TmpTable.Next; // próximo registro
         end;
     finally
         TmpTable.Close; // fecha a tabela
         TmpTable.Free; // libera objeto da memória
     end;
     StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total);
end;
Isto já deverá reduzir alguns erros que você obteve na compilação. Tentando adiantar algum problema... Se o índice (chave em uso) da tabela de itens (TmpTable) não possuir como 1º campo o NumeroPedido, além de poder posicionar no pedido errado, o seu WHILE vai furar, já que poderá aparecer um novo pedido antes que todos os desejados tenham sido encontrados. Por ex., se a chave for algo como NumItem|NumPedido, você terá numa sequência:
1 | 100  (Item 1 do pedido 100)
1 | 101  (Item 1 do pedido 101)
1 | 102  (Item 1 do pedido 102)
2 | 100  (Item 2 do pedido 100)
2 | 101  (Item 2 do pedido 101)
3 | 100  (Item 3 do pedido 100)
3 | 101  (Item 4 do pedido 101)
donde resulta que após encontrar o registro com o número de pedido solicitado em FindKey, o próximo corresponderá a outro pedido, encerrando o loop. Agora, sendo prático, por que é que você não utiliza uma query para fazer este somatório? Seria penas um componente do tipo Query (TQuery, ZQuery, ...) com a propriedade SQL deste modo:
SELECT SUM(preço) AS PrecoTotal FROM ITENS_PEDIDO WHERE NumeroPedido = :NumeroPedido
depois o seu procedimento seria apenas algo como:
procedure TCPedidos.RecalculaPedido;
begin
 // *** para o caso de você NÃO querer adicionar o sql em design-time, você pode adicionar aqui
 // *** tirando o comentário das 4 linhas a seguir
 // QueryTotal.SQL.Clear;
 // QueryTotal.SQL.Add('SELECT SUM(preço) AS PrecoTotal');
 // QueryTotal.SQL.Add('FROM ITENS_PEDIDO');
 // QueryTotal.SQL.Add('WHERE NumeroPedido = :NumeroPedido');
  QueryTotal.ParamByName('NumeroPedido').AsInteger := TablePedidosNumeroPedido.AsInteger;
  QueryTotal.Open;
  StaticTextTotal.Caption := FormatCurr('###,###,##0.00', QueryTotal.FieldByName('PrecoTotal').AsCurrency);
  QueryTotal.Close;
end;

Link para o comentário
Compartilhar em outros sites

  • 0

Ola.

Obrigado pelas dicas.

Diminuiram muito os erros mas ainda tem alguns:

Esses já queimei muito neuronio mas nada.

Por favor, me continue ajudado que eu vou chegar lá:

[Error] CadPedidos.pas(259): Incompatible types: 'String' and 'TField'
[Error] CadPedidos.pas(340): Operator not applicable to this operand type
[Fatal Error] SaneRio.dpr(15): Could not compile used unit 'CadPedidos.pas'
Eis o codigo todo, onde sera que esta o erro:
unit CadPedidos;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, DBCtrls, Grids, DBGrids, ExtCtrls, DB,
  ZAbstractRODataset, ZAbstractDataset, ZAbstractTable, ZDataset, Mask;

type
  TCPedidos = class(TForm)
    PanelDados: TPanel;
    PanelBotoes: TPanel;
    DBGridItens: TDBGrid;
    DBNavigatorPedidos: TDBNavigator;
    SpdBtnAlterar: TSpeedButton;
    SpdBtnIncluir: TSpeedButton;
    SpdBtnProcurar: TSpeedButton;
    SpdBtnCancelar: TSpeedButton;
    SpdBtnGravar: TSpeedButton;
    SpdBtnExcluir: TSpeedButton;
    BitBtnFechar: TBitBtn;
    TablePedidos: TZTable;
    TableItens: TZTable;
    TableClientes: TZTable;
    TableProdutos: TZTable;
    DSPedidos: TDataSource;
    DSItens: TDataSource;
    TablePedidosCodigoPedido: TIntegerField;
    TablePedidosCondicaoPgto: TStringField;
    TablePedidosCodigoCliente: TIntegerField;
    TablePedidosNomeCli: TStringField;
    TablePedidosLocalFatura: TStringField;
    TablePedidosLocalCobranca: TStringField;
    TablePedidosLocalEntrega: TStringField;
    TablePedidosCPF_CNPJ: TStringField;
    TablePedidosCEP: TStringField;
    TablePedidosDataCadastro: TDateField;
    TableClientesCodigoCliente: TIntegerField;
    TableClientesNome: TStringField;
    TableClientesTipo: TStringField;
    TableClientesEndereco: TStringField;
    TableClientesEmail: TStringField;
    TableClientesBairro: TStringField;
    TableClientesCidade: TStringField;
    TableClientesEstado: TStringField;
    TableClientesTelefone: TStringField;
    TableClientesCPF_CNPJ: TStringField;
    TableClientesDataCadastro: TDateField;
    TablePedidosNomeCliente: TStringField;
    TableProdutosCodigoProduto: TIntegerField;
    TableProdutosDescricao: TStringField;
    TableProdutosPrecoUni: TIntegerField;
    TableItensItem: TIntegerField;
    TableItensCodigoProduto: TIntegerField;
    TableItensQuantidade: TIntegerField;
    TableItensPrecoUni: TIntegerField;
    TableItensDescricao: TStringField;
    TableItensTotal: TCurrencyField;
    TableItensNumeroPedido: TIntegerField;
    LabelCodigoPedido: TLabel;
    DBEditCodigoPedido: TDBEdit;
    LabelCondicaoPagamento: TLabel;
    DBEditCondicaoPagamento: TDBEdit;
    LabelCodigoCliente: TLabel;
    DBEditCodigoCliente: TDBEdit;
    LabelNomeCliente: TLabel;
    DBLookupComboBoxNomeCliente: TDBLookupComboBox;
    LabelLocalFatura: TLabel;
    DBEditLocalFatura: TDBEdit;
    LabelLocalCobranca: TLabel;
    DBEditLocalCobranca: TDBEdit;
    LabelLocalEntrega: TLabel;
    DBEditLocalEntrega: TDBEdit;
    LabelCPF_CNPJ: TLabel;
    DBEditCPF_CNPJ: TDBEdit;
    LabelCEP: TLabel;
    DBEditCEP: TDBEdit;
    LabelDataCadastro: TLabel;
    DBEditDataCadastro: TDBEdit;
    LabelTotalPedido: TLabel;
    StaticTextTotal: TStaticText;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure TablePedidosNewRecord(DataSet: TDataSet);
    procedure TableItensCalcFields(DataSet: TDataSet);
    procedure TableItensNewRecord(DataSet: TDataSet);
    procedure TableItensBeforeInsert(DataSet: TDataSet);
    procedure TableItensBeforePost(DataSet: TDataSet);
    procedure DBGridItensKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure TableItensCodigoProdutoValidate(Sender: TField);
    procedure TablePedidosDataCadastroSetText(Sender: TField;
      const Text: String);
    procedure SpdBtnIncluirClick(Sender: TObject);
    procedure SpdBtnAlterarClick(Sender: TObject);
    procedure SpdBtnExcluirClick(Sender: TObject);
    procedure SpdBtnGravarClick(Sender: TObject);
    procedure SpdBtnCancelarClick(Sender: TObject);
  private
    procedure AtivarControles(Ativar: Boolean);
    procedure RecalculaPedido;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  CPedidos: TCPedidos;

implementation

uses dmsane;

{$R *.dfm}

procedure TCPedidos.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree; // remove o form da memória
CPedidos := NIL; // informa que foi destruído (não criado
end;

procedure TCPedidos.FormCreate(Sender: TObject);
begin
TableProdutos.Open;
TableClientes.Open;
TablePedidos.Open;
TableItens.Open;
end;

procedure TCPedidos.FormDestroy(Sender: TObject);
begin
TableProdutos.Close;
TableClientes.Close;
TablePedidos.Close;
TableItens.Close;
end;

procedure TCPedidos.TablePedidosNewRecord(DataSet: TDataSet);
begin
TablePedidosDataCadastro.AsDateTime := Date; //inicia com a data atual
end;

procedure TCPedidos.AtivarControles(Ativar: Boolean);
begin
    PanelDados.Enabled := Ativar;
    DBNavigatorPedidos.Enabled := (not Ativar);
    DBGridItens.ReadOnly := (not Ativar);
    SpdBtnIncluir.Enabled := (not Ativar);
    SpdBtnAlterar.Enabled := (not Ativar);
    SpdBtnExcluir.Enabled := (not Ativar);
    SpdBtnGravar.Enabled := Ativar;
    SpdBtnCancelar.Enabled := Ativar;
    SpdBtnProcurar.Enabled := (not Ativar);
end;


procedure TCPedidos.RecalculaPedido;
var
    TmpTable:TZTable;
    Total:Currency; // armazena valores do tipo moeda
begin
    // cria um objeto Table via codificação
    TmpTable := TZTable.Create(Application);
    try
        // define DatabaseName e TableName via codificação
        TmpTable.Connection := TableItens.Connection;
        TmpTable.TableName := TableItens.TableName;
        TmpTable.Open;
        TmpTable.FindField(TablePedidosCodigoPedido.AsString);
        Total := 0; // inicializa a variavel totalizadora
        while (not TmpTable.Eof) and
           (TmpTable.FieldByName('NumeroPedido').AsInteger = TablePedidosCodigoPedido.AsInteger) do
         begin
             // Acumula o Total da linha
             Total := Total + (TmpTable.FieldByName('PrecoUni').AsCurrency * TmpTable.FieldByName('Quantidade').AsFloat);
             TmpTable.Next; // próximo registro
         end;
     finally
         TmpTable.Close; // fecha a tabela
         TmpTable.Free; // libera objeto da memória
     end;
     StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total);
 end;

procedure TCPedidos.TableItensCalcFields(DataSet: TDataSet);
begin
if (TableItensQuantidade.AsFloat > 0) and
        (TableItensPrecoUni.AsCurrency > 0) then
        TableItensTotal.AsCurrency := TableItensPrecoUni.AsCurrency * TableItensQuantidade.AsFloat;
        RecalculaPedido; // recalcula e exibe novamente
end;

procedure TCPedidos.TableItensNewRecord(DataSet: TDataSet);
begin
TableItensQuantidade.AsFloat := 1;
DBGridItens.SelectedIndex := 0; //código
end;

procedure TCPedidos.TableItensBeforeInsert(DataSet: TDataSet);
begin
if TablePedidosCodigoPedido.AsString = '' then
    begin
        if TablePedidos.State = dsInsert then
        begin
            // grava para salvar o número do pedido na tabela pai
            TablePedidos.Post;
            // ativa a alteração novamente
            TablePedidos.Edit;
        end;
    end;
end;

procedure TCPedidos.TableItensBeforePost(DataSet: TDataSet);
begin
 if TableItensNumeroPedido.AsString = '' then
        TableItensNumeroPedido.AsInteger := TablePedidosCodigoPedido.AsInteger;
    if TableItensCodigoProduto.AsString = '' then
    begin
        DBGridItens.SelectedIndex := 0; // seleciona a coluna código
        ShowMessage('Código do produto deve ser informado!');
        Abort; // interrompe a gravação
    end;
    if TableItensQuantidade.AsFloat <= 0 then
    begin
        DBGridItens.SelectedIndex := 2; // seleciona coluna quantidade
        ShowMessage('Código do produto deve ser informado!');
        Abort; // interrompe a gravação
    end;
end;

procedure TCPedidos.DBGridItensKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
// muda para a próxima coluna se pressionar Enter
if Key = VK_RETURN then // pressionou ENTER
begin
    case DBGridItens.SelectedIndex of
        0: DBGridItens.SelectedIndex := 2; //quantidade
        1: DBGridItens.SelectedIndex := 2; //quantidade
        2: DBGridItens.SelectedIndex := 3; //preço
    else
        DBGridItens.SelectedIndex := 0; //código
        TableItens.Next;
        if TableItens.Eof then
            TableItens.Append;
    end;
end;


end;

procedure TCPedidos.TableItensCodigoProdutoValidate(Sender: TField);
begin

if TableItensCodigoProduto.AsString <> '' then
begin
    if TableProdutos.FindField(TableItensCodigoProduto.AsString) <> '' then
    TableItensPrecoUni.AsCurrency := TableProdutos.FieldByName('PrecoUni').AsCurrency
    else
    begin
        ShowMessage('Código inválido');
        Abort;
    end;
end;
end;

procedure TCPedidos.TablePedidosDataCadastroSetText(Sender: TField;
  const Text: String);
begin
if Text = '  /  /    ' then
        Sender.Clear // apaga o campo data
    else
        // atribui a data digitada ao campo
        try
            Sender.AsString := Text;
        except
            ShowMessage('Data inválida!');
        end;
end;

procedure TCPedidos.SpdBtnIncluirClick(Sender: TObject);
begin
    AtivarControles(True); // ativa os controles para digitação
    TablePedidos.Append; // inclui um novo registro na tabela
    DBEditDataCadastro.SetFocus;
end;

procedure TCPedidos.SpdBtnAlterarClick(Sender: TObject);
begin
  if TablePedidos.IsEmpty then
    begin
        // a tabela está vazia, então devemos incluir
        SpdBtnIncluir.Click; // executa o click no botão
        Exit; // retorna
    end;
    AtivarControles(True); // ativa os controles para digitação
    TablePedidos.Edit; // permite alterar os dados
    DBEditDataCadastro.SetFocus;
end;

procedure TCPedidos.SpdBtnExcluirClick(Sender: TObject);
begin
if Application.MessageBox('Deseja excluir este pedido?','Confirme',
        MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = IDNO then
        Exit; // retorna (sem fazer nada)
    // devemos excluir os itens primeiro, para não termos
    // registros órfãos
    try
        TableItens.First; // posiciona no primeiro item
        while not TableItens.Eof do // executa até o fim do arquivo
        begin
            TableItens.Delete; // exclui o item
            TableItens.First;
        end;
        TablePedidos.Delete; // exclui o pedido
    except
        ShowMessage('Ocorreu um erro durante a exclusão do pedido');
    end;
end;

procedure TCPedidos.SpdBtnGravarClick(Sender: TObject);
begin
if TablePedidosCodigoPedido.AsInteger <= 0 then
    begin
        ShowMessage('Digite o número do pedido!');
        DBEditCodigoPedido.SetFocus;
        Exit;
    end;
    if TablePedidosDataCadastro.IsNull then
    begin
        ShowMessage('Digite a data do pedido!');
        DBEditDataCadastro.SetFocus;
        Exit;
    end;
    if TablePedidosNomeCliente.AsInteger > 0 then
    begin
        // procura pelo cliente usando o código
        if not TableClientes.FindField(TablePedidosNomeCliente.AsString) = '' then
        begin
            ShowMessage('Código de cliente inválido!');
            DBEditCodigoCliente.SetFocus;
            Exit;
        end;
    end
    else
    begin
        ShowMessage('Digite o código do cliente!');
        DBEditCodigoCliente.SetFocus;
        Exit;
    end;
    TablePedidos.Post;
    if TableItens.State in [dsInsert,dsEdit] then
        TableItens.Post;
    AtivarControles(False); // desativa os controles
end;

procedure TCPedidos.SpdBtnCancelarClick(Sender: TObject);
begin
 TablePedidos.Cancel; // cancela inclusão/alteração
    AtivarControles(False); // desativa os controles
end;

end.

Link para o comentário
Compartilhar em outros sites

  • 0

Vixe!!!

Carlos Rocha, agora você deu uma viajada legal...

Que negócio é esse de usar FindField onde, aparentemente, deveria utilizar FindKey?! :blink:

Resolva isto e você vai avançar mais um pouco.

Mais alguns comentários/sugestões sobre a codificação:

...
    if TablePedidosCodigoPedido.AsInteger <= 0 then
    begin
        ShowMessage('Digite o número do pedido!');
        DBEditCodigoPedido.SetFocus;
        Exit;
    end;
    if TablePedidosDataCadastro.IsNull then
    begin
        ShowMessage('Digite a data do pedido!');
        DBEditDataCadastro.SetFocus;
        Exit;
    end;
    if TablePedidosNomeCliente.AsInteger > 0 then
    begin
        // procura pelo cliente usando o código
        if not TableClientes.FindField(TablePedidosNomeCliente.AsString) = '' then
        begin
            ShowMessage('Código de cliente inválido!');
            DBEditCodigoCliente.SetFocus;
            Exit;
        end;
    end
    else
    begin
        ShowMessage('Digite o código do cliente!');
        DBEditCodigoCliente.SetFocus;
        Exit;
    end;
    TablePedidos.Post;
    if TableItens.State in [dsInsert,dsEdit] then
        TableItens.Post;
    AtivarControles(False); // desativa os controles
end;
Numa sequência como esta, em que satisfeito um if..then é executado um exit, o mais apropriado seria aninhar adequadamente utilizando else's e não exit. Observe que haverá uma única condição em que as linhas a partir de "TablePedidos.Post;" serão executadas: quando NomeCliente.AsInteger > 0 e for encontrado; para as demais opções você utiliza o exit para evitar o Post. Utilizando a lógica, você poderia escrever o procedimento desta forma:
...
    if TablePedidosCodigoPedido.AsInteger <= 0 then
    begin
        ShowMessage('Digite o número do pedido!');
        DBEditCodigoPedido.SetFocus;
    end 
    else if TablePedidosDataCadastro.IsNull then
    begin
        ShowMessage('Digite a data do pedido!');
        DBEditDataCadastro.SetFocus;
    end
    else if TablePedidosNomeCliente.AsInteger > 0 then
    begin
        // procura pelo cliente usando o código
        if not TableClientes.FindField(TablePedidosNomeCliente.AsString) = '' then
        begin
            ShowMessage('Código de cliente inválido!');
            DBEditCodigoCliente.SetFocus;
        end 
        else
        begin
            TablePedidos.Post;
            if TableItens.State in [dsInsert,dsEdit] then
                TableItens.Post;
            AtivarControles(False); // desativa os controles
        end;
    end
    else
    begin
        ShowMessage('Digite o código do cliente!');
        DBEditCodigoCliente.SetFocus;
    end;
end;

é claro que existem situações que não tem jeito, mas sempre que possível, dê preferência a algo nesta linha.

Outra coisa é a seguinte: tá meio estranho você fazer um "type-cast" de um campo string para interger e compará-lo com zero. Pelo menos, é o que parece ao olhar esta linha TablePedidosNomeCliente.AsInteger > 0. Eu lhe diria que não faz o menor sentido. Se este campo possui realmente o nome de um cliente, seria mais apropriado que você testasse se ele é nulo ou está vazio, o que poderia ser feito com Trim(TablePedidosNomeCliente.AsString) <> ''

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ola Micheus. Tudo bem?

Primeiramente, quero agradecer pela força que você esta me dando.

Cada informação que vocês me passam, esta sendo por min muito analizada mas minha pequena(ou quem sabe 'NULA') experiencia, muitas das veses não me ajuda muito.

Mas vamos lá.

Estou usando Zeos pra conectar o Banco Mysql.

Eu tentei usar:

if not TableClientes.FindField(TablePedidosNomeCliente.AsString)
Pois não tem FindKey na ZTable mas continua dando erro. Preciso da tua ajuda. Aproveitando o ensejo, gostaria de fazer outra pergunta: Minha tabela ZeusTableClientes, ão entra de jeito nenhum em estado de edição e inserção. Pus o código abaixo em um button e a resposta sempre é não.
if (ZTableclientes.State in [dsInsert,dsEdit]) then //Verifica se a tabela esta em estado de edição ou inserção
   begin
     showmessage('OK');
   end
else
  begin
     showmessage ('Não deu');
  end
end;

Como fazer para passar o estado dela para edição e inserção?

Link para o comentário
Compartilhar em outros sites

  • 0

Mas num da certo de jeito nenhum.

alguém sabe onde ficam:

1) A propriedade .FindKey da ZeosTable

2) A propriedade .CancelRange da ZeosTable

3) A propriedade .SetRange da ZeosTable

4) A propriedade .GotoCurrent da ZeosTable

Valeu!

Editado por Carlos Rocha
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,9k
×
×
  • Criar Novo...