• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7097
  • Last Modified:

Array as olevariant

IN VB I have:


Dim aArgs(2) As String
 
aArgs(0) = sFilePath
aArgs(1) = "QuoteFileName"
aArgs(2) = "N"

Test.InvokeMethod("ABC", aArgs).

Try to do the same from delphi.

The problem is that the second parameter of InvokeMethod is an ole variant

(so I can't send in my array of string there).

How do I convert my array of string to an olevariant?


0
pucko
Asked:
pucko
  • 7
  • 4
1 Solution
 
geobulCommented:
Test.InvokeMethod('ABC', VarArrayOf([aArgs[0],aArgs[1],aArgs[2]]));
0
 
geobulCommented:
Another way is to declare aArgs as Variant instead:

var
  aArgs: Variant;
  sFilePath: string;

procedure TForm1.Button1Click(Sender: TObject);
begin
  aArgs := VarArrayCreate([0,2], varVariant);
  aArgs[0] := sFilePath;
  aArgs[1] := 'QuoteFileName';
  aArgs[2] := 'N';

  Test.InvokeMethod('ABC', aArgs) then ShowMessage('OK');
end;

Regards, Geo
0
 
geobulCommented:
Or try the function below for converting an array of string to variant:

var
  aArgs: array [0..2] of string;
  sFilePath: string;

function StringArrayToVariant(ar: array of string): Variant;
var
  Min,Max, i: integer;
begin
  Min := Low(ar);
  Max := High(ar);
  result := VarArrayCreate([Min,Max], varVariant);
  for i := Min to Max do begin
    result[i] := ar[i];
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  sFilePath := 'c:\';
  aArgs[0] := sFilePath;
  aArgs[1] := 'QuoteFileName';
  aArgs[2] := 'N';

  Test.InvokeMethod('ABC', StringArrayToVariant(aArgs));
end;
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Ivanov_GCommented:
as Geobul said - VarArrayCreate. In addition to his answer, if you want to access the array server-side:

var
  i : Integer;
begin
  for i := VarArrayLowBound(aArgs, 1) to VarArrayHighBound(aArgs, 1) do
    begin
      aArgs[i] := ..............
      .............
    end;
end;
0
 
puckoAuthor Commented:
It seems like I still have this problem.

To be more specific:

Function in VB:


Private Function CreateAttachment(sFilePath As String)

    Dim errCode As Integer
    Dim aArgs(2) As String
    Dim RetValue As String

    CreateAttachment = True
   
    With bcQuoteAtt
        Set bcQuoteAtt = boOpty.GetBusComp("Quote Attachment")
       
        aArgs(0) = sFilePath
        aArgs(1) = "QuoteFileName"
        aArgs(2) = "N"

        bcQuoteAtt.NewRecord 0
        RetValue = bcQuoteAtt.InvokeMethod("CreateFile", aArgs)
       
        End If
    End With
   
End Function


In Delphi:



function  CreateAttachment(sFilePath : WideString) :String;
var
   Args : Array [0..2] Of WideString;
   TmpArgs : OleVariant;

begin
  Result:= '';

  bcQuoteAtt:= boOpty.GetBusComp('Quote Attachment');
  with bcQuoteAtt do
  begin
    NewRecord(0);


    args[0]:= sFilePath;
    args[1]:= 'QuoteFileName2';
    args[2]:= 'N';
    tmpArgs:= StringArrayToVariant(args);
  end;
  Result:= bcQuoteAtt.InvokeMethod('CreateFile',Args);
 
end;


And from the TypeLibrary:

function InvokeMethod(const Name: WideString; args: OleVariant): WideString; safecall;


When running from VB the server do what it shuld.

But not from the delphi code.


When running the VB code


0
 
puckoAuthor Commented:
I found this but I don't know how to do. (how to pass the array as a widestring)


The Ole Automation method was called with an invalid argument when a string or an array of strings was expected."

Initially it was thought that the declaration of the methodArgs variable (argument), as type OleVariant was incorrect, as according to Technical Note number 198 (Accessing File Attachments through Siebel VB and Siebel BusObject Interfaces), the GetFile method, invoked through InvokeMethod is expecting this argument as a String.

However, Delphi's structure definition of InvokeMethod is (SiebelApplicationServer_TLB Unit Created by Delphi When importing the Type Library):
...
SiebelBusComp = dispinterface
    ['{2F076E20-0B36-11D0-A52E-00C04FD20274}']
    ...
    function InvokeMethod(const methodName: WideString; var methodArgs: OleVariant; var errCode: Smallint): WideString; dispid 32;
...

Delphi is interpreting methodArgs as the Delphi data type, OleVariant.

This issue was resolved by simply changing the type of the MethodArgs argument to WideString instead of OleVariant in the Delphi function declaration. This now compiles and the function completes correctly at run time.

 

Bu
0
 
geobulCommented:
Your aArgs is array is of WideString type (in your Delphi representation) and that is totally different compared to array of string. Make the function StringArrayToVariant to accept 'array of WideString' instead. That, perhaps, will solve the problem.
0
 
puckoAuthor Commented:
No it don't help.

I tried array of string first. And then array of widestring since VB's String is a widestring.
0
 
geobulCommented:
I've just read your last comment and don't think that replacing OveVariant with WideString in the method definition (Delphi code) would be correct enough (well, in a particular case it might be but not speaking in general). OveVariant is a generic type designed for COM communication that can represent everything. Same as in VB (Variant type was designed by VB developers because there were lots of VB programmers who were unable to distingush an integer number from a real one ;-) Simply try changing the StringArrayToVariant function definition as descrbed in my previous post and see what's going on. I understand now (hope I'm right) that you're communicating with a COM object,
0
 
puckoAuthor Commented:
It's realy hard for me to understand what's happening here.

The server gives me some strange response when I send this in from delphi.

When I do it from VB it looks ok.

As I said before, my first try was with array of string.

Then I tried what I wrote above since vb's string definition is the same as widestring in delphi (not ansi string).
0
 
geobulCommented:
Have you tried my first proposal? Using VarArrayOf function?

Another thing: OleVariant in Delphi is just a 'subset' of Variant which should automatically convert string to WideString. So, your code

var
  TmpArgs : OleVariant;
...
  tmpArgs:= StringArrayToVariant(args);

should have done it if you have called the method like:
  Result:= bcQuoteAtt.InvokeMethod('CreateFile',tmpArgs);

Regards, Geo
0
 
geobulCommented:
One more thing:

the result of the CreateAttachment function should be of WideString type, not string!
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now