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

Um Problema Um Tanto Complicado


Carlos Rocha

Pergunta

estava usado o compmnente table num cadastro de pedidos, e resolvi trocar o table pelo componente zquery.

Na migração, foi tudo bem porem, quando abro o formulario, da uma mensagen de "sql error: query was empty".

mas não consigo matar esse erro. obs: o codigo compila certinho.

segue o codigo que estou usando. se alguém puder me ajudar, muito obrigado

unit CadPedidos;

interface

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

type
  TCPedidos = class(TForm)
    PanelDados: TPanel;
    LabelCodigoPedido: TLabel;
    LabelCondicaoPagamento: TLabel;
    LabelCodigoCliente: TLabel;
    LabelLocalFatura: TLabel;
    LabelLocalCobranca: TLabel;
    LabelLocalEntrega: TLabel;
    LabelCPF_CNPJ: TLabel;
    LabelCEP: TLabel;
    LabelDataCadastro: TLabel;
    LabelTotalPedido: TLabel;
    DBEditCodigoPedido: TDBEdit;
    DBEditCondicaoPagamento: TDBEdit;
    DBEditCodigoCliente: TDBEdit;
    DBEditLocalFatura: TDBEdit;
    DBEditLocalCobranca: TDBEdit;
    DBEditLocalEntrega: TDBEdit;
    DBEditCPF_CNPJ: TDBEdit;
    DBEditCEP: TDBEdit;
    DBEditDataCadastro: TDBEdit;
    StaticTextTotal: TStaticText;
    PanelBotoes: TPanel;
    SpdBtnAlterar: TSpeedButton;
    SpdBtnIncluir: TSpeedButton;
    SpdBtnProcurar: TSpeedButton;
    SpdBtnCancelar: TSpeedButton;
    SpdBtnGravar: TSpeedButton;
    SpdBtnExcluir: TSpeedButton;
    DBNavigatorPedidos: TDBNavigator;
    BitBtnFechar: TBitBtn;
    Button1: TButton;
    DBGridItens: TDBGrid;
    DSPedidos: TDataSource;
    DSItens: TDataSource;
    QryClientes2: TZQuery;
    QryClientes2CodigoCliente: TIntegerField;
    QryClientes2Nome: TStringField;
    QryClientes2Tipo: TStringField;
    QryClientes2Endereco: TStringField;
    QryClientes2Email: TStringField;
    QryClientes2Bairro: TStringField;
    QryClientes2Cidade: TStringField;
    QryClientes2Estado: TStringField;
    QryClientes2Telefone: TStringField;
    QryClientes2CPF_CNPJ: TStringField;
    QryClientes2DataCadastro: TDateField;
    DSClientes: TDataSource;
    QryPedidos: TZQuery;
    QryItens: TZQuery;
    QryClientes: TZQuery;
    QryProdutos: TZQuery;
    QryPedidosCodigoPedido: TIntegerField;
    QryPedidosCondicaoPgto: TStringField;
    QryPedidosCodigoCliente: TIntegerField;
    QryPedidosNomeCli: TStringField;
    QryPedidosLocalFatura: TStringField;
    QryPedidosLocalCobranca: TStringField;
    QryPedidosLocalEntrega: TStringField;
    QryPedidosCPF_CNPJ: TStringField;
    QryPedidosCEP: TStringField;
    QryPedidosDataCadastro: TDateField;
    QryPedidosNomeCliente: TStringField;
    Label1: TLabel;
    DBLookupComboBoxNomeCliente: TDBLookupComboBox;
    QryItensItem: TIntegerField;
    QryItensNumeroPedido: TIntegerField;
    QryItensCodigoProduto: TIntegerField;
    QryItensQuantidade: TIntegerField;
    QryItensPrecoUni: TIntegerField;
    QryProdutosCodigoProduto: TIntegerField;
    QryProdutosDescricao: TStringField;
    QryProdutosPrecoUni: TIntegerField;
    QryClientesCodigoCliente: TIntegerField;
    QryClientesDataCadastro: TDateField;
    QryClientesTipo: TStringField;
    QryClientesCPF_CNPJ: TStringField;
    QryClientesNome: TStringField;
    QryClientesEndereco: TStringField;
    QryClientesBairro: TStringField;
    QryClientesCidade: TStringField;
    QryClientesEstado: TStringField;
    QryClientesTelefone: TStringField;
    QryClientesEmail: TStringField;
    QryItensTotal: TCurrencyField;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure QryPedidosNewRecord(DataSet: TDataSet);
    procedure QryItensNewRecord(DataSet: TDataSet);
    procedure QryItensCalcFields(DataSet: TDataSet);
    procedure QryItensBeforeInsert(DataSet: TDataSet);
    procedure QryItensBeforePost(DataSet: TDataSet);
    procedure DBGridItensKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure QryItensCodigoProdutoValidate(Sender: TField);
    procedure QryPedidosDataCadastroSetText(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);
    procedure SpdBtnProcurarClick(Sender: TObject);
    procedure DBLookupComboBoxNomeClienteClick(Sender: TObject);
  private
   { Private declarations }
    procedure AtivarControles(Ativar: Boolean);
    procedure RecalculaPedido;
  public
    { Public declarations }
  end;

