【问题标题】:EXCEL VBA Showing a Userform from a Different Worksheet or WorkbookEXCEL VBA 显示来自不同工作表或工作簿的用户窗体
【发布时间】:2018-03-10 22:37:26
【问题描述】:

我在 EXCEL 2016 中为 PC 开发了一个用户表单。如果用户从与上次启动或显示相同的工作簿/工作表启动用户表单(从我的加载项添加到功能区的按钮),那么我希望用户表单记住上次使用的所有用户设置。因此,当用户完成特定用途时,我只是将表单隐藏起来。到目前为止,这运作良好。

但是,如果用户随后从不同的工作表或工作簿显示用户窗体,则 EXCEL 会“快速”返回到启动用户窗体的原始工作簿/工作表。在这种情况下,我希望用户窗体重置并出现在“新”活动工作簿/工作表中。

我可以想象这样的伪代码:

Public wb0 As Workbook
Public ws0 As Worksheet

'  IF the userform is being used for the 1st time

Public Sub UserForm_Initialize()
    yada yada yada...

    wb0 = current workbook
    ws0 = current worksheet
End Sub

Private Sub UserForm_Activate()
    If wb0 <> ActiveWorkbook OR ws0 <> ActiveWorkSheet Then
        (**Force the userform to open in the current workbook/worksheet**)
        Call Reset
        wb0 = current workbook
        ws0 = current worksheet
    End If
End Sub

但是,我不确定如何:

1) 测试当前活动工作簿和工作表是否与上次使用的活动工作簿和工作表相同。我应该将 wb0 设置为 ActiveWorkbook 的 Name 属性吗?

wb0 = ActiveWorkbook.Name

然后测试将是:

If wb0 <> ActiveWorkbook.Name ...

2) 另外,不确定如何强制用户窗体在当前工作表中打开。

====

或者,也许最好有类似的东西:

Private Sub UserForm_Activate()
    If wb0 <> ActiveWorkbook OR ws0 <> ActiveWorkSheet Then
        Unload userform
        Reload userform
    End If
End Sub

这样一切都会自动重置...

====

有人可以建议吗?

谢谢!!

【问题讨论】:

  • 您可以使用隐藏表并将用户表单的所有值存储在那里,然后让用户表单在初始化时自行填充。这样它就会一直工作。我猜这是一种黑客攻击
  • 您好道格,感谢您的回复。因此,每次使用第二个隐藏表来存储值并卸载主表。然后,每次重新初始化主工作表,如果值保存在第二个隐藏工作表上,然后从第二个工作表重新填充主工作表,对吗?如何创建隐藏表?是否有一种简单的方法可以从另一个工作表重新填充一个工作表,或者是否必须为用户表单中的每个字段完成?

标签: excel vba userform


【解决方案1】:

我在一个大插件中使用一些用户窗体来做这个。

想象一个名为 F_UserForm 的用户窗体。调用它的大量精简模块如下所示:

Option Explicit

Dim gF_UserForm As F_UserForm

Sub CallUserForm()

  If Not gF_UserForm Is Nothing Then
    On Error Resume Next
    If gF_UserForm.ActiveWkbk.FullName <> ActiveWorkbook.FullName Then
      Unload gF_UserForm
      Set gF_UserForm = Nothing
    End If
  End If

  If gF_UserForm Is Nothing Then
    Set gF_UserForm = New F_UserForm
  End If

  With gF_UserForm
    Set .ActiveWkbk = ActiveWorkbook
    .Show
  End With

End Sub

精简后的用户窗体代码如下所示:

Option Explicit

Dim m_Wkbk As Workbook

Public Property Set ActiveWkbk(wkbk As Workbook)
  Set m_Wkbk = wkbk
End Property

对于 OP 的情况,我的 main 例程可以替换成下面的,我在上面添加到 userform 代码中的部分不需要更改,但应该合并到 Reg_Userform 中。

Option Explicit

Dim gReg_Userform As Reg_Userform

Sub conRegBox(control As IRibbonControl)

  If Not gReg_Userform Is Nothing Then
    On Error Resume Next
    If gReg_Userform.ActiveWkbk.FullName <> ActiveWorkbook.FullName Then
      Unload gReg_Userform
      Set gReg_Userform = Nothing
    End If
  End If

  If gReg_Userform Is Nothing Then
    Set gReg_Userform = New Reg_Userform
  End If

  With gReg_Userform
    Set .ActiveWkbk = ActiveWorkbook
    .Show
  End With

End Sub

【讨论】:

  • 您好乔恩,感谢您的回复。我一直在研究你的方法,我有几个问题:
  • 1) 所以,我的加载项只有 1 个用户表单。我相信这对应于您的 F_Userform 并且 gF_Userform 是 F_Userform 的虚拟副本?那是对的吗?如果是这样,我假设我应该用我的用户表单 Reg_Userform 的名称替换 F_Userform。对吗?
  • 2) 启动我的用户表单的模块非常简单。它由
  • Sub conRegBox(control As IRibbonControl) Reg_Userform.Show End Sub
  • ...那么,您的 CallUserform 子代码会在我的 .Show 代码行之前还是替换它?这将是此代码的正确位置吗?谢谢!!最好的,丹
猜你喜欢
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-19
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多