Click to See Complete Forum and Search --> : Word's Symbol font and VBA


Yves M
March 4th, 2005, 03:36 PM
This problem has plagued me for quite some time now. When you are treating a sentence in Word which has a symbol in the Symbol font using VBA, you can't get the symbol, but instead you always get a closing bracket ")". Why? And more importantly is there a way around it?

To compound the problem, Word doesn't even tell you that the symbol is in a different font. This makes the distinction between a real ")" and a symbol in the symbol font plainly impossible. Has anyone ever encountered this and found a way to detect it or even get the real text?


Attached is a small VBA macro that exhibits this problem.

Thanks,

Yves

Sahir
March 9th, 2005, 05:31 PM
When you add a Symbol in the same font as that of the current style it looks like this in the script editor.


<body lang=EN-US style='tab-interval:36.0pt'>
<div class=Section1>
<p class=MsoNormal>a symbol≤</p>
</div>
</body>
</body>



Or if you insert the symbol in a different font


<body lang=EN-US style='tab-interval:36.0pt'>
<div class=Section1>
<p class=MsoNormal>Symbol
<span style='font-family:Arial'>≤</span></p>
</div>
</body>



When you add a Symbol symbol, Word seems to go mad.


<body lang=EN-US style='tab-interval:36.0pt'>
<div class=Section1>
<p class=MsoNormal>a symbol
<span style='font-family:Symbol;
mso-ascii-font-family:"Times New Roman";
mso-hansi-font-family:"Times New Roman";
mso-char-type:symbol;
mso-symbol-font-family:Symbol'>
<span style='mso-char-type:symbol;
mso-symbol-font-family:Symbol'>£
</span>
</span>
</p>
</div>
</body>


Perhaps the character and it's font are not accessible due to the nesting of the tags.

Sahir
March 10th, 2005, 05:04 PM
This thing had been niggling at the back of my mind since yesterday. Finally, I thought of something. Why not use the clipboard ?



Public Sub Test()
Dim r As Range
Dim i As Integer, strMsg As String
Dim dObj As New DataObject, ch As String
Dim fontName As String
Set r = ThisDocument.StoryRanges(wdMainTextStory)
ListBox1.Clear
For i = r.Start + 1 To r.End - 1
If r.Characters(i).Text = "(" Then
r.Characters(i).Select
Selection.Copy
dObj.GetFromClipboard
ch = dObj.GetText
If AscW(ch) = 40 Then
strMsg = "Char: " & ch & " | Val: " & AscW(ch) _
& " | Font : " & r.Characters(i).Font.Name
Else
strMsg = "Char: " & ch & " | Val: " & Asc(ch) _
& " | Font : Symbol, Marlett, Wingdings etc. "
End If
Else
strMsg = "Char: " & r.Characters(i).Text & " | Val: " _
& AscW(r.Characters(i).Text) & " | Font : " _
& r.Characters(i).Font.Name
Selection.Collapse Direction:=wdCollapseEnd
End If
ListBox1.AddItem strMsg
Next
End Sub



This is not a perfect solution though, if some other process writes to the clipboard between calls to Selection.Copy and dObj.GetText then it could fail. This is purely an academic exercise. The best solution is to select (normal text) when you insert a symbol. :)

Yves M
March 11th, 2005, 12:21 AM
Interesting, thanks. I'll have a look and check how I can integrate that.

I just hope it won't be too slow to do this on large documents (I'm handinling docs which can have more than 10k words e.g.)

Sahir
March 11th, 2005, 06:42 AM
Your code was


Public Sub main()
Dim r As Range
Dim i As Integer
Set r = ThisDocument.StoryRanges(wdMainTextStory)
Debug.Print "The complete text is: " & r.Text
For i = r.Start + 1 To r.End
Debug.Print "Character: " & r.Characters(i).Text & " Font: "; r.Characters(i).Font.Name
Next
End Sub


I modified this slightly so that we could measure the time.


Public Sub Test()
Dim r As Range
Dim i As Long, ch As String
Set r = ThisDocument.StoryRanges(wdMainTextStory)

Selection.TypeText Chr(13)
Selection.TypeText Format(Now, "hh:nn:ss")
Selection.TypeText Chr(13)

For i = r.Start + 1 To r.End
ch = r.Characters(i).Text
If i > 5000 Then
Exit For
End If
Next

r.Characters(i).Select
Selection.TypeText Chr(13)
Selection.TypeText Format(Now, "hh:nn:ss")
Selection.TypeText Chr(13)
End Sub


On a Pentium 4 (2.99Ghz) machine it showed the following start/end times.

Time :
start - 13:55:58
finish - 13:58:23

It seems iterating through a range object is inherently slow.

Now the same routine with the addition of the my copy to clipboard solution.


Public Sub Test()
Dim r As Range, i As Long
Dim dObj As New DataObject, ch As String
Set r = ThisDocument.StoryRanges(wdMainTextStory)

r.Characters(1).Select
Selection.TypeText Chr(13)
Selection.TypeText Format(Now, "hh:nn:ss")
Selection.TypeText Chr(13)

For i = r.Start + 1 To r.End
r.Characters(i).Select
Selection.Copy
dObj.GetFromClipboard
ch = dObj.GetText
dObj.Clear
If i > 5000 Then
Exit For
End If
Next
r.Characters(i).Select
Selection.TypeText Chr(13)
Selection.TypeText Format(Now, "hh:nn:ss")
Selection.TypeText Chr(13)
End Sub



Time :
start - 14:20:43
finish - 14:23:15

An increase of 4.82% when you copy every character to the clipboard.
If you are only slecting and copying Symbol symbol characters to clipboard and if there aren't too many of them, the increase is negligible.

Yves M
March 11th, 2005, 07:45 AM
Yes, it's more the iterating character by character that makes me a bit nervous, but well, it's not necessarily that bad.

Thanks a lot for the help :)