Как выгрузить содержимое Delphi OleVariant в файл? - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть многоуровневое приложение, которое использует переменные OleVariant для отправки и получения данных через линию с использованием пользовательской среды связи. Обычно содержимое этой переменной OleVariant происходит из TClientDataSet.Data (который, конечно, имеет тип OleVariant). У меня есть подозрение, что коммуникационная среда изменяет содержимое этой переменной OleVariant, и поэтому я хотел бы вывести содержимое переменной перед отправкой и после получения данных. Я использую код:

TmpOrder: OleVariant;
Tmp: TStringList;

Tmp:=TStringList.Create;
try
  Tmp.LoadFromFile('D:\test.txt');
  Tmp.Add('---');
  Tmp.Add(TmpOrder);
  Tmp.SaveToFile('D:\test.txt');
finally
  Tmp.Free;
end;

Но содержание файла не имеет смысла. Например, следующее содержимое файла может представлять содержимое TClientDataSet.Data:

---
??

Конечно, происходит что-то другое.

Итак - как захватить содержимоепеременная OleVariant.

Сохранение TClientDataSet как XML для меня не вариант, потому что для связи используется OleVariant, а не XML.

Я использую Unciode Delphi (Delphi 2009 и выше).

1 Ответ

3 голосов
/ 08 ноября 2019

Вот некоторый код, который преобразует TClientDataSet.Data в строку и подпрограмму тестирования, которая ее выполняет.

function VariantToString(V : OleVariant) : String;
  procedure VariantToStringInner(V : OleVariant; var AString : String);
  var
    IsArray : Boolean;
    DimCount : Integer;
    i : Integer;
  begin
    IsArray := VarIsArray(V);

    if not IsArray then begin
      //  Handle the case where V is not an array
      if (VarIsEmpty(V) or VarIsNull(V)) then begin
        AString := AString + ' ';
        exit;
      end
      else
        AString := AString + VarToStr(V);
    end
    else begin
      //  V is an array, so first we need to know how many dimensions it has
      DimCount := VarArrayDimCount(V);

      //  For TClientDataSet.Data the answer AFAIK should be 1
      //  so we'll process only dimension 1
      Assert(DimCount = 1);

      //  Recurse into this proc so that we handle the cases where V[i] is an array
      //  and where it isn't
      for i := VarArrayLowBound(V, 1) to VarArrayHighBound(V, 1) do begin
        VariantToStringInner(V[i], AString);
      end;
    end;
  end;

begin
  Result := '';
  VariantToStringInner(V, Result);
end;

procedure TForm1.TestVarToStr;
var
  V : OleVariant;
  S : String;
begin
  V := 'hello world';
  S := VariantToString(V) + #13#10;

  V := CDS1.Data;
  S := S + VariantToString(V);
  Memo1.Lines.Text := S;
end;

Очевидно, что если вы хотите сохранить результат в файл, просто вызовите Memo1.Lines.SaveToFile()

1006 * в результате я получаю

привет мир 150252241891000240005020003000202027368401000107838566848980692073080651171161111051109904689711610140600000678117109981011144010000047897109101107300010587736884722020200586971081171011073000105877368847220202002010677265787169957679714013006000100000004000200000004000126585847973786786657685694010300044011000578971091014944002000578971091015026567

данные же CDS, сохраненные в виде XML выглядит следующим образом:

1014 *
...