var
  CPedidos: TCPedidos;

implementation

uses dmsane, ListaPedidos; //RelatorioPedidos;

{$R *.dfm}
procedure TCPedidos.FormCreate(Sender: TObject);
begin
  QryProdutos.Close;
  QryClientes.Close;
  QryPedidos.Close;
  QryItens.Close;
end;

procedure TCPedidos.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  QryProdutos.Open;
  QryClientes.Open;
  QryPedidos.Open;
  QryItens.Open;
end;

procedure TCPedidos.FormDestroy(Sender: TObject);
begin
//Action:= cafree;// remove o form da memória
//CPedidos := NIL; // informa que foi destruído (não criado
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.DBLookupComboBoxNomeClienteClick(Sender: TObject);
begin
  QryClientes2.Close;
  QryClientes2.sql.Clear;
  QryClientes2.SQL.Add('Select * from Clientes where Nome = '+''''+DBLookupComboBoxNomeCliente.Text+''''+'');
  QryClientes2.Open;

  QryClientes2.first;
  while not QryClientes2.EOF do
  begin
    DBEditCodigoCliente.Text := QryClientes2.Fields[0].Value;
    DBEditLocalCobranca.Text := QryClientes2.Fields[3].Value +', '+ QryClientes2.Fields[5].Value +' - ' + QryClientes2.Fields[6].Value +'/' +QryClientes2.Fields[7].Value;
    DBEditCPF_CNPJ.Text := QryClientes2.Fields[9].Value;
    QryClientes2.Next;
  end;
end;

procedure TCPedidos.SpdBtnProcurarClick(Sender: TObject);
begin
  Application.CreateForm(TLPedidos, LPedidos);
  LPedidos.Show;
end;

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

procedure TCPedidos.QryItensCodigoProdutoValidate(Sender: TField);
begin
if QryItensCodigoProduto.AsString <> '' then
begin
if QryItensCodigoProduto.AsString <> '' then
    QryItensPrecoUni.AsCurrency := QryProdutos.FieldByName('PrecoUni').AsCurrency
    else
    begin
        ShowMessage('Código inválido');
        Abort;
    end;
end;
end;

procedure TCPedidos.QryPedidosDataCadastroSetText(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
    QryPedidos.Append; // inclui um novo registro na tabela
    DBLookupComboBoxNomeCliente.SetFocus;
end;

procedure TCPedidos.SpdBtnAlterarClick(Sender: TObject);
begin
  if QryPedidos.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
    QryPedidos.Edit; // permite alterar os dados
    DBLookupComboBoxNomeCliente.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
        QryItens.First; // posiciona no primeiro item
        while not QryItens.Eof do // executa até o fim do arquivo
        begin
            QryItens.Delete; // exclui o item
            QryItens.First;
        end;
        QryPedidos.Delete; // exclui o pedido
    except
        ShowMessage('Ocorreu um erro durante a exclusão do pedido');
    end;
end;

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

    QryPedidos.Post;
    if QryItens.State in [dsInsert,dsEdit] then
        QryItens.Post;
    AtivarControles(False); // desativa os controles
end;

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

procedure TCPedidos.QryPedidosNewRecord(DataSet: TDataSet);
begin
QryPedidosDataCadastro.AsDateTime := Date; //inicia com a data atual
end;
procedure TCPedidos.QryItensNewRecord(DataSet: TDataSet);
begin
QryItensQuantidade.AsFloat := 1;
DBGridItens.SelectedIndex := 0; //código
end;

procedure TCPedidos.QryItensCalcFields(DataSet: TDataSet);
begin
if (QryItensQuantidade.AsFloat > 0) and
       (QryItensPrecoUni.AsCurrency > 0) then
        QryItensTotal.AsCurrency := QryItensPrecoUni.AsCurrency * QryItensQuantidade.AsFloat;
        RecalculaPedido; // recalcula e exibe novamente
end;

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

procedure TCPedidos.QryItensBeforePost(DataSet: TDataSet);
begin
 if QryItensNumeroPedido.AsString = '' then
        QryItensNumeroPedido.AsInteger := QryPedidosCodigoPedido.AsInteger;
    if QryItensCodigoProduto.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 QryItensQuantidade.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
        QryItens.Next;
        if QryItens.Eof then
            QryItens.Append;
    end;

 end;
end;
end.

Link para o comentário
Compartilhar em outros sites

7 respostass a esta questão

Posts Recomendados

  • 0

Carlos, a mensagem parece indicar que você está abrindo uma query sem as instruções SQL definidas na respectiva propriedade. Pelo código não dá para verificar isso, já que aparentemente você adiciona-as em design-time (só com o projeto na mão).

Mas, queria lhe sugerir que desse uma boa revisada no seu código. Do meu ponto de vista tem algumas coisas estranhas:

1) No Create normalmente as queries seriam abertas - não fechadas;

2) No Close normalmente as queruies seriam fechadas - não abertas;

3) Apesar de comentado, aquele Action := caFree, nunca existirá no OnDestroy - mas sim no OnClose;

