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?


LVL 1
puckoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.