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

Definindo As Propriedades De Campos Numericos Em Um


paulobergo

Pergunta

Criando um TTable em "runtime", definindo o tipo dos campos numéricos conforme a tabela.

Segue um fragmento da rotina de criação, em "runtime", de um componente TTable com

tipos de campos variados.

A motivação para isso é:

- Tendo um programa para edição de uma tabela de inventário, é preciso que este programa

abra tabelas de diferentes gerenciadores; as tabelas tem, em comum, determinados campos,

necessários para se fazer um inventário: codigointerno, codigoean, descricao, unidade,

custoun, saldo;

- Uma vez que as tabelas podem ser diferentes (MySQL, Paradox, FoxPro ou VisualdBase7),

os campos numericos são diferentes (tFloat ou tBCD)... e como há um campo calculado (no

caso, o valor do produto = custoun X saldo), é preciso definir no dataset da tabela os

campos que serão utilizados;

- Como não conseguia "redefinir" os tipos dos campos que geravam problema (custoun e saldo),

utilizava quatro componentes TTable distintos, um para cada tipo de gerenciador;

- Para eliminar estes componentes, a solução foi criar um único TTable, em "runtime",

com os campos necessários...

Como o código todo é muito extenso, coloquei somente as partes mais importantes...

Nome do form: formInveEdit ("formulário para Edição de Inventário")

//

Procedure TformInveEdit.FormCreate(Sender: TObject);
Begin
  // Criar o componente TTable aqui, ao criar o form
  Invent := TTable.Create(Application);
  InventDS.DataSet := Invent;
  Invent.OnCalcFields := InventCalcFields;
End;

Procedure TformInveEdit.InventCalcFields(DataSet: TDataSet);
Begin
  // Este evento "calcula" o valor de cada item, multiplicando o custo unitário pela quantidade
  // do produto.
  With Invent do Begin
    Try
      FieldByName('valor').AsFloat :=
        FieldByName('custoun').AsFloat*
        FieldByName('saldo').AsFloat;
    Except
      FieldByName('valor').AsFloat := 0;
    End;
  End;{With Invent}
End;

Procedure TformInveEdit.AbrirButtonClick(Sender: TObject); // Botão para Abrir/Fechar a Tabela
Var
  MyFieldCustoUnBCD, MyFieldSaldoBCD: TBCDField;
  MyFieldValor, MyFieldCustoFloat, MyFieldSaldoFloat: TFloatField;
  MyFieldDescricao: TStringField;
