Excel 表单中的表单-VBA右键单击复制/粘贴多页

Excel 表单中的表单-VBA右键单击复制/粘贴多页,excel,multipage,vba,Excel,Multipage,Vba,但是,当我在第二个表单中输入代码时,得到的错误与我最初在主表单中收到的错误相同 下面是放置在表单和类模块中的代码以及一些屏幕截图,以更好地说明第二个表单,因为我不确定我是否解释得非常清楚 提前非常感谢大家 格式中的代码: Dim cBar As clsBar Private Sub UserForm_Initialize() On Error GoTo Whoa Application.EnableEvents = False Set cBar = New clsB

但是,当我在第二个表单中输入代码时,得到的错误与我最初在主表单中收到的错误相同

下面是放置在表单和类模块中的代码以及一些屏幕截图,以更好地说明第二个表单,因为我不确定我是否解释得非常清楚

提前非常感谢大家

格式中的代码:

Dim cBar As clsBar

Private Sub UserForm_Initialize()

    On Error GoTo Whoa
    Application.EnableEvents = False

    Set cBar = New clsBar
    cBar.Initialize Me

Letscontinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume Letscontinue

End Sub
类模块中的代码

'Popup objects
Private cmdBar As CommandBar
Private WithEvents cmdCopyButton As CommandBarButton
Private WithEvents cmdPasteButton As CommandBarButton

'Useform to use
Private fmUserform As Object

'Control array of textbox
Private colControls As Collection

'Textbox Control
Private WithEvents tbControl As MSForms.TextBox

'Adds all the textbox in the userform to use the popup bar
Sub Initialize(ByVal UF As Object)
    Dim Ctl As MSForms.Control
    Dim cBar As clsBar

    For Each Ctl In UF.Controls
        If TypeName(Ctl) = "TextBox" Then

            'Check if we have initialized the control array
            If colControls Is Nothing Then
                Set colControls = New Collection
                Set fmUserform = UF
                'Create the popup
                CreateBar
            End If

            'Create a new instance of this class for each textbox
            Set cBar = New clsBar
            cBar.AssignControl Ctl, cmdBar
            'Add it to the control array
            colControls.Add cBar

        End If
    Next Ctl
End Sub

Private Sub Class_Terminate()
    'Delete the commandbar when the class is destroyed
    On Error Resume Next
    cmdBar.Delete
End Sub

'Click event of the copy button
Private Sub cmdCopyButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    Dim sACN As String
    sACN = ActiveControlName(fmUserform)    ' find control's name
    ' Debug.Print sACN & ".Copy"
    fmUserform.Controls(sACN).copy          ' << instead of fmUserform.ActiveControl.Copy
    CancelDefault = True
End Sub

'Click event of the paste button
Private Sub cmdPasteButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    Dim sACN As String
    sACN = ActiveControlName(fmUserform)
    ' Debug.Print sACN & ".Paste"
    fmUserform.Controls(sACN).Paste    ' << instead of fmUserform.ActiveControl.Paste
    CancelDefault = True
End Sub

'Right click event of each textbox
Private Sub tbControl_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If Button = 2 And Shift = 0 Then
        'Display the popup
        cmdBar.ShowPopup
    End If
End Sub

Private Sub CreateBar()
    Set cmdBar = Application.CommandBars.Add(, msoBarPopup, False, True)
    'We’ll use the builtin Copy and Paste controls
    Set cmdCopyButton = cmdBar.Controls.Add(ID:=19)
    Set cmdPasteButton = cmdBar.Controls.Add(ID:=22)
End Sub

'Assigns the Textbox and the CommandBar to this instance of the class
Sub AssignControl(TB As MSForms.TextBox, Bar As CommandBar)
    Set tbControl = TB
    Set cmdBar = Bar
End Sub

