locked
Problem mixing WindowSelectionChange & Undo in Word 2010 RRS feed

  • Question

  • I don't understand what happens when Word is undoing a group (UndoRecord) of actions. It seems that the whole normal model's objects commands are no more available and the 6197 error arise.

    I try to be more specific.

    I'm developing a Project Template for Word 2007 and 2010.
    Basically I have a Table blocked by a Group Content Control. So all the editing in the table must be accomplishing by first removing the Group Content Control  and then, at the end, putting it back.

    Since I want to update the Ribbon accordingly the row selected, I used the WindowSelectionChange event.

    No problems undoing without the WindowSelectionChange. No problems WindowSelectionChange without undoing.

    BUT if the two are in place together, a 6197 error ("Model's objects command not available in the present event") arise when I undo a group of actions.

    Why? it seems that while undoing the model's objects commands aro no more there?

    I would appreciate very much some insight.

    I same good heart fellow would try it; I attach a cutted to the bones version of my project.

    I have 4 modules. 2 classes and 2 normal modules.

    1. clsMyObject 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.
    2. clsEventApp is used to take trace of the cursor so I can update the ribbon
    3. modToolsAndGlobal holds the global variables and some istrumental routines
    4. 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

    Here is the code.

    clsMyObject

    Option Explicit Private pBkmrkMyObject As Bookmark Private pURecord As UndoRecord

    '---------------------------------------------------------------------------------------
    ' Property  : BkmrkMyObject
    ' Purpose   : To mark MyTable
    '--------------------------------------------------------------------------------------- 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 : to return MyTable inside MyObject or Nothing if the document is not well formed '--------------------------------------------------------------------------------------- Public Property Get TblMyObject() As Table On Error Resume Next Set TblMyObject = BkmrkMyObject.Range.Tables(1) End Property '--------------------------------------------------------------------------------------- ' Property : CntCtrlMyObject ' Ritorna : To return the Group Content Control used to block MyTable inside MyObject) or Nothing '--------------------------------------------------------------------------------------- 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 the one row 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 Set pURecord = Application.UndoRecord pURecord.StartCustomRecord "DoSomething" 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 pURecord.EndCustomRecord 'end finishing DoSomethingInRow_Exit: Exit Function DoSomethingInRow_Error: DoSomethingInRow = True MsgBox "Errore " & Err.Number & " (" & Err.Description & ")" Resume DoSomethingInRow_Exit End Function

    clsEventApp

    Option Explicit Public WithEvents App As Word.Application 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 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 End Sub


    modToolsAndGlobal

    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

    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
    

    To replicate the problems

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

    I know that I'm asking too much; but any help would be very apreciated.

    Lauro

    Thursday, March 8, 2012 10:15 PM