Listar campos de uma tabela e exibir no stringgrid

30/05/2010

0

Boa tarde, galera. Estou abrindo um novo post, pois o último que postei ficou muito complicado de entender, preciso começar de novo. Vamos ao caso: Preciso exibir a soma dos valores anuais de três empresas em forma de grid. Ex:   Ano         Firma1         Firma2       Firma3 2009       1000,00       2000,00    3000,00 2010       1500,00       2500,00    3500,00 ....           ........            ...              ...             E assim por diante. Todos os dados estão numa tabela só. Ex: Cod_Firma, Data_Recebimento, Valor_Recebido. Estou usando " simpledataset" (Precisa ser com ele as funções); Aí vem a questão como pegar os dados e exibir no stringgrid??? Fiz um select na Query que está mais ou menos assim: ******************************************* Select Distinct Extract (Year From Data_Recebimento) as Ano,
Cod_firma,coalesce(sum(valor_Recebido),0) as Total
 from Historicos_Recebimento
Group By 1,2
Order by 1,2 Gostaria de saber como fazer, peciso ser meio(bastante mastigado), já tive ajuda de algumas pessoas, mas não consegui fazer os dados a serem exibidos  passarem da segunda coluna. Preciso muito da ajuda de vocês Obrigado.   Eduardo  
Eduardo

Eduardo

Responder

Posts

30/05/2010

Eduardo

Gente o desespero é tanto que montei este procedimento no botão, só que os campos no stringgrid estão duplicados, alguém poderia corrigir o código. Ver também se está mais ou menos certo???     procedure TformPeriodo.BitBtn1Click(Sender: TObject);
var
Total_Firma:array[1..3] of string;
ano:integer;
J:integer;
CodFirma:integer;
begin   strGrdTeste.Cells[0,0]:='Ano';
  strGrdTEste.Cells[1,0]:='Firma1';
  strGrdTeste.Cells[2,0]:='Firma2';
  strGrdTeste.Cells[3,0]:='Firma3';      strGrdTeste.RowCount:=11;
     strGrdTeste.ColCount:=5;        strGrdTeste.RowCount:=strGrdTeste.RowCount +1;
       j:=1;
       dm2.sdsTeste3.DisableControls;
       dm2.sdsTeste3.First;
       while not dm2.sdsTeste3.Eof do
        begin
           CodFirma:=dm2.sdsTeste3COD_FIRMA.AsInteger;
            if CodFirma = 1 then
            begin             Total_Firma[1]:=dm2.sdsteste3Total.asstring;
            end
            else
            if CodFirma = 2 then
            begin
              Total_Firma[2]:=dm2.sdsTeste3TOTAL.AsString;
              end
               else
               if CodFirma = 3 then
               begin
              Total_Firma[3]:=dm2.sdsTeste3TOTAL.AsString;             end;
           strGrdTeste.Cells[1,j]:=Total_Firma[1];
           strGrdTeste.Cells[2,j]:=Total_Firma[2];
           strGrdTeste.Cells[3,j]:=Total_Firma[3];           dm2.sdsteste3.next;
          inc(j);
          end;
          dm2.sdsTeste3.First;
          dm2.sdsTeste3.EnableControls;
           end; Obrigado
Responder

31/05/2010

Emerson Nascimento

instrução:

Select
  Extract(Year From Data_Recebimento) as Ano,
  Cod_firma,
  Coalesce(sum(valor_Recebido),0) as Total
from
  Historicos_Recebimento
Group By 1,2



código do procedimento (só funciona da forma como está se as firmas tiverem código 1, 2 e 3):

procedure TformPeriodo.BitBtn1Click(Sender: TObject);
var
  Total_Firma:array of array[0..3] of string;
  Ano: string;
  J, nElemento:integer;
  CodFirma:integer;

  // função interna usada verificar se o ano já foi manipulado
  function FindYear(sYear: string): integer;
  var
    i: integer;
  begin
    Result := -1;
    if Length(Total_Firma) > 0 then
      for i := 0 to High(Total_Firma) do
        if Total_Firma[i, 0] = sYear then
        begin
          Result := i;
          exit;
        end;
  end;
