learningthisstuff
learningthisstuff

Reputation: 101

Call a Sub Within a User Form

I have a pretty straight-forward question that I cannot seem to get a definite answer on, so asking it here.

I have a user form that works. Within that form there is a function. The code for the command button works fine and calls the function just fine. I can also call subs from other modules just fine.

What I do not seem to be able to do is call a sub that is also within the form. As I said, the functions work fine as long as prefaced with 'me'.

That does not work for subs though. I have tried to make the subs private, public, tried Form and Frm as well. If I run it as 'me' I get an automation error, noting the callee connections have failed. If I run it as 'Form' I get an error saying that the object is required.

So my question is...can you call subs that are stored within the same form? I figured yes given that functions work but it does not seem to be the case.

The reason I want them in the form is so that when I roll it out to users I do not have to also roll out 10 other subs as well. If I can store them all in the same form, that would be helpful.

Thanks

Here is a portion of the code I am talking about. Profile1 is the sub I am trying to call, which as you can see is located within the same form. As noted, it calls the GetBoiler function without an issue. Included the call to Profile2 just to demonstrate the Form option I tried.

Private Sub CommandButton1_Click()


    findStr = Me.ComboBox1.Value
    Unload Me

    If findStr = "Vendor1" Then Me.Profile1
    If findStr = "Vendor2" Then Form.Profile2
    If findStr = 'Vendor3" Then Me.GetBoiler (SigString)   


   End Sub

Function GetBoiler(ByVal sFile As String) As String
    Dim fso As Object
    Dim ts As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
    GetBoiler = ts.ReadAll
    ts.Close
End Function

Private Sub Profile1()



     Select Case Application.ActiveWindow.Class
           Case olInspector
                Set oMail = ActiveInspector.CurrentItem
           Case olExplorer
                Set oMail = ActiveExplorer.Selection.Item(1)
    End Select
              SigString = Environ("appdata") & _
                "\Microsoft\Signatures\Profile1.htm"

Upvotes: 0

Views: 1191

Answers (1)

Mathieu Guindon
Mathieu Guindon

Reputation: 71167

The Me qualifier refers to the current instance of the class you're in (yes, a form is a class), and gives you the public members of that object.

Profile1 is Private, so that member is not on the object's public interface, therefore won't show up in IntelliSense as a member of Me.

Just... don't qualify it:

If findStr = "Vendor1" Then Profile1
If findStr = "Vendor2" Then Profile2

The GetBoiler function being implicitly Public, the Me qualifier works:

If findStr = "Vendor3" Then Me.GetBoiler (SigString)

Except, you have a function, and you're using it as a procedure, i.e. you're discarding its return value. When calling a function like this, you need to drop the parentheses:

If findStr = "Vendor3" Then GetBoiler SigString

Parentheses are otherwise forcing the evaluation of the argument expression, and passing the result ByVal, regardless of what the function's signature says - here it says ByVal anyway, so the parentheses are purely redundant.

You do need the parentheses when you're not discarding the function's return value:

MsgBox "Message", vbOkOnly
result = MsgBox("Message", vbOkCancel)

Seeing that Unload Me in the middle of a procedure is rather scary. I'd recommend reading this article I wrote a little while ago - it's a bit advanced, but very much worth understanding.

Upvotes: 2

Related Questions