Search code examples
vbacaptionuserformsolidworks

VBA UserForm running twice when changing .Caption


I'm running a VBA macro from SolidWorks. The form doubles as an input for two types of document. In the UserForm.Initialize subroutine I'm changing the name of the UserForm's Caption depending on which document type is open. Whenever I do this though, the program reruns UserForm.Initialize, and when it's all done, it carries on from where it left of, effectively running twice.

Does anyone know a way around this bizarre behaviour? I tried putting the FormName.Caption command into its own Sub but the result is the same.

Many thanks.


Solution

  • I can't replicate the problem and I don't know what SolidWorks is, so that may have something to do with it. Perhaps you can post a made-up example that shows Initialize being called twice.

    My guess would be that it's related to auto-instantiating variables. When you use UserForm1, you are instantiating an object variable called UserForm1 that points to an object, also called UserForm1. It's similar to using the New keyword in a Dim statement. You never defined UserForm1 (the variable), but VBA did and the first time you use it, it instantiates automatically.

    You should try to use the Me keyword when working inside the userforms class module (userforms are classes just like other objects except that they have a user interface element). In the Initialize event, say

    Me.Caption = "blah"
    

    instead of

    UserForm1.Caption = "blah"
    

    It could be (just a theory that I wasn't able to prove) that the flag that gets set to say "I'm pointing to a real instance" isn't set by the time you change the Caption property, and that by using the auto-instantiating variable UserForm1, you are forcing another instantiation.

    Even better, don't use auto-instantiating variables, convenient though they are (and don't use the New keyword in a Dim statement either). You can control when your variables are created and destroyed and it's a best practice. Something like this in a standard module

    Sub uftst()
    
        Dim uf As UserForm1
    
        Set uf = New UserForm1 'you control instantiation here
    
        'Now you can change properties before you show it
        uf.Caption = "blech"
        uf.Show
    
        Set uf = Nothing 'overkill, but you control destruction here
    
    End Sub
    

    Note that if the ShowModal property is set to False that the code will continue to execute, so don't destroy the variable if running modeless.