I want change a word to superscript in macro.
word 2016.
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "7th of every month."
.Replacement.Text = "7^th of every month."
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchAllWordForms = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
End Sub
when i run the macro instead of making "th" as supercript it just create space between "7" and "h"
Result is like this "The meeting is on 7 h of every month."enter image description here
The following code searches for one or two digits, immediately followed by th and superscripts the th. This makes it more flexible than searching the specific string.
It works with a Range rather than a Selection object which will make it faster. The search type is a "wildcard" search.
Sub SuperScript_th_()
Dim rngFind As Word.Range
Dim searchText As String
Dim found As Boolean
Set rngFind = ActiveDocument.content
searchText = "[0-9]{1;2}th"
'searchText = "7th"
With rngFind.Find
.Text = searchText
.MatchWildcards = True
.wrap = wdFindStop
found = .Execute
Do While found
rngFind.Collapse wdCollapseEnd
rngFind.MoveStart wdCharacter, -2
rngFind.Font.Superscript = True
rngFind.End = ActiveDocument.content.End
found = .Execute
Loop
End With
End Sub
The ^t is the instruction in Word's Find to insert a TAB (like pressing the Tab-key on the keyboard). That's why the code in the quesiton is inserting space between the 7 the h in the Replacement.Text.
While Word's Find/Replace is able to format text as part of the Replacement, the difficulty here is that
Not all the text being found should be formatted
The entire text needs to be retained
It's not possible to tell Find/Replace to find text, then format only part of it. That's why the Find needs to be separate from the formatting action. If the entire found text needed to be formatted, then Find/Replace alone would work.
There are also no commands in Word's Find/Replace to apply formatting as a "code" in the Replacement.Text string.
Why don't simply try like this
With Selection.Find
.Text = "7th of every month."
'.Replacement.Text = "7^th of every month."
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchAllWordForms = False
.MatchWholeWord = True
.MatchWildcards = False
.MatchSoundsLike = False
Do While .Execute
ActiveDocument.Range(Selection.Range.Start + 1, Selection.Range.Start + 3).Font.Superscript = True
Loop
End With
Edit: With turning off some word options etc the 8 sec time to process 60 pages and 1240 replacement may be reduced to around 2 seconds. the test code
Sub test2()
Dim Rng As Range, tm As Double
tm = Timer
TurnOnOff False
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "7th of every month."
X = 0
Do While .Execute
ActiveDocument.Range(Selection.Range.Start + 1, Selection.Range.Start + 3).Font.Superscript = True
X = X + 1
Loop
End With
Debug.Print X, Timer - tm
TurnOnOff True
End Sub
Sub TurnOnOff(OnOff As Boolean)
Application.ScreenUpdating = OnOff
With Options
.Pagination = OnOff
.CheckSpellingAsYouType = OnOff
.CheckGrammarAsYouType = OnOff
End With
End Sub
Related
What I want to do is something simple (maybe). I have written a find method to loop around the document. I have find value - ']' and insert value - '[('. In between those two there can be any kind of number most likely from 1 - 100.
My current code is this:
Sub FindBracket()
Dim FindValue As String
Dim ReplaceValue As String
Dim oRange As Range
Set oRange = ActiveDocument.Range
FindValue = "]"
InsertValue = "(["
With oRange.Find
.Text = FindValue
.MatchWholeWord = False
Do While .Execute = True
If .Found Then
oRange.InsertBefore (InsertValue)
End If
oRange.Start = oRange.End
oRange.End = ActiveDocument.Range.End
Loop
End With
End Sub
The find method works good, but I need to modify .InsertBefore method.
Example
I would need to transform ' Dummy text 1] ' to this ' Dummy text [(1] ' but from the code I get ' Dummy text 1[(] ', I cannot seem to figure out how to do that, and I have only previous experience with Excel VBA only.
Would appreciate any help on this, than you.
Try this:
Sub FindBracket()
Dim FindValue As String
Dim ReplaceValue As String
Dim oRange As Range
Set oRange = ActiveDocument.Content
FindValue = "[0-9]#\]"
InsertValue = "[(^&" ' ^& - found number
With oRange.Find
.Text = FindValue
.Replacement.Text = InsertValue
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True ' enabled regular expressions
.Execute Replace:=wdReplaceAll
End With
End Sub
Before:
Dummy text 1234]
Dummy text 4321]
Dummy text 0]
Dummy text 1]
After:
Dummy text [(1234]
Dummy text [(4321]
Dummy text [(0]
Dummy text [(1]
All you need is:
Sub FindBracket()
Application.ScreenUpdating = False
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[0-9]#\]"
.Replacement.Text = "[(^&"
.Forward = True
.Format = False
.Wrap = wdFindContinue
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
Application.ScreenUpdating = True
End Sub
Indeed, you don't even need a macro - it could all be done through the GUI using a wildcard Find/Replace with the same F/R expressions.
I am trying to create VBA to insert before and after Supercript and subscript. My code is below.
Public Sub MySubscriptSuperscript()
Dim myRange As Word.Range, myChr
For Each myRange In ActiveDocument.StoryRanges
Do
For Each myChr In myRange.Characters
If myChr.Font.Superscript = True Then
myChr.Font.Superscript = False
myChr.InsertBefore "<sup>"
myChr.InsertAfter "</sup>"
End If
If myChr.Font.Subscript = True Then
myChr.Font.Subscript = False
myChr.InsertBefore "<sub>"
myChr.InsertAfter "</sub>"
End If
Next
Set myRange = myRange.NextStoryRange
Loop Until myRange Is Nothing
Next
End Sub
This code is working good for each character of superscript and subscript.
But, I am looking for VBA which insert tags before and after complete superscript/subscript word/letters.
Example
C12H22O11 and x23 + y397 + x67
Above VBA is giving following Output
C<sub>1</sub><sub>2</sub>H<sub>2</sub><sub>2</sub>O<sub>1</sub><sub>1</sub><sub> </sub><sub> </sub> and x<sup>2</sup><sup>3</sup> + y<sup>3</sup><sup>9</sup><sup>7</sup> + x<sup>6</sup><sup>7</sup>
But I am looking for this output
C<sub>12</sub>H<sub>22</sub>O<sub>11</sub> and x<sup>23</sup> + y<sup>397</sup> + x<sup>67</sup>
Pls guide, how this can be achieved.
I would be tempted to go for easiest way to get the end result - at the end, simply do a replace of </sub><sub> and </sup><sup> with an empty string "".
But then, I am lazy this way...
Edit - just an idea:
wouldn't it be faster to do the whole thing with replace? You wouldn't have to check every character. Here is what Word does record for the replacement, it would need a bit of polishing:
Selection.Find.Replacement.ClearFormatting
With Selection.Find.Replacement.Font
.Superscript = False
.Subscript = False
End With
With Selection.Find
.Text = "^?"
.Replacement.Text = "<sup>^&</sup>"
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
So, at the end, you would run search&replace 4 times:
replace superscript
delete the closing and opening tags for superscript
replace subscript
delete the closing and opening tags for subscript
Try:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Text = ""
.Wrap = wdFindContinue
.Font.Subscript = True
.Replacement.Text = "<sub>^&<\sub>"
.Execute Replace:=wdReplaceAll
.Font.Superscript = True
.Replacement.Text = "<sup>^&<\sup>"
.Execute Replace:=wdReplaceAll
End With
End With
Application.ScreenUpdating = True
End Sub
It's not apparent why you'd be looping through all storyranges, as such content would ordinarily only be in the document body. That said, it's easy enough to modify the code to work with all storyranges.
I want to delete a paragraph that starts with string "Page:" from the selection
Here is the sample text that I have:
Page: 28
Page: 44 contains a lot of example. But look up here for the detailed
explanation. This may go for more than one, two or three lines. This
totally depends upon the length of the text
Date: 10 Jan 2018
Some text goes here with Page: 108
I’ve some more text here
Few more
Final Text
Page: 208
This is the end
The code I have so far:
Sub DelPara()
Dim para As Paragraph
With Selection.Range.Find
.ClearFormatting
.Text = "[^13^11]Page:"
.Forward = True
.MatchWildcards = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute
If (Selection.Range.Find = True) Then
para.Range.Delete
End If
End With
End Sub
The output should be
Date: 10 Jan 2018
Some text goes here with Page: 108
I’ve some more text here
Few more
Final Text
This is the end
The code below will search all instances of the search term in the current selection and delete the search term plus the entire paragraph in which the end of the term is located.
The key to this is using two Range objects: one for the original Range to be searched (the selection), the other for the actual search. In this way, the range that performs the actual search can be extended from the end of the last successful search to the end of the original range.
Sub DelPara()
Dim rngFind As Word.Range, rngSel As Word.Range
Dim para As Paragraph
Dim bFound As Boolean
Set rngSel = Selection.Range
Set rngFind = rngSel.Duplicate
With rngFind.Find
.ClearFormatting
.text = "[^13^11]Page:"
.Forward = True
.MatchWildcards = True
.wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
bFound = rngFind.Find.Execute
Do While bFound
rngFind.End = rngFind.paragraphs.Last.Range.End
rngFind.Delete
rngFind.Collapse wdCollapseEnd
rngFind.End = rngSel.End
bFound = rngFind.Find.Execute
Loop
End Sub
All you need is a wildcard Find/Replace with:
Find = ^13Page:[!^13]{1,}
Replace = nothing
No code required. At most, you might need to insert an empty paragraph at the beginning of the document and delete it afterwards - but then only if the first para starts with 'Page:'. Nevertheless, as a macro:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
.InsertBefore vbCr
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "^13Page:[!^13]{1,}"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
.Characters.First = vbNullString
End With
Application.ScreenUpdating = True
End Sub
If you want to process only the selected range, change 'ActiveDocument' to 'Selection'.
My macro is supposed to do the following:
Look for instances of double spaces.
Replace those instances of double spaces with single spaces.
Go through the document again to see if there are any more double spaces and to replace them, if there are. For instance, if there were originally 4 spaces in a row somewhere, there will still be double spaces, so, replace remaining double spaces with single spaces.
Repeat the previous step until there are no more double spaces.
The problem is that the macro works perfectly in debug mode but only runs one pass if run normally. What am I doing wrong? Please note that my code may not be the most compact, but that's not the point; what I'm really wondering is why the code only works in debug mode and not in normal run mode, and how this can be fixed.
Sub Test_for_doubles()
'
' Test_for_doubles Macro
'
Dim blnFoundDoubles As Boolean
blnFoundDoubles = True
Do While blnFoundDoubles = True
Selection.HomeKey Unit:=wdStory 'Go to the beginning of the document.
blnFoundDoubles = False 'Don't go through this loop again unless we find a double this time through
With Selection.Find
.Text = " "
.Replacement.Text = " "
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
If .Found = True Then
blnFoundDoubles = True
End If
End With
Selection.Find.Execute Replace:=wdReplaceAll
Loop
End Sub
I've always found that testing the Found property is a bit hit-and-miss: sometimes it works, sometimes not. I prefer to declare a Boolean variable and assign it to Find.Execute since the method returns True if the find is successful, otherwise False.
The code you show has another problem: it's testing Found before the Find is executed. Try changing your code to something more like this:
Dim blnFoundDoubles As Boolean
Dim bFound as Boolean
blnFoundDoubles = True
bFound = False
Do While blnFoundDoubles = True
Selection.HomeKey Unit:=wdStory 'Go to the beginning of the document.
blnFoundDoubles = False 'Don't go through this loop again unless we find a double this time through
With Selection.Find
.Text = " "
.Replacement.Text = " "
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
bFound = .Execute(Replace:=wdReplaceAll)
If bFound Then
blnFoundDoubles = True
End If
'OR
'blnFoundDoubles = bFound
End With
Loop
I am trying to remove all the whitespace before and after all table objects in my word document.
This is the code I have so far:
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "^p^p"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With
This seems to delete some new line breaks but not all of them. After I have run this macro, when I click to Show all hidden characters it still shows some of the |P tags.
Try change
.Text = "^p^p"
to
.Text = Chr(32)
To find out which characters to replace, select your text and run the following macro.
Sub DebugAscCode()
For i = 1 To Len(Selection.Text)
Debug.Print Asc(Mid(Selection.Text, i))
Next i
End Sub
Using replace on VBA
Sub ReplaceAscCode()
Dim tmpArray As Variant
tmpArray = Array(7, 13, 32)
For j = LBound(tmpArray) To UBound(tmpArray)
Selection.Text = Replace(Selection.Text, ASC(tmpArray(j)), "")
Next j
End Sub
I've used in my work and it works perfectly this way, each character will always be represented by an ASC code
[]'s