【问题标题】:Dynamically Duplicating a page in a Multipage在多页中动态复制页面
【发布时间】:2017-08-13 18:17:05
【问题描述】:

下午好,所以我被分配了一项任务,我应该采用我制作的日历用户表单并实现根据需要复制多页用户表单上的选项卡的日历的能力。

我的问题是:是否可以动态地这样做?我将所有控件复制到另一个选项卡以对其进行测试,但是所有控件按钮都被重命名,并且由于命名时出现歧义错误,我无法将它们命名为与“母版页”上的按钮相同的名称一个用户窗体上的 2 个按钮相同。

我可以使用新按钮名称编写新代码,但这无法动态完成,因为每次添加新标签时,我必须在创建之前为它准备好代码。

任何帮助将不胜感激。

【问题讨论】:

  • 为什么要复制功能而不是在需要时使用单独的日历表单?

标签: vba excel


【解决方案1】:

Demo Workbook

处理此类问题的关键是创建一个类来保存对新创建控件的引用。使用WithEvents 将允许您处理引用控件的事件。

在此处了解WithEventsEvents And Event Procedures In VBA

为了完成这项工作,您必须在新创建的 Page 控件及其类中的分身之间进行 Set 引用。您还需要通过将类引用添加到全局集合、字典或数组来保持类引用有效。

在我的示例中,我创建了一个子例程,它将遍历模板页面控件,创建并复制声明变量所需的代码并将引用设置到 Windows 剪贴板中。

最后一步是将用户窗体中的事件代码复制到类模块中。

下载Demo Workbook获取代码示例。

或者,您可以将Multipage 控件替换为TabStrip 控件。不同之处在于您可以在所有Tabs 范围内拥有TabStrip 上的控件。您可以使用TabStrip1_Change() 根据所选选项卡 (TabStrip1.SelectedItem) 更新控件。

【讨论】:

    【解决方案2】:

    首先,我建议您查看 Thomas Inzina 的答案。 但是,在我的一个工作表中,我做了同样的事情,而不依赖 WithEvents,所以我想展示另一种方法。

    此方法按照预定格式设置控件的名称(例如“Input1_”(计数器 + 1)),以便其他操作轻松引用控件。

    控件本身位于带有设置标题的框架中,因此在它们被复制后我仍然可以引用它们。

    自从我从较长的过程中剥离代码后,我已经对代码进行了一些编辑,但希望它仍然完好无损。

    Dim Ctrl As msforms.Control
    Dim Mpage As msforms.Control
    Dim Ctrl2 As msforms.Control
    Dim pge As msforms.Page
    Dim L As Double, R As Double
    Dim PageName As String, PageTitle As String
    Dim counter As Long
    
    counter = 0
    Set Mpage = Me.Controls("Multipage_1") 'set Multipage
    
    'count current number of tabs within MPage
    For Each pge In Mpage.Pages    
        counter = counter + 1
    Next pge
    
    'set name/title for new page
    PageName = "Tab_" & (counter + 1)
    PageTitle = "Tab " & (counter + 1)
    
    With Mpage    'add tab
        .Pages.Add PageName, PageTitle
        .Pages(0).Controls.Copy
        .Pages(counter).Paste
    End With
    
    'get position of original frame (controls are within this frame)
    For Each Ctrl In Mpage.Pages(0).Controls    
        If TypeOf Ctrl Is msforms.Frame Then
            L = Ctrl.Left
            R = Ctrl.Top
            Exit For
        End If
    Next
    
    'apply position to new frame
    For Each Ctrl In Mpage.Pages(counter).Controls    
        If TypeOf Ctrl Is msforms.Frame Then
            Ctrl.Left = L
            Ctrl.Top = R
            Exit For
        End If
    Next
    
    'renames input-controls and removes copied values by looping through frames
    'that contain the controls, since frame-captions can be duplicates
    For Each Ctrl In Mpage.Pages(counter).Controls    
        If TypeOf Ctrl Is msforms.Frame Then
            Select Case Ctrl.Caption
                Case "Input1"
                    For Each Ctrl2 In Ctrl.Controls
                        Ctrl2.Name = "Input1_" (counter + 1)
                        Ctrl2.Text = ""
                    Next Ctrl2
                Case "Input2"
                    For Each Ctrl2 In Ctrl.Controls
                        Ctrl2.Name = "Input2_" (counter + 1)         
                        Ctrl2.Text = ""
                    Next Ctrl2
                Case "Input3"
                    For Each Ctrl2 In Ctrl.Controls
                        Ctrl2.Name = "Input3_" (counter + 1)
                        Ctrl2.Text = ""
                    Next Ctrl2
            End Select
        End If
    Next Ctrl
    

    【讨论】:

      【解决方案3】:

      为控件名称使用前缀。例如。 tab1_button1tab2_button1tab33_button1。然后只有一个事件处理程序服务所有事件(按钮按下,复选框点击)

      这里有一些信息using one sub for multiple buttons in excel vba

      【讨论】:

      • 问题是 OP 没有命名控件。当他复制和粘贴 MultiPage 时,VBA 会自动命名新控件。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多