Mismatch Error when all elements of a variant array are the same

I have a function:

BuildMenu (ByRef pBase AS MenuItem, pMenu() AS Variant) AS Boolean

I call it with a mixture of strings and booleans, as in:

Result = BuildMenu (base, Array ("Run", False, "Edit", "Rename", "Delete") )

‘False’ means the previous menu item is disabled (‘True’ means it is enabled, but is optional and assumed)

Because the boolean elements are optional, it is possible to make a call using only string elements, such as:

Result = BuildMenu (base, Array ("Run", "Edit", "Rename", "Delete") )

But when I do this, I get the following compile error:

When I try:

BuildMenu (base, Variant (Array ("Run", "Edit", "Rename", "Delete") ) )

I get the following error:

I can fix it by adding a redundant boolean argument in the function call, as in:

Result =  BuildMenu (base, Array ("Run", "Edit", "Rename", "Delete", True) )

I don’t know how to call the BuildMenu function with only string array elements without causing a type mismatch error. Any thoughts?

Thanks in advance,


why are you using variant at all… why not just use string

Because, in addition to adding a menu item, I want to enable or disable each menu item individually. I could use a string, as in:

but that means I could never have a menu item ‘False’.

personally I’d rethink that design, but thats just me

I am fairly new to Xojo, and I have found this forum to be exceptionally helpful, long before I even posted my first question. I will take your constructive criticism as intended, and I will re-examine how best to design this method.

That said, for future reference, and returning to the original question, is there a way to pass an array of all strings to a method that expects variants without causing a type mismatch error?


the array function builds an array of the given items and makes an array of the best matching type

when you pass all strings to that function you have no means to force it to create an array of variants

when you pass things of mixed types, booleans and strings, you get “the best match” for those types which is variants

EDIT : the other issue with variants is that you wont get much help from the compiler (like it trying to tell you that you have tried to assign a string to an integer or that you;re passing incompatible types)
As a strongly typed language the compiler enforces and warns about such things

Variants circumvent that and you almost never get a compile error and may not get a runtime error when you use them becuase they will automatically convert themselves from one type to another and do so silently

I’m sure I could call BuildMenu like

Result = BuildMenu (base, Array (new Date, "Run", 6, msgbox("123",5), "Edit", "Rename", "Delete") )

since variants are enormously forgiving

What happens when you define pMenu as a ParamArray of Variant in the BuildMenu input parameters list?

Norm just changes the call to

Result = BuildMenu (base, new Date, "Run", 6, msgbox("123",5), "Edit", "Rename", "Delete") 

variants result in APIs that work “by convention” not “by design”
If you call this method as intended

Result = BuildMenu (base, Array ("Run", False, "Edit", "Rename", "Delete") )

you get whats expected
If you happen to call it slightly wrong

Result = BuildMenu (base, Array (false, "Run", False, "Edit", "Rename", "Delete") )

you may not get what you expect

And in neither case can the compiler help you at all

Personally I might turn this into

Result = BuildMenu (base, builditem( "Run", false), buildItem("edit"), buildItem("Rename"), Builditem("Delete"))

with buildmenu defined as

Sub BuildMenu(base as menuitem, paramarray items as menuitem)
        // just append the items passed to the base
        for i as integer = 0 to items.ubound
               base.append items(i)
end sub

and BuildItem as

Function BuildItem(name as string, enabled as boolean = false)
     dim item as new menuitem(name)
    item.enabled = enabled
    return item
end function

and now if you call buildmenu or builditem wrong you get the compiler telling you so at compile time not later att run time


Thanks for taking the time to suggest that approach, Norman. I had not thought of that. It looks very clean. I will give it a try.


No problem
Just trying to help you learn “good habits” about how to write code so the compiler can help you out earlier rather than run into issues later like when your applications is running - or worse just crashes for unknown and hard to track down reasons

Another option would be to overload the method name and add a method that accepts an array of strings, builds an array of variants, and then calls your original method. Eg.,

Function BuildMenu (ByRef pBase AS MenuItem, pMenu() AS String) AS Boolean
   dim v() as variant
   for I as integer = 0 to ubound(pMenu)
      v.append pMenu(I)

   return BuildMenu(pBase, v)
End Function

still blech