Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi Converting Array Variant to String

Tags:

delphi

In my delphi program I am communication with a webservice.

On WSDL import I got the following function created-

    function  call(const sessionId: WideString; const resourcePath: WideString;
 const args: Variant): Variant; stdcall;

now when I call this inside my code , I want to see what is the returned value

var
p:WideString;
v:variant;
VarArray:variant;
begin

   //varArray := VarArrayCreate([0,50],varVariant);

   v := (httprio1 as  Mtest).call(a,'giftgit.gift', '28184');


   //p := VarArrayget(V,[1] ) ;
   p := vartostr(v[1]);

I get this error in the last line

Could not convert variant of type (Array Variant) into type (String)

I tried with varArray but same problem. how can I solve this ?

Thank you

like image 684
James Avatar asked Apr 25 '12 11:04

James


1 Answers

The error indicates that V[1] is a variant array. You can check that it is indeed with VarIsArray(V[1])

I have a couple of methods that will help you to display it:

  TPsVarDataType = (
    vdtDefault, // varEmpty
    vdtNull,
    vdtSmallint,
    vdtInteger,
    vdtSingle,
    vdtDouble,
    vdtCurrency,
    vdtDate,
    vdtOleStr,  // varOleStr, varString, varUString
    vdtDispatch,
    vdtError,
    vdtBoolean,
    vdtVariant,
    vdtUnknown,
    vdtDecimal,
    vdtUndefined,
    vdtShortint,
    vdtByte,
    vdtWord,
    vdtLongWord,
    vdtInt64,
  {$IFDEF D2009_OR_LATER}
    vdtUInt64,
  {$ENDIF}
    vdtUnsupported
    {Usupported types
    VT_UI8  = 21,
    VT_INT  = 22,
    VT_UINT = 23,
    VT_VOID = 24,
    VT_HRESULT  = 25,
    VT_PTR  = 26,
    VT_SAFEARRAY    = 27,
    VT_CARRAY   = 28,
    VT_USERDEFINED  = 29,
    VT_LPSTR    = 30,
    VT_LPWSTR   = 31,
    VT_RECORD   = 36,
    VT_FILETIME = 64,
    VT_BLOB = 65,
    VT_STREAM   = 66,
    VT_STORAGE  = 67,
    VT_STREAMED_OBJECT  = 68,
    VT_STORED_OBJECT    = 69,
    VT_BLOB_OBJECT  = 70,
    VT_CF   = 71,
    VT_CLSID    = 72,
    VT_VERSIONED_STREAM = 73,
    VT_BSTR_BLOB    = 0xfff,
    VT_VECTOR   = 0x1000,
    VT_ARRAY    = 0x2000,
    VT_BYREF    = 0x4000,
    VT_RESERVED = 0x8000,
    VT_ILLEGAL  = 0xffff,
    VT_ILLEGALMASKED    = 0xfff,
    VT_TYPEMASK = 0xfff
    }
  );

const
  SPsVarDataTypes: array [TPsVarDataType] of string  = (
    'Default',
    'Null',
    'Smallint',
    'Integer',
    'Single',
    'Double',
    'Currency',
    'Date',
    'OleStr',
    'Dispatch',
    'Error',
    'Boolean',
    'Variant',
    'Unknown',
    'Decimal',
    'Undefined',
    'Shortint',
    'Byte',
    'Word',
    'LongWord',
    'Int64',
  {$IFDEF D2009_OR_LATER}
    'UInt64',
  {$ENDIF}
    'Unsupported'
  );

const
  SPsVarDataTypes: array [TPsVarDataType] of string  = (
    'Default',
    'Null',
    'Smallint',
    'Integer',
    'Single',
    'Double',
    'Currency',
    'Date',
    'OleStr',
    'Dispatch',
    'Error',
    'Boolean',
    'Variant',
    'Unknown',
    'Decimal',
    'Undefined',
    'Shortint',
    'Byte',
    'Word',
    'LongWord',
    'Int64',
  {$IFDEF D2009_OR_LATER}
    'UInt64',
  {$ENDIF}
    'Unsupported'
  );

  SPsVarArray = 'Array of %s';
  SPsVarByRef = '%s (Reference)';

