Consulting

Results 1 to 6 of 6

Thread: Strange behaviour of some accented characters when cycling through wdNextCase

  1. #1

    Strange behaviour of some accented characters when cycling through wdNextCase

    Here's a strange behaviour of Word both in VBA and using a Word command. To check it out, download the attached (tiny) file and work on that. I doubt if the behaviour can be reproduced by copy-pasting the text of the file reproduced below....

    Place the text cursor on each instance of the word ‘dǎoyǐn’ and cycle through Word’s “Change Case” command.

    The first instance performs correctly. The second one has the two accented characters changed to the SimSun font. When changed back by selecting the text and resetting the font to Times New Roman, the above error re-occurs.

    dǎoyǐn

    dǎoyǐn


    The same thing happens if the case change is done in VBA, with the notable difference that ‘Selection.Font.Name = sFont’ does not correct the font. Only manual selection of the text and manual changing of the font works.

    Sub Test()
        Dim sFont As String  
        sFont = Selection.Font.Name
        Selection.Range.Case = wdNextCase
        Selection.Font.Name = sFont   
    End Sub
    What is different about the second ‘dǎoyǐn’ that is creating this behaviour? I thought that maybe is was the application of a character style, but no such styles are apparent.
    Attached Files Attached Files
    Last edited by johndavidson; 08-08-2017 at 11:48 PM.

  2. #2
    VBAX Tutor
    Joined
    Jul 2016
    Posts
    266
    Location
    John I deleted the second ‘dǎoyǐn’ and then copy pasted the first ‘dǎoyǐn’ into its place and the problem has disappeared. I have no explanation of why this solved the problem.
    Last edited by Kilroy; 08-15-2017 at 09:23 AM.

  3. #3
    Yes. It is because the first 'dǎoyǐn' does not exhibit the problem. You can copy it where you like and it will behave correctly.

    Also, if you select the second 'dǎoyǐn' and click 'Clear Formatting' or copy/paste without formatting - either as a Word command or using VBA, the problem remains. So it is not an immediately obvious formatting issue. Even if you change the font to 'Times New Roman', it reverts to SimSun when you cycle through Change Case.

    It's something to do with the functioning of the SimSun font - but what?? Probably to do with where Word is keeping the information that is differentiating between the occurrence of ǎ and ǐ in the two 'dǎoyǐn's. ǎ is character code: 01CE in the Latin-Extended-B region of the unicode symbols, whatever the font.

  4. #4
    Ah!! ... I tried copying the offending line and then copy-pasted in 'unformatted Unicode text' and the problem goes away. So maybe I can work that into VBA. Will have a look later.

  5. #5
    OK. Prompted by Kilroy (thanks for the prompt), I messed about with various options and came up with this. May be of use to someone, sometime ...

    Sub CaseChange()
        ' Gets around a problem with SimSun font sometimes for an unknown reason replacing (some/all?) Latin Extended-B characters with SimSun font. 
        ' Something to do with the use of Pinyin and Chinese characters, at least in my instance
        ' Note that font attributes are lost unless the entire word or selected text is not all of the same attribute(s). Highlighting is always lost.
        ' To avoid this, use the standard Word Change Case button (which may then result in the Pinyin/SimSun problem!)
    
    
        Dim sStart As Long, sEnd As Long, sStart1 As Long, sEnd1 As Long
        
        sStart = Selection.Start
        sEnd = Selection.End
        
        If Selection.Start = Selection.End Then
            Selection.Words(1).Select
            Do While Selection.Characters.Last = " "
                Selection.End = Selection.End - 1
            Loop
        End If
        
        sStart1 = Selection.Start
        sEnd1 = Selection.End
        Selection.Range.Case = wdNextCase
        Selection.Start = sStart1
        Selection.Copy
        Call PasteFormat
        Selection.Start = sStart
        Selection.End = sEnd
    
    
    End Sub
    
    Sub PasteFormat()
    '   Paste text and in the format of text into which it has been pasted.
    '   Note that if a style itself has a font attribute such as italics that is overridden in the actual text,
    '   it will revert to the original attribute when pasted as plain text.
    '   This does not happen when the text is pasted manually, only when the pasting is done programmatically
    
    
        Dim sEnd As Long
        
        If ClipboardIsEmpty = True Then Exit Sub
        
        On Error GoTo DoRegularPastePlainText   ' For when PasteSpecial fails
        sEnd = Selection.End
        Selection.PasteSpecial Link:=False, DataType:=20, Placement:=wdInLine, DisplayAsIcon:=False
        Exit Sub
        
    DoRegularPastePlainText:
        ' Sometimes, the above returns an error due to clipboard content that PasteSpecial cannot handle (such as copying text from the VBA editor),
        ' so revert to the simple way of doing it
        If Selection.End = sEnd Then Selection.PasteAndFormat (wdFormatPlainText)
    End Sub
    If anyone knows why Word exhibits this behaviour, I'd be interested to know. Maybe associated with the fact that much of the Word code predates the introduction of Unicode.
    Last edited by johndavidson; 08-16-2017 at 03:30 AM.

  6. #6
    The function ClipboardIsEmpty is also needed; and I added a check for an image on the clipboard, which otherwise causes a runtime error. I suspect the problem is related to a combination of pre-Unicode code in Word and some DataType confusion. Haven't investigated further. The updated code (in case anyone is interested!) looks like:

    Sub CaseChange()
        ' Gets around a problem with SimSun font sometimes for an unknown reason replacing (some/all?) Latin Extended-B characters with SimSun font.
        ' Something to do with the use of Pinyin and Chinese characters, at least in my instance
        ' Note that font attributes are lost unless the entire word or selected text is not all of the same attribute(s). Highlighting is always lost.
        ' To avoid this, use the standard Word Change Case button (which may then result in the Pinyin/SimSun problem!)
    
    
        Dim sStart As Long, sEnd As Long, sStart1 As Long, sEnd1 As Long
        
        sStart = Selection.Start
        sEnd = Selection.End
        
        If Selection.Start = Selection.End Then
            Selection.Words(1).Select
            Do While Selection.Characters.Last = " "
                Selection.End = Selection.End - 1
            Loop
        End If
        
        sStart1 = Selection.Start
        sEnd1 = Selection.End
        Selection.Range.Case = wdNextCase
        Selection.Start = sStart1
        Selection.Copy
        Call PasteFormat
        Selection.Start = sStart
        Selection.End = sEnd
    
    
    End Sub
    
    
    Sub PasteFormat()
    '   Paste text and in the format of text into which it has been pasted.
    '   Note that if a style itself has a font attribute such as italics that is overridden in the actual text,
    '   it will revert to the original attribute when pasted as plain text.
    '   This does not happen when the text is pasted manually, only when the pasting is done programmatically
    
    
        Dim sEnd As Long
        
        Select Case ClipboardIsEmpty
            Case Is = 0
                Exit Sub
        
            Case Is = 999
                MsgBox "To paste unformatted, the clipboard content must be text, not an image.", , "Paste Unformatted"
                Exit Sub
        End Select
        
        On Error GoTo DoRegularPastePlainText   ' For when PasteSpecial fails
        sEnd = Selection.End
        Selection.PasteSpecial Link:=False, DataType:=20, Placement:=wdInLine, DisplayAsIcon:=False
        Exit Sub
        
    DoRegularPastePlainText:
        ' Sometimes, the above returns an error due to clipboard content that PasteSpecial cannot handle (such as copying text from the VBA editor),
        ' so revert to the simple way of doing it
        If Selection.End = sEnd Then Selection.PasteAndFormat (wdFormatPlainText)
    End Sub
    
    Function ClipboardIsEmpty() As Integer
        Dim MyDataObject As DataObject
        
        Set MyDataObject = New DataObject
        On Error GoTo NotTextContent
        MyDataObject.GetFromClipboard
        ' ClipboardIsEmpty = (Len(MyDataObject.GetText(1)) = 0) ' Use if ClipboardIsEmpty is Boolean
        ClipboardIsEmpty = (Len(MyDataObject.GetText(1)))
        Exit Function
        
    NotTextContent:
        ClipboardIsEmpty = 999
    End Function
    Last edited by johndavidson; 08-17-2017 at 01:51 AM.

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
  •