begin
  strGrdTeste.RowCount := 2;
  strGrdTeste.ColCount := 4;
  strGrdTeste.FixedCols := 0;
  strGrdTeste.FixedRows := 1;

  strGrdTeste.Cells[0,0]:='Ano';
  strGrdTEste.Cells[1,0]:='Firma1';
  strGrdTeste.Cells[2,0]:='Firma2';
  strGrdTeste.Cells[3,0]:='Firma3';

  // preenche o array, que será usado para preencher a stringgrid
  dm2.sdsTeste3.DisableControls;
  dm2.sdsTeste3.First;
  while not dm2.sdsTeste3.Eof do
  begin
    CodFirma := dm2.sdsTeste3COD_FIRMA.AsInteger;
    Ano := dm2.sdsTeste3ANO.AsString;
    nElemento := FindYear(Ano);
    if nElemento < 0 then
    begin
      SetLength(Total_Firma, Length(Total_Firma)+1);
      nElemento := High(Total_Firma);
      Total_Firma[nElemento, 0] := Ano;
    end;
    Total_Firma[nElemento, CodFirma] := dm2.sdsteste3Total.AsString;

    dm2.sdsTeste3.Next;
  end;
  dm2.sdsTeste3.First;
  dm2.sdsTeste3.EnableControls;

  // com o array manipulado, preenche a stringgrid
  if Length(Total_Firma) > 0 then
    for j := 0 to High(Total_Firma) do
    begin
      strGrdTeste.Cells[0,j+1] := Total_Firma[j, 0];
      strGrdTeste.Cells[1,j+1] := Total_Firma[j, 1];
      strGrdTeste.Cells[2,j+1] := Total_Firma[j, 2];
      strGrdTeste.Cells[3,j+1] := Total_Firma[j, 3];
      strGrdTeste.RowCount := strGrdTeste.RowCount +1;
    end;
end;

Responder

31/05/2010

Eduardo

Boa noite e obrigado por começar a ajudar. Esqueci de dizer que estou usando Delphi 2010 e Firebird 2.15 e dbExpress. Fiz o código que me passou mas deu um erro: [DCC Error] uformPeriodo.pas(117): E2157 Element 0 inaccessible - use 'Length' or 'SetLength'.   Tem idéia do que seja??? Obrigado
Responder

01/06/2010

Emerson Nascimento

você colou o código exatamente como foi postado aqui?

informe qual é a linha 117 do seu código fonte....
Responder

01/06/2010

Wilson Junior

O problema está na declaração da variável "Total_Firma:array of array[0..3] of string;", pois é uma matriz e está sendo passado somente o tamanho de uma das dimensões.

Espero ter colaborado.
Responder

01/06/2010

Emerson Nascimento

"O problema está na declaração da variável "Total_Firma:array of array[0..3] of string;", pois é uma matriz e está sendo passado somente o tamanho de uma das dimensões."

é assim mesmo que é pra ser passado. só é sabido o tamanho de uma das dimensões. a outra é dinâmica e será manipulada pela SetLength().

isso funciona em todas as versões desde o Delphi 3 até o Delphi 2006, que é o que eu uso atualmente. não sei nas versões mais recentes.

mas acredito que não seja esse o problema.
Responder

01/06/2010

Eduardo

O codigo foi feito exatamente como passado e conferido. Só informando que os campos em minha tabela estão: Data_Recebimento (Date) Valor_Recebido       (Decimal); Cod_Firma               (integer); O Erro na hora de compilar começa aqui:   [DCC Error] uformPeriodo.pas(89): E2010 Incompatible types: 'string' and 'Integer'
[DCC Error] uformPeriodo.pas(115): E2008 Incompatible types
[DCC Error] uformPeriodo.pas(117): E2157 Element 0 inaccessible - use 'Length' or 'SetLength'
[DCC Error] uformPeriodo.pas(119): E2010 Incompatible types: 'Char' and 'string'
[DCC Error] uformPeriodo.pas(127): E2157 Element 0 inaccessible - use 'Length' or 'SetLength'
[DCC Fatal Error] Controles.dpr(28): F2063 Could not compile used unit 'uformPeriodo.pas'   "if Total_Firma[i,0] = sYear then" (1º erro) "SetLength(Total_Firma, Length(Total_Firma)+1);" "Total_Firma[nElemento,0]:=Ano;" "Total_Firma[nElemento,CodFirma]:=dm2.sdsTeste3TOTAL.AsString;" "strGrdTeste.Cells[0,j+1]:=Total_Firma[j,0];" ''uRecebimento_Vendedor in 'uRecebimento_Vendedor.pas' ;'' Erros listados em ordem.   Obrigado
Responder

