I give up...

  • Thread starter Jean-Guy Marcil
  • Start date
J

Jean-Guy Marcil

I am either too tired to think straight or I am overlooking something
simple here...

Here is the background:
Word 2003.
A document contains some characters that are formatted with the Symbol font
and that were inserted with the Insert Symbol dialog.
The same document also contains "(" that are meaningful.
A macro is looking for those "(" but since AscW(Selection.Text) returns 40
for the "(" and for the Symbol font characters, we need to tell if the
character is really a "(" or not. We do not care what symbol it is, as long
as we can tell the symbol apart from the "(".

So, I came up with this macro using some of the clever code I found from
Klaus Linke:

'_______________________________________
Sub MainMacro()

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Ne pas traiter ce caractère."
Else
MsgBox "Traiter cette parenthèse."
End If
End If
Next

End Sub
'_______________________________________

'_______________________________________
Function CheckIfSymbol(MyCar As Range) As Boolean

CheckIfSymbol = False

With Selection.Find
.Text = "[" & ChrW(61472) & "-" & ChrW(61695) & "]"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute
If .Found Then
MsgBox "Ce n'est pas un parenthèse ouvrante"
CheckIfSymbol = True
End If
End With

End Function
'_______________________________________

Basically, I check every character that are selected, if I find that one of
them is a "(", I double check to make sure that it really is a "(" and not a
symbol.

Here is the problem:
With
.Wrap = wdFindStop
in the function, the .Found property is always false, even if a symbol is
currently selected.
If I change
.Wrap = wdFindStop
to
.Wrap = wdFindContinue
Then the .Found property is always true because it always finds the symbol
character in the document, even if it is not in the original selected range.

Why is the Find actually working to tell symbols apart from "(" when doing a
document wide search, but not when checking a specific character?

I have done this before, but not with symbol characters. I remember doing
this to tell if a selected character was a section break or a page break. I
used basically the same kind of code and it worked without any problem. This
isn't working and I cannot tell why! Something to do with wild cards?

Arrrggghhh! I need a coffee!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
H

Helmut Weber

Hi Jean-Guy,

I don't understand Klaus' solution.
Have to learn from him.
May I come up with another approach?
Which lacks a method to distinguish between
all kinds of decorative fonts and ordinary fonts.
Limited to Symbol.
....
Sub Test0000()
Dim rChr As Range
Dim oDlg As Dialog
ResetSearch
For Each rChr In ActiveDocument.Characters
If rChr = "(" Then
rChr.Select
Set oDlg = Dialogs(wdDialogInsertSymbol)
If oDlg.Font = "Symbol" Then
' Or other decorative fonts, that's the question
rChr.HighlightColorIndex = wdYellow
End If
End If
Next
ResetSearch
End Sub
' ----
Public Sub ResetSearch()
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
' plus some more if needed
.Execute
End With
End Sub

Greetings from Bavaria, Germany

Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word XP, Win 98
http://word.mvps.org/
 
D

Dave Lett

Hi Jean-Guy,

I think you can use something like the following:

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
CheckCar.Select
With Dialogs(wdDialogInsertSymbol)
If .CharNum = 40 Then
Debug.Print .CharNum
Debug.Print "Not a symbol"
Else
Debug.Print .CharNum
Debug.Print "A Symbol"
End If
End With

End If
Next
MyRange.Select

I got the idea from "Finding and replacing symbols" at
http://word.mvps.org/faqs/macrosvba/FindReplaceSymbols.htm

HTH,
Dave


Jean-Guy Marcil said:
I am either too tired to think straight or I am overlooking something
simple here...

Here is the background:
Word 2003.
A document contains some characters that are formatted with the Symbol font
and that were inserted with the Insert Symbol dialog.
The same document also contains "(" that are meaningful.
A macro is looking for those "(" but since AscW(Selection.Text) returns 40
for the "(" and for the Symbol font characters, we need to tell if the
character is really a "(" or not. We do not care what symbol it is, as long
as we can tell the symbol apart from the "(".

