Solved

# Array as olevariant

Posted on 2004-10-29
6,764 Views
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
Question by:pucko

LVL 17

Expert Comment

Test.InvokeMethod('ABC', VarArrayOf([aArgs[0],aArgs[1],aArgs[2]]));
0

LVL 17

Expert Comment

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

LVL 17

Expert Comment

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

LVL 12

Expert Comment

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

LVL 1

Author Comment

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

LVL 1

Author Comment

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

LVL 17

Expert Comment

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

LVL 1

Author Comment

No it don't help.

I tried array of string first. And then array of widestring since VB's String is a widestring.
0

LVL 17

Expert Comment

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

LVL 1

Author Comment

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

LVL 17

Expert Comment

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

LVL 17

Accepted Solution

One more thing:

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

## Featured Post

### Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This video Micro Tutorial is the first in a two-part series that shows how to create and use custom scanning profiles in Nuance's PaperPort 14.5 (http://www.experts-exchange.com/articles/17490/). But the ability to create custom scanning profiles al…
To add imagery to an HTML email signature, you have two options available to you. You can either add a logo/image by embedding it directly into the signature or hosting it externally and linking to it. The vast majority of email clients display l…