01/06/2010

Emerson Nascimento

publique o código exatamente como está no seu fonte... não acho que estejam idênticos...
Responder

01/06/2010

Eduardo

Mil, desculpas. Realmente estava errado meu código: Aqui estava faltando " of array" Total_firma:array of array [0..3] of string;   Ficou muito bom, só amolando mais um pouco, será que é possível me explicar este código linha por linha para que possa entender o funcionamento. Gostaria de aprender mais sobre array, laço for, tem aluma apostila, algum artigo, ou mesmo nome de um livro para que possa comprar, os livros que tenho fala muito pouco sobre este assunto.   E também agora que este código está praticamente resolvido, será que tem como somar em uma nova coluna, a soma anual por empresa. Ex:   Ano           Firma1          Firma2         Firma3        Total 2009         1000,00        2000,00      3000,00 =  6000,00  ...   e assim também:                   1000,00       2000,00      3000,00       6000,00   poderia ser label ou no grid mesmo o que for mais fácil.   Desde já agradeço muito. Ficou Showwwww!!!!!
Responder

02/06/2010

Emerson Nascimento

usando array, como no exemplo passado por você:

procedure TForm12.Button1Click(Sender: TObject);
var
  Total_Firma:array of array[0..4] of variant;
  Ano: integer;
  J, nElemento:integer;
  CodFirma:integer;
  nCol1, nCol2, nCol3, nCol4: variant;

  // função interna usada verificar se o ano já foi manipulado
  function FindYear(sYear: integer): integer;
  var
    i: integer;
  begin
    Result := -1; // resulta -1, indicando que não encontrou o ano informado
    // se há elementos no array, procura pelo ano informado
    if Length(Total_Firma) > 0 then
      for i := 0 to High(Total_Firma) do // varrendo o array...
        if Total_Firma[i, 0] = sYear then // se o ano informado for encontrado...
        begin
          Result := i; // manda como resultado da função o índice do elemento encontrado
          exit;        // e sai do laço
        end;
  end;
