Treeview usando banco de dados

Delphi

22/10/2012

Galera o urrando com sistema e para visualização de um plano de contas resolví usar um treeview achei um código que funcionou parcial, na minha tabela tenho uma sequincia de numeros que define menu e sub menu..
um exemplo:
1 - admistração (menu principal)
1.01 - serviços externos ( este fica dentro adminitração )
1.01.001 - Telefone ( que fica dentro serviçoes externo)
1.01.002 - Agua ( que tbm fica dentro serviços externo)
2 - Transporte (outro menu principal)
2.01 - Caminhões(este fica dentro trasnporte)
2.01.001 - Motorista(este fica dentro de caminhões)

e assim sucetivamente..o codigo que tenho não esta usasndo o ponto como limitador do menú..gostaria de uma análise dos senhores

 var
   index     : Integer;                   {Número sequencial para criação dos itens}
   intLen1   : Integer;                   {Guarda o tamanho da conta de classificação - atual}
   intLen2   : Integer;                   {Guarda o tamanho da conta de classificação - anterior}
   intPosIni : Integer;                   {Determina o tamanho da conta primeira conta de classificação}

  MyNode    : Array[0..10] of TTreeNode; {Matriz que guarda a posição dos níveis}
   NodeSup   : TTreeNode;                 {Node - da Raiz Principal}
   NodeTmp   : TTreeNode;                 {Node - temporaria}

  strTexto  : String;                    {Obtem o nome da conta de classificação}

begin
   TreeView1.Items.Clear;
   index := -1;

   //Inicializacao
   NodeTmp   := nil;
   NodeSup   := nil;
   intLen2   := 0;
   intPosIni := 1;  {numero de digitos da primeira conta de classificação "Plano de contas" que será utilizada como Nó principal no Treeview }

   //Inicializa a Array que guarda os Nos que determina o grau do plano de contas.
   for intlen1 := 0 to 10 do
     begin
       MyNode[intLen1] := NodeTmp;
     end;
  //Percorre a pesquisa para monta o TreeView
   while not DMConsulta.Cds_Pesc_CentCust .Eof do
     begin
       intLen1   := length(DMConsulta.Cds_Pesc_CentCust.FieldByName('ID_CC').AsString);
       strTexto  := DMConsulta.Cds_Pesc_CentCust.FieldByName('DSC_CC').AsString;
       index     := index + 1;

       //Contralo a criação do nivel principal
       if intLen1 = intPosIni then
         begin
           MyNode[intLen1] := NodeTmp;
           if intLen2 = 0  then
             begin
               NodeSup := treeview1.Items.Add(nil, strTexto);
               index   := index - 1;
             end
           else
             treeview1.Items.Add(NodeSup, strTexto);
         end
       else
         begin
           if intLen1 > intLen2 then
             begin
               NodeTmp         := TreeView1.Items[index];
               MyNode[intLen2] := NodeTmp;
               treeview1.Items.AddChild(TreeView1.Items[index], strTexto);
             end
           else if intLen1 < intLen2 then
             begin
               NodeTmp := TreeView1.Items[index];
               treeview1.Items.Add(MyNode[intLen1],strTexto);
             end
           else if intLen1 = intLen2 then
             begin
               NodeTmp := TreeView1.Items[index];
               MyNode[intLen1] := NodeTmp;
              treeview1.Items.Add(TreeView1.Items[index], strTexto);
             end;
         end;
     if intLen1 <> intLen2 then
        begin
          intLen2 := intLen1;
        end;
     //Avança para o próximo registro
      DMConsulta.Cds_Pesc_CentCust.Next;
     end;


o código está comentado más não entendi muito bem não..vlw
Gilmar Moraes

Gilmar Moraes

Curtidas 0

Respostas

Gilmar Moraes

Gilmar Moraes

22/10/2012

achei este código que usa o ponto como divisor más não usa banco de dados..acho que baseado neste posso fazer o que me atenda.
    function calcularNivelDependente(textoOrigem, adiciona: String): String;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


function TForm1.calcularNivelDependente(textoOrigem: String; adiciona : String): String ;
var
  nivel : array [0..20] of integer;
  i, nivelC  : SmallInt;
  niveisTxt  : TStringList;
  saida : String;