Function ActiveControlName(form As UserForm) As String
    'cf Site: https://stackoverflow.com/questions/47745663/get-activecontrol-inside-multipage
    'Purpose: get ActiveControl

    Dim MyMultiPage As MSForms.MultiPage, myPage As MSForms.Page

    If form.ActiveControl Is Nothing Then
        ' do nothing
    ElseIf TypeName(form.ActiveControl) = "MultiPage" Then
        Set MyMultiPage = form.ActiveControl
        Set myPage = MyMultiPage.SelectedItem
        ActiveControlName = myPage.ActiveControl.Name
    Else
        ActiveControlName = form.ActiveControl.Name
    End If
End Function
Sub ShowYODA
    With New YODA           ' temporary new UF instance
        .Show vbModeless
    End With
End Sub
”弹出对象
作为命令栏的专用cmdBar
Private WithEvents cmdCopyButton作为CommandBarButton
Private WithEvents cmdPaste按钮作为CommandBarButton
“使用表单来使用
私有fmUserform作为对象
'文本框的控件数组
作为集合的专用控件
'文本框控件
Private with events tbControl As MSForms.TextBox
'在userform中添加所有文本框以使用弹出栏
子初始化(ByVal UF作为对象)
作为MSForms.Control的Dim Ctl
作为clsBar的Dim cBar
对于UF.控件中的每个Ctl
如果TypeName(Ctl)=“文本框”,则
'检查是否已初始化控制阵列
如果colControls什么都不是
Set colControls=新集合
设置fmUserform=UF
'创建弹出窗口
CreateBar
如果结束
'为每个文本框创建此类的新实例
设置cBar=新的clsBar
cBar.AssignControl Ctl,cmdBar
'将其添加到控件数组中
colControls.addcbar
如果结束
下一个Ctl
端接头
私有子类_Terminate()
'销毁类时删除命令栏
出错时继续下一步
cmdBar.Delete
端接头
'单击“复制”按钮的事件
私有子CMDComyButton_单击(ByVal Ctrl作为Office.CommandBarButton,CancelDefault作为布尔值)
作为字符串的Dim sACN
sACN=ActiveControlName(fmUserform)'查找控件的名称
“调试.打印sACN&”“复制”

fmUserform.Controls(sACN).copy'第二次用户表单调用的必要修改

在第一个表单中直接显示第二个表单似乎会出现问题,因为单击事件也会从单击的“CAT”控件获取返回值