begin
  strGrdTeste.RowCount := 2;
  strGrdTeste.ColCount := 5;
  strGrdTeste.FixedCols := 0;
  strGrdTeste.FixedRows := 1;

  strGrdTeste.Cells[0,0]:='Ano';
  strGrdTEste.Cells[1,0]:='Firma1';
  strGrdTeste.Cells[2,0]:='Firma2';
  strGrdTeste.Cells[3,0]:='Firma3';
  strGrdTeste.Cells[4,0]:='Total Ano';

  // preenche o array, que será usado para popular a stringgrid
  dm2.sdsTeste3.DisableControls;
  dm2.sdsTeste3.First;
  while not dm2.sdsTeste3.Eof do
  begin
    CodFirma := dm2.sdsTeste3COD_FIRMA.AsInteger;
    Ano := dm2.sdsTeste3ANO.AsInteger;
    nElemento := FindYear(Ano); // verifica se o ano atual já está no array
    // se o ano NÃO está no array
    if nElemento < 0 then
    begin
      // incrementa o número de elementos do array
      SetLength(Total_Firma, Length(Total_Firma)+1);
      nElemento := High(Total_Firma); // obtém o índice do último elemento
      Total_Firma[nElemento, 0] := Ano; // atribui o ano à primeira coluna do novo elemento
      Total_Firma[nElemento, 1] := 0; // atribui zero às demais colunas Firma1
      Total_Firma[nElemento, 2] := 0; //                                Firma2
      Total_Firma[nElemento, 3] := 0; //                                Firma3
      Total_Firma[nElemento, 4] := 0; //                                Total Ano
    end;
    // atribui o valor do campo à coluna correspondente à firma atual
    Total_Firma[nElemento, CodFirma] := dm2.sdsteste3Total.AsFloat;
    // atribui o valor à coluna de totais, sempre somando o valor da firma posicionada
    Total_Firma[nElemento, 4] := (Total_Firma[nElemento, 4] + dm2.sdsteste3Total.AsFloat);

    // vai para o próximo registro da tabela
    dm2.sdsTeste3.Next;
  end;
  dm2.sdsTeste3.First;
  dm2.sdsTeste3.EnableControls;

  // variáveis onde serão calculados os totais das colunas
  nCol1 := 0;
  nCol2 := 0;
  nCol3 := 0;
  nCol4 := 0;

  // com o array manipulado, preenche a stringgrid
  if Length(Total_Firma) > 0 then
  begin
    for j := 0 to High(Total_Firma) do
    begin
      // atribui o valor obtido no array às colunas da stringgrid
      strGrdTeste.Cells[0,j+1] := Total_Firma[j, 0];
      strGrdTeste.Cells[1,j+1] := Total_Firma[j, 1];
      strGrdTeste.Cells[2,j+1] := Total_Firma[j, 2];
      strGrdTeste.Cells[3,j+1] := Total_Firma[j, 3];
      strGrdTeste.Cells[4,j+1] := Total_Firma[j, 4];

      // acumula os valores nas variáveis
      nCol1 := nCol1 + Total_Firma[j, 1];
      nCol2 := nCol2 + Total_Firma[j, 2];
      nCol3 := nCol3 + Total_Firma[j, 3];
      nCol4 := nCol4 + Total_Firma[j, 4];

      // cria uma nova linha
      strGrdTeste.RowCount := strGrdTeste.RowCount +1;
    end;

    // grava os totais na stringgrid
    j := strGrdTeste.RowCount-1;
    strGrdTeste.Cells[0, j] := 'TOT.GERAL';
    strGrdTeste.Cells[1, j] := nCol1;
    strGrdTeste.Cells[2, j] := nCol2;
    strGrdTeste.Cells[3, j] := nCol3;
    strGrdTeste.Cells[4, j] := nCol4;
  end;
end;



você pode também eliminar o array, colocando os valores diretamente na grade:

procedure TForm12.Button2Click(Sender: TObject);
var
  Ano: integer;
  i, j, nElemento:integer;
  CodFirma:integer;

  // função interna usada verificar se o ano já foi manipulado
  function FindYear(sYear: integer): integer;
  var
    i: integer;
  begin
    Result := -1; // resulta -1, indicando que não encontrou o ano informado
    // se há registros na stringgris, procura pelo ano informado
    if strGrdTeste.RowCount > 2 then
      for i := 1 to strGrdTeste.RowCount-1 do // varrendo o array...
        if strGrdTeste.Cells[0, i] = IntTostr(sYear) then // se o ano informado for encontrado...
        begin
          Result := i; // manda como resultado da função o índice da linha encontrada
          exit;        // e sai do laço
        end;
  end;