Begin

  sTable := sTableEdit.Text;
  If AbrirButton.Caption = '&Abrir' then
    Begin
      If Invent.Active then
        Invent.Close;
      {EndIf}
      AbrirButton.Caption := 'Fechar';
      Invent.TableName := sTable+IIF(bMySQLUse,'','.dbf'); 
      // ********** Só consigo definir os campos na primeira vez que acesso a tabela.
      //            Do contrário, teria que "destruir" o componente e criá-lo de
      //            novo. 
      If bFirstOpen then
        Begin
          // ********************** Definições dos campos. Início.
      // Primeiro, o campo "calculado", valor, sempre "tFloat".
          Invent.FieldDefs.Clear;
          MyFieldValorFloat := TFloatField.Create(Invent); //  .Create(Invent);
          With MyFieldValorFloat do Begin
            FieldName := 'valor';
            Calculated := True;
            DataSet := Invent;
            Name := 'Invent'+'valor';
            DisplayFormat := '0.00';
            Invent.FieldDefs.Add(Name, ftFloat, 0, false);
            Invent.FieldDefs.Update;
          End;
          MyFieldDescricao := TStringField.Create(Invent);
          With MyFieldDescricao do Begin
            FieldName := 'descricao';
            Calculated := False;
            DataSet := Invent;
            Size := 6;
            Name := 'Invent'+'descricao';
            Invent.FieldDefs.Add(Name, ftString, 06, false);
          End;
          If bMySQLUse or bIsParadox then
        // Se quero abrir uma tabela de inventário feita no Paradox ou MySQL, criar
        // campos de saldo e custo unitário como tFloat
            Begin
              MyFieldCustoUnFloat := TFloatField.Create(Invent);
              With MyFieldCustoUnFloat do Begin
                FieldName := 'custoun';
                Calculated := False;
                DataSet := Invent;
                Name := 'Invent'+'custoun';
                Precision := 0;
                Size := 0;
                // sFormatoCusto depende de cada empresa;
        // Numa fabrica de raçoes, onde o custo unitário tem até quatro casas decimais,
        // é "0.0000"; num comércio comu, é "0.00"
                DisplayFormat := sFormatoCusto;
                EditFormat    := sFormatoCusto;
                Invent.FieldDefs.Add(Name, ftFloat, 0, false);
              End;
              // Se tabela pelo MySQL, usar TFloat ********** Início ********
              MyFieldSaldoFloat := TFloatField.Create(Invent);
              With MyFieldSaldoFloat do Begin
                FieldName := 'saldo';
                Calculated := False;
                DataSet := Invent;
                Name := 'Invent'+'saldo';
                Precision := 0;
                Size := 0;
                // sFormatoEstoque depende de cada empresa;
        // Numa loja que não tem estoque fracionado, será "0" e numa loja que tem
        // estoque fracionado (agropecuária por exemplo), pode ser "0.000"
                DisplayFormat := sFormatoEstoque;
                EditFormat    := sFormatoEstoque;
                Invent.FieldDefs.Add(Name, ftFloat, 0, false);
              End;{With MyFieldEstestaFloat}
              // Se tabela pelo MySQL ou Paradox, usar TFloat ********** Fim ********
            End
          Else
            Begin
              // Se tabela ttDbase ou ttFoxPro, usar TBCD ********** Início ********
              MyFieldCustoUnBCD := TBCDField.Create(Invent);
              With MyFieldCustoUnBCD do Begin
                FieldName := 'custoun';
                Calculated := False;
                DataSet := Invent;
                Name := 'Invent'+'custoun';
                Precision := 0;
                Size := 4;
                // sFormatoCusto depende de cada empresa;
        // Numa fabrica de raçoes, onde o custo unitário tem até quatro casas decimais,
        // é "0.0000"; num comércio comu, é "0.00"
                DisplayFormat := sFormatoCusto;
                EditFormat    := sFormatoCusto;
                Invent.FieldDefs.Add(Name, ftBCD, 4, false);
              End;
              MyFieldSaldoBCD := TBCDField.Create(Invent);
              With MyFieldSaldoBCD do Begin
                FieldName := 'saldo';
                Calculated := False;
                DataSet := Invent;
                Name := 'Invent'+'saldo';
                Precision := 0;
                Size := 3;
                // sFormatoEstoque depende de cada empresa;
        // Numa loja que não tem estoque fracionado, será "0" e numa loja que tem
        // estoque fracionado (agropecuária por exemplo), pode ser "0.000"
                DisplayFormat := sFormatoEstoque;
                EditFormat    := sFormatoEstoque;
                Invent.FieldDefs.Add(Name, ftBCD, 3, false);
              End;{With MyFieldEstestaBCD}
              // Se tabela ttDbase, usar TBCD ********** Fim ********
            End;
          {EndIf}
          // ********************** Definições dos campos. Final.
        End;
      {EndIf bFirstOpen then
      bFirstOpen := False;
      Invent.Open;
      Invent.First;
      StatusBar1.SimpleText := IntToStr(Invent.RecNo)+'/'+IntToStr(Invent.RecordCount);
    End
  Else
    Begin
      Invent.Close;
      StatusBar1.SimpleText := '0/0';
      AbrirButton.Caption := '&Abrir';
    End;
  {EndIf}
  ..
  ..
  ..

Espero que seja de alguma utilidade!

Abraços!

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

2 respostass a esta questão

Posts Recomendados

  • 0

paulobergo, pelo que você menciona: "Por exemplo, se o campo precocusto estiver definido como tFloatField (para abrir as tabelas do VisualDBase), se tento abrir uma tabela do FoxPro, recebo a mensagem "Type mismatch for field "precocusto", expecting: Float actual BCD" ";

parece-me que você adicionou os campos (fields) ao seu dataset. Seria isto?

Se for, e eu sou favorável a esta modalidade, mas acho que para esta situação em específico faz-se necessário não acioná-los ao dataset. Isto fará com que ao ser aberto seu dataset, independente de qual banco você esteja acessando, a rotina responsável pela criação dos fields, automaticamente criará a instância correta dos mesmos e você poderá acessá-los no código pelo indexador ou pelo método FieldByName (prefiro este pela clareza no código). Para viabilizar isto, você deveria remover os fields de seu dataset.

Já testou desta forma?

Você não deu maiores detalhes de como utiliza este dataset, então para o caso de ele estar ligado a um DBGrid e queira ajustar o label dos mesmos, há meios para isso via código ou até mesmo em design-time.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Olá!

O problema é que preciso de um campo calculado (o valor de cada produto, no caso, qtde x custo)...

Daí sou obrigado a colocar os campos necessários na definição da tabela...

Quanto ao uso da tabela, realmente ela é aberta em um dbGrid, para correção de algumas informações... quanto ao Dbgrid não há problema...

Agora estou pensando na possibilidade de criar o componente TTable em runtime... por enquanto, vou mantendo três ttables no form (um para VisualDBase, um para FoxPro e outro para MySQL)...

De qualquer forma, grato pela atenção...

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,3k
    • Posts
      652,5k
×
×
  • Criar Novo...