[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Array as olevariant

Posted on 2004-10-29
12
Medium Priority
?
6,995 Views
Last Modified: 2007-12-19
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
Comment
Question by:pucko
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
12 Comments
 
LVL 17

Expert Comment

by:geobul
ID: 12443146
Test.InvokeMethod('ABC', VarArrayOf([aArgs[0],aArgs[1],aArgs[2]]));
0
 
LVL 17

Expert Comment

by:geobul
ID: 12443207
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

by:geobul
ID: 12443238
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12443245
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

by:pucko
ID: 12443856
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

by:pucko
ID: 12444927
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

by:geobul
ID: 12445956
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

by:pucko
ID: 12446095
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

by:geobul
ID: 12446128
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

by:pucko
ID: 12446184
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

by:geobul
ID: 12447092
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

by:
geobul earned 1000 total points
ID: 12447108
One more thing:

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

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question