在第一个文档 opened/unloaded 之后,Word Userform 将不会在第二个当前活动的文档中打开
Word Userform won't open in second, currently active document after opened/unloaded in first document
标题确实说明了一切,但这是我的情况:我设置了一个用户窗体来收集用户输入,然后在宏中使用该输入并执行它。这本身就完全按照我想要的方式工作。打开多个文档时会出现问题。
为了说明:我有两个文档,'doc a' 和 'doc b'。我打开两个文档,然后 select 'doc a',使用 show userform 宏打开用户窗体,输入我的数据,然后点击 'Okay' 或 'Cancel'(两者都已设置单击后卸载用户窗体)。宏运行s,然后我select'doc b'做同样的事情。然而,这一次,当我 运行 我的 'show userform' 宏时, 'doc a' 被 selected 并且在那里打开了用户表单。
这似乎是一个非常基本的问题,但我还没有找到任何解决办法。将 'unload me' 放入我的 button-click 子程序后失败,我尝试创建一个卸载宏并从这些子程序中调用它,但两者都不适合我。有什么想法吗? (此外,虽然我已经在这里 - 是否有任何好的技巧可以使用最近填充的数据自动填充用户表单?不是在 opening/closing 字之间,我已经看到了一些解决方案,但只是在字打开时,我正在活动文档之间切换)
Option Explicit
Option Compare Text
Private Sub UserForm_Initialize()
Folder_Name = ""
Tag_Name = ""
Checklist.Value = True
Site_Report.Value = False
Space_Check.Value = False
End Sub
Public Sub Okay_Click()
folder = Folder_Name.Text
tag = Tag_Name.Text
tagtxt = Tag_Name.Text & "[0-9]{1,}"
tagnum = Len(Tag_Name.Text)
If Checklist.Value = True Then
report_type = "cl"
Else
report_type = "sr"
End If
If Space_Check.Value = True Then
space = "yes"
Else
space = "no"
End If
If Len(Folder_Name.Text) > 0 Then
Application.Run "Mass_Hyperlink_v_5_0"
Application.Run "UnloadIt"
Else
Application.Run "UnloadIt"
End If
Unload Me
End Sub
Private Sub Cancel_Click()
Application.Run "UnloadIt"
Unload Me
End Sub
我认为问题不在于此用户窗体使用的宏(它 运行 本身没问题,尽管代码可能有点老套),但这里是衡量良好的代码:
Option Explicit
Option Compare Text
Public tag As String
Public tagtxt As String
Public tagnum As String
Public folder As String
Public space As String
Public report_type As String
Public Sub Mass_Hyperlink_v_5_0()
Dim fileName As String
Dim filePath As String
Dim rng As Word.Range
Dim rng2 As Word.Range
Dim fileType As String
Dim start As String
Dim temp As String
Application.ScreenUpdating = False
fileType = "jpg"
If space = "Yes" Then
start = "%20("
Else: start = "("
End If
If report_type = "cl" Then
folder = "..\Images\" & folder
Set rng = ActiveDocument.Range
Else: folder = folder
End If
If report_type = "sr" Then
folder = "Images\" & folder
Set rng = Selection.Range
Else: folder = folder
End If
Set rng2 = rng.Duplicate
'tagtxt = tag & "[0-9]{1,}"
If Len(rng) > 0 And report_type = "sr" Then
With rng.Find
.Text = tagtxt
.Forward = False
.MatchWildcards = True
.Wrap = wdFindStop
Do While .Execute(findText:=tagtxt) = True
If rng.InRange(rng2) Then
rng.Select
'Selection.start = Selection.start + Len(tag)
Selection.start = Selection.start + tagnum
'ActiveDocument.Range(Selection.start - Len(tag), Selection.start).Delete
ActiveDocument.Range(Selection.start - tagnum, Selection.start).Delete
fileName = Selection.Text
filePath = folder & "\" & Hyperlinker.Tag_Name.Text & start & fileName & ")" & "." & fileType
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, address:= _
filePath, SubAddress:="", ScreenTip:="", TextToDisplay:= _
(Hyperlinker.Tag_Name.Text & Selection.Text)
Else
Exit Sub
End If
rng.Collapse wdCollapseStart
Loop
End With
End If
If report_type = "cl" Then
With rng.Find
.Text = tagtxt
.Forward = False
.MatchWildcards = True
.Wrap = wdFindStop
Do While .Execute(findText:=tagtxt) = True
If rng.InRange(rng2) Then
rng.Select
'Selection.start = Selection.start + Len(tag)
Selection.start = Selection.start + tagnum
'ActiveDocument.Range(Selection.start - Len(tag), Selection.start).Delete
ActiveDocument.Range(Selection.start - tagnum, Selection.start).Delete
fileName = Selection.Text
filePath = folder & "\" & Hyperlinker.Tag_Name.Text & start & fileName & ")" & "." & fileType
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, address:= _
filePath, SubAddress:="", ScreenTip:="", TextToDisplay:= _
(Hyperlinker.Tag_Name.Text & Selection.Text)
Else
Exit Sub
End If
rng.Collapse wdCollapseStart
Loop
End With
End If
Application.ScreenUpdating = True
End Sub
Sub Show_Linker()
Hyperlinker.Show
Hyperlinker.Folder_Name.SetFocus
End Sub
Sub UnloadIt()
Unload Hyperlinker
End Sub
在 VBA 中使用用户表单可能会很棘手,因为它们实际上是 Class 的一种。由于 VBA 试图使一切变得异常简单,因此 classes 并不明显,如何正确使用它们也不明显。在某些情况下,它们会成为粗心者的陷阱。
因此 VBA 使您可以使用 UserForm class 的实例,而无需声明和实例化新对象,而 class 对象。结果是该对象可以 "hang around" 并导致意外行为,例如您所看到的。
使用用户窗体的更正确的方法可能看起来需要更多的工作(代码类型和复杂性),但它有助于保持事情的有序性。事实上,这种方法理论上允许您为各种文档创建一个单独的用户窗体。
Dim frmHyperlinker as Hyperlinker
Set frmHyperlinker = New Hyperlinker
frmHyperlinker.Folder_Name.SetFocus
frmHyperlinker.Show
'Execution waits...
'Now you're done with it, so clean up
Unload frmHyperlinker
Set frmHyperlinker = Nothing
虽然该问题的主题与您的不同,但此讨论中有一个涉及更多技术细节的答案:Add Public Methods to a Userform Module in VBA
标题确实说明了一切,但这是我的情况:我设置了一个用户窗体来收集用户输入,然后在宏中使用该输入并执行它。这本身就完全按照我想要的方式工作。打开多个文档时会出现问题。
为了说明:我有两个文档,'doc a' 和 'doc b'。我打开两个文档,然后 select 'doc a',使用 show userform 宏打开用户窗体,输入我的数据,然后点击 'Okay' 或 'Cancel'(两者都已设置单击后卸载用户窗体)。宏运行s,然后我select'doc b'做同样的事情。然而,这一次,当我 运行 我的 'show userform' 宏时, 'doc a' 被 selected 并且在那里打开了用户表单。
这似乎是一个非常基本的问题,但我还没有找到任何解决办法。将 'unload me' 放入我的 button-click 子程序后失败,我尝试创建一个卸载宏并从这些子程序中调用它,但两者都不适合我。有什么想法吗? (此外,虽然我已经在这里 - 是否有任何好的技巧可以使用最近填充的数据自动填充用户表单?不是在 opening/closing 字之间,我已经看到了一些解决方案,但只是在字打开时,我正在活动文档之间切换)
Option Explicit
Option Compare Text
Private Sub UserForm_Initialize()
Folder_Name = ""
Tag_Name = ""
Checklist.Value = True
Site_Report.Value = False
Space_Check.Value = False
End Sub
Public Sub Okay_Click()
folder = Folder_Name.Text
tag = Tag_Name.Text
tagtxt = Tag_Name.Text & "[0-9]{1,}"
tagnum = Len(Tag_Name.Text)
If Checklist.Value = True Then
report_type = "cl"
Else
report_type = "sr"
End If
If Space_Check.Value = True Then
space = "yes"
Else
space = "no"
End If
If Len(Folder_Name.Text) > 0 Then
Application.Run "Mass_Hyperlink_v_5_0"
Application.Run "UnloadIt"
Else
Application.Run "UnloadIt"
End If
Unload Me
End Sub
Private Sub Cancel_Click()
Application.Run "UnloadIt"
Unload Me
End Sub
我认为问题不在于此用户窗体使用的宏(它 运行 本身没问题,尽管代码可能有点老套),但这里是衡量良好的代码:
Option Explicit
Option Compare Text
Public tag As String
Public tagtxt As String
Public tagnum As String
Public folder As String
Public space As String
Public report_type As String
Public Sub Mass_Hyperlink_v_5_0()
Dim fileName As String
Dim filePath As String
Dim rng As Word.Range
Dim rng2 As Word.Range
Dim fileType As String
Dim start As String
Dim temp As String
Application.ScreenUpdating = False
fileType = "jpg"
If space = "Yes" Then
start = "%20("
Else: start = "("
End If
If report_type = "cl" Then
folder = "..\Images\" & folder
Set rng = ActiveDocument.Range
Else: folder = folder
End If
If report_type = "sr" Then
folder = "Images\" & folder
Set rng = Selection.Range
Else: folder = folder
End If
Set rng2 = rng.Duplicate
'tagtxt = tag & "[0-9]{1,}"
If Len(rng) > 0 And report_type = "sr" Then
With rng.Find
.Text = tagtxt
.Forward = False
.MatchWildcards = True
.Wrap = wdFindStop
Do While .Execute(findText:=tagtxt) = True
If rng.InRange(rng2) Then
rng.Select
'Selection.start = Selection.start + Len(tag)
Selection.start = Selection.start + tagnum
'ActiveDocument.Range(Selection.start - Len(tag), Selection.start).Delete
ActiveDocument.Range(Selection.start - tagnum, Selection.start).Delete
fileName = Selection.Text
filePath = folder & "\" & Hyperlinker.Tag_Name.Text & start & fileName & ")" & "." & fileType
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, address:= _
filePath, SubAddress:="", ScreenTip:="", TextToDisplay:= _
(Hyperlinker.Tag_Name.Text & Selection.Text)
Else
Exit Sub
End If
rng.Collapse wdCollapseStart
Loop
End With
End If
If report_type = "cl" Then
With rng.Find
.Text = tagtxt
.Forward = False
.MatchWildcards = True
.Wrap = wdFindStop
Do While .Execute(findText:=tagtxt) = True
If rng.InRange(rng2) Then
rng.Select
'Selection.start = Selection.start + Len(tag)
Selection.start = Selection.start + tagnum
'ActiveDocument.Range(Selection.start - Len(tag), Selection.start).Delete
ActiveDocument.Range(Selection.start - tagnum, Selection.start).Delete
fileName = Selection.Text
filePath = folder & "\" & Hyperlinker.Tag_Name.Text & start & fileName & ")" & "." & fileType
ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, address:= _
filePath, SubAddress:="", ScreenTip:="", TextToDisplay:= _
(Hyperlinker.Tag_Name.Text & Selection.Text)
Else
Exit Sub
End If
rng.Collapse wdCollapseStart
Loop
End With
End If
Application.ScreenUpdating = True
End Sub
Sub Show_Linker()
Hyperlinker.Show
Hyperlinker.Folder_Name.SetFocus
End Sub
Sub UnloadIt()
Unload Hyperlinker
End Sub
在 VBA 中使用用户表单可能会很棘手,因为它们实际上是 Class 的一种。由于 VBA 试图使一切变得异常简单,因此 classes 并不明显,如何正确使用它们也不明显。在某些情况下,它们会成为粗心者的陷阱。
因此 VBA 使您可以使用 UserForm class 的实例,而无需声明和实例化新对象,而 class 对象。结果是该对象可以 "hang around" 并导致意外行为,例如您所看到的。
使用用户窗体的更正确的方法可能看起来需要更多的工作(代码类型和复杂性),但它有助于保持事情的有序性。事实上,这种方法理论上允许您为各种文档创建一个单独的用户窗体。
Dim frmHyperlinker as Hyperlinker
Set frmHyperlinker = New Hyperlinker
frmHyperlinker.Folder_Name.SetFocus
frmHyperlinker.Show
'Execution waits...
'Now you're done with it, so clean up
Unload frmHyperlinker
Set frmHyperlinker = Nothing
虽然该问题的主题与您的不同,但此讨论中有一个涉及更多技术细节的答案:Add Public Methods to a Userform Module in VBA