I have a transliteration function (from cyrillic to latin). I will use this function in a unviersal subroutine (with text of any lenght). This sub must to copy the source text, transliterate (from cyrillic to latin) and paste it below without any formatting changes and without using selection. The next step is reverse transliteration (again copy and paste below). There must be 3 textes in the final. I kinda know how to realize it, but i don't know what i should use instead of selection.
*
P.S. i tried use For Each word In ActiveDocument.Range.Words but it works bad with reverse transliteration (exactly that. without it, the function works perfectly in debugging)
P.P.S. sorry for mistakes in the text, i'm not a native speaker
Since you haven't posted any actual transliteration code, I'll leave you to add the cyrillic and latin character sets to the code below:
Sub Transliterate()
Application.ScreenUpdating = False
Dim p As Long, i As Long, StrLng1, StrLng2
'Insert the character codes for the cyrillic characters here
StrLng1 = Array(ChrW(&H430), ChrW(&H431), ChrW(&H432))
'Insert the corresponding latin characters here
StrLng2 = Array("a", "b", "c")
With ActiveDocument.Range
Do While .Characters.Last.Previous = vbCr
.Characters.Last.Previous.Delete
Loop
.InsertAfter vbCr
'Duplicate Content
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Wrap = wdFindContinue
.MatchWildcards = True
.Text = "^13"
.Replacement.Text = "^l"
.Execute Replace:=wdReplaceAll
.Font.Bold = True
.Text = "[!^l]#^l"
.Replacement.Text = "^p^&"
.Execute Replace:=wdReplaceAll
.ClearFormatting
.Text = "^l^13"
.Replacement.Text = "^p"
.Execute Replace:=wdReplaceAll
.Execute Replace:=wdReplaceAll
.Text = "[!^13]#^13"
.Replacement.Text = "^&^&^p"
.Execute Replace:=wdReplaceAll
End With
.Characters.Last.Previous.Delete
.Characters.First.Delete
'Loop through duplicated paragraphs
For p = .Paragraphs.Count - 1 To 2 Step -3
With .Paragraphs(p).Range
.Font.Italic = True
'Transliterate paragraph
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Wrap = wdFindStop
.MatchWildcards = False
.MatchCase = True
.Font.Bold = False
For i = 0 To UBound(StrLng1)
.Text = StrLng1(i)
.Replacement.Text = StrLng2(i)
.Execute Replace:=wdReplaceAll
Next
End With
'Duplicate translated paragraph
.Characters.Last.Next.FormattedText = .FormattedText
End With
Next
.Characters.Last.Previous.Delete
'Loop through duplicated paragraphs
For p = .Paragraphs.Count To 3 Step -3
With .Paragraphs(p).Range
.Font.Underline = wdUnderlineSingle
'Reverse Transliterate paragraph
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Wrap = wdFindStop
.MatchWildcards = False
.Font.Bold = False
.MatchCase = True
For i = 0 To UBound(StrLng1)
.Text = StrLng2(i)
.Replacement.Text = StrLng1(i)
.Execute Replace:=wdReplaceAll
Next
End With
End With
Next
End With
Application.ScreenUpdating = True
End Sub
Related
I can find the words starting with a capital letter using the following command
Selection.Find.Text = "<([A-Z][0-9A-Z\a-z]{1,15})>"
What exactly I'm struggling with is to take each word one by one and finding similar words in the document first one word and find all duplicates and next second word. I hope I had expressed what I'm trying to create.
Any help is much appreciated
Your questions is poorly worded and, hence, it is difficult to understand what you're trying to achieve. Try:
Sub Demo()
Application.ScreenUpdating = False
Options.DefaultHighlightColorIndex = wdBrightGreen
Dim StrFnd As String, i As Long
StrFnd = "|"
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "<[A-Z][A-Za-z]#>"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
End With
Do While .Find.Execute
If InStr(StrFnd, "|" & .Text & "|") = 0 Then StrFnd = StrFnd & .Text & "|"
.Collapse wdCollapseEnd
Loop
With .Find
.Wrap = wdFindContinue
.MatchCase = False
.MatchWildcards = False
.MatchWholeWord = True
.Replacement.Highlight = True
For i = 0 To UBound(Split(StrFnd, "|"))
.Text = Split(StrFnd, "|")(i)
.Replacement.Text = "^&"
.Execute Replace:=wdReplaceAll
Next
End With
End With
Application.ScreenUpdating = True
End Sub
I have a macro that uses wildcards to find acronyms in a Word document.
I want to 'unhighlight' that acronym if it is followed by a (.
For example, my content might say "BRB (be right back)" so BRB would not be highlighted. But, LOL would be highlighted if (laughing out loud) does not immediately follow the text.
I am trying to avoid false positives. Is there way I can exclude the 'BRB' results?
With ActiveDocument.Content.Find
.ClearFormatting
.Text = "<[A-Z]{2,}>"
With .Replacement
.Text = "^&"
.ClearFormatting
.Highlight = True
End With
Try this out:
Sub HighlightAcronyms()
Dim rng As Range, r2 As Range
Set rng = ActiveDocument.Content
Set r2 = ActiveDocument.Content
With rng.Find
.ClearFormatting
.Text = "<[A-Z]{2,}>"
.Forward = True
.Wrap = wdFindStop
.MatchCase = True
.MatchWildcards = True
.Format = False
Do While .Execute
'look two characters past the found acroynm
r2.Start = rng.End + 1
r2.End = rng.End + 3
Debug.Print rng.Text, r2.Text
'highlight if r2 has a "(" otherwise clear highlight
rng.HighlightColorIndex = IIf(r2.Text Like "*(*", _
wdAuto, wdYellow)
Loop
End With
End Sub
I have a Find and Replace macro that adds a space between the end of one sentence and the beginning of another when missing. This sometimes happens when I move sentences around in word.
I notice that if the cursor is to either side of the punctuation mark, the macro can’t see the Find pattern and doesn’t fix it. I assume it’s because Find and Replace starts searching from the cursor position. Is there a way to tweak the code so it finds them too?
I know I could just tell the macro to start from the beginning, but I would much rather it left the cursor in its current position, especially if I run it near the end of a long document.
Sub AddOneSpaceBetweenSentences()
' AddOneSpaceBetweenSentences Macro
'
With Selection.Find
.Forward = True
.Text = "(?)([.\?\!])([A-Z])"
.ClearFormatting
.Replacement.Text = "\1\2 \3" 'there is a space between \2 and \3
.MatchWildcards = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
End Sub
Better still:
Sub AddOneSpaceBetweenSentences()
Application.ScreenUpdating = False
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Format = False
.MatchWildcards = True
.Wrap = wdFindContinue
.Text = "([.\?\!])([A-Z])"
.Replacement.Text = "\1 \2"
.Execute Replace:=wdReplaceAll
End With
Application.ScreenUpdating = True
End Sub
The most reliable way is to use Range objects instead of Selection. When working with a Range the selection in the document doesn't change.
Sub AddOneSpaceBetweenSentences()
' AddOneSpaceBetweenSentences Macro
'
Dim rng as Word.Range
Set rng = ActiveDocument.Content
With rng.Find
.Forward = True
.Text = "(?)([.\?\!])([A-Z])"
.ClearFormatting
.Replacement.Text = "\1\2 \3" 'there is a space between \2 and \3
.MatchWildcards = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
End Sub
Is it really necessary to have a character before the end signs . or ? or !
If not, just replace "([.\?\!])([A-Z])" by "\1 \2"
Simple attempt: Just extend the selection by 2 characters to the left.
If cursor is on the first two characters of the documents, you would get an error. To prevent that and to prevent counting of characters, I just used Selection.Start > 10
If Selection.Start > 10 Then
Selection.Previous(Unit:=wdCharacter, Count:=2).Select
End If
... or do it a little more complicated:
Sub AddOneSpaceBetweenSentences()
Dim SearchText As String
Dim ReplaceText As String
' extend selection by 1 character
If Selection.Start > 0 Then
Selection.Previous(Unit:=wdCharacter, Count:=1).Select
End If
Selection.Collapse
' if selection begins directly before end of sentence (.?!)
' adapt search & replace pattern
If InStr(1, ".?!", Selection.Characters(1), vbBinaryCompare) > 0 Then
SearchText = "([.\?\!])([A-Z])"
ReplaceText = "\1 \2"
Else
SearchText = "(?)([.\?\!])([A-Z])"
ReplaceText = "\1\2 \3"
End If
With Selection.Find
.Forward = True
.text = SearchText
.ClearFormatting
.Replacement.text = ReplaceText
.MatchWildcards = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
End Sub
Thanks in advance for any reply.
I am working on presentation of some reports. The periodical reports are imported from a different software into Word template. For all tables and for each row I would like to change the color of the negative numbers in column 14 only if there is a certain text in column 3.
Unfortunately I have to use a Word template to do this. It seems that a macro is my only option so I have tried to Frankenstein something from different macros I found online:
Dim varColumn As Column
Dim clColumn As Column
Dim cCell As Variant
Set clColumn = Selection.Columns(3)
Set varColumn = Selection.Columns(14)
With clColumn
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.text = "value"
.Replacement.text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
If .Information(wdWithInTable) = True Then
Selection.MoveRight Unit:=wdCell, Count:=11
End If
If cCell < 0 Then
Selection.Font.color = wdColorRed
End If
Loop
End With
End Sub
I think the macro needs lines to repeat the search. See the two lines added before Loop.
With Selection
.HomeKey Unit:=wdStory 'Starts at the beginning, to search all tables.
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "value"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
If .Information(wdWithInTable) = True And _
.Cells(1).ColumnIndex = 3 Then 'Confirms it's in the 3rd column.
.MoveRight Unit:=wdCell, Count:=11
End If
If .Range < 0 Then
.Font.Color = wdColorRed
End If
.Collapse wdCollapseEnd 'Collapses the selection to no characters.
.Find.Execute 'Searches again from the current selection point.
Loop
End With
Try:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "-[0-9][0-9,.]{1,}"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found = True
If .Information(wdWithInTable) = True Then
If .Cells(1).ColumnIndex = 14 Then
If Split(.Rows(1).Cells(3).Range.Text, vbCr)(0) = "specified text" Then
.Font.ColorIndex = wdRed
End If
End If
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
If the table might have vertically-merged cells, change:
If Split(.Rows(1).Cells(3).Range.Text, vbCr)(0) = "specified text" Then
to:
If Split(.Tables(1).Cell(.Cells(1).RowIndex, 3).Range.Text, vbCr)(0) = "specified text" Then
i am attempting to write a macro that with find/replace a string and than move it to an existing heading. The original text is like this:
1. Heading 1
ID: abcd
1.1 Heading 2
ID: abcd
And it should look like:
1.Heading 1 abcd
1.1 Heading 2 abcd
I am having some problems with the code i tried to write, mostly because i am kinda new, but this is what i created so far:
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Style = "Heading 2"
With Selection.Find
.Text = "abcd"
.Replacement.Text = "abcd^p"
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = True
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
The text is not so important because i managed to replace with what i want but i don't know how to align it with the Heading style.. Thanks
EDIT: I hope i don't screw up again, sorry big :). So i have raw which is the raw text and i want to process it to look like this final. I already found out, thanks to you how to replace the text, it's just that i stuck in the raw version. Thanks, I kinda own you a beer, or two
LATER EDIT: So i have 5 types of Heading formats, 1. Heading 1, 1.1 Heading 2 etc till 5, and all of them have below them an ID, each with a specific number, but the name is the same, ID ASD_PC_AWP_[XXXX]. I just have to get rid of ID ASD_PC_ and put AWP_[xxxx] at same level of the Heading eg: 1.Heading 1 AWP_[xxxx1] ** , **2. Heading 2 AWP_[xxx2]...
Try:
Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "ID:*^13"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
Set Rng = .Duplicate.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
Rng.End = Rng.Paragraphs.First.Range.End - 1
Rng.InsertAfter Split(Split(.Duplicate.Text, ":")(1), vbCr)(0)
.Text = vbNullString
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
Do a wildcard find for any paragraph marker which is followed by ID:.
.Text = "^13ID:"
.Replacement.Text = ""
You will need to specify the style of the replacement text to the heading style because when you delete the paragraph marker at the end of the Heading paragraph you will also delete the style information for the heading paragraph.
You will need to do this with every style heading followed by the ID: text.
Updated 2018-11-01
The following code should work. I got some hints from Macropods ingeneous code.
Update 2 2018-11-01
Revised to work with a list of styles defined by user at OPs request
Sub ConsolidateHeadingWithID()
Const HEADINGS As String = "Heading 1,Heading 2,Heading 3,Heading 4,Heading 5,Other style,another style"
Dim my_headings As Variant
Dim my_heading As Variant
my_headings = Split(HEADINGS, ",")
For Each my_heading In my_headings
With ActiveDocument.StoryRanges(wdMainTextStory)
With .Find
.ClearFormatting
.format = True
.Text = ""
.Style = my_heading
.MatchWildcards = True
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found
If .Duplicate.Next(unit:=wdWord).Text = "ID" Then
.Duplicate.Next(unit:=wdParagraph).Style = my_heading
End If
.Collapse wdCollapseEnd
.MoveStart unit:=wdCharacter, Count:=2
.Find.Execute
Loop
End With
With ActiveDocument.Range.Find
.ClearFormatting
.format = True
.Text = "(^13)(ID:)(*)(AWP_)([0-9]{1,})"
.Style = my_heading
.Replacement.Text = " [\4\5]"
.MatchWildcards = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Next
End Sub