Word Userform won't open in second, currently active document after opened/unloaded in first document

江枫思渺然 提交于 2019-12-25 18:36:40

问题


The headline really says it all, but here's my situation: I have a userform set up to collect user input, then uses that input in a macro and executes it. That, in itself, works exactly like I want it to. The problem comes when more than one document is open.

To illustrate: I have two documents, 'doc a' and 'doc b'. I open both documents, then select 'doc a', open the userform using a show userform macro, input my data, and hit either 'Okay' or 'Cancel' (both of which are set to unload the userform once clicked). The macro runs, and then I select 'doc b' to do the same. This time, however, when I run my 'show userform' macro, 'doc a' is selected and the userform is opened there.

This seems like a pretty basic issue, but I haven't been able to figure out any fixes. After putting 'unload me' failed to work in my button-click subs, I tried creating an unload macro and calling it from those subs instead, but neither is working for me. Any thoughts? (Also, while I'm already here- are there any good tricks to autofill the Userform with the most recently filled data? Not between opening/closing word, which I've seen some solutions for, but just while word is open, and I'm switching between active documents)

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

I don't think the issue is with the macros that this userform uses (it runs fine on its own, though the code is likely a bit hackneyed), but here's the code for good measure:

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

回答1:


Working with UserForms in VBA can be tricky, because they're actually a kind of Class. Since VBA tries to make everything exceptionally simple, classes are not obvious, nor is how to work with them correctly. There are situations where they become traps for the unwary.

So VBA makes it possible for you to work with an instance of a UserForm class without you needing to declare and instantiate a new object, as would normally be the case with a class object. The result being that the object can "hang around" and cause unexpected behavior, such as you're seeing.

The more correct way to work with a UserForm may seem like a lot more work (code to type and complexity), but it helps to keep things sorted. Indeed, this approach would theoretically allow you to have a separate UserForm for various documents.

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

There's an Answer in this discussion that goes into more technical detail, although the topic of that question is different from yours: Add Public Methods to a Userform Module in VBA



来源:https://stackoverflow.com/questions/36432835/word-userform-wont-open-in-second-currently-active-document-after-opened-unloa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!