Pregunta

I am dynamically adding fields to a TDataSet using the following code:

while not ibSQL.Eof do
   fieldname := Trim(ibSql.FieldByName('columnnameofchange').AsString);
   TDataSet.FieldDefs.Add(fieldname , ftString, 255);
end

Problem is that I might get duplicate names so what is the easiest way to screen for duplicates and not add the duplicates that are already added.

I hope not to traverse through the TDataSet.FieldDefList for each column added as this would be tedious for every single column addition. And there can be many additions.

Please supply another solution if possible. If not then I am stuck using the FieldDefList iteration.

I will also add that screening out duplicates on the SQL query is an option but not a desired option.

Thanks

¿Fue útil?

Solución

TFieldDefs has a method IndexOf that returns -1 when a field with the given name does not exist.

Otros consejos

If I understand you correctly, the easiest way would probably be to put all of the existing field names in a TStringList. You could then check for the existence before adding a new field, and if you add it you simply add the name to the list:

var
  FldList: TStringList;
  i: Integer;
begin
  FldList := TStringList.Create;
  try
    for i := 0 to DataSet.FieldCount - 1 do
      FldList.Add(DataSet.Fields[i].FieldName);

    while not ibSQL.Eof do
    begin
      fieldname := Trim(ibSql.FieldByName('columnnameofchange').AsString);
      if FldList.IndexOf(fieldName) = -1 then
      begin
        FldList.Add(fieldName);
        DataSet.FieldDefs.Add(fieldname , ftString, 255);
      end;
      ibSQL.Next;
    end;
  finally
    FldList.Free;
  end;
end;

I'm posting this anyway as I finished writing it, but clearly screening on the query was my preference for this problem.

I'm having a bit of trouble understanding what you're aiming for so forgive me if I'm not answering your question. Also, it has been years since I used Delphi regularly so this is definitely not a specific answer.

If you're using the TADOQuery (or whatever TDataSet you're using) in the way I expect my workaround was to do something like:

//SQL
SELECT
  a.field1,
  a....   ,
  a.fieldN,
  b.field1 as "AlternateName"
FROM 
  Table a INNER JOIN Table b
WHERE ...

As which point it automatically used AlternateName instead of field1 (thus the collision where you're forced to work by index or rename the columns.

Obviously if you're opening a table for writing this isn't a great solution. In my experience with Delphi most of the hardship could be stripped out with simple SQL tricks so that you did not need to waste time playing with the fields.

Essentially this is just doing what you're doing at the source instead of the destination and it is a heck of a lot easier to update.

What I'd do is keep a TStringList with Sorted := true and Duplicates := dupError set. For each field, do myStringList.Add(UpperCase(FieldName)); inside a try block, and if it throws an exception, you know it's a duplicate.

TStringList is really an incredibly versatile class. It's always a bit surprising all the uses you can find for it...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top