So, I came up with this macro using some of the clever code I found from
Klaus Linke:

'_______________________________________
Sub MainMacro()

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Ne pas traiter ce caractère."
Else
MsgBox "Traiter cette parenthèse."
End If
End If
Next

End Sub
'_______________________________________

'_______________________________________
Function CheckIfSymbol(MyCar As Range) As Boolean

CheckIfSymbol = False

With Selection.Find
.Text = "[" & ChrW(61472) & "-" & ChrW(61695) & "]"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute
If .Found Then
MsgBox "Ce n'est pas un parenthèse ouvrante"
CheckIfSymbol = True
End If
End With

End Function
'_______________________________________

Basically, I check every character that are selected, if I find that one of
them is a "(", I double check to make sure that it really is a "(" and not a
symbol.

Here is the problem:
With
.Wrap = wdFindStop
in the function, the .Found property is always false, even if a symbol is
currently selected.
If I change
.Wrap = wdFindStop
to
.Wrap = wdFindContinue
Then the .Found property is always true because it always finds the symbol
character in the document, even if it is not in the original selected range.

Why is the Find actually working to tell symbols apart from "(" when doing a
document wide search, but not when checking a specific character?

I have done this before, but not with symbol characters. I remember doing
this to tell if a selected character was a section break or a page break. I
used basically the same kind of code and it worked without any problem. This
isn't working and I cannot tell why! Something to do with wild cards?

Arrrggghhh! I need a coffee!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
J

Jean-Guy Marcil

Dave Lett was telling us:
Dave Lett nous racontait que :
Hi Jean-Guy,

I think you can use something like the following:

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
CheckCar.Select
With Dialogs(wdDialogInsertSymbol)
If .CharNum = 40 Then
Debug.Print .CharNum
Debug.Print "Not a symbol"
Else
Debug.Print .CharNum
Debug.Print "A Symbol"
End If
End With

End If
Next
MyRange.Select

I got the idea from "Finding and replacing symbols" at
http://word.mvps.org/faqs/macrosvba/FindReplaceSymbols.htm

Thanks Helmut and Dave,

I appreciate your ideas and will look into them.

But...

I still do not know why my stuff did not work with wdFindStop...

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
H

Helmut Weber

Hi Jean-Guy,

I think,
if one character is in the selection,
and you do a wildcard search for a 2 byte
character, then the search fails.

Somehow the second byte seems kind of hidden
before the selected character. What may support
this kind of hypothesis is the fact, that the kind
of search you've posted it, fails,
if you extend the selection to the right.
However, if you extend it to the left,
then the search is successfull.

And what's more, using selection seems to be
essential, too.

Hoping, I've relieved you of a headache.

'---------------------
Sub MainMacro()

Dim MyRange As Range
Dim CheckCar As Range
' Only one character selected, which is from font "symbol"
' and was inserted by the apprtopriate dialog !!!
' Selection.WholeStory for testing
Set MyRange = Selection.Range
For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Symbol"
Else
MsgBox "No Smybol" ' !!!
End If
End If
Next
Stop
' MyRange.End = MyRange.End + 1 ' no use
MyRange.Start = MyRange.Start - 1 ' yes
' but not at the start of doc
' extending the range alone doesn't work
MyRange.Select
' has to be selected
For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Symbol"
Else
MsgBox "No Smybol"
End If
End If
Next

End Sub
'_______________________________________

'_______________________________________
Function CheckIfSymbol(MyCar As Range) As Boolean

CheckIfSymbol = False

With MyCar.Find
.Text = "[" & ChrW(61472) & "-" & ChrW(61695) & "]"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute
If .Found Then
' MsgBox "Ce n'est pas un parenthèse ouvrante"
CheckIfSymbol = True
End If
End With

End Function
' ------------------------------


