Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Oi Pessoal...
Meu problema é o seguinte:
Uso um mesmo programa de inventário para acesso a arquivo de, claro, inventário...
As tabelas de inventário tem muitos campos, mas ela usa apenas: codigoint, codigoean, unidade, qtde e precocusto.
Ocorre que as tabelas podem ser:
Aí, tenho que manter quatro datasets distintos, um para cada tipo de tabela...
Então tentei deixar um só dataset e tentar modificar as propriedades dos campos problemáticos (qtde e precocusto)...
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"
Tem alguma forma de contornar isso? tipo... criar os campos que eu preciso no dataset durante a execução?
Em tempo: coisas que já tentei mas não obtive sucesso:
With invent do Begin FieldDefs.Add('qtde',ftBCD,0,True); FieldDefs.Add('precocusto',ftBCD,0,True); End;{With} ou With FieldDefs.AddFieldDef do Begin DataType := ftBCD; Name := 'qtde'; Precision := 3; End;{With Field...} With FieldDefs.AddFieldDef do Begin DataType := ftBCD; Name := 'precocusto'; Precision := 3; End;{With Field...}
Grato por qualquer ajuda!
Criando um TTable em "runtime"
Segue um fragmento da rotina de criação, em "runtime", de um componente TTable com
tipos de campos variados.
A motivação para isso é:
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;
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;
utilizava quatro componentes TTable distintos, um para cada tipo de gerenciador;
com os campos necessários...
Como o código todo é muito extenso, coloquei somente a parte mais importante...
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 TabelaVar 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} .. .. ..
Ok?
Espero que a rotina acima seja útil!
Uma coisa que pode fazer é remover os campos da Query e das Tabelas, e quando precisar acessar, usar o FieldByName, tipo:
tabela.FieldByName('NOME_DO_CAMPO').Value:=0;
Assim ele vai abrir a tabela de acordo com o campo do BD.