i have many documents with variable-words inside brackets like this:
[my_word]
My code already finds all those words and i save them as String.
Now I need a function to replace this String with a ContentControl Element. Is this possible? Because I first need to generate an element, then change the text inside and the tag of it, both with [my_word].
Any help is appreciated.
My Code so far looks like this (right now it is possible to replace one word at a time with a control element; I would like to replace all inside on macro. Word tells me it is not possible to replace multiple Selections, so I would have to rerun this macro mutliple times manually..)
Sub ReplaceTags()
'
' ReplaceTags Macro
'
'
Selection.Find.ClearFormatting
With Selection.Find
.Text = "\<?*\>"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute
Selection.Range.ContentControls.Add (wdContentControlText)
End Sub
EDIT:
I worked on my code a little bit and found a solution to replace the text I am looking for:
Sub ReplaceTags()
'
' ReplaceTags Macro
'
'
With Selection.Find
.ClearFormatting
.Text = "\<?*\>"
.Execute Forward:=True
.MatchWildcards = True
End With
If Selection.Find.Found = True Then
Selection.Range.ContentControls.Add (wdContentControlText)
Selection.ParentContentControl.Tag = Selection.Text
End If
End Sub
Still I am not quite sure how to do this on the complete document without having to click "run macro" a whole lot of times
EDIT(EDIT):
I solved it. In case somebody has the same problem in future:
Sub ReplaceAllTags()
'
' ReplaceAllTags Macro
'
'
For i = 0 To ActiveDocument.Words.Count
Selection.EscapeKey
Application.Run MacroName:="ReplaceTags"
Next
End Sub
ReplaceTags() is the same function as above.
Related
I wrote the 1st ever macro.(Windows 10, WORD 2019)
I'm trying to find words that start with a capital letter in Standard style and continue to have Italic style.
Unfortunately, if I search a document using too many letters in the query - the macro closes (after checking, for example, 1.5 pages) or resets the WORD program.
If I reduce the number of words searched - the macro starts to run longer and longer.
With, for example, a search for 1 letter (U) instead of 32 (ABCDEFGHIJKLŁMNOPQRSTUVWXYZĆŚŃŻŹ) - it does not crash the program.
I tried to add
Application.ScreenUpdating = False at the beginning and
Application.ScreenUpdating = True at the end of the code but it doesn't help much.
Sub Makro1()
Dim Rng As Range
Selection.MoveRight Unit:=wdCharacter, Count:=2
Selection.find.ClearFormatting
With Selection.find.Font
.Bold = False
.Italic = False
End With
Selection.find.Replacement.ClearFormatting
With Selection.find
.Text = "U"
'.Text = "([ABCDEFGHI])"
'.Text = "([ABCDEFGHI])"
'.Text = "([JKLŁMNOP])"
'.Text = "([QRSTUVWX])"
'.Text = "([YZĆŚŃŻŹ])"
'.Text = "([ABCDEFGHIJKLŁMNOPQRSTUVWXYZĆŚŃŻŹ])"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.find.Execute
Selection.MoveRight Unit:=wdCharacter, Count:=2
Set Rng = Selection.Range
If Rng.Italic = True Then
MsgBox "FIND"
End
If Rng.Italic = False Then
Call Makro1
End If
End If
Call Makro1
End Sub
Thanks but your code didn't work. I change the code to:
If .Words.Last.Characters(2).Font.Italic = True Then
.Characters(1).Font.Italic = True
End If
.find.Execute
but it only worked sometimes. When I enabled the macro on a longer text, the macro would hang, show error 5941 "collection object not exist" and stop on the line:
If .Words.Last.Characters(2).Font.Italic = True Then
I spent a lot of time before I discovered why. It turns out that the macro crashes because sometimes there is a punctuation mark in the text next to a capital letter, e.g. period comma...etc. e.g A. B; C: D., The code would have to be improved to ignore this. I try add .IgnorePunct = True after .MatchCase = True but didn't help and macro still crashes
I try change code:
.Text = "<[A-Z][!.,;:„”#$%-+=[\[/[//[#[?[![#[$[%[*[([)[&[*[{[}]*>"
Macro fix some errors in text, work longer but still somewhere is an unacceptable sign after a character with a capital letter and the macro crashes.
Add more unwanted signs
.Text = "<[A-Z][!.,;:„”#$%-+=[\[/[//[#[?[![#[$[%[*[([)[&[*[{[}[<[>_|` - …]*>"
and still the macro crashes.
After rewriting the code to show live which words it checks, I was able to understand in part why the macro crashes.
Problem is hard space:
1 and the comma after digit
if I use normal space instead of hard space - macro work OK.
If change to N = 5, to N = 5 , also work OK.
Another place with STOP working:
2
3
I don't know what other adjustments to make so that the macro doesn't hang up in these places.
[EDIT]
I don't know too much what I'm doing, but I changed the code to:
Sub m1select()
Application.ScreenUpdating = False
With Selection.find
.Text = "<[A-Za-z0-9][! ^13.^s^t^+^=,;:„”#$%-+=[\[[\][\\[\/[\//[\#[\?[\![\#[\$[\%[\*[\([\)[\&[\*[\{[\}[\<[\>_|` - …-]*>"
.MatchWildcards = True
.Execute Forward:=True, Wrap:=wdFindStop
End With
With ActiveDocument.Content
Do While Selection.find.Found
If Selection.Words.Last.Characters(1).Font.Italic = True Or Selection.Words.Last.Characters(2).Font.Italic = True Then
Selection.Font.Italic = True
End If
Selection.find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
and it works. It now corrects all words with partial Italic font not just capitalized.
Admittedly, it does it slowly because I used "Select" , but that way I can see what character the macro hangs on and add it to the exclusion in after the [!
( as all the time is Application.ScreenUpdating = True)
Doesn't work on expressions with a single U e.g.
U letter (after correction it should be U letter) but I make it myself with another script.
You guided me to the solution.
The problem was calling the macro in a loop using Call.
After adding START: at the beginning (and then the rest of the code) and instead of "Call Macro 1" writing "GoTo START" in two places solved the problem.
you're not finishing your code correctly.
When calling a macro from that macro you're creating a loop which never ends. By calling macro1 all the time, the runtime will terminate the Word Application after too many iterations.
You probably don't need to loop (which is a wired loop you created there) through the selection.
The Find-Object provides everything you need. To write all capital letters which are the first ones in a word to italic, when it's not bold or underlined, you could use this, for example:
Sub m()
With ActiveDocument.Content.Find
.Text = "<[A-Z]"
.Style = "Standard"
.Font.Bold = False
.Font.Underline = False
.MatchWildcards = True
.MatchCase = True
.Replacement.Font.Italic = True
.Execute Replace:=wdReplaceAll, Forward:=True, Wrap:=wdFindContinue
End With
End Sub
If you want to set the first capital character of a word to italic, when the secnd character is italic too, you have to loop over all possible words:
Sub m1()
With ActiveDocument.Content
With .Find
.Text = "<[A-Z]*>"
.MatchWildcards = True
.MatchCase = True
.Execute Forward:=True, Wrap:=wdFindStop
End With
Do While .Find.Found
If .Words.Last.Characters(2).Font.Italic = True Then .Font.Italic = True
.Find.Execute
Loop
End With
End Sub
You could specify other letters like you did above if you need/want.
If you need more precise selection criteria, you can search them on the help page:
https://learn.microsoft.com/en/office/vba/api/word.find
Good Luck
I have a question about a problem i need do solve.
I have a word doc, on which i want to run a search and replace query.
But i dont want to change the actual text, i want to put the changed text
in the clipboard and leave the actual one unchanged.
Sub SearchAndReplace()
' marks all bold words,italic words, underlined
Selection.Find.ClearFormatting
Selection.Find.Font.Bold = True
Selection.Find.Font.Italic = True
Selection.Find.Font.Underline = wdUnderlineSingle
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = ""
.Replacement.Text = "[test]^&[/test]"
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = True
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
Cautious:
I guess there are better ways to achieve what you want to do as this is not proper coding. (Also as the clipboard only has a limit of 24 items), but for the sake of making your code works, here is my answer:
To copy the text in the clipboard instead of replacing it, you can just use the .copy method.
If you replace your line:
Selection.Find.Execute Replace:=wdReplaceAll
by
Dim iCount As Long
Selection.Find.Execute
Selection.Copy
Do While Selection.Find.Found = True And iCount < 1000
iCount = iCount + 1
Selection.Find.Execute
Selection.Copy
Loop
it should work.
The code is simply copying the item found after each search.
Selection.Find.Execute searches the next itteration of the search every time it appears in the code.
Once there are no search found anymore (or there are too many searches), the loop will stop.
This code allows to change all text with style "myStyleOne" for "myStyleTwo".
Option Explicit
Sub replaceStyleForAnotherStyle()
Selection.Find.ClearFormatting
Selection.Find.Style = ActiveDocument.Styles("myStyleOne")
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Style = ActiveDocument.Styles("myStyleTwo")
With Selection.Find
.Text = ""
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
What should the code look like if I want to turn only the last paragraph of "myStyleOne" into "myStyleTwo"?
To find the last paragraph with a given style:
Function lastOfStyle(st As String) As Paragraph
For i = ActiveDocument.Paragraphs.Count To 1 Step -1
If ActiveDocument.Paragraphs(i).Style = st Then
Set lastOfStyle = ActiveDocument.Paragraphs(i)
Exit Function
End If
Next
End Function
Now you can change the style with this simple statement:
lastOfStyle("MyStyle1").Style = "MyStyle2"
But if you want to do it in your macro, for other reasons that I missed, then you should add the following at the beginning of your macro:
Dim p as Paragraph: Set p = lastOfStyle("Normal")
if p Is Nothing then Exit Sub
p.Range.Select
Then set .Wrap = wdFindStop in the With Selection.Find bloc instead of * .Wrap = wdFindContinue *
Have you seen this answer? It really helps: answer. The things you might know: in VBA there are subroutines (sub) and functions. Functions can be used in many subroutines and should go separately.
Great. You want to copy and use the code? Here you are, just copy it all to the developer tab on the ribbon: http://codepad.org/Wd5Rer4y. Then you can run sub replaceStyleForAnotherStyleSimple() or sub replaceStyleForAnotherStyleComplicated(). Both of them rely on function lastOfStyle. Click alt+f8 and choose wisely.
Great. But is it possible to do the same thing without function?
Sure! Here it comes! replaceStyleForAnotherStyleNoFunction()
Sub replaceStyleForAnotherStyleNoFunction()
Dim parCountDown, i, sMyPar
parCountDown = ActiveDocument.Paragraphs.Count
For i = parCountDown To 1 Step -1
If ActiveDocument.Paragraphs(i).Style = "myStyleOne" Then 'change the part for: "Normal"
ActiveDocument.Paragraphs(i).Style = "myStyleTwo" 'change the part for: "Heading 1"
'sMyPar = ActiveDocument.Paragraphs(i).Range.Text
'MsgBox (sMyPar) 'message box with that paragraph
Exit Sub
End If
Next
End Sub
So you see here three ways to do the same thing and easy path to copy all that. Stay tuned and Good luck!
I am trying to search an ActiveX TextBox (TextBox1) to replace a phrase with nothing...
I have this code that seems to just wipe the entire box rather than the phrase in isolation.
Private Sub CommandButton3_Click()
TextBox1 = Selection
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "This is the text to remove!"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
With some additions (like selecting all shapes in the active document)- the code works with an ordinary TextBox - and with the rest of the document too... just not the ActiveX box (which is what I want!!)
Please help!
You can simply use the built-in VBA Replace function:
Private Sub CommandButton3_Click()
TextBox1.Value = Replace(TextBox1.Value, "This is the text to remove!", "")
End Sub
I make a several page word document every week. I copy text from a PDF and paste it into a word document, I then format the text that I pasted.
This takes a long time and i would like to automate it.
I need a macro or some code to select specific text, then make that text bold. The specific text i need to bold is what i call a scrap code.
There are 60 different codes. For example "FIPS", or "LILL".
Something like this:
Sub A()
'
' a Macro
'
'
Dim A(3) As String
A(1) = "code1"
A(2) = "code2"
A(3) = "code3"
For i = 1 To 3
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Replacement.Font.Bold = True
.Execute FindText:=A(i), ReplaceWith:=A(i), Format:=True, _
Replace:=wdReplaceAll
End With
Next i
End Sub
HTH!
Edit
To switch dollar amounts to bold
Sub a()
'
' a Macro
'
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Font.Bold = True
With Selection.Find
.Text = "$([0-9.,]{1,})"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
I would suggest recording a macro.
Then do all the modifications and formatting.
Finally, look at the code of the macro and see how it did it.
The one thing you need to figure out is how you logically want to locate the text you want to bold.
Is it a specific line? Is it at the beginning of a known word?
Once you have that answered, you can combine it with the code of the macro and automate the task.