这对我很有用:

  • 建议通过
    ShowYODA
    仅在UF模块中显示第二个用户表单,即调用位于单独模块中的过程,例如
  • 在单独模块中调用第二个表单的示例

    'Popup objects
    Private cmdBar As CommandBar
    Private WithEvents cmdCopyButton As CommandBarButton
    Private WithEvents cmdPasteButton As CommandBarButton
    
    'Useform to use
    Private fmUserform As Object
    
    'Control array of textbox
    Private colControls As Collection
    
    'Textbox Control
    Private WithEvents tbControl As MSForms.TextBox
    
    'Adds all the textbox in the userform to use the popup bar
    Sub Initialize(ByVal UF As Object)
        Dim Ctl As MSForms.Control
        Dim cBar As clsBar
    
        For Each Ctl In UF.Controls
            If TypeName(Ctl) = "TextBox" Then
    
                'Check if we have initialized the control array
                If colControls Is Nothing Then
                    Set colControls = New Collection
                    Set fmUserform = UF
                    'Create the popup
                    CreateBar
                End If
    
                'Create a new instance of this class for each textbox
                Set cBar = New clsBar
                cBar.AssignControl Ctl, cmdBar
                'Add it to the control array
                colControls.Add cBar
    
            End If
        Next Ctl
    End Sub
    
    Private Sub Class_Terminate()
        'Delete the commandbar when the class is destroyed
        On Error Resume Next
        cmdBar.Delete
    End Sub
    
    'Click event of the copy button
    Private Sub cmdCopyButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
        Dim sACN As String
        sACN = ActiveControlName(fmUserform)    ' find control's name
        ' Debug.Print sACN & ".Copy"
        fmUserform.Controls(sACN).copy          ' << instead of fmUserform.ActiveControl.Copy
        CancelDefault = True
    End Sub
    
    'Click event of the paste button
    Private Sub cmdPasteButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
        Dim sACN As String
        sACN = ActiveControlName(fmUserform)
        ' Debug.Print sACN & ".Paste"
        fmUserform.Controls(sACN).Paste    ' << instead of fmUserform.ActiveControl.Paste
        CancelDefault = True
    End Sub
    
    'Right click event of each textbox
    Private Sub tbControl_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
        If Button = 2 And Shift = 0 Then
            'Display the popup
            cmdBar.ShowPopup
        End If
    End Sub
    
    Private Sub CreateBar()
        Set cmdBar = Application.CommandBars.Add(, msoBarPopup, False, True)
        'We’ll use the builtin Copy and Paste controls
        Set cmdCopyButton = cmdBar.Controls.Add(ID:=19)
        Set cmdPasteButton = cmdBar.Controls.Add(ID:=22)
    End Sub
    
    'Assigns the Textbox and the CommandBar to this instance of the class
    Sub AssignControl(TB As MSForms.TextBox, Bar As CommandBar)
        Set tbControl = TB
        Set cmdBar = Bar
    End Sub
    
    Function ActiveControlName(form As UserForm) As String
        'cf Site: https://stackoverflow.com/questions/47745663/get-activecontrol-inside-multipage
        'Purpose: get ActiveControl
    
        Dim MyMultiPage As MSForms.MultiPage, myPage As MSForms.Page
    
        If form.ActiveControl Is Nothing Then
            ' do nothing
        ElseIf TypeName(form.ActiveControl) = "MultiPage" Then
            Set MyMultiPage = form.ActiveControl
            Set myPage = MyMultiPage.SelectedItem
            ActiveControlName = myPage.ActiveControl.Name
        Else
            ActiveControlName = form.ActiveControl.Name
        End If
    End Function
    
    Sub ShowYODA
        With New YODA           ' temporary new UF instance
            .Show vbModeless
        End With
    End Sub
    
  • 以下事件过程和被调用的助手函数中需要进行更改(仅对将在调用事件中修剪的文本框使用结束空间标记):
  • 相关点击事件

    'Click event of the copy button
    Private Sub cmdCopyButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    Dim sACN As String
    sACN = ActiveControlName(fmUserform)    ' find control's name
    If Right$(sACN, 1) = " " Then           ' marker (=ending space) for textboxes only!
           Debug.Print Trim(sACN) & ".Copy"
       fmUserform.Controls(Trim(sACN)).Copy ' << instead of fmUserform.ActiveControl.Copy /438 unterstü.d.Meth nicht!
       CancelDefault = True
    End If
    End Sub
    
    'Click event of the paste button
    Private Sub cmdPasteButton_Click(ByVal Ctrl As Office.CommandBarButton, CancelDefault As Boolean)
    Dim sACN As String
    sACN = ActiveControlName(fmUserform)    ' find control's name
    If Right$(sACN, 1) = " " Then           ' marker (=ending space) for textboxes only!
           Debug.Print Trim(sACN) & ".Copy"
       fmUserform.Controls(Trim(sACN)).Paste    ' << instead of fmUserform.ActiveControl.Copy
       CancelDefault = True
    End If
    End Sub
    

    请编辑显示原始用户表单和第二个用户表单的代码。由于您的类模块是相同的,我怀疑问题出在调用代码中的某个地方。我在第二个表单中的代码与我在原始表单中的代码(我文章中的第一个代码)相同。我认为这将是因为它调用了相同的代码,只是将其应用于不同的表单。对于误解,我感到抱歉-我认为阅读a)按钮“FAT”后面的确切代码以启动第二个用户表单以及b)调用主表单的代码和c)如果您显示的是非模态或模态的,可能会有所帮助。哦!对不起,我完全误解了。按钮中的代码是:CAT.Show vbModeless主窗体中的代码是:YODA.Show vbModeless为您的第二个用户窗体问题找到了解决方案。-你能试试我的答案吗?