none
String Compare Stumber RRS feed

  • Question

  • I'm stumped with a string compare problem.  The following code should illustrate.  I am trying to detect a change in a RichText type content control.  I want to detect any changes e.g., format etc. and not just a text change.  I've attempted to set a string variable equal to the WordOpenXML string value of the CC range.  I then attempted to run a loop to compare the string variable to the WordOpenXML string.  When they are no longer equal represents a change.

    For some reason (and the number 3500 may just be on my PC), the strings match up to the 3500th character and then they no longer match.  Can anyone replicate/explain this weird behavior?

    Note:  This is cross posted at VBExpress: 

    http://www.vbaexpress.com/forum/showthread.php?51121-String-Compare-Stumper

    Option Explicit
    Option Compare Text
    Sub Test()
      With ActiveDocument
        .Range.Delete
        .Range.InsertBefore vbCr + vbCr
        .ContentControls.Add wdContentControlText, .Paragraphs(1).Range
        .ContentControls.Add wdContentControlRichText, .Paragraphs(2).Range
        .ContentControls(1).Range.Text = "A"
        .ContentControls(2).Range.Text = "A"
        MsgBox CCChange(.ContentControls(1))
        MsgBox CCChange(.ContentControls(2))
        MsgBox CCChange(.ContentControls(2), False)
      End With
    End Sub
    Function CCChange(oCC As ContentControl, Optional bNormal = True) As Boolean
    Dim lngIndex As Long 'For demo/testing only.
    Dim strCC_Text As String
      CCChange = False
      Select Case oCC.Type
        Case 1, 3, 4, 5, 8
          strCC_Text = oCC.Range.Text
          Do While strCC_Text = oCC.Range.Text
            DoEvents
            On Error GoTo Err_Object
            lngIndex = lngIndex + 1 'For demo/testing only to trigger a simulated change.
            If strCC_Text <> oCC.Range.Text Or lngIndex = 3 Then
              CCChange = True
              Exit Function
            End If
          Loop
        Case 0, 2
          strCC_Text = vbNullString
          strCC_Text = CStr(oCC.Range.WordOpenXML)
          If Len(strCC_Text) = Len(oCC.Range.WordOpenXML) Then
            MsgBox Len(strCC_Text) & " " & Len(oCC.Range.WordOpenXML) & " They appear to be the same at least by characters count."
          End If
          Select Case True
            Case bNormal
              Do While strCC_Text = oCC.Range.WordOpenXML
                'So why does't this code execute?
                DoEvents
                If strCC_Text <> oCC.Range.WordOpenXML Then
                  DoEvents
                  CCChange = True
                  Exit Function
                End If
              Loop
            Case Else
              'It seems there is a difference with the 3501 character :-(
              Debug.Print Mid(strCC_Text, 3051, 1) & " " & Mid(oCC.Range.WordOpenXML, 3051, 1)
              'Why would that be since the first string is set to = the second string?
              Do While Mid(strCC_Text, 1, 3050) = Mid(oCC.Range.WordOpenXML, 1, 3050)
                
                DoEvents
                If strCC_Text <> oCC.Range.WordOpenXML Then
                  DoEvents
                  CCChange = True
                  Exit Function
                End If
              Loop
            End Select
      End Select
    lbl_Exit:
      DoEvents
      Exit Function
    Err_Object:
      Resume lbl_Exit
    End Function


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm

    Sunday, November 9, 2014 4:27 PM