Greetings from Bavaria, Germany
Helmut Weber, MVP
"red.sys" & chr(64) & "t-online.de"
Word 2002, Windows 2000
 
J

Jean-Guy Marcil

Helmut Weber was telling us:
Helmut Weber nous racontait que :
Hi Jean-Guy,

I think,
if one character is in the selection,
and you do a wildcard search for a 2 byte
character, then the search fails.

Somehow the second byte seems kind of hidden
before the selected character. What may support
this kind of hypothesis is the fact, that the kind
of search you've posted it, fails,
if you extend the selection to the right.
However, if you extend it to the left,
then the search is successfull.

That was excatly it! Brilliant!
And what's more, using selection seems to be
essential, too.

Not on my machine, it worked with a range or a selection object. See the
code I used below. But as you wrote, it will not work if the first character
in the document is a symbol. Your code will though... So I would use your
code If I was certain that I only had to deal with the Symbol font, but I
would use mine otherwise (and find a way to handle the first character case,
like adding a temporary Arial character....)
Hoping, I've relieved you of a headache.

Thanks!

'_______________________________________
Sub Test1()

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Ne pas traiter ce caractère."
Else
MsgBox "Traiter cette parenthèse."
End If
End If
Next

End Sub
'_______________________________________

'_______________________________________
Function CheckIfSymbol(MyCar As Range) As Boolean

CheckIfSymbol = False

ClearFindAndReplaceParameters

MyCar.MoveStart wdCharacter, -1

With MyCar.Find
.Text = "[" & ChrW(61472) & "-" & ChrW(61695) & "]"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute
If .Found Then
MsgBox "Ce n'est pas un parenthèse ouvrante"
.Parent.Select
CheckIfSymbol = True
End If
End With

ClearFindAndReplaceParameters

End Function
'_______________________________________

'_______________________________________

Sub ClearFindAndReplaceParameters()

With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With

End Sub
'_______________________________________

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
K

Klaus Linke

Hi Jean-Guy,

Since I don't speak (much) French, I doubt it's my code ;-)

You don't need Find since you already know which character to check...

Helmut and Dave have given alternative solutions.
You could also look if its code is between &HF020 and &HF0FF (61472 and 61695):

Function CheckIfSymbol(MyCar As Range) As Boolean
Dim lChar As Long
lChar = AscW(MyCar.Text)
Select Case lChar
Case 61472 To 61695
CheckIfSymbol = False
Case Else
CheckIfSymbol = True
End Select
End Function