begin
  nivelC := 0;
  niveisTxt := TStringList.Create;
  for i := 0 to 20 do
    nivel[i] := -1;
  try
    niveisTxt.Text := StringReplace(textoOrigem, '.', #13, [rfReplaceAll, rfIgnoreCase]);
    for i := 0 to niveisTxt.Count - 2 do
    begin
      nivel[i] := StrToInt(niveisTxt.Strings[i]);
      nivelC := i;
    end;
    if adiciona = '=' then
      if nivel[nivelC + 1] = -1 then
        nivel[nivelC + 1] := 1;
    if adiciona = '+' then
      if nivel[nivelC] = -1 then
        nivel[nivelC] := 1
      else
        nivel[nivelC] := nivel[nivelC] + 1;

    if adiciona = '=' then
      for i := 0 to nivelC + 1 do
        saida := saida + IntToStr(nivel[i]) + '.';
    if adiciona = '+' then
      for i := 0 to nivelC do
        saida := saida + IntToStr(nivel[i]) + '.';

    Result := saida;
  finally
    niveisTxt.Free;
  end;
end;

procedure TForm1.trv_PlanoCEditing(Sender: TObject; Node: TTreeNode;
  var AllowEdit: Boolean);
begin
  if Node.Enabled = False then
  begin
    Application.MessageBox(Pchar(Format('A Conta "%s" foi Cancelada e não pode mais ser reutilizada !',[trv_PlanoC.selected.Text])),
     'Conta Cancelada', MB_ICONINFORMATION);
    AllowEdit := False;
  end;
end;

procedure TForm1.trv_PlanoCKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  i, n, ponto, oldV, newV : Integer;
  textoPos : String;
begin
  if ((Key = VK_INSERT) or (key = VK_F2)) then //inserir um item
    if (trv_PlanoC.Selected = nil) then
    begin
      if trv_PlanoC.Items.Count = 0 then
        trv_PlanoC.Items.Add(nil, '1. ')
      else begin
        oldV  := 0;
        newV  := 0;
        //ponto := 0;
        for i := 0 to pred(trv_PlanoC.Items.Count) do
        begin
          n := 1;
          while n <= Length(trv_PlanoC.Items.Item[i].Text) do
          begin
            if (Copy(trv_PlanoC.Items.Item[i].Text, n, 1) = '.') then
            begin
              ponto := n;
              if ponto > 1 then
                newV := StrToInt(Copy(trv_PlanoC.Items.Item[i].Text, 1, ponto - 1));
              if oldV < newV then
              begin
                oldV := newV;
                newV := 0;
              end;
              Break;
            end;
            n := n + 1;
          end;
        end;
        trv_PlanoC.Items.Add(nil, format('%d. ',[oldV + 1]));
      end;
    end else begin
      with trv_PlanoC do
      begin
        Items.BeginUpdate;
        if (Selected.HasChildren = False) then
        begin
          with trv_PlanoC.Items.AddChild(trv_PlanoC.Selected, format('%s ',[calcularNivelDependente(trv_PlanoC.Selected.Text, '=')])) do
            MakeVisible;
        end else begin
          textoPos := trv_PlanoC.Selected.GetLastChild.Text;
          with trv_PlanoC.Items.AddChild(trv_PlanoC.Selected, format('%s ',[calcularNivelDependente(textoPos, '+')])) do
            MakeVisible;
        end;
        Items.EndUpdate;
      end;
    end;

  if (Key = VK_ESCAPE) then //sair da seleção
    trv_PlanoC.Selected := nil;

  if (Key = VK_F4) then
  begin
    if trv_PlanoC.Selected = nil then
      Application.MessageBox('Para poder cancelar uma conta, você deve selecionar a conta primeiro !', 'Sem Seleção de Conta', MB_ICONWARNING)
    else
      if Application.MessageBox(Pchar(format('Você deseja cancelar o uso da conta "%s" ?',[ trv_PlanoC.Selected.Text])),
        'Cancelar Conta', MB_ICONQUESTION + MB_YESNO) = mrYes then
          trv_PlanoC.Selected.Enabled := False;
  end;

end;

procedure TForm1.trv_PlanoCKeyPress(Sender: TObject; var Key: Char);
begin
  If CharInSet(key, ['.']) then
  begin
    MessageDlg('Não digite ponto (.), o sistema usa esse sinal para nivelar as contas.',
    mtInformation, [mbOK], 0);
    key := #0;
  end;
end;

end.
GOSTEI 0
Gilmar Moraes

Gilmar Moraes

22/10/2012

se eu tentar tirar os pontos deve funcionar tbm..
GOSTEI 0
Jurandi Frade

Jurandi Frade

22/10/2012

Veja em http://delphi.about.com/od/vclusing/l/aa060603a.htm
Bons exemplos para o que vc quer.

Sds,
GOSTEI 0
Gilmar Moraes

Gilmar Moraes

22/10/2012

Veja em http://delphi.about.com/od/vclusing/l/aa060603a.htm
Bons exemplos para o que vc quer.

Sds,


vlw mesmo pela ajuda dei uma olhada, o meu treeview está bem andiatando, o prmeiro código que postei ele funciona e ordena os dados da tabela, más dakela forma que espliquei acima..o problema que este componete é bem compplicado, dei uma lida sobre o componente más sinceramente to quebrando bem a cuca com isso..

más o que fiz até agora foi lista por orbem pelo cógido na tabela..faço uma loop pela tabela e pego todos os dados no treeview até aí funciona más não da forma certa, ele fica desordenado tem menu entrando onde não devia.. o problema já indetifiquei más não sei resolver, o código foi feito para numeros odernados para funcionar deta forma..

1 - admistração (menu principal)
101 - serviços externos ( este fica dentro adminitração )
101001 - Telefone ( que fica dentro serviçoes externo)
101002 - Agua ( que tbm fica dentro serviços externo)
2 - Transporte (outro menu principal)
201 - Caminhões(este fica dentro trasnporte)
201001 - Motorista(este fica dentro de caminhões)

neste caso ele funciona perfeito. o problema é que tenho uma tabela pronta com muitos registros, achei que seria mais viável mudar o código do que os registros..que deveriam funionar com esta tabela;.

1 - admistração (menu principal)
1.01 - serviços externos ( este fica dentro adminitração )
1.01.001 - Telefone ( que fica dentro serviçoes externo)
1.01.002 - Agua ( que tbm fica dentro serviços externo)
2 - Transporte (outro menu principal)
2.01 - Caminhões(este fica dentro trasnporte)
2.01.001 - Motorista(este fica dentro de caminhões)

neste momento estou endo a possibilidade de usar uma função para quando ele tiver verificando a tabela retirar o ponto na hora da leitura, más já estou estudando a possibilidade de mudas os dados ao invés da função..

vlw..se tiver mais alguma idéia..vlw mesmo
GOSTEI 0
Alisson Santos

Alisson Santos

22/10/2012

estou concluindo o tópico qualquer duvida nos notificar.
GOSTEI 0
POSTAR