I am setting up some vba userforms for grabbing info in Microstation and storing it in an access database. Since the forms will be doing the same thing for different data, I wanted to write public functions for the form actions (clear form, check for duplicate records, etc) So I tried to pass the "Me" keyword to the function with:
Public function clearform( frm as form)
for each ctl in frm.controls
blah
end function
in the forms button I would have
clearform(me) 'to call the funtion.
I am getting type mismatch error.
I don't know if I am missing a reference, I've tried different variations like "frm as userform"
If anyone had an example I would greatly appreciate it
Thanks in advance
Hi,
Try "frm as Object"
In my routine (Mstn v8i) I happen to say "Set frm =MyFormName", so I have not tested the "Me" function.
--Robert
I tried "frm as Object",
I'm not sure if I should be referring to "forms" "userForms" "MsForms" or what. The last route I tried was passing the form name and using "frm.show"
Didn't work, but at this point I'm not sure if it was the syntax or the process.
I will have to regroup and post some code if I still can't get it to work. It has been a couple years since I played with vba forms, I have to figure out what I did know.
I appreciate any information, and will have time to play with this this weekend, but no internet. I will check for responses, or post new findings next week.
Thanks again
There's something wrong with VBA here. I can reproduce your perplexity.
According to VBA Help, a UserForm has a Show method. In other words, the following should be legal …
Dim oForm As UserForm Set oForm = New MyUserForm oForm.Show
However, when I examine that code, I can see that UserForm.Show does not exist, nor does it show up in the object browser (key F2).
I don't know whether this is something to do with VBA versioning, but whatever it is we have no control over it. File a Trouble Report (TR) with Bentley Systems.
Regards, Jon Summers LA Solutions
Here's a test routine. This seems to work... (I'm using v8i, not XM.) In the routine I use on a daily basis, I say "Set MyForm = MyFormName", "Load MyForm", "MyForm.show", "MyForm.Left = xxx", and "Unload MyForm". The attributes do not auto-fill like most commands, but they do seem to auto-Capitalize, and they work.
What isn't working is assigning a variable of type UserForm to your form, which is also of type UserForm (your UserForm inherits from UserForm). According to the VBA documentation, you should be able to assign a generic UserForm to your UserForm :
Dim oMyForm As MyUserForm
...
Dim oUserForm As UserForm
Set oUserForm = oMyForm
Although you can do that, the generic UserForm seems to have lost the Show method.
This is a tough one.The UserForm class is a base class from which your implemented form is a descendant.VBA creates your userform as a seperate class with its own interface behind the scenes.Unfortunately, they did not expose the interfaces you would expect for a UserForm.Actually, I think the hidden "must inherit" class is _Form which inherites from UserForm.Why they did it this way is beyond me since so many other aspects of VBA have been made so very user friendly.
You could pass it simply as an Object and hope that late binding works.This is how / why RobertArnold's example works.
As usual, I can't just leave it there and will continue on with possibly more info than you cared for :-) ...
If you wish to use early binding, there is another practical option but maybe not as straight forward as we feel it "should" be.Since VBA does not expose the desired interface, you could just create your own and implement it.VBA does not support inheritance or creating true interfaces, however it is very good at polymorphism, which is just a fancy way to say that it fakes it really well.
Create your Interface as a class with only methods that will be common to all your forms.In this case I created a class call IMyStandardDataForm:
'----------------------------------------' IMyStandardDataFormPublic Function GetControls() As Controls 'Interface Only, no codeEnd Function'---------------------------------------- Now in the code for each of your forms you can add a line at the top:
'----------------------------------------' IMyStandardDataFormPublic Function GetControls() As Controls 'Interface Only, no codeEnd Function'----------------------------------------
Implements IMyStandardDataForm
This tells VBA you plan to implement this interface; which of course you must now do by adding a method similar to:
'--------------------------------------------------Private Function IMyStandardDataForm_GetControls() As MSForms.Controls Set IMyStandardDataForm_GetControls = Me.ControlsEnd Function'--------------------------------------------------
You can then create a public method in a module designed to accept objects that support this interface. For example:
'--------------------------------------------------Public Sub PrintFormControlNames(ByVal frm As IMyStandardDataForm) Dim ctl As Control For Each ctl In frm.GetControls Debug.Print ctl.Name NextEnd Sub'--------------------------------------------------
'--------------------------------------------------Public Sub PrintFormControlNames(ByVal frm As IMyStandardDataForm) Dim ctl As Control For Each ctl In frm.GetControls Debug.Print ctl.Name Next
End Sub'--------------------------------------------------
Now from within any of your forms that have implemented the IMyStandardDataForm interface as above, you can now call this shared public method as desired:
PrintFormControlNames Me
You might find all that to be more trouble than it's worth, but it works quite well and the way I usually do it.
Enjoy,-G-
Perfect, not only was I able to figure it out, I got it to work!
Thanks, I think that will work, and opens a world I haven't seen before, being self taught.