Consulting

Page 1 of 2 1 2 LastLast
Results 1 to 20 of 23

Thread: How to de-link a document from a userform

  1. #1

    How to de-link a document from a userform

    I have a VBA macro that opens three documents (A, B & C), putting them in an array for later referral. The macro then opens a small userform that permits various Word searches in A, B & C.

    However, whenever I click anywhere on the userform, the last of the three documents opened (C) comes to the fore. Why does this happen and how to prevent it? It is as if the userform has developed a permanent link with C. If the user closes C, then clicking on the userform no longer changes the focus document.

    The code is all in a separate template, the documents have no code in them at all.

    There is a statement aDoc.Activate that makes A, B or C the current active document, but clicking anywhere on the userform always brings C into focus, obscuring the other docs.

    ShowModal is False and the userform is ‘shown’ with vbModeless.

    I have an API call that keeps the small userform on top.

    I’m using Word 2003 under Windows 7.

    When minimizing doc C, the userform goes out of focus until doc C is brought back into focus.

    Closing doc C does the trick, but is somewhat radical for our purposes.

    The code is a little complex to post here.

    Any guidance on underlying principles would be most welcome!

    Thanks

  2. #2
    Moderator VBAX Guru Aussiebear's Avatar
    Joined
    Dec 2005
    Location
    Queensland
    Posts
    4,132
    Location
    Without seeing the code, most people will simply be guessing, so be prepared for all sorts of answers. Can a.Doc be set to nothing on exit?
    Remember To Do the Following....
    Use tags when posting code to the thread,
    Mark your thread as Solved if satisfied by using the Thread Tools options.
    If posting the same issue to another forum please show the link

  3. #3
    Yes, I'm more or less reduced to wild guesses myself. I do frequently reach places in my programming where I'm uncertain whats going on!

    Well, that suggestion is good housekeeping and I've added a couple of Set aDoc = Nothing at appropriate places but it makes no difference.

    Whatever is the last document opened and activated before opening the user form remains linked to the the userform until that document is closed.

  4. #4
    Quote Originally Posted by Aussiebear View Post
    Without seeing the code, most people will simply be guessing, so be prepared for all sorts of answers.
    OK. Here's the code, a little simplified ...

    Public aDocArray(1 To 10) As Variant    ' max no of docs
    Public DocNameArray(1 To 10) As String  ' max no of docs
    Public arrCnt As Integer
    Public arrNoofDocs As Integer
    Public sFRText As String
    Public frmFRT As frmFRTPARTs
    
    Sub FindIn()'   Find-Replace, inn PARTs I, II & III
    ' This routine opens the three documents and loads the userform.
    ' Clicking the START/NEXT/FINISH button on the userform simply calls the routine DoTDocs (see below)
    ' There is nothing else of any significance to this issue in the userform code
    
    
        Dim currDocFR As Word.Document
        Dim sStart As Long, sEnd As Long
        Dim currDocFRName As String
        
        If Documents.count < 1 Then
            MsgBox "Please open a document"
            Exit Sub
        End If
        
        Set currDocFR = Application.ActiveDocument
        
        If currDocFR.ActiveWindow.View.SplitSpecial <> wdPaneNone Then
            MsgBox "Please close any open endnote or other viewing pane"
            Exit Sub
        End If
        
        sStart = Selection.Start
        sEnd = Selection.End
        
        Application.ScreenUpdating = False
        
        '   Save selected text, if any
        If Selection.Start <> Selection.End Then
            sFRText = Selection.Text
            Selection.Collapse wdCollapseStart
        Else
            MsgBox "Please select a search string"
            Exit Sub
        End If
        
        Call OpenDoc("PART IV")                                             ' Path and filenames are correct. These are abbreviations for the sake of this post
        Set aDocArray(3) = Application.ActiveDocument
        DocNameArray(3) = "PART IV"
        
        Call OpenDoc("PART III")
        Set aDocArray(2) = Application.ActiveDocument
        DocNameArray(2) = "PART III"
            
        Call OpenDoc("PART II")
        Set aDocArray(1) = Application.ActiveDocument
        DocNameArray(1) = "PART II"
          
        arrNoofDocs = 3
        arrCnt = 1
        Set frmFRT = New frmFRTPARTs
        
        Call ClearFormatting1                      ' Does what it says
        Call API_NamedWindowOnTop("Find-Replace", 1290, 218)
        
    End Sub
    
    
    Sub DoTDocs()
    
    
    '   On clicking the Start/Next button, we sequentially make each document PART active
    '   If the user has selected a string in the original document, and that string is found,
    '   we hand control back to the user until he clicks 'Next'.
    '   Else we search the next document PART in sequence
    
    '   ********** There are other buttons on the userform. Clicking these or any other part of the userform, brings the PART II document to the fore,
    'even if the user was working on, say, the PART III or PART IV documents. THIS IS THE ESSENCE OF THE PROBLEM  ****************
    
    
        Dim doc As Document
        Dim aDoc As Document
        
    Nextdoc:
        If arrCnt > arrNoofDocs Then
            Call CloseDocs
            MsgBox "Searched all requested documents"
            Set aDoc = Nothing
            Unload frmFRT
            Exit Sub
        End If
          
    Nextdoc1:
        Set aDoc = aDocArray(arrCnt)
        arrCnt = arrCnt + 1
        On Error GoTo Nextdoc                                                                     ' If user has closed the doc, read next doc in array
        If IsFileOpen(DocNameArray(arrCnt - 1)) = False Then GoTo Nextdoc   ' On Error GoTo Nextdoc does not always catch it
        aDoc.Activate
        frmFRT.lblCurrDoc.Caption = aDoc & vbCrLf & vbCrLf & "Search string:" & vbCrLf & vbCrLf & sFRText
        
        If arrCnt > arrNoofDocs Then
            frmFRT.cmdDoTDocs.Caption = "Finish"
        Else
            frmFRT.cmdDoTDocs.Caption = "Next PART"
        End If
        
        frmFRT.cmdSearchNext.Enabled = True
        frmFRT.Repaint
        DoEvents
        
        Selection.HomeKey Unit:=wdStory
        With Selection.Find
            .ClearFormatting
            .Replacement.ClearFormatting
            .Text = sFRText
            .Replacement.Text = sFRText
            .Wrap = wdFindAsk
            .Forward = True
            .Format = False
            .MatchCase = frmFRT.chkMatchCase
            .MatchWholeWord = frmFRT.chkWholeWord
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
        End With
    
    
        If Selection.Find.Execute = False Then
            If Application.ActiveDocument = aDoc Then
                aDoc.Close                                                        'Close doc after not finding the string
            End If
            GoTo Nextdoc
        End If
        
        ' If string found or no string selected
        Set aDoc = Nothing
        Application.ScreenUpdating = True
        Call PosTopToMid(True)                                            ' Position found text 10 lines down from the top of the screen
        CommandBars("Edit").Controls("Replace...").Execute  ' Find & Replace
    
    
    End Sub
    
    
    Sub CloseDocs()
        Dim i As Integer
        Dim aDoc As Document
        
        For i = 1 To arrNoofDocs
            Set aDoc = aDocArray(i)
            If IsFileOpen(DocNameArray(i)) = True Then aDoc.Close
        Next
    End Sub

  5. #5
    Moderator VBAX Guru Aussiebear's Avatar
    Joined
    Dec 2005
    Location
    Queensland
    Posts
    4,132
    Location
    can you set current document crrDocFr to nothing? To me this seems to relate to what ever is left over in memory as the active document.
    Remember To Do the Following....
    Use tags when posting code to the thread,
    Mark your thread as Solved if satisfied by using the Thread Tools options.
    If posting the same issue to another forum please show the link

  6. #6
    That sounded like a good idea, but I put 'Set currDocFR = Nothing' before 'Call OpenDoc("PART IV")' and again before 'End Sub' and the problem persists.

    It seems to me that the issue is definitely the relationship between the userform and whatever is the active document at the time the userform is opened. As soon as the user clicks anywhere on that userform, whatever was the active document when the userform was opened takes the focus, also obscuring other documents if they are on the same screen. Use of the API to bring the userform to the top helps (it stops the userform from disappearing), but is not the complete answer.

    I've had this with other userforms (also toolbars). A connection is established between the active document and the userform/toolbar that is active when the userform/toolbar is opened/loaded.

  7. #7
    I just tried making currDocFR the active document just before opening the userform. Then closing and reopening currDocFR and setting currDocFR to Nothing. Didn't work! In fact it made matters worse because the userform disappeared too, only showing its face when currDocFR was again made the focus by the user.

    Closing currDocFR would work I suspect (but that defeats the object), just as closing the PART II document after searching works, which is what I presently have it doing.

    What/why is the connection of a userform to a document and how to disengage it?

  8. #8
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,380
    Location
    Quote Originally Posted by johndavidson View Post
    I have a VBA macro that opens three documents (A, B & C), putting them in an array for later referral. The macro then opens a small userform that permits various Word searches in A, B & C.
    Attach the DOCM with the macro and userform to make it easier to review
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  9. #9
    I understand, and I really appreciate the input, but I've been trying to keep it simple. The template (*.dot actually for Word 2003) containing this macro and userform is in fact 4.6MB in size with hundreds of macros and multiple userforms, also linked to other templates for various utility routines. Three decades of intermittent programming to address various needs on a huge literary project. About 12MB in all. It would be easier to write a sample macro that illustrates the issue. I'll have a think about it. Time is presently at a premium. I was hoping there would be something simple that I was doing wrong that the experts could easily spot!

  10. #10
    Actually, I think the problem can be demonstrated very simply without programming. It even looks like its ‘the way Word/VBA works’, so what I’m looking for is a VBA workaround.

    Try this:

    1. Open a Word document (‘A’).

    2. Open any simple modeless userform you may have. This appears to link document 'A' to the userform.

    3. With the userform positioned over document ‘A’, open another Word document (‘B’) – the userform disappears unless you have set it as topmost using the API.

    4. Now bring A back into focus, and the userform re-appears. This demonstrates that in some way the userform is linked to document A.

    5. Move the userform onto another screen or part of the screen if you are using only one screen.

    6. Now bring document B into focus.

    7. Now click any blank space on the userform – document A retakes the focus.

    8. The issue is, “How to de-link document A from the userform”. This can be achieved by closing document A. Then the userform is either closed with document A, or if it is not closed, it remains on top even if you have more than one document open. Why the userform is sometimes closed when document A is closed is another part of the mystery. Note, Modeless is set both when the userform is loaded and in the userform properties. Closing document A is of course not a desirable way of doing things. The user may want to have kept it open.
    Last edited by johndavidson; 05-19-2022 at 02:50 AM.

  11. #11
    I think I’ve found a way to do it: When the next doc to be processed has been made the active document, unload the existing userform and then reopen it. Seems to be working.

    Will check more tomorrow.

  12. #12
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,380
    Location
    2. Open any simple modeless userform you may have. This appears to link document 'A' to the userform.
    Where is this UF located? A or B or C?
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  13. #13
    The UF and its code are in a separate template (John.dot), which is loaded when Word is started. i.e. it lives in C:\Users\<username>\AppData\Roaming\Microsoft\Word\StartUp\John.dot.

    The UF is initially associated with doc C, which happens to be the active document when the UF is opened. When the user indicates (by clicking a NEXT button on the UF) that work on doc C has been completed, then, by closing the UF, making B the active doc, and then (in the re-jigged routine) re-opening the UF, the UF is then associated with doc B. Likewise for doc C. This seems to get around the problems I was having.

    It seems to me that UFs always begin life associated with the document that is active at the time the UF is opened, which is why, when you have multiple Word docs open at one time, a UF can disappear off screen or even get closed when the original doc is closed or when another doc is given the focus by clicking on it or from within VBA.

    It would be good to know if there is a way to open a userform that is entirely unrelated to any particular Word document.
    Last edited by johndavidson; 05-20-2022 at 08:02 PM.

  14. #14
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,380
    Location
    What triggers the UF in John.dot?

    I don't have Word 2003 and Win7, so i (and most others I'm assuming) can only guess
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  15. #15
    The VBA macros work the same in Word 2003 as they do in later versions of Word. Except that from Word 2007 onwards, intensive text processing macros work up to eight times slower in the ribbon versions of Word than they do in Word 2003. Did you try out the doc/userform check (steps 1 to 8 above)? I suspect that the issue will be the same. It's a global issue, not one related to a particular macro.

    Thanks to yourself & Aussiebear for your input. Often with these problems all that is needed is for someone to suggest an alternative way of looking at it to provide the stimulation to come up with a solution. Or to pose the question, What exactly are you trying to achieve (always a good question!)? That's what happened here. Great stuff, guys!

  16. #16
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,380
    Location
    Quote Originally Posted by johndavidson View Post
    The UF and its code are in a separate template (John.dot), which is loaded when Word is started. i.e. it lives in C:\Users\<username>\AppData\Roaming\Microsoft\Word\StartUp\John.dot.

    The UF is initially associated with doc C, which happens to be the active document when the UF is opened. When the user indicates (by clicking a NEXT button on the UF) that work on doc C has been completed, then, by closing the UF, making B the active doc, and then (in the re-jigged routine) re-opening the UF, the UF is then associated with doc B. Likewise for doc C. This seems to get around the problems I was having.

    It seems to me that UFs always begin life associated with the document that is active at the time the UF is opened, which is why, when you have multiple Word docs open at one time, a UF can disappear off screen or even get closed when the original doc is closed or when another doc is given the focus by clicking on it or from within VBA.

    It would be good to know if there is a way to open a userform that is entirely unrelated to any particular Word document.
    So, IF i'm understanding

    1. John.dot has a UF and is in Word\StartUp

    2. Word is NOT running yet

    3. You start Word via command and File, Open C.doc -- OR -- just by double clicking C.doc

    The UF will not display until something causes it to, either running a macro in John.dot or possibly an application event

    What triggers the macro to get displayed?



    However, I believe that just possibly 2003's Single Document Interface might have some thing to do with it.

    Maybe C.doc is running Word in it's own window and showing the UF, B.doc is running in it's own window. That could explain

    It seems to me that UFs always begin life associated with the document that is active at the time the UF is opened, which is why, when you have multiple Word docs open at one time, a UF can disappear off screen or even get closed when the original doc is closed or when another doc is given the focus by clicking on it or from within VBA.


    The article has some things you can try


    https://support.microsoft.com/en-us/...3-7f60b30ff49d


    By default, versions of Word that are later than Microsoft Word 97 use the Single Document Interface (SDI) design, in which each document occupies its own window (just as in Microsoft Outlook each message occupies its own window). This behavior is different from Word 97 and earlier versions of Word, which use the Multiple Document Interface (MDI), in which each document is a separate window within the Word program window. SDI was introduced in Word 2000.
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  17. #17
    I think that the problem is simply that the UF has to be associated with a document. Part of the way VBA works with Word. I have worked around this by closing the user userform when closing a doc, and then opening the next doc and reopening the userform. Everything is working fine now. The problem is generic, not with just this particular macro. My 8 steps to demonstate post above simply identifies the way Word works. I think you can demonstrate this for yourself by opening two or more documents, and then opening any macro with a userform. Select any document other than the one that was open when you opened the userform, then click the userform. The doc that had the focus when you opened the userform will now have focus. I don't think it is an issue associated with Word 2003 alone.

    To answer your question, I generally open Word by clicking on its icon in the Win. 7 taskbar. And the UF is invoked by clicking on an icon in a toolbar. John.dot and a bunch of other templates are loaded when Word is opened. This particular userform is just one of multiple macros that can be run either from menu items or from toolbar icons.

  18. #18
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,380
    Location
    Quote Originally Posted by johndavidson View Post
    I think that the problem is simply that the UF has to be associated with a document. Part of the way VBA works with Word. I have worked around this by closing the user userform when closing a doc, and then opening the next doc and reopening the userform. Everything is working fine now. The problem is generic, not with just this particular macro..
    That might happen if the macro code (which you've never posted) uses ActiveDocument.
    ---------------------------------------------------------------------------------------------------------------------

    Paul


    Remember: Tell us WHAT you want to do, not HOW you think you want to do it

    1. Use [CODE] ....[/CODE ] Tags for readability
    [CODE]PasteYourCodeHere[/CODE ] -- (or paste your code, select it, click [#] button)
    2. Upload an example
    Go Advanced / Attachments - Manage Attachments / Add Files / Select Files / Select the file(s) / Upload Files / Done
    3. Mark the thread as [Solved] when you have an answer
    Thread Tools (on the top right corner, above the first message)
    4. Read the Forum FAQ, especially the part about cross-posting in other forums
    http://www.vbaexpress.com/forum/faq...._new_faq_item3

  19. #19
    Yes, it does use Active Document. And I did post the relevant part of the code. See above, post 4.

    Is there another way of doing things so that the user can edit the document?

  20. #20
    Here we go. The code is in the attached FindInTreasury_code.doc. See notes at the top of the doc. Couldn't get the upload *.frm to work so it's all in a Word doc for copy/pasting.

    FindInTreasury_code.doc

    I am happy with this code as it is, so the code is only for your interest and in case you can come up with a better way of doing it (highly likely, but what I've got here has the virtue of working). One can search docs using the range facility, but the results of a search will still have to be presented to the user in an active document that can be further edited.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •