Gre*_*edo 7 excel vba excel-vba vbe
我有一个插件和一个工作簿打开.插件是.xlam文件,在工作簿中我添加了对它的引用.插件受密码保护.
可以从我的工作簿中运行addin的公共方法.然而,在一个插件的方法使用的VBA.UserForms.Add
打开是在运行时创建的窗体像这样
让我们说一个引用的工作簿myAddin
有这个:
Private Sub callAddin()
myAddin.ShowForm ThisWorkbook
End Sub
Run Code Online (Sandbox Code Playgroud)
通常,我的插件中的代码如下所示:
Public Sub ShowForm(CallerWorkbook As Workbook)
Const vbext_ct_MSForm As Long = 3
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
'Add to ThisWorkbook, not supplied workbook or VBE will crash - ignore CallerWorkbook
Dim myForm As Object
Set myForm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
'Create the User Form
With myForm
.Properties("Caption") = "Select"
.Properties("Width") = 300
.Properties("Height") = 270
End With
'Show the form
Dim finalForm As Object
Set finalForm = VBA.UserForms.Add(myForm.Name)
finalForm.Show
'Remove form
ThisWorkbook.VBProject.VBComponents.Remove myForm
End Sub
Run Code Online (Sandbox Code Playgroud)
哪个工作正常.但是,当我的插件受密码保护时,不允许尝试向其添加临时用户表单.没问题,我只是将临时用户表单添加到调用代码的工作簿中,因为这不受密码保护
Sub ShowForm(CallerWorkbook As Workbook)
Const vbext_ct_MSForm As Long = 3
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
'Add to CallerWorkbook instead
Dim myForm As Object
Set myForm = CallerWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
'Create the User Form
With myForm
.Properties("Caption") = "Select"
.Properties("Width") = 300
.Properties("Height") = 270
End With
'Show the form
Dim finalForm As Object
'Now myForm cannot be found and added
Set finalForm = VBA.UserForms.Add(myForm.Name)
finalForm.Show
'Remove form
CallerWorkbook.VBProject.VBComponents.Remove myForm
End Sub
Run Code Online (Sandbox Code Playgroud)
然而VBA似乎无法看到哪里myForm.Name
点到现在,所以Add方法失败"Run time error 424: Object required"
有没有办法在另一个工作簿中显示在运行时创建的表单?
您遇到的问题是默认情况下UserForms是私有实例.这意味着项目不能引用另一个项目中的UserForm,如果您不能引用该表单,则无法调用它的Show
方法.
你的Set myForm = CallerWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
陈述返回a VbComponent
而不是a UserForm
,这就是你不能再使用的原因VBA.UserForms.Add(myForm.Name)
有两种方法:
PublicNotCreatable
在加载项中创建模板UserFormUserForm就像一个类,所以它可以Instancing
设置其属性,就像一个类.但是,VBE不会Instancing
在UserForms的"属性"窗口中公开该属性,因此要设置实例化,您需要导出表单,然后Attribute VB_Exposed
在文本编辑器中编辑FRM文件中的属性,然后再次导入表单.以下是步骤:
TemplateForm
在加载项项目中命名的UserFormTemplateForm
并选择导出表单后再删除它TemplateForm.frm
在文本编辑器中打开文件Attribute VB_Exposed = False
以便读取Attribute VB_Exposed = True
TemplateForm.frm
TemplateForm.frm
到您的加载项添加一个公共函数,该函数返回TemplateForm
加载项的新实例.我已使此函数接受工作簿引用,以便加载项可以在窗体上配置任何工作簿特定的属性:
Public Function GetTemplateForm(CallerWorkbook As Workbook) As TemplateForm
Dim frm As TemplateForm
Set frm = New TemplateForm
'Set early-bound properties with intellisense
frm.Caption = "Select"
frm.Width = 300
frm.Height = 270
'Configure CallerWorkbook specific form properties here
'...
Set GetTemplateForm = frm
End Function
Run Code Online (Sandbox Code Playgroud)在用户的工作簿中,您可以显示TemplateForm的实例,而无需动态添加表单,或处理屏幕闪烁或难以调试的代码:
Sub ShowAddinForm()
With MyAddin.GetTemplateForm(ThisWorkbook)
'Do more workbook specific propery setting here...
'...
.Show
End With
End Sub
Run Code Online (Sandbox Code Playgroud)**注意 - Rubberduck VBA加载项很快就可以添加PublicNotCreatable
UserForm.
这种方法并不那么优雅.用户需要管理更多代码,屏幕闪烁,代码调试困难.以下是步骤:
将此代码添加到加载项:
Public Function GetTempFormName(CallerWorkbook As Workbook) As String
Const vbext_ct_MSForm As Long = 3
'This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
'Add to CallerWorkbook instead
With CallerWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm)
.Properties("Caption") = "Select"
.Properties("Width") = 300
.Properties("Height") = 270
GetTempFormName = .Name
End With
End Function
Public Sub RemoveTempForm(CallerWorkbook As Workbook, FormName As String)
With CallerWorkbook.VBProject.VBComponents
Dim comp As Object
Set comp = .Item(FormName)
.Remove .Item(FormName)
End With
End Sub
Run Code Online (Sandbox Code Playgroud)然后,在用户的工作簿中,添加以下代码:
Sub GetAddinToCreateForm()
Dim FormName As String
FormName = MyAddin.GetTempFormName(ThisWorkbook)
With VBA.UserForms.Add(FormName)
.Show
End With
MyAddin.RemoveTempForm ThisWorkbook, FormName
End Sub
Run Code Online (Sandbox Code Playgroud)