All replies

  • Hi Fei,

    The index for a richtext control is 0 not 1.  The code I am using is:

    Case 0, 2
          strCC_Text = vbNullString
          strCC_Text = CStr(oCC.Range.WordOpenXML)
          If Len(strCC_Text) = Len(oCC.Range.WordOpenXML) Then
            MsgBox Len(strCC_Text) & " " & Len(oCC.Range.WordOpenXML) & " They appear to be the same at least by characters count."
          End If
          Select Case True
            Case bNormal
              Do While strCC_Text = oCC.Range.WordOpenXML
                'So why does't this code execute?
                DoEvents
                If strCC_Text <> oCC.Range.WordOpenXML Then
                  DoEvents
                  CCChange = True
                  Exit Function
                End If
              Loop
    


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm

    Monday, November 10, 2014 2:54 PM
  • Greg,

    The problem is because the strCC_Text is set equal to a property of the Range, and the value of that property has changed by the time you next access it. When I did my testing here, the first thing I noticed that had changed was that the XML contained a different Rsid value.

    Rsids are AFAIK used for tracking changes. You can stop them from being inserted (or at least reduce the number inserted) by going to Word Options->Trust Center->Trust Center Settings->Privacy Options and unchecking "Store random number to improve combine accuracy". Or you can set Word.Options.StoreRSIDOnSave to false. It's possible that you have to restart Word after that - I leave you to discover.

    What this suggests is that Word probably regenerates the WordOpenXML each time you ask for it, rather than picking it out of memory, and generates new Rsids as it does so. So if you are able to switch off RSID generation dynamically and switch it back on again as appropriate, that may be enough to achieve the next step. Otherwise, I think you would probably have to parse the XML and remove all the RSid attributes and elements before doing your comparison. Eric White has some code for that - see
    http://blogs.msdn.com/b/ericwhite/archive/2008/11/04/remove-rsid-attributes-and-elements-before-comparing-documents.aspx

    Whether that will be enough to allow you to do a robust comparisonis another matter - if Word generates XML containing other material such as date/time stamps (e.g if the rich text XML contains document property values, or perhaps even if the rich text contains a TIME field, even if it does not appear to have been updated), they too might change "while you're not looking".


    Peter Jamieson


    • Edited by Peter Jamieson Monday, November 10, 2014 11:40 PM fixed link
    Monday, November 10, 2014 3:10 PM
  • Peter,

    I was stumbling down that same path.  I was running the following modified code and discovered the differences in the RSid values you mention:

    Sub M_snb()
      With ActiveDocument
        .Content.Delete
        .Content = String(1, vbCr)
        .ContentControls.Add(0, .Paragraphs(1).Range).Range = "A"
        MsgBox CCChange(.ContentControls(1))
        MsgBox CCChange(.ContentControls(1), False)
      End With
    End Sub
    Function CCChange(oCC As ContentControl, Optional bNormal = True)
      c00 = CStr(oCC.Range.WordOpenXML)
      If Len(c00) = Len(oCC.Range.WordOpenXML) Then MsgBox "Equal size", , Len(c00)
      Select Case bNormal
        Case True
          CCChange = IIf(StrComp(c00, oCC.Range.WordOpenXML) = 0, "", "no ") & "Equal content"
        Case Else
          For j = 3000 To 3100
            If StrComp(Mid(c00, j, 1), Mid(oCC.Range.WordOpenXML, j, 1)) <> 0 Then
              Debug.Print Mid(c00, j, 1) & " - "; Mid(oCC.Range.WordOpenXML, j, 1)
              ActiveDocument.Range.InsertAfter vbCr & Mid(c00, 3000, 100) & vbCr + vbCr & Mid(oCC.Range.WordOpenXML, 3000, 100)
              Exit For
            End If
         Next
      End Select
    End Function
    I'm afraid I may be out of luck in my quest to create a change event for rich text CC formatting changes.  It appears the amount of behind the scene processing will be so great as to make the process sluggish or too slow for practical use :-(.  Thanks!


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm



    • Edited by Greg Maxey Monday, November 10, 2014 3:48 PM
    Monday, November 10, 2014 3:25 PM
  • Hi Greg Maxey,

    Sorry for the confusion. I agree with you and Peter that the un-matching is caused by the RSID.

    Since it will cause performance issue and the there is no change event for rich content control in Word object model,

    I suggest that you submit the feedback from link below:
    Submit Feedback - Microsoft Office

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, November 11, 2014 9:21 AM
    Moderator
  • Fei,

    There is no change event for "ANY" content controls.  In my opinion that is a very unfortunate design oversight going all the way back to Word 2007.  I will not be submitting feedback to MS.  I learned the old saw about the senselessness of you know what'ing into the wind a long time ago.

    Thanks. 


    Greg Maxey Please visit my website at: http://gregmaxey.mvps.org/word_tips.htm

    Tuesday, November 11, 2014 1:04 PM