Dicas Delphi

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 26

http://www.arquivodecodigos.net/dicas/delphi-efetuando-calculos-de-porcentagem-emdelphi-2707.

html

Efetuando clculos de porcentagem em Delphi Clculos de porcentagens esto presentes em boa parte das aplicaes que desenvolvemos. Porm, h momentos em que a mente trava e no conseguimos lembrar com clareza como estes clculos so feitos, principalmente em Delphi. Esta anotao tem o objetivo de ser uma fonte de pesquisa para os momentos em que suas habilidades matemticas insistirem em continuar ocultas. Ex: 1 - Suponhamos que um produto que custe R$ 178,00 sofra um acrscimo de 15%. Qual o valor final do produto? Veja o cdigo em Delphi:

procedure TForm1.Button1Click(Sender: TObject); var valor, percentual, valor_final: double; begin valor := 178.00; // valor original percentual := 15.0 / 100.0; // 15% valor_final := valor + (percentual * valor); ShowMessage('O valor final do produto : ' + FloatToStr(valor_final)); // O resultado ser 204,70 end;
Ex: 2 - Um produto, cujo valor original era de R$ 250,00, teve um desconto de 8%. Qual foi seu valor final? Veja o cdigo em Delphi:

procedure TForm1.Button1Click(Sender: TObject); var valor, percentual, valor_final: double; begin valor := 250.00; // valor original percentual := 8.0 / 100.0; // 8% valor_final := valor - (percentual * valor); ShowMessage('O valor final do produto : ' + FloatToStr(valor_final)); // O resultado ser 230,00 end;
Ex: 3 - Em um concurso de perguntas e respostas, um jovem acertou 72 das 90 perguntas apresentadas. Qual foi a porcentagem de acertos? E a porcentagem de erros? Veja o cdigo em Delphi:

procedure TForm1.Button1Click(Sender: TObject); var perguntas, acertos: double; begin perguntas := 90.0; acertos := 72.0; ShowMessage('Porcentagem de acertos: ' + FloatToStr(((acertos / perguntas) * 100)) + '%'); ShowMessage('Porcentagem de erros: ' + FloatToStr((((perguntas - acertos) / perguntas) * 100)) + '%'); // Os resultados sero 80% e 20% end;
Ex: 4 - Um aparelho de CD foi adquirido por R$ 300,00 e revendido por R$ 240,00. Qual foi a porcentagem de lucro na transao? Veja o cdigo em Delphi:

procedure TForm1.Button1Click(Sender: TObject); var v_ant, v_nov, p_lucro: double; begin v_ant := 300.0; // valor anterior v_nov := 340.0; // valor novo p_lucro := 0.0; // porcentagem de lucro while(v_ant + ((p_lucro / 100.0) * v_ant) < v_nov) do begin p_lucro := p_lucro + 0.1; end; ShowMessage('A porcentagem de lucro foi de: ' + FloatToStr(p_lucro) + '%'); // O resultado ser 13,39 end;
Ex: 5 - Uma loja repassa 5% do lucro a seus vendedores. Se um produto custa R$ 70,00, qual o valor em reais repassado a um determinado vendedor? Veja o cdigo em Delphi:

procedure TForm1.Button1Click(Sender: TObject); var valor, porcent, comissao: double; begin valor := 70.0; // valor do produto porcent := 5.0 / 100.0; // 5% comissao := porcent * valor; ShowMessage('O valor repassado ao vendedor : ' + FloatToStr(comissao)); // O resultado ser 3,5 end;