4) Eu não tenho como conferir agora, mas se não estou enganado FindField é utilizado para encontrar um campo (classe TField..) na lista de fields da query/table e não como um FindKey que é o que parece você pretendia utilizar com TmpQry.FindField(QryPedidosCodigoPedido.AsString) na procedure RecalculaPedido;

Sugestões:

1) Não use Abort onde apenas a lógica resolve o problema. Quando você a utiliza dentro dos if..then..else e nada mais poderia vir a ser executado não faz o menor sentido utilizá-las (está apenas poluindo seu código); Um lugar onde ela poderia ser realmente útil é no SpdBtnGravarClick. Observe que lá você faz uma série de validações e utiliza showmessage com setfocus, mas isso não evitará que o Post no final do procedimento seja executado - então, a validação não está atingindo seu propósito.

2) evite utilizar a propriedade Fields como em QryClientes2.Fields[0].Value. Além de não ficar claro de qual campo você está tratando, caso você venha a incluir novos campos na query/tabela e alguma coluna mudar de posição, isto lhe acarretará proclemas. Então, se você não trabalhar com os campos adicionados ao projeto, sugiro que você utilize FieldByName(nome_campo) no lugar de Fields[indice];

3) em teste como if Text = ' / / ' then, eu lhe recomendaria utilizar if Trim(Text) = '/ /' then (sem os espaços do dia e ano), porque se você mudar a máscara de 4 para 2 dígitos para o ano, não terá qualquer efeito colateral.

Não leve a mal os comentários, mas achei que poderia ser interessante lhe chamar a atenção para eles. Se coloquei algo de errado, por favor, me corrija - sem problemas.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Fiz as devidas alterações e continua dando o erro:

"error: query was empty"

Esse erro da, quando, no menu do form pricipal, eu chamo o form de cadastro de pedidos. Nem está abrindo o formulario.

Pois é, tenho 5 querys no form todas com a instrução inicial "Select * from Tabela" e está dando esse erro.

QryProdutos

QryClientes

QryClientes2

QryPedidos.

QryItens

Como faço pra ver em, que linha da o erro se o programa não da erro na compilação???

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

  • 0
Como faço pra ver em, que linha da o erro se o programa não da erro na compilação???
A menos que você tenha desabilitado a depuração integrada (no D7 Tools->Debugger Options->Language Exceptions, Stop on Delphi Exceptions desmarcada), na ocorrência de um erro de execução o fluxo do programa deveria ser desviado para dentro da IDE do Delphi sendo o cursor posicionado na linha (senão, próximo a ela) da ocorrência do erro.

De qualquer modo, se você não estiver com esta opção desabilitada, você pode colocar um break-point na linha aonde você chama seu cadastro de pedidos ou, no cadastro de pedidos, colocá-lo num ponto aonde você imagina possa estar o problema (tipo um .open) e executar passo-a-passo de modo a avaliar o conteúdo de variáveis/propriedades e descobrir aonde está o problema.

Esse negócio de depuração é bem pessoal e você aprende a achar os pontos a monitorar a medida que entende como as coisas funcionam (o uso contínuo lhe trará a experiência). Se você não tiver uma idéia aproximada de como utilizar os break-points/evaluate-modify, dê uma lida neste post (link) mais a nota no rodapé deste post (link) e este último (link), talvez sirvam de pontos de partida.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ola.

Essa é a parte do código que esta dando erro:

É aqui que a query está voltando valor vazio e a Table retorna valor diferente de vazio.

procedure TCPedidos.RecalculaPedido;
var
    TmpQry:TZQuery;
    Total:Currency; // armazena valores do tipo moeda
begin
    // cria um objeto Qry via codificação
    TmpQry := TZQuery.Create(Application);
    try
        // define DatabaseName e QryName via codificação
        TmpQry.Connection := QryItens.Connection;
        TmpQry.Name := QryItens.Name;
        TmpQry.Open;
        TmpQry.FindField(QryPedidosCodigoPedido.AsString);
        Total := 0; // inicializa a variavel totalizadora
        while (not TmpQry.Eof) and (TmpQry.FieldByName('NumeroPedido').AsInteger = QryPedidosCodigoPedido.AsInteger) do
         begin
             // Acumula o Total da linha
             Total := Total + (TmpQry.FieldByName('PrecoUni').AsCurrency * TmpQry.FieldByName('Quantidade').AsFloat);
             TmpQry.Next; // próximo registro
         end;
     finally
         TmpQry.Close; // fecha a tabela
         TmpQry.Free; // libera objeto da memória
     end;
     StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total);
 end;
Quando era com Table(Codigo abaixo), num tava dando erro, depois que passei usar ZQuery está dando o erro.
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;

Onde sera que esta o erro????????

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

  • 0
A tmp.Qry esta recebendo os dados da QryItens e esta esta atíva.
É não enxerguei :rolleyes:

Mas você tentou depurar e verificar o conteúdo das query's, antes do Open?

Experimentou copiar os dados (SQL) da QryItens para TmpQry para testar se o resto está ok, ao invés de ela receber os dados?

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...