Q:how to call a method with a variable number of parameters?

RogerH

Registered User.
Local time
Today, 01:50
Joined
Mar 21, 2016
Messages
34
Given that this works:
MyObject.MyMethod ("foo","bar")

this would work:

str1 = "foo"
str2 = "bar"
MyObject.MyMethod (str1,str2)

but this will not:
str1= Chr(34) & "foo" & Chr(34) & "," & Chr(34) & "bar" & Chr(34)
MyObject.MyMethod (str1)

even though str1 = "foo","bar" it is still one *parameter* being passed to MyMethod.
I get all that.

I have a COM object with a Method that takes between one and an infinite number of parameters. (like giving a DOS COPY command a list of
filenames.) I need to loop trough a dataset and assemble a list of these parameters (but obviously not as ONE STRING) and the call the method.

So i have a dataset that looks like:
"foo","12"
"bar","43"
"foo2" "89"

and need to build
MyObject.MyMethod ("foo","12","bar","43","foo2","89")

I can handle the DO...LOOP but how do I give that parameter LIST to the method?

wait, is THIS what an *array* is for? (I've heard of those, actually used one ONCE in python) if yes, how do I used it in VBA?

aha TIA
Roger
 
An array still gets passed as one parameter, so I don't think that will work. I believe you will have to look into the Eval function (https://msdn.microsoft.com/en-us/li...v=office.11).aspx?f=255&MSPPError=-2147217396).

Basically, you construct the string of the code you want run, then put that all inside an Eval() and it runs whatever the strings says. For example:

str1="Hello"
Eval("MsgBox(str1)")

Would spit out "Hello" in a prompt box.
 
OOOHHH.

it is a string but the "MyObject.MyMethod (" and ")" bit is part of the string then we EVAL string!
 
There is such a thing as declaring a parameter as being Optional, in which case what you do is test for each optional parameter via NZ. This would give you the behavior of a variable-argument call, but I'm not sure that you wanted to go in that particular direction based on your description. It is rather confusing.

There is also the SPLIT function, where you have some sort of delimiter, pass in a string, and get back a string array that splits the input into as many segments as are separated by your delimiter. However, using a comma as a delimiter COULD be a problem if one of the components of your input contains a quoted comma. (I've not tested that particular case.)

Anyway, the Optional keyword and the SPLIT function might give you two ways to deal with the issue.
 
Hi Guys,
It definitely looks like Eval() is what I'm looking for ...

but...

IT DOESN'T WORK! :banghead:

I thought it was me at first, but PLOG's own example code fails with "cannot find the name Str1"

Sub PlogTest()
str1 = "Hello"
Eval ("MsgBox(str1)")
End Sub


Doesn;t matter if I enter the command as part of the Eval call or in the string:

str1 = ("MsgBox (" & Chr(34) & "Hello:" & Chr(34) & ")"
Eval str1
End Sub
EDIT: WAIT THAT DOES WORK.

This fails:
str1 = "Hello"
str2 ="MsgBox(str1)"
Eval str2

cannot find str1

Eval() Fails on the first reference to a variable.

Problem is that I am trying to use it on an Object that I just referenced!


What now???
 
Last edited:
Can you post a copy of the database involved? Compact and repair, then zip and post.
 
I got quote mark happy. This should work:


Code:
Sub PlogTest()
str1 = "hello"
Eval (MsgBox(str1)) 
End Sub
 
Can you post a copy of the database involved? Compact and repair, then zip and post.

Sorry, its a commercial app, a couple of hundred MB compressed.

I'm almost there.

Access help talks about about Eval() using Functions. I'm trying to call a method of a COM object. maybe I need to wrap that in a function!
 
A Parameter Array allows an arbitrary number of parameters to be passed.
 
UPDATE:
Thanks plog, that's better.

but now all of ACCESS JUST EXITS when it get to that line of code

str1= "foo","12","bar","43","foo2","89"

Eval(MyObject.MyMethod (str1)) --- poof!

5pm: time for a pint.
back to this in the morning
 
Last edited:
There is such a thing as declaring a parameter as being Optional, in which case what you do is test for each optional parameter via NZ.

Nz() cannot test for a parameter that is not there. The argument would have to be assigned a default value of Null. Otherwise an error is returned.

Unused optional parameters are tested with the IsMissing() function.

Either way, the argument must be a Variant.
 
Hi guys, here’s the update:

I’ve been wrestling with this for most of the day, it’s definitely a problem with the Eval function combining with myObject and myMethod, and it’s causing Access to abruptly quit out. As soon as it gets to that line of code Access just shuts down.

Using MSA 2007 (yeah)

I think the following is unnecessary information but here goes anyway: the “MyObject” at hand is a COM object compiled from open source C code. It’s an Image processing library called “ImageMagick” its rock solid been using it for years. I’ve Dimensioned it as an object and Set the object reference.

The “MyMethod” is a command called “Convert” the “foo” and “bar” represent filepaths, the numbers, XY coordinates. The entire command assembled various images at various xy coordinates.
So the actual string I assemble looks like:

"(", "c:\test1\Preprod\Trk1Seg71.png", "-repage", "+1300+0", ")", "(", "c:\test1\Preprod\Trk1Seg72.png", "-repage", "+1500+0", ")", "(", "c:\test1\Preprod\Trk1Seg73.png", "-repage", "+1700+0", ")", "-layers", "mosaic", "c:\test1\Preprod\TLTrack1.png"

And the command:
strConvertResult = Eval(objMagImage.convert(strIMTrkCommand))

Yes all those quotes and parentheses and quotes inside the parentheses are all correct. Because I can hardcode this:

strConvertResult = objMagImage.convert("(", "c:\test1\Preprod\Trk1Seg71.png", "-repage", "+1300+0", ")", "(", "c:\test1\Preprod\Trk1Seg72.png", "-repage", "+1500+0", ")", "(", "c:\test1\Preprod\Trk1Seg73.png", "-repage", "+1700+0", ")", "-layers", "mosaic", "c:\test1\Preprod\TLTrack1.png")

and it works
But as soon as I get to
strConvertResult = Eval(objMagImage.convert(strIMTrkCommand))

Access just quits out, which, as you can imagine, is severely hampering my attempts to debug it.

Any ideas? Anyone?
 
Eval seems a lot more complicated than Glaxiom's suggestion in #9
Code:
Function Myfunction()
Dim cls As MyMethod
Dim var(50) As Variant

var(1) = 5
var(2) = 3
var(3) = 10
var(4) = 6

Set cls = New MyMethod
cls.Method (var)

End Function

MyMethod class:
Option Compare Database
Option Explicit

Sub Method(X As Variant)
   Dim n As Integer
   Dim lngSum As Long
   
   lngSum = 0
   For n = 1 To UBound(X)
      lngSum = lngSum + X(n)
   Next
   Debug.Print lngSum
   
End Sub
 
Eval seems a lot more complicated than Glaxiom's suggestion in #9
Code:
Function Myfunction()
Dim cls As MyMethod
Dim var(50) As Variant

var(1) = 5
var(2) = 3
var(3) = 10
var(4) = 6

-snip


Yeah, I saw that. Thanks, but you two are totally off-topic. I'm not trying to WRITE a method. I'm not trying take in an odd number of parameters.

I'm trying to CALL an existing method, and GIVE it an odd number of parameters. depending on data in a table.

Clearly Eval() is in the right direction. If I could only get it to work.
Thanks again.
 
so back to the top - why can you not pass the array?

you could use the array if it were not passed to the function, so why can you not pass it to the function?


you can process your values into an array so

"foo","12","bar","43","foo2","89" becomes a 2-D array

"foo","12"
"bar","43"
"foo2","89"

then pass the 2-D array which can be seen to have 3 sets of values.





Clearly these two are not the same thing at all.
myfunc("foo",bar")
and
myfunc("foo,bar")
 
so back to the top - why can you not pass the array?

you could use the array if it were not passed to the function, so why can you not pass it to the function?
/QUOTE]

Its a Method not a Function (and one that's already written and compiled into a DLL) and it takes in, as individual parameters, between one and an infinite number of strings.

I've been using it for years but always with a constant number of parameters that I hardcoded in. Now I need VBA to generate that command.

I can easily (have already) have Access generate one long string, now I need VBA hand that to the method as several individual parameters.

That exactly what Eval() is supposed to do.
keyword: supposed
 
well if you use eval, the string inside eval needs to look exactly like the function call would look

given

MyObject.MyMethod (....)

you need a string that looks like

MyObject.MyMethod (param1, param2, ......)

(I am not sure offhand if you can actually pass a variable reference, rather than an actual parameter value. I doubt it, as you would need to be able to pass the address of the variable, and VBA doesn't do pointers. Maybe someone knows how.)

evalstrg = "MyObject.MyMethod (" & Chr(34) & param1 & Chr(34) & " , " & param2 & Chr(34) & .... etc..... & " )"

to build up a string that looks exactly like ....

MyObject.MyMethod ("foo", "12", "bar", "13", etc)

then just call it in this way

eval(evalstrg)

I think that should work
 
Last edited:
I am not sure offhand if you can actually pass a variable reference rather than an actual parameter value.

Exactly the problem.

Eval only sees the literal string. It can't interpret a reference to a variable in that string.
 
well if you use eval, the string inside eval needs to look exactly like the function call would look

given

MyObject.MyMethod (....)

you need a string that looks like

MyObject.MyMethod (param1, param2, ......)

(I am not sure offhand if you can actually pass a variable reference, rather than an actual parameter value. I doubt it, as you would need to be able to pass the address of the variable, and VBA doesn't do pointers. Maybe someone knows how.)

evalstrg = "MyObject.MyMethod (" & Chr(34) & param1 & Chr(34) & " , " & param2 & Chr(34) & .... etc..... & " )"

to build up a string that looks exactly like ....

MyObject.MyMethod ("foo", "12", "bar", "13", etc)

then just call it in this way

eval(evalstrg)

I think that should work


No that won't work. you cannot place a variable INSIDE a string. MyObject is a variable.

evalstr=Chr(34) & param1 & Chr(34) & " , " & param2 & Chr(34)
strresult=Eval(MyObject.MyMethod(evalstr))
EDIT: NO NO NO --- I have that WRONG (I wish this editor had strike through)


SHOULD (NOT) work, assuming MyMethod returns a string (or number)

BUT that is where MSA is quitting out on me now. Which is not helpful.


"(I am not sure offhand if you can actually pass a variable reference, rather than an actual parameter value. I doubt it, as you would need to be able to pass the address of the variable, and VBA doesn't do pointers. Maybe someone knows how.)"

--- isn't that ByRef as apposed to the default of ByVal? (but that goes in the function)
 
Last edited:
wait a minute.
Plog and I had this conversation earlier in this thread:

>I thought it was me at first, but PLOG's own example code fails with "cannot find the name Str1"

Sub PlogTest()
str1 = "Hello"
Eval ("MsgBox(str1)")
End Sub

>I got quote mark happy. This should work:

Sub PlogTest()
str1 = "hello"
Eval (MsgBox(str1))
End Sub

and it DOES. but it shouldn't according to the webpage:
https://msdn.microsoft.com/en-us/library/office/aa172212%28v=office.11%29.aspx?f=255&MSPPError=-2147217396

Where EVERYTHING is in quotes. esp all the function names.

That page also seems to contradict ITSELF when it says:
"The stringexpr argument must evaluate to a string or numeric value; it can't evaluate to a Microsoft Access object."

but then gives this example:

Dim ctl As Control
Dim strCtl As String

Set ctl = Forms!Employees!LastName
strCtl = "Forms!Employees!LastName"
MsgBox ("The current value of " & ctl.Name & " is " & Eval(strCtl))

isn;t that evaluating to an Access object ??

this makes no sense.
 

Users who are viewing this thread

Back
Top Bottom