function Arredonda(Valor: Real): Real; var Modo: TFPURoundingMode; begin Modo := GetRoundMode; try SetRoundMode(rmTruncate); Result := RoundTo(Valor, -2); finally SetRoundMode(Modo); end; end; if FrmPrincipal.DSBotoes.State in [dsEdit,dsinsert] Then DmDados.ProdutosPrecoVenda.AsFloat := Arredonda((DmDados.ProdutosPrecoCusto.AsFloat -

((DmDados.ProdutosPrecoCusto.AsFloat * DmDados.ProdutosDesconto

procedure TForm1.Button1Click(Sender: TObject); var valor, valor1, indice, resultado : Currency; begin valor := StrToCurr(StringReplace(Edit1.Text, '.', '', [])); valor1 := ( Valor /30 ) * StrToFloat(StringReplace(Edit2.Text, '.', '', [])); indice := StrToFloat(StringReplace(Edit3.Text, '.', '', [])); resultado := ( valor1 * indice) / 100; // so esta calculando para 30 dias EXATO Label2.Caption := FormatCurr('###,###,##0.00',resultado); label3.Caption := FormatCurr('###,###,##0.00',valor-resultado); end;

http://www.scriptbrasil.com.br/forum/lofiversion/index.php/t100022.html

Carlos Rocha 11/04/2007 - 13:09 Copiei essa procedure de um programa que baixei da net. o programa, ele era Table da Guia BDE, eu coverti em Query do Zeos Lib. Acontece que a linha "TmpQry.Connection := QryItens.Connection;", a conexao um est sendo feita. Codigo que copiei:

CODE procedure tformcadpedidos.recalculapedido; var tmptable:ttable; total:currency; begin

tmptable:=ttable.Create(application); try tmptable.DatabaseName:=tableitens.DatabaseName; tmptable.TableName:=tableitens.TableName; tmptable.Open; tmptable.FindKey([tablepedidosnumeropedido.asInteger]); total:=0; while (not tmptable.Eof) and (tmptable.FieldByName('NumeroPedido').AsInteger= tablepedidosnumeropedido.AsInteger) do begin total:=total+(tmptable.fieldbyname('valorunitario').AsCurrency * tmptable.fieldbyname('quantidade').AsFloat); tmptable.Next; end; finally tmptable.Close; tmptable.Free; end; statictexttotal.Caption:=formatcurr('###,###,##0.00',total); end;

Codigo que transformei:(No consigo criar a TmpQry de jeito nenhum)

CODE procedure TCPedidos.RecalculaPedido; var TmpQry:TZQuery; Total:Currency; // armazena valores do tipo moeda begin // cria um objeto Qry via codificao TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificao TmpQry.Connection := QryItens.Connection; TmpQry.Name := QryItens.Name; TmpQry.SQL.Text := 'Select * from Itens'; TmpQry.Open; //Observe que, para um novo pedido, o CodigoPedido ainda no foi gerado.Self // Da QryPedidosCodigoPedido.AsString sempre tera valor nulo e no ter tens o pedido. TmpQry.Locate('NumeroPedido', QryPedidosCodigoPedido.AsInteger, []);

//

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; // prximo registro end; finally TmpQry.Close; // fecha a tabela TmpQry.Free; // libera objeto da memria end; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total); end; Micheus 11/04/2007 - 15:35 QUOTE(Carlos Rocha @ 11/04/2007 - 01:09) ... Codigo que transformei:(No consigo criar a TmpQry de jeito nenhum)

CODE procedure TCPedidos.RecalculaPedido; var TmpQry:TZQuery; Total:Currency; // armazena valores do tipo moeda begin // cria um objeto Qry via codificao TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificao TmpQry.Connection := QryItens.Connection; TmpQry.Name := QryItens.Name; TmpQry.SQL.Text := 'Select * from Itens'; TmpQry.Open; //Observe que, para um novo pedido, o CodigoPedido ainda no foi gerado.Self // Da QryPedidosCodigoPedido.AsString sempre tera valor nulo e no ter tens o pedido. TmpQry.Locate('NumeroPedido', QryPedidosCodigoPedido.AsInteger, []); // 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; // prximo registro end; finally TmpQry.Close; // fecha a tabela TmpQry.Free; // libera objeto da memria end; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total); end; Carlos Rocha, parece-me que voc quer recalcular o valor total de um determinado pedido, certo?! Primeiramente algumas observaes: 1) note que o exemplo original limitado pelo uso de dataset do tipo Table. Quando voc utiliza dataset do tipo Query, muitas limitaes no existem e facilidades nos esto disponveis; 2) a linha TmpQry.Name := QryItens.Name dever resultar em problema j que os identificadores devem ser nicos e deste modo voc est tentando duplicar o nome do componente; 3) quando voc observa: Observe que, para um novo pedido, o CodigoPedido ainda no foi gerado. Da QryPedidosCodigoPedido.AsString sempre tera valor nulo e no ter tens o pedido.; entendo que no haveria nada a fazer (processar) neste caso; 4) apesar de estar comentada, a linha TmpQry.FindField(QryPedidosCodigoPedido.AsString); no deve ser utilizada da forma como parece ter sido imaginada. FindField procura pelo nome de um campo na lista de Fields do dataset, no nno resultado da consulta/tabela; Ento, vamos tentar abandonar alguns dos vcios impostos pelas limitaes do Paradox e simplificar. Inicialmente, verificamos se devemos fazer, ou no, qualquer processamento em funo da situao do pedido (Novo ou no). Segundo sua observao, quando CodigoPedido for nulo (novo pedido) ainda no havero itens, logo, no faremos qualquer contabilizao. J quando o pedido estiver gravado e poder ter itens, ento vamos procurar pelos mesmos e executar os clculos. Entretanto, o SQL nos oferece funes como o SUM (somatrio) que nos permite enviar numa instruo SELECT a orientao para que o banco faa os clculos e nos retorne o resultado prontinho. Fazemos, ento, uso deste recurso, limitando os itens a serem calculados em funo do CodigoPedido passado como parmetro para a clusula WHERE. CODE

procedure TCPedidos.RecalculaPedido; var TmpQry:TZQuery; Total:Currency; // armazena valores do tipo moeda begin StaticTextTotal.Caption := '0,00'; // se o pedido no tiver itens ou houver exception, este o valor apresentado if not QryPedidosCodigoPedido.IsNull then begin // cria um objeto Qry via codificao TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificao TmpQry.Connection := QryItens.Connection; TmpQry.Name := 'TmpQry'; // *** o Nome do componente deve ser nico!!! TmpQry.SQL.Add('Select SUM(PrecoUni *Quantidade) as Total'); TmpQry.SQL.Add('From Itens'); TmpQry.SQL.Add('Where NumeroPedido = :NumeroPedido'); TmpQry.ParamByName('NumeroPedido').Value := QryPedidosCodigoPedido.AsInteger; TmpQry.Open; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').Value); finally TmpQry.Free; end; end; A forma como foi montada a instruo SQL (temos apenas a funo de agregao - SUM no SELECT) permite que omitamos a clusula GROUP BY, utilizado quando queremos agrupar os valores. Por exemplo, se fosse para gerar uma lista com o total de todos os pedidos, totalizado pedido-a-pedido, teramos de defin-la desta forma:

QUOTE Select NumeroPedido, SUM(PrecoUni *Quantidade) as Total From Itens Group By NumeroPedido Nesta situao, todos as colunas no SELECT, que no so funo de agregao devem ser colocadas na clusula Group By. Aquele AS antes do nome do campo que estamos calculando, no obrigatrio, mas no MSAccess (se no me engano) necessrio. Abraos Carlos Rocha

12/04/2007 - 12:08 Ok, eu entendi. Tentei usar da forma que voc explicou, porem no caso de eu passar um novo pedido(QryPedidos.insert), a a variavel total no funciona, so fica 0,00. Segue o cdigo completo do Formulario.

CODE 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; LabelCodigoCliente: TLabel; LabelLocalFatura: TLabel; LabelLocalCobranca: TLabel; LabelLocalEntrega: TLabel; LabelCPF_CNPJ: TLabel; LabelCEP: TLabel; LabelDataCadastro: TLabel; LabelTotalPedido: TLabel; DBEditCodigoPedido: 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; DBGridItens: TDBGrid; DSPedidos: TDataSource; DSItens: TDataSource; QryClientes2: TZQuery; DSClientes: TDataSource; QryPedidos: TZQuery; QryItens: TZQuery; QryClientes: TZQuery; QryProdutos: TZQuery; 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; QryItensDescricao: TStringField; QryClientes2CodigoCliente: TIntegerField; QryClientes2DataCadastro: TDateField; QryClientes2Tipo: TStringField; QryClientes2CPF_CNPJ: TStringField; QryClientes2Nome: TStringField; QryClientes2Endereco: TStringField; QryClientes2Bairro: TStringField; QryClientes2Cidade: TStringField; QryClientes2Estado: TStringField; QryClientes2Telefone: TStringField; QryClientes2Email: TStringField;

DBRadioGroupCondicaoPagamento: TDBRadioGroup; SpeedButtonImprimir: TSpeedButton; NomeCliente: TLabel; DBLookupComboBoxNomeCliente: TDBLookupComboBox; QryPedidosCodigoPedido: TIntegerField; QryPedidosCondicaoPgto: TStringField; QryPedidosDataCadastro: TDateField; QryPedidosCodigoCliente: TIntegerField; QryPedidosNomeCli: TStringField; QryPedidosLocalFatura: TStringField; QryPedidosLocalCobranca: TStringField; QryPedidosLocalEntrega: TStringField; QryPedidosCPF_CNPJ: TStringField; QryPedidosCEP: TStringField; QryPedidosNomeCliente: TStringField; 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); procedure SpeedButtonImprimirClick(Sender: TObject); procedure QryPedidosCPF_CNPJGetText(Sender: TField; var Text: String; DisplayText: Boolean); private { Private declarations } procedure AtivarControles(Ativar: Boolean); procedure RecalculaPedido; public { Public declarations } end;

var CPedidos: TCPedidos; implementation uses dmsane, PesqPed, RelatorioPedidos, MaskUtils, Math; {$R *.dfm}

procedure TCPedidos.FormCreate(Sender: TObject); begin QryProdutos.Open; QryClientes.Open; QryPedidos.Open; QryItens.Open; end; procedure TCPedidos.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:= cafree; // remove o form da memria CPedidos := NIL; // informa que foi destrudo (no criado) end; procedure TCPedidos.FormDestroy(Sender: TObject); begin QryProdutos.Close; QryClientes.Close; QryPedidos.Close; QryItens.Close; end; procedure TCPedidos.QryPedidosNewRecord(DataSet: TDataSet); begin QryPedidosDataCadastro.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 TmpQry:TZQuery; Total:Currency; // armazena valores do tipo moeda begin // cria um objeto Qry via codificao TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificao TmpQry.Connection := QryItens.Connection; TmpQry.Name := QryItens.Name; TmpQry.SQL.Text := 'Select * from Itens'; TmpQry.Open; //Observe que, para um novo pedido, o CodigoPedido ainda no foi gerado.Self // Da QryPedidosCodigoPedido.AsString sempre tera valor nulo e no ter tens o pedido. TmpQry.Locate('NumeroPedido', QryPedidosCodigoPedido.AsInteger, []); // 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; // prximo registro end; finally TmpQry.Close; // fecha a tabela TmpQry.Free; // libera objeto da memria end; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', Total); end; } procedure TCPedidos.RecalculaPedido; var TmpQry:TZQuery; // Total:Currency; // armazena valores do tipo moeda begin

StaticTextTotal.Caption := '0,00'; // se o pedido no tiver itens ou houver exception, este o valor apresentado if not QryPedidosCodigoPedido.IsNull then begin // cria um objeto Qry via codificao TmpQry := TZQuery.Create(Application); try // define DatabaseName e QryName via codificao TmpQry.Connection := QryItens.Connection; TmpQry.Name := 'TmpQry'; // *** o Nome do componente deve ser nico!!! TmpQry.SQL.Add('Select SUM(PrecoUni * Quantidade) as Total'); TmpQry.SQL.Add('From Itens Where NumeroPedido = :NumeroPedido'); TmpQry.ParamByName('NumeroPedido').Value := QryPedidosCodigoPedido.AsInteger; TmpQry.Open; StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').Value); finally TmpQry.Free; end; end; 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.QryItensNewRecord(DataSet: TDataSet); begin QryItensQuantidade.AsFloat := 1; DBGridItens.SelectedIndex := 0; //cdigo end;

procedure TCPedidos.QryItensBeforeInsert(DataSet: TDataSet); begin if QryPedidosCodigoPedido.AsString = '' then begin if QryPedidos.State = dsInsert then begin // grava para salvar o nmero do pedido na tabela pai QryPedidos.Post;

// ativa a alterao 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 cdigo ShowMessage('Cdigo do produto deve ser informado!'); Abort; // interrompe a gravao end; if QryItensQuantidade.AsFloat <= 0 then begin DBGridItens.SelectedIndex := 2; // seleciona coluna quantidade ShowMessage('Cdigo do produto deve ser informado!'); Abort; // interrompe a gravao end; end; procedure TCPedidos.DBGridItensKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin // muda para a prxima 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; //preo else DBGridItens.SelectedIndex := 0; //cdigo QryItens.Next; if QryItens.Eof then QryItens.Append; end; end; end; procedure TCPedidos.QryItensCodigoProdutoValidate(Sender: TField); begin

if QryItensCodigoProduto.AsString <> '' then begin if QryProdutos.Locate('CodigoProduto', QryItensCodigoProduto.AsInteger, []) then QryItensPrecoUni.AsCurrency := QryProdutosPrecoUni.AsCurrency else begin ShowMessage('Cdigo invlido'); 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 invlida!'); end; end; procedure TCPedidos.SpdBtnIncluirClick(Sender: TObject); begin AtivarControles(True); // ativa os controles para digitao 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, ento devemos incluir SpdBtnIncluir.Click; // executa o click no boto Exit; // retorna end; AtivarControles(True); // ativa os controles para digitao 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 no termos registros rfos 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 excluso do pedido'); end; end; procedure TCPedidos.SpdBtnGravarClick(Sender: TObject); begin if QryPedidosCodigoPedido.AsInteger <= 0 then begin ShowMessage('Digite o nmero do pedido!'); // DBEditCodigoPedido.Enabled := true; DBEditCodigoPedido.SetFocus; end; if DBRadioGroupCondicaoPagamento.Value = '' then begin ShowMessage('Escolha a Condio do Pagamento'); DBRadioGroupCondicaoPagamento.SetFocus; // posiciona o cursor Abort; // no grava e continua editando end; if QryPedidosCodigoCliente.AsInteger > 0 then begin // procura pelo cliente usando o cdigo if not QryClientes.Locate('CodigoCliente', QryPedidosCodigoCliente.AsInteger, []) then begin ShowMessage('Cdigo de cliente invlido!'); DBLookupComboBoxNomeCliente.SetFocus; Exit; end; if QryPedidosCodigoCliente.AsString = '' then

begin ShowMessage('Digite o Cdigo do Cliente!'); DBEditCodigoCliente.SetFocus; Exit; end; end; if DBLookupComboBoxNomeCliente.Text = '' then begin ShowMessage('Por Favor! Escolha o Cliente!'); DBLookupComboBoxNomeCliente.SetFocus; Exit; end; if DBEditLocalFatura.Text = '' then begin ShowMessage('Por Favor! Qual o local da Fatura!'); DBEditLocalFatura.SetFocus; Exit; end; if DBEditLocalCobranca.Text = '' then begin ShowMessage('Por Favor! Qual o local de Cobrana!'); DBEditLocalCobranca.SetFocus; Exit; end; if DBEditLocalEntrega.Text = '' then begin ShowMessage('Por Favor! Qual o local de Entrega!'); DBEditLocalEntrega.SetFocus; Exit; end; if DBEditCPF_CNPJ.Text = '' then begin ShowMessage('Por Favor! Preencha o Documento!'); DBEditCPF_CNPJ.SetFocus; Exit; end; if DBEditCEP.Text = '' then begin ShowMessage('Por Favor! Preencha o CEP!'); DBEditCEP.SetFocus; Exit; 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 incluso/alterao AtivarControles(False); // desativa os controles end; procedure TCPedidos.SpdBtnProcurarClick(Sender: TObject); begin Application.CreateForm(TPPedido, PPedido); PPedido.Show; 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 if QryClientes2Tipo.Value = 'F' then begin QryPedidosCPF_CNPJ.EditMask:='999\.999\.999\-99;0;_'; end else begin QryPedidosCPF_CNPJ.EditMask:='99\.999\.999\/9999\-99;0;_'; end; DBEditCPF_CNPJ.Text := QryClientes2.Fields[3].Value; DBEditCodigoCliente.Text := QryClientes2.Fields[0].Value; DBEditLocalCobranca.Text := QryClientes2.Fields[5].Value +', '+ QryClientes2.Fields[6].Value +' - ' + QryClientes2.Fields[7].Value +'/' +QryClientes2.Fields[8].Value; QryClientes2.Next; end; end; procedure TCPedidos.SpeedButtonImprimirClick(Sender: TObject); begin

QryPedidos.Filter := 'CodigoPedido = ' + DBEditCodigoPedido.Text; QryPedidos.Filtered := true; QryItens.Filter := 'CodigoPedido = ' + QryPedidosCodigoPedido.AsString; QryItens.Filtered := true; Application.CreateForm(TRPedidos, RPedidos); RPedidos.QuickRepPedidos.PreviewModal; RPedidos.Free; end; procedure TCPedidos.QryPedidosCPF_CNPJGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if Sender.IsNull then Text := '' else if length(Sender.AsString)=11 then Text := FormatMaskText('999\.999\.999\-99;0;_', Sender.AsString) else if length(Sender.AsString)=14 then Text := FormatMaskText('99\.999\.999\/9999\-99;0;_', Sender.AsString); end; end.

Te enviei por email os arquivos do projeto pra voc me dar uma ajuda. Desde j meu muito obrigado. Micheus 12/04/2007 - 14:12 QUOTE(Carlos Rocha @ 12/04/2007 - 12:08) Ok, eu entendi. Tentei usar da forma que voc explicou, porem no caso de eu passar um novo pedido(QryPedidos.insert), a a variavel total no funciona, so fica 0,00. Carlos Rocha, acho que no captei a idia ento. Quando voc inclui um novo pedido, inicialmente (at que ele tenha itens) ele no deveria apresentar o valor "0,00" ? No comentrio que eu fiz no post anterior, tomei como regra que em no havendo itens (caso da incluso) o valor do pedido apresentado seria "0,00": 3) quando voc observa: Observe que, para um novo pedido, o CodigoPedido ainda no foi gerado. Da QryPedidosCodigoPedido.AsString sempre tera valor nulo e no ter tens o pedido.; entendo que no haveria nada a fazer (processar) neste caso;

Esta situao j estava descrita nesta linha do cdigo sugerido: StaticTextTotal.Caption := '0,00'; // se o pedido no tiver itens ou houver exception, este o valor apresentado Abraos Carlos Rocha 12/04/2007 - 17:45 voc recebeu o e-mail que te passei no MSN? La tem um arquivo zipado com todo o cdigo do programa. Micheus, da um olhada la que voc vera qual o problema. Micheus 13/04/2007 - 12:20 QUOTE(Carlos Rocha @ 12/04/2007 - 05:45) voc recebeu o e-mail que te passei no MSN? La tem um arquivo zipado com todo o cdigo do programa. Micheus, da um olhada la que voc vera qual o problema. Recebi sim, mas como voc trabalha com MySQL e como eu imaginava - no tenho a estrutura do seu banco para ger-lo aqui - logo, s posso ver suas telas mas no posso executar o programa. Se no tiver como gerar print-screen que mostrem a situao, ento exporte a estrutura do banco (metadata) para que eu possa tentar visualizar o que voc est querendo que eu entenda. Outra informao a verso do Zeos que voc utiliza, j que ao abrir o projeto, h duas propriedades do componente TZQuery que minha verso (6.6.0 - beta) instalada no reconhece. Abraos Carlos Rocha 13/04/2007 - 17:48 Observe que tem um arquivo com noime SaneRio.Sql, ele tem o script das minhas tabelas e s abrir com o bloco de notas. qualquer coisa, a vai a estrutura:

CODE CREATE TABLE IF NOT EXISTS clientes ( CodigoCliente int(4) unsigned NOT NULL auto_increment, DataCadastro date NOT NULL DEFAULT '0000-00-00' , Tipo char(1) NOT NULL DEFAULT '' , CPF_CNPJ varchar(22) NOT NULL DEFAULT '' , Nome varchar(100) NOT NULL DEFAULT '' , Endereco varchar(200) NOT NULL DEFAULT '' , Bairro varchar(200) NOT NULL DEFAULT '' , Cidade varchar(200) NOT NULL DEFAULT '' , Estado varchar(200) NOT NULL DEFAULT '' , Telefone varchar(22) NOT NULL DEFAULT '0' , Email varchar(100) , PRIMARY KEY (CodigoCliente) );

CREATE TABLE IF NOT EXISTS fornecedores ( CodigoFornecedor int(4) unsigned NOT NULL auto_increment, DataCadastro date NOT NULL DEFAULT '0000-00-00' , Tipo char(1) NOT NULL DEFAULT '' , CPF_CNPJ varchar(22) NOT NULL DEFAULT '' , Nome varchar(100) NOT NULL DEFAULT '' , Endereco varchar(200) NOT NULL DEFAULT '' , Bairro varchar(200) NOT NULL DEFAULT '' , Cidade varchar(200) NOT NULL DEFAULT '' , Estado varchar(200) NOT NULL DEFAULT '' , Telefone varchar(22) NOT NULL DEFAULT '0' , Email varchar(100) , PRIMARY KEY (CodigoFornecedor) ); CREATE TABLE IF NOT EXISTS itens ( Item int(4) unsigned NOT NULL auto_increment, NumeroPedido int(4) NOT NULL DEFAULT '0' , CodigoProduto int(4) NOT NULL DEFAULT '0' , Quantidade int(4) NOT NULL DEFAULT '0' , PrecoUni int(11) NOT NULL DEFAULT '0' , PRIMARY KEY (Item) );

CREATE TABLE IF NOT EXISTS pedidos ( CodigoPedido int(4) unsigned NOT NULL auto_increment, CondicaoPgto varchar(200) NOT NULL DEFAULT '' , DataCadastro date NOT NULL DEFAULT '0000-00-00' , CodigoCliente int(4) NOT NULL DEFAULT '0' , NomeCli varchar(100) NOT NULL DEFAULT '' , LocalFatura varchar(200) NOT NULL DEFAULT '' , LocalCobranca varchar(200) NOT NULL DEFAULT '' , LocalEntrega varchar(200) NOT NULL DEFAULT '' , CPF_CNPJ varchar(22) NOT NULL DEFAULT '' , CEP varchar(20) NOT NULL DEFAULT '' , PRIMARY KEY (CodigoPedido) );

CREATE TABLE IF NOT EXISTS produtos ( CodigoProduto int(4) unsigned NOT NULL auto_increment, Descricao varchar(200) NOT NULL DEFAULT '' , PrecoUni int(11) NOT NULL DEFAULT '0' , PRIMARY KEY (CodigoProduto) ); Micheus 13/04/2007 - 19:55 QUOTE(Carlos Rocha @ 13/04/2007 - 05:48) Observe que tem um arquivo com noime SaneRio.Sql, ele tem o script das minhas tabelas e s abrir com o bloco de notas. No sei o que que eu estava procurando, porque no enxerguei este arquivo - agora eu o encontrei. Vou verificar e at amanh dou um "parecer" - ainda tenho que instalar o MySQL aqui em casa. Carlos Rocha 13/04/2007 - 20:04 ento ok. Ficarei aguardando. Desde j meu muito obrigado pela ateno Micheus 14/04/2007 - 15:31

Carlos Rocha, cara tive um trabalhinho extra, j que voc no me respondeu que verso do Zeos est utilizando - As verses recentes no apresentam as propriedades RequestLive e ShowRecordTypes no componente TZQuery e que o compilador insistia em utilizar - tive que remover seus componentes e adicionar os da minha paleta (claro que s troquei os da tela de pedidos). Primeiramente, acho que seria interessante voc definir os relacionamentos em seu banco de dados caso no os tenha definido (no script no havia nenhuma definio) - isso garantir a integridade das informaes e dar um aspecto mais profissional ao seu projeto. Em Paradox este recurso era problemtico, porque neste "prottipo de banco" os arquivos corrompem com certa facilidade - o que no fcil com banco de dados "de verdade". Se precisar de uma ferramenta de modelagem de dados para o MySQL d uma olhada neste post. Executando o programa, consegui realmente ver o que voc queria dizer, entretanto o problema ocorre devido ao fato de ter sido definido o relacionamento entre os dataset's QryPedidos e QryItens dentro do programa. Isso poderia ser feito utilizando Filter, clausula WHERE e deveria funcionar tambm ao setar MasterSource/MasterField/LinkedFields. Eu prefiro utilizar a clusula WHERE. Ento a sugesto para correo seria substituir o SQL de QryItens para: CODE Select * from Itens where NumeroPedido = :CodigoPedido

E associar a sua propriedade DataSource o datasource DSPedidos de onde ser obtido o parmetro CodigoPedido definido no novo SQL. Deste modo, ao abrir QryItens, ser filtrado apenas os itens correspondentes ao Pedido selecionado. Na procedure RecalculaPedido substitua: StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').Value); por StaticTextTotal.Caption := FormatCurr('###,###,##0.00', TmpQry.FieldByName('Total').AsCurrency); isso evitar erro quando Total for nulo (ocorre sempre que no existirem itens ainda). Quando voc utiliza o AsCurrency a converso feita implicitamente e voc tem como resultado 0 (zero). O evento OnCalcFields ocorre para cada item existente no DBGrid, assim recalcular o total a cada evento no ser muito interessante. Digamos que o lgico seria: - quando mudamos de pedido; - quando gravamos um item do pedido (post de um insert ou edit); - quando exclumos um item do pedido.

Assim a sugesto seria utilizar o evento AfterPost, AfterDelete de QryItens e o evento OnDataChange do datasource DSPedidos:

CODE procedure TCPedidos.QryItensAfterPost(DataSet: TDataSet); begin RecalculaPedido; end; esta procedure seria atribuda ao evento AfterDelete tambm ( s associar o evento ao procedimento j existente)

CODE procedure TCPedidos.DSPedidosDataChange(Sender: TObject; Field: TField); begin RecalculaPedido; end;

Faa a ordenao dos seus campos na tela - o Tab Order, j que chato voc teclar TAB e ir para outro campo que no seja o prximo. D uma olhada no evento OnClick do boto de impresso do relatrio, voc vai observar que no texto da propriedade Filter do dataset QryItens voc est utilizando "CodigoPedido = ...", mas o nome do campo na tabela de itens na verdade NumeroPedido! (aqui voc vtima de sua prpria pegadinha...). conveniente que os campos de relacionamentos tenham o mesmo nome nas tabelas envolvidas. Voce enctrar outros pequenos problemas, mas melhor que voc os encontre. Por hora acho que s, espero no ter esquecido de nada. Abraos Carlos Rocha 14/04/2007 - 17:14 Desculpe. ZeosDbo 6.6.0 Carlos Rocha

21/04/2007 - 15:14 Ok Eu queria agora o Seguinte: Fiz o meu QReport(Relatrio), s que eu preciso que as bordas de cada QRBand, tenham cantos arredondados e preciso tambem, colocar uma figura da Logo da empresa no topo do Relatrio e mais uma coisa, Na Aba "Detail", eu queria que, mesmo tendo apenas 2 ou 3 tens o pedido(por exemplo), a borda fizesse linhas entre eles pelo menos ate que uma folha de "A4" se acabasse. Um abrao. Micheus 21/04/2007 - 15:39 QUOTE(Carlos Rocha @ 21/04/2007 - 03:14) Eu queria agora o Seguinte: Fiz o meu QReport(Relatrio), s que eu preciso que as bordas de cada QRBand, tenham cantos arredondados e preciso tambem, colocar uma figura da Logo da empresa no topo do Relatrio e mais uma coisa, Na Aba "Detail", eu queria que, mesmo tendo apenas 2 ou 3 tens o pedido(por exemplo), a borda fizesse linhas entre eles pelo menos ate que uma folha de "A4" se acabasse. Melhor seria voc literalmente desenhar. D para fazer uma prvia do que voc quer e postar um link da imagem? Acho que ficaria mais fcil algum dar sugestes. Mas para adiantar, a parte do logo s voc adicionar uma banda Title e colocar um componente TQRImage (se vier do disco) ou TQRDBImage (se vier do banco). No caso do borda do Detail, no resolve voc definir a propriedade Frame.DrawBottom = True ? Abraos Carlos Rocha 21/04/2007 - 16:32 No funciona porque o que eu quero que, alem de ter a Borda, que a borda seja com os cantos arredodados. Da uma revisada na perguta fazendo favor.

Valeu. Micheus 22/04/2007 - 15:26 QUOTE(Carlos Rocha @ 21/04/2007 - 04:32) No funciona porque o que eu quero que, alem de ter a Borda, que a borda seja com os cantos arredodados. Da uma revisada na perguta fazendo favor. Carlos Rocha, no conheo outro meio que no seja escrevendo um componente para isso.

Você também pode gostar