begin
  // limpa todas as celulas da stringgrid
  for j := 0 to strGrdTeste.RowCount - 1 do
    for nElemento := 0 to strGrdTeste.ColCount - 1 do
      strGrdTeste.Cells[nElemento, j] := '0';

  // configura a stringgrid
  strGrdTeste.RowCount := 2;
  strGrdTeste.ColCount := 5;
  strGrdTeste.FixedCols := 0;
  strGrdTeste.FixedRows := 1;

  strGrdTeste.Cells[0,0]:='Ano';
  strGrdTEste.Cells[1,0]:='Firma1';
  strGrdTeste.Cells[2,0]:='Firma2';
  strGrdTeste.Cells[3,0]:='Firma3';
  strGrdTeste.Cells[4,0]:='Total Ano';

  // varre a tabela e preenche a stringgrid
  dm2.sdsTeste3.DisableControls;
  dm2.sdsTeste3.First;
  while not dm2.sdsTeste3.Eof do
  begin
    CodFirma := dm2.sdsTeste3COD_FIRMA.AsInteger;
    Ano := dm2.sdsTeste3ANO.AsInteger;
    nElemento := FindYear(Ano); // verifica se o ano atual já está na stringgrid
    // se o ano NÃO está na stringgrid...
    if nElemento < 0 then
    begin
      nElemento := strGrdTeste.RowCount-1; // obtém a última linha da stringgrid
      strGrdTeste.Cells[0, nElemento] := IntToStr(Ano);
      strGrdTeste.Cells[1, nElemento] := '0'; // atribui zero às demais colunas Firma1
      strGrdTeste.Cells[2, nElemento] := '0'; //                                Firma2
      strGrdTeste.Cells[3, nElemento] := '0'; //                                Firma3
      strGrdTeste.Cells[4, nElemento] := '0'; //                                Total Ano
      //incrementa o número de linhas da stringgrid
      strGrdTeste.RowCount := strGrdTeste.RowCount + 1;
    end;
    // atribui o valor do campo na coluna correspondente à firma atual
    strGrdTeste.Cells[CodFirma, nElemento] := dm2.sdsteste3Total.AsString;
    // atribui o valor à coluna de totais, sempre adicionando o valor da firma posicionada
    strGrdTeste.Cells[4, nElemento] :=
       FloatToStr(StrToFloat(strGrdTeste.Cells[4, nElemento]) +
       dm2.sdsteste3Total.AsFloat);

    // vai para o próximo registro da tabela
    dm2.sdsTeste3.Next;
  end;
  dm2.sdsTeste3.First;
  dm2.sdsTeste3.EnableControls;

  // totaliza as colunas da stringgrid
  i := strGrdTeste.RowCount-1;
  strGrdTeste.Cells[0, i] := 'TOT.GERAL';
  for nElemento := 1 to strGrdTeste.ColCount - 1 do
    for j := 1 to strGrdTeste.RowCount - 2 do
      strGrdTeste.Cells[nElemento, i] :=
         FloatToStr(StrToFloat(strGrdTeste.Cells[nElemento, i]) +
         StrToFloat(strGrdTeste.Cells[nElemento, j]));
end;

Responder

05/06/2010

Eduardo

Show de bolaaaaa!!!!!!!!!!Emerson Desculpa da demora em responder, estava um pouco atarefado. Mas agora, acho que estamos quase terminando esta aula. Você deveria fazer um artigo sobre isto e postar no site, pois percebo que muita gente procura por isto e não encontra uma explicação tão bem detalhada. Mas até agora faltou a formatação dos valores no stringgrid 'R$ 0,00' e o alinhamento das colunas. Com isto vai ficar show. Obrigado
Responder

09/06/2010

Carlos Mazzi

POr favor, fechar o chamado. abracos++
Responder

09/06/2010

Eduardo

Quais são os códitos para formatar as celulas com R$?????? E o alinhamento também?????? Obrigado
Responder

26/09/2010

Eduardo

Boa tarde, com este código acima que ficou show de bola, agora preciso alinhar à direita do stringrid e colocar a soma das colunas com negrito e fonte diferente. Como faço???? Obrigado
Responder

27/09/2010

Wilson Junior

No evento OnDrawCell do TStringGrid coloque:

var
  aLeft: integer;
  Texto:  string;
begin
  if  ACol = INDICE_COLUNA_ALINHAR then
    begin
      with NomeStringGrid.Canvas do
      begin
        { Alinha a direita o conteúdo da coluna INDICE_COLUNA_ALINHAR }
        Texto := NomeStringGrid.Cells[ACol, ARow];
        aLeft := Rect.Right - TextWidth( Texto ) - 5

        { Coloca em negrito e a cor em azul }
        Font.Color := clBlue;
        Font.Style := Font.Style + [fsBold];

        TextRect( Rect, aLeft, Rect.Top + 2, Texto );
      end;
    end
  ;
end;


Espero ter colaborado.
Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar