none
problem with ActiveDocument.Bookmarks.Exists RRS feed

  • Question

  • Hi,

       I don't understand why sometime a piece of code of mine with

    ActiveDocument.Bookmarks.Exists

    is perfectly fine, but sometime it trows a 6197 run time error.

    In the latter case in the watch window I can see only the properties of

    ActiveDocument.Bookmarks

    and not its methods.

    Why, Lauro

    Sunday, February 19, 2012 5:08 AM

All replies

  • Hi Lauro,

    How are you using 'ActiveDocument.Bookmarks.Exists' when the error occurs?


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Sunday, February 19, 2012 7:44 AM
  • Hi Lauro

    What's the text for error 6197?

    As Paul says, please show us the code that illustrates how you're using it.

    Which version of Word are you using?


    Cindy Meister, VSTO/Word MVP


    Sunday, February 19, 2012 8:28 AM
    Moderator
  • Thank you to both of you, Cindy and Paul.

    I'm using Word 2010.

    The text of the run time error 6197 is "Comando del modello a oggetti non disponibile nell'evento corrente", which can be loosely translated as "Model's objects command not available in the present event".

    More difficult is to explain the circumstances in which the error arise.

    It happens when both of the following apply:
    - I'm clicking on the undo button to reverse an UndoRecord actions
    - The application respond to the WindowSelectionChange event.

    More specifically. As I said in another post, I need my Ribbon to be updated according to the position of the cursor.
    So I did:
    - I chose to transform my application in a application with a WindowSelectionChange implemented.
    - Since the Ribbon doesn't need to be updated by my code; I set a global variable at the beginning and at the end of my routines to tell WindowSelectionChange event to do nothing and Exit Sub.
    - Since I want the user to be able to reverse an action I'm using an UndoRecord to group my code actions.

    When I don't have in use the WindowSelectionChange the undo works fine. But When it is on, the same commands which were working fine before (for instance ActiveDocument.Bookmarks.Exists) don't work.

    Moreover, how can I detect when an undoing is taking place to tell the WindowSelectionChange?

    Thanks, Lauro
    Sunday, February 19, 2012 10:49 AM
  • Hi Cindy, hi Paul

    I have tried to cut my application to the bones, to illustrate  where and how my problem arise. I'm sorry because I think it is still a lot of code.

    Ok, I have two classes: a) clsMyObject and b) clsEventApp; and two normal modules: c) modToolsAndGlobal and d) modMain

    MyObject is basically a Table blocked by a Group Content Control (in the rows there are RTF CC), so every adding, erasing, etc. of rows as to be done by code first removing the GCC and then put it back.

    Option Explicit
    
    Private pBkmrkMyObject As Bookmark
    #If VBA7 Then
    Private pURecord As UndoRecord
    #End If
    
    '--------------------------------------------------
    ' Property  : BkmrkMyObject
    ' Purpose   : To mark MyTable by an hidden bookmark
    '-------------------------------------------------
    Public Property Get BkmrkMyObject() As Bookmark
       Set BkmrkMyObject = pBkmrkMyObject
    End Property
    Public Property Set BkmrkMyObject(aBookmark As Bookmark)
       Set pBkmrkMyObject = aBookmark
    End Property
    
    '-----------------------------------------------------
    ' Property  : TblMyObject
    ' Purpose   : return MyTable or Nothing if doc is not well formed
    '----------------------------------------------------
    Public Property Get TblMyObject() As Table
       On Error Resume Next
       Set TblMyObject = BkmrkMyObject.Range.Tables(1)
    End Property
    
    '--------------------------------------------------
    ' Property  : CntCtrlMyObject
    ' Return    : The Group Content Control used to block MyTable or Nothing if doc is not well formed
    '-----------------------------------------------------
    Public Property Get CntCtrlMyObject() As ContentControl
       On Error Resume Next
       Set CntCtrlMyObject = GetContentControlByTag(TAGMYOBJECT)
    End Property
    
    Private Sub Class_Initialize()
       Set BkmrkMyObject = GetBookmark(TAGMYOBJECT)
    End Sub
    
    
    Private Function SelectionOutTable() As Boolean
       SelectionOutTable = Not Selection.InRange(Me.TblMyObject.Range)
    End Function
    
    
    '--------------------------------------------------
    ' Procedure : GetNumberSelectedRow
    ' Return    : O if out of MyTable or more then one row is selected
    '--------------------------------------------------
    Public Function GetNumberSelectedRow() As Long
       Dim lgStart As Long
       Dim lgEnd As Long
    
       GetNumberSelectedRow = 0
       If SelectionOutTable() Then Exit Function
       lgStart= Selection.Information(wdStartOfRangeRowNumber)
       lgEnd = Selection.Information(wdEndOfRangeRowNumber)
       If lgStart <> lgEnd Then Exit Function
       GetNumberSelectedRow = lgStart
    End Function
    
    
    Public Function DoSomethingInRow(riga As Long) As Boolean
       Dim rng As Range
       Dim objCC As ContentControl
    
       DoSomethingInRow = True
       On Error GoTo DoSomethingInRow_Error
       
       'start preparation
       #If VBA7 Then
          Set pURecord = Application.UndoRecord
          pURecord.StartCustomRecord "DoSomething"
       #End If
       ActiveDocument.Bookmarks.Add "_InMacro_" ' used to go back if something is wrong in word 2007
       With Me.CntCtrlMyObject
          .LockContentControl = False
          .Delete
       End With
       'end preparation
       
       Me.TblMyObject.Rows(riga).Cells(2).Range.Delete
       Me.TblMyObject.Rows(riga).Cells(2).Range.Text = "Text changed"
    
       'start finishing
       Set rng = Me.TblMyObject.Range
       rng.MoveStart wdParagraph, -1
       rng.MoveEnd wdParagraph, 1
       rng.Select
       Set objCC = ActiveDocument.ContentControls.Add(wdContentControlGroup)
       With objCC
          .Tag = TAGMYOBJECT
          .LockContentControl = True
       End With
       ActiveDocument.Bookmarks("_InMacro_").Delete
       #If VBA7 Then
          pURecord.EndCustomRecord
       #Else
          ActiveDocument.UndoClear
       #End If
       'end finishing
       
    DoSomethingInRow_Exit:
       Exit Function
    DoSomethingInRow_Error:
       DoSomethingInRow = True
       MsgBox "Errore " & Err.Number & " (" & Err.Description & ")"
       Resume DoSomethingInRow_Exit
    End Function
    

    clsEventApp is used to take trace of the cursor so I can update the ribbon:

    Option Explicit
    Public WithEvents App As Word.Application
    
    Private Sub App_WindowSelectionChange(ByVal SEL As Selection)
    Dim l As Long
    Dim objTempMyObject As clsMyObject
    
       On Error GoTo error_App_WindowSelectionChange
          
          ' if I don't want refresh the ribbon then exit
          If NoRefresh Then Exit Sub
          
          Set objTempMyObject = New clsMyObject
          l = objTempMyObject.GetNumberSelectedRow
          
          'if selection didn't change row then exit
          If l = RowNumber Then Exit Sub
          
          RowNumber = l
          If l > 0 Then
             MsgBox "Selected row: " & l
          Else
             MsgBox "No row selected"
          End If
       
    exit_App_WindowSelectionChange:
       Exit Sub
    error_App_WindowSelectionChange:
       MsgBox "Error n.: " & Err.Number & " (" & Err.Description & ") "
       Resume exit_App_WindowSelectionChange
    End Sub
    

    modToolsAndGlobal holds the global variables and some istrumental routines:

    Option Explicit
    
    Public NoRefresh As Boolean
    Public gobjMyObject As clsMyObject
    Public RowNumber As Long
    Public Const TAGMYOBJECT As String = "MyObject"
    Public MyApp As clsEventApp
    
    Public Function GetContentControlByTag(strTag As String) As ContentControl
        Dim objCC As ContentControl
        
        Set GetContentControlByTag = Nothing
        For Each objCC In ActiveDocument.ContentControls
            If objCC.Tag = strTag Then
                Set GetContentControlByTag = objCC
                Exit Function
            End If
        Next objCC
    End Function
    
    
    Public Function GetBookmark(aBookmarkName As String) As Bookmark
       If ActiveDocument.Bookmarks.Exists(aBookmarkName) Then
          Set GetBookmark = ActiveDocument.Bookmarks(aBookmarkName)
       End If
    End Function
    
    
    Public Sub PrepareMyObjectInDoc()
       Dim objTemplate As Template
       Dim rng As Range, rng1 As Range, rng2 As Range
       Dim objCC As ContentControl
       Dim i As Long
       
       Selection.TypeParagraph
       Selection.TypeParagraph
       Selection.TypeParagraph
       Selection.TypeParagraph
       Selection.Move wdParagraph, -2
       
       ActiveDocument.Tables.Add Selection.Range, NumRows:=4, NumColumns:=2
       ActiveDocument.Tables(1).Borders.Enable = True
       
       For i = 1 To 4
          ActiveDocument.Tables(1).Cell(i, 2).Range.Text = "original text in row n. " & i
       Next i
       
       'Aggiusta range e stili per i paragrafi precedente e successivo alla tabella
       Set rng1 = ActiveDocument.Tables(1).Range
       rng1.Collapse Direction:=wdCollapseStart
       rng1.Move wdParagraph, -1
       rng1.InsertAfter " "
       Set rng2 = ActiveDocument.Tables(1).Range
       rng2.Move wdParagraph, 1
       rng2.InsertAfter " "
    
       'inserisce il Bookmark "MyObject"
       Set rng = ActiveDocument.Tables(1).Range
       rng.SetRange rng1.Start + 1, rng2.End
       ActiveDocument.Bookmarks.Add TAGMYOBJECT, rng
    
       'Blocca tutta la tabella MyObject
       rng.MoveStart wdCharacter, -1
       rng.MoveEnd wdCharacter, 1
       rng.Select
       Set objCC = ActiveDocument.ContentControls.Add(wdContentControlGroup)
       With objCC
          .Tag = TAGMYOBJECT
          .LockContentControl = True
       End With
    
    End Sub
    

    modMain has two sub: one to set the appliction to respond to the ChangedSelection event and the other to try to do something with MyObject:

    Option Explicit
    
    Public Sub Try()
       Set gobjMyObject = New clsMyObject
       gobjMyObject.DoSomethingInRow 2
    
    End Sub
    
    Public Sub SetEventApplication()
       Set MyApp = New clsEventApp
       Set MyApp.App = Word.Application
    End Sub
    

    And that is it! I know it was very long. I will appreciate very much if you could try it.

    You should:

    1. run the Sub PrepareMyObjectInDoc to have the blocked table on wich to work.
    2. run the Sub SetEventApplication to follow the movement of the selection
    3. run the Sub Try

    The problem arise in word 2010 when I undo this last operation.

    Notice that there is no problem if don't do step 2.

    Thank you very, very much Lauro

    Sunday, February 26, 2012 5:31 PM
  • Hi Lauro,

    It seems to be a timing issue. The code you posted runs fine with some minor changes to the WindowSelectionChange event:

    Private Sub App_WindowSelectionChange(ByVal SEL As Selection)
    Dim l As Long
    Dim objTempMyObject As clsMyObject

          ' if I don't want refresh the ribbon then exit
          If NoRefresh Then Exit Sub
         
          ' wait until the object model command becomes available
          While Error = 6197
              Set objTempMyObject = New clsMyObject
              l = objTempMyObject.GetNumberSelectedRow
          Wend
         
          'if selection didn't change row then exit
          If l = RowNumber Then Exit Sub
         
          RowNumber = l
          If l > 0 Then
             MsgBox "Selected row: " & l
          Else
             MsgBox "No row selected"
          End If
    End Sub


    Cheers
    Paul Edstein
    [MS MVP - Word]


    • Edited by macropodMVP Monday, February 27, 2012 11:54 AM
    Monday, February 27, 2012 11:53 AM
  • Hi Paul,

          thank you very much for the time you spent on my code.

          I never heard of such "timing issue"...

         Anyway, I don't understand your code:

          ' wait until the object model command becomes available
          While Error = 6197
              Set objTempMyObject = New clsMyObject
              l = objTempMyObject.GetNumberSelectedRow
          Wend

    More then waiting, it seems to me that the two lines of code, that I used to get the number of the row selected, are never entered and therefore I don't get any message also if the selection was moved between the table's rows.

    Or am I wrong?

    Thanks again, Lauro

    Tuesday, February 28, 2012 7:25 PM
  • Hi Lauro,

    my bad - it's not a timing issue and, even if it were, my 'solution' wouldn't have worked as the loop would never get entered. I'll take another look at it later.


    Cheers
    Paul Edstein
    [MS MVP - Word]

    Wednesday, February 29, 2012 8:39 PM