質問

I have a user-form which is made up of many subs, this is assigned as a macro to a button on the worksheet. When the user is finished with this user-form they can press a button on it which causes its visibility to become false and when entered again everything appears how it was left resulting in a save like feature.

I now need to apply this to multiple buttons on the worksheet and each user form needs to have the exact same code and same buttons but be a separate form as each individual button requires it's own save like feature. The way I was planning on doing this was to copy the existing user form and paste it many times with different names however, if a modification is required it will take a long time to carry out therefore, is there a method such as "include" which could use a base module from which all the code is accessed so that if I ever need to change anything I just do it on that one module and everything else updates via the include?

EDIT:

I now have a public function called costing() and am getting an error when I used:

Private Sub material_Change()
Call costing
End Sub
役に立ちましたか?

解決

You can have multiple instances of the same form. You can use this to retain multiple sets of form values

Try this:

Create your form, as usual. Let's call it MyForm

Create several buttons on your sheet. My example uses ActiveX buttons, but Form Control buttons can be used too. Let's call them CommandButton1 and CommandButton2

In your form module, include a Terminate Sub, which includes this code

Private Sub UserForm_Terminate()
    '  any other code you may need...
    Unload Me
End Sub

The Form buton to save/Hide the form needs to be

Private Sub btnSaveAndHide_Click()
    Me.Hide
End Sub

The Sheet Button code is as follows

  • The code is identical for each button (and calls a common Sub), and each button has its own Static form variable.)

  • The Error handler is needed to deal with the case a form is not properly closed. In this case the instance no longer exists, but the local Static variable is also not Nothing

  • Example shows form shown as Modeless, you can change this to Modal if you want.

     Private Sub CommandButton1_Click()
         Static frm As MyForm
         ShowMyForm frm
     End Sub
    
     Private Sub CommandButton2_Click()
         Static frm As MyForm
         ShowMyForm frm
     End Sub
    
    
     Private Sub ShowMyForm(frm As MyForm)
         If frm Is Nothing Then Set frm = New MyForm
    
         On Error GoTo EH
         frm.Show vbModeless
     Exit Sub
     EH:
         If Err.Number = -2147418105 Then
             On Error GoTo 0
             Set frm = Nothing
             Set frm = New MyForm
             frm.Show
         End If
         On Error GoTo 0
     End Sub
    

End result: multiple copies of the same form, each with their own values

enter image description here


In responce to comment How would I access the variables inside of each user form externally

In the example above the Form instances are only accessable in the Command Button Click Handler routines, or within the Form module itself. If you can write your code in the form module, then no change is needed.

To make the Form instances available elsewhere, consider moving their declaration to Module Scope of a standard Module. You could declare them as, eg individual variables, an array (either static or dynamic), a Collection, a Dictionary. Which structure is best will depend on how you want to manage and access your form instances.

For example, a Static Array: Code in a standard Module

Option Explicit
Global MyForms(1 To 2) As MyForm

Update the CommandButton code to

Private Sub CommandButton1_Click()
    ShowMyForm Module1.MyForms(1)
End Sub
    
Private Sub CommandButton2_Click()
    ShowMyForm Module1.MyForms(2)
End Sub

Private Sub ShowMyForm(frm As MyForm) no change, same as before

The code works the same as before, but you can now access the Global variable in a standard Module

Sub Demo()
    Dim i As Long
    
    For i = LBound(MyForms) To UBound(MyForms)
        If Not MyForms(i) Is Nothing Then
            MsgBox "Form " & i & " Value = " & MyForms(i).TextBox1.Value
        End If
    Next
End Sub

他のヒント

You don't need an "Include" (none exists in VBA); all you need to do is create a module and make the common methods public.

For example, if you create a module and have a function like this:

Public Function Add(first As Integer, second As Integer) As Integer
    Add = first + second
End Function

Then you can access it like this from another module/form/class module:

Sub test()
    MsgBox Add(3, 6)
End Sub
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top