The reason the search fails is that Word will jump to the next found symbol if you already have a symbol selected (... Try selecting an "a" and then search for "a" in the user interface: It'll go to the next "a" immediately).

The idea behind using a wildcard search was to avoid the slow "For each character" in your MainMacro <g>.

And it will not find all symbols, but those inserted from "Insert > Symbol". The others could be easily found searching for the "Symbol" font (which doesn't work for the former ones).

Regards,
Klaus



Jean-Guy Marcil said:
I am either too tired to think straight or I am overlooking something
simple here...

Here is the background:
Word 2003.
A document contains some characters that are formatted with the Symbol font
and that were inserted with the Insert Symbol dialog.
The same document also contains "(" that are meaningful.
A macro is looking for those "(" but since AscW(Selection.Text) returns 40
for the "(" and for the Symbol font characters, we need to tell if the
character is really a "(" or not. We do not care what symbol it is, as long
as we can tell the symbol apart from the "(".

So, I came up with this macro using some of the clever code I found from
Klaus Linke:

'_______________________________________
Sub MainMacro()

Dim MyRange As Range
Dim CheckCar As Range

Set MyRange = Selection.Range

For Each CheckCar In MyRange.Characters
If AscW(CheckCar) = 40 Then
If CheckIfSymbol(CheckCar) Then
MsgBox "Ne pas traiter ce caractère."
Else
MsgBox "Traiter cette parenthèse."
End If
End If
Next

End Sub
'_______________________________________

'_______________________________________
Function CheckIfSymbol(MyCar As Range) As Boolean

CheckIfSymbol = False

With Selection.Find
.Text = "[" & ChrW(61472) & "-" & ChrW(61695) & "]"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
.Execute
If .Found Then
MsgBox "Ce n'est pas un parenthèse ouvrante"
CheckIfSymbol = True
End If
End With

End Function
'_______________________________________

Basically, I check every character that are selected, if I find that one of
them is a "(", I double check to make sure that it really is a "(" and not a
symbol.

Here is the problem:
With
.Wrap = wdFindStop
in the function, the .Found property is always false, even if a symbol is
currently selected.
If I change
.Wrap = wdFindStop
to
.Wrap = wdFindContinue
Then the .Found property is always true because it always finds the symbol
character in the document, even if it is not in the original selected range.

Why is the Find actually working to tell symbols apart from "(" when doing a
document wide search, but not when checking a specific character?

I have done this before, but not with symbol characters. I remember doing
this to tell if a selected character was a section break or a page break. I
used basically the same kind of code and it worked without any problem. This
isn't working and I cannot tell why! Something to do with wild cards?

Arrrggghhh! I need a coffee!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
J

Jean-Guy Marcil

Klaus Linke was telling us:
Klaus Linke nous racontait que :
Hi Jean-Guy,

Since I don't speak (much) French, I doubt it's my code ;-)

Right.. My question was really about the Find/Search behaviour...
You don't need Find since you already know which character to check...

Helmut and Dave have given alternative solutions.
You could also look if its code is between &HF020 and &HF0FF (61472
and 61695):

Function CheckIfSymbol(MyCar As Range) As Boolean
Dim lChar As Long
lChar = AscW(MyCar.Text)
Select Case lChar
Case 61472 To 61695
CheckIfSymbol = False
Case Else
CheckIfSymbol = True
End Select
End Function

Ahhh... Why didn't I think of that? A good ol' Select Case!

Thanks!
The reason the search fails is that Word will jump to the next found
symbol if you already have a symbol selected (... Try selecting an
"a" and then search for "a" in the user interface: It'll go to the
next "a" immediately).

This is a bug if you ask me. This means you cannot use this to
search/compare single characters... silly if you ask me... what about case
where you have a range that could be any number of characters? It will fail
whenever the range happens to be one character long?

Have a good weekend!

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
(e-mail address removed)
Word MVP site: http://www.word.mvps.org
 
K

Klaus Linke

This is a bug if you ask me. This means you cannot use this to
search/compare single characters... silly if you ask me... what about
case where you have a range that could be any number of characters?
It will fail whenever the range happens to be one character long?

Try. It happens whenever the string you're searching for is already matched, and with Ranges as well as the Selection.

Since it makes sense from the user interface, it doesn't look like a bug to me.
If you select a word, Word will pop it into "Find what". Or the text might still be in "Find what" from a previous search.
It would be confusing if nothing at all happened the first time you clicked "Find". Most editors including "Notepad" immediately jump to the next match.
As a "work-around", you could always check if Range.Text=Range.Find.Text (and only .Execute the Find if they don't match).

Have a good weekend!

Same to you!
Salut,
Klaus
 
K

Klaus Linke

Salut Guy,

BTW, you might be interested in a macro to turn characters from the Symbol font into the corresponding Unicode characters:
From: "Klaus Linke" <[email protected]>
Subject: Re: Symbol problems in Word 2004 for mac
Date: Mon, 11 Apr 2005 19:28:55 +0200
Message-ID: <[email protected]>
Newsgroups: microsoft.public.mac.office.word

It's "daddy", from which you probably got the code, worked only on the main document story, and you had to "unprotect" symbols with another macro first. The new version should handle protected and unprotected symbols, and in all story ranges.

Regards,
Klaus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top