function VariantToStr(V: Variant; IncludeType: Boolean = False): string;
begin
  if VarIsArray(V) then
    Result := VarArrayToStr(V)
  else
    case VarType(V) of
      varError:
        Result := Format('Error($%x)', [TVarData(v).VError]);
      varNull:
        Result := '#NULL';
      varEmpty:
        Result := '#EMPTY';
      varDate:
        Result := FormatDateTime(ShortDateFormat + ' ' + LongTimeFormat + '.zzz', V)
    else
      Result := VarToStr(V);
    end;
  if IncludeType then
    Result := Format('%s{%s}', [Result, VarTypeToString(VarType(V))]);
end;


function VarArrayToStr(v: Variant; Delimiter: Char = #0; LineDelimiter: Char =
    #13): string;
var
  i,j,d: Integer;
  line: string;
begin
  if VarIsArray(v) then
  begin
    if Delimiter = #0 then
      Delimiter := ListSeparator;
    if LineDelimiter = #0 then
      LineDelimiter := ListSeparator;
    d := VarArrayDimCount(v);
    // The elements
    case d of
      1:
      begin
        Result := '';
        for i := VarArrayLowBound(v,1) to VarArrayHighBound(v,1) do
          Result := Result + VariantToStr(v[i]) + Delimiter;
        if Length(Result) > 0 then
          SetLength(Result, Length(Result)-1);
      end;
      2:
      begin
        Result := '';
        if (VarArrayLowBound(v,1) <= VarArrayHighBound(v,1)) and
          (VarArrayLowBound(v,2) <= VarArrayHighBound(v,2)) then
        begin
          for i := VarArrayLowBound(v,1) to VarArrayHighBound(v,1) do
          begin
            line := '';
            for j := VarArrayLowBound(v,2) to VarArrayHighBound(v,2) do
              line := line + VariantToStr(v[i,j]) + Delimiter;
            if Length(Result) > 0 then
              SetLength(line, Length(line)-1);
            Result := Result + LineDelimiter + Format('[%s]', [line]);
          end;
        end;
      end // 2
    else
      Result := 'Array Dim=' + IntToStr(d);
    end;
    Result := Format('[%s]', [Result]);
  end
  else
    Result := VarToStr(v);
end;


function VarTypeToString(varType: Integer): string;
var
  T: TPsVarDataType;
begin
  if varType = varString then
    Result := 'string'
  else
  begin
    T := VarTypeToPsVarDataType(varType);
    if T = vdtUnSupported then
      Result := IntToStr(varType and varTypeMask)
    else
      Result := SPsVarDataTypes[T];
  end;
  if (varType and varArray) <> 0 then
    Result := Format(SPsVarArray,[Result]);

  if (varType and varByRef) <> 0  then
    Result := Format(SPsVarByRef,[Result]);
end;


function VarTypeToPsVarDataType(Value: Word): TPsVarDataType;
var
  v: Word;
begin
  debugEnter('VarTypeToPsVarDataType');
  v := Value and varTypeMask;
  debugInt('Value', v);
  if v < Word(vdtUnsupported) then
    result := TPsVarDataType(v)
  else if v = varString then
    result := vdtOleStr
  {$IFDEF D2009_OR_LATER}
  else if v = varUString then
    result := vdtOleStr
  {$ENDIF}
  else
    result := vdtUnsupported;
  debugLeave;
end;

function PsVarDataTypeToVarType(Value: TPsVarDataType; IsArray: Boolean =
    False): Word;
begin
  if Value = vdtUnsupported then
    Result := varEmpty
  else
  begin
    Result := Word(Value);
    if IsArray then
      Result := Result or varArray;
  end;
end;

UPDATE 2012-09-20: Seems like I missed the string constants. Added. UPDATE 2012-11-02: TPsVarDataType, VarTypeToPsVarDataType() & VarTypeToPsVarDataType();

like image 200
Jouni Aro Avatar answered Oct 18 '22 10:10

Jouni Aro