PDA

View Full Version : Macro which can skip matches in one condition



Ors
03-08-2013, 01:43 AM
HELLO :hi:

To make a long story short: I have a mission. I need to use a macro that can find every word which starts with "Y" (till here it's a piece of cake) -- unless the previous word ends with X.

For example:
"I like to fax yellow papers, do you?"
I want the macro to select the second match only.

The full story:
In my language (Hebrew), you can find a "naked" letter (for example: ל) or a vocalized letter (to help young children to read texts; a letter with optional diacritics): ל + ּ (Dagesh, a small point) = לּ
According to the language's rules, one will never find the לּ (Lamed + Dagesh) as the first letter of a word -- UNLESS the previous word is "מַה".

I've "recordered" a macro to find any word which starts with "לּ" (pay attention to the space: .Text = " לּ", but I really don't know how to make it skip any match which comes after the word "מַה".

Sub FIND()
'
' FIND Macro
'
'
Selection.FIND.ClearFormatting
With Selection.FIND
.Text = " לּ"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchKashida = False
.MatchDiacritics = True
.MatchAlefHamza = False
.MatchControl = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.FIND.Execute
End Sub
How can I do it?
THANK YOU!!!

macropod
03-08-2013, 02:27 AM
What you need to do is to find whole strings that don't include the previous two characters, then highlight only the last character. For that, you need a wildcard Find.

Try:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[!" & ChrW(&HFB3E) & "][!" & ChrW(&HFB34) & "] " & ChrW(&HFB3C)
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
.Start = .End - 1
.HighlightColorIndex = wdBrightGreen
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
The above finds strings that do not begin with 'מּהּ', but end with ' לּ'. Since the 'Find is running from left to right, you might need to change the order of the characters in the expression and/or the find direction, to suit the Hebrew language. You may also need to change the actual characters as I'm not sure whether you're using the same ones - I used the unicode for the characters with vowel points, whereas you indicated the use of combining diacritics.

Ors
03-08-2013, 03:34 AM
THANK you! you're a genious!
Could you please rewrite the next line as if the "fax yello papers" example was real?
("I like to fax yellow papers, do you?")
.Text = "[!" & ChrW(&HFB3E) & "][!" & ChrW(&HFB34) & "] " & ChrW(&HFB3C)

The unicode characters make the Word (and me, I admit) a little bit confused. I would prefer adjusting the line with Latin characters although the RTL-LTR difference.

As a matter of fact, the Lamed (ל) + Dagesh (ּ) are two different characters that come together on the screen as if they were one letter only - but they are not.
When you write ל and right after it ּ (Dagesh) - it looks like this: לּ. I think you used the super-rare ONE character לּ. I think nobody uses it at all.
Try this: copy the first green לּ to Notepad, press the End button and then Backspace. What you'll get is ל without the diacritic point. If you try to do the same on the second green לּ - you'll delete the whole one character.

:)

macropod
03-08-2013, 03:46 AM
The Find for (not) fax yellow would be:
.Text = "[!a][!x] y"

Actually a more robust form would be:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = " y"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
.MoveStart wdcharater - 2
If Left(.Text, 2) = "ax" Then
.Start = .End - 1
.HighlightColorIndex = wdBrightGreen
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
This says that, having found ' y', check whether the previous two characters are 'ax' and, if not, highlight the last character (y).

As for the codes I used, Word works fine with them - that's where I got them from. You'll find them via Insert|Symbol with any font that supports the Hebrew portion of the Unicode specifications.

Ors
03-08-2013, 04:23 AM
Thank you.

I tried the last code you wrote on the original "fax yellow" example, without any moficication. Somehow there's an error (error 4120): Invalid parameter.
The ".MoveStart wdcharater - 2" line is highlighted in the debugging mode.

(I can't share links yet, and the PNG file is "too large"):
i49.tinypic.c_o_m/2yyqu15.png

Thank you, Paul

macropod
03-08-2013, 04:33 AM
Typo:
".MoveStart wdcharacter - 2"

Ors
03-08-2013, 04:39 AM
Oh, I had to find the misspelling by myself.
But the same error is coming again...

Sub Dexmo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = " y"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
.MoveStart wdCharacter - 2
If Left(.Text, 2) = "ax" Then
.Start = .End - 1
.HighlightColorIndex = wdBrightGreen
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub

Ors
03-08-2013, 05:13 AM
I used the first code you'vw written. It almost worked!
I added ".MatchDiacritics = True" (which doesn't seem to help) and tried to gather the [!a][!b][!c] into [!abc], which also doesn't seem to help.

Thank you...! :cloud9:

macropod
03-08-2013, 05:40 AM
I used the first code you'vw written. It almost worked!
I added ".MatchDiacritics = True" (which doesn't seem to help) and tried to gather the [!a][!b][!c] into [!abc], which also doesn't seem to help.
Combining the [!a][!b][!c] into [!abc] tells Word to find any one of the characters, not all three, in the preceding position - not each character in order in the 3 preceding positions.

This works (another typo fixed):
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = " y"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
.MoveStart wdCharacter, -2
If Left(.Text, 2) = "ax" Then
.Start = .End - 1
.HighlightColorIndex = wdBrightGreen
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub

Ors
03-08-2013, 08:51 AM
Thank you for the expanation! You're a good teacher!

I tried to run the exact code you wrote and it seems like it does exactly the opposite...
http://i45.tinypic.com/2j0m690.png

:)

macropod
03-08-2013, 05:59 PM
I tried to run the exact code you wrote and it seems like it does exactly the opposite...
In that case, change:
If Left(.Text, 2) = "ax" Then
to:
If Left(.Text, 2) <> "ax" Then

Ors
03-09-2013, 06:52 AM
FANTASTIC!!!
Now, thank to you, it works well!

THANK YOU,Paul!

תּוֹדָה רַבָּה!‏

:)

P.S - how to add OR-s to the .Text = " y"? I mean: how to write ".Text = " y/ u/ z" (find any word that starts with y OR u OR z...)? I assume that copying the whole code again and again will work - but it's too heavy and not really smart.
(Edited: I see I can simply duplicate the green line one after the other... Edit: not, it isn't working; the engine "reads" the last line only)

Doug Robbins
03-09-2013, 05:18 PM
Use


.Text = " [uyz]"