Searching words in selected area - vba

I'm trying to search specific words in the selected/highlighted text. The result should show how much the word is used throughout the highlighted selected area.
I wrote a macro, but the total value of words shown is calculated through the entire document, not the selected part.
Sub CountWords()
'macros for counting specific words in the document
'to count the number of a specified word, this word needs to be highlighted
Dim rng As Range
Dim sWord As String
Dim i As Long
Dim sWord As String
Set rng = Selection.Range
Application.ScreenUpdating = False
sWord = InputBox( _
Prompt:="What word do you want to count?", _
Title:="Count Words", Default:="")
With rng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = sWord
.Forward = True
.MatchWholeWord = True
.MatchWildcards = False
.Wrap = wdFindStop
Do While .Execute
i = i + 1
Loop
End With
Select Case i
Case 2 To 4
MsgBox "word " & Chr(171) & sWord & Chr(187) & " occurred in the document " & i & " times", _
vbInformation, "word count"
Case 1
MsgBox "word " & Chr(171) & sWord & Chr(187) & " occurred in the document " & i & " times", _
vbInformation, "word count"
Case Else
MsgBox "word " & Chr(171) & sWord & Chr(187) & " occurred in the document " & i & " times", _
vbInformation, "word count"
End Select
rng.Find.Text = ""
Application.ScreenUpdating = True
End Sub
I've tried a bunch of stuff, even other peoples codes. Every one of them counts specific words throughout the entire document.

For example:
Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range, sWord As String, i As Long
sWord = InputBox(Prompt:="What word do you want to count?", Title:="Count Words", Default:="")
With Selection
Set Rng = .Range
.Collapse wdCollapseStart
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = sWord
.Forward = True
.MatchWholeWord = True
.MatchWildcards = False
.Wrap = wdFindStop
End With
Do While .Find.Execute
If .InRange(Rng) = False Then Exit Do
i = i + 1
Loop
End With
End With
Rng.Select
MsgBox "The word " & Chr(171) & sWord & Chr(187) & " occurred " & i & " times in the selected range.", _
vbInformation, "word count"
Application.ScreenUpdating = True
End Sub

Related

Word VBA Find And Replace

I am trying to find all of the cells with a certain text of "0.118" in column 2 of my table and do a list of commands for that row
I am also trying to take the value from column 5 of that selected text found in that row and subtract the value I put in the input box for that row.
The problem I am having is that it only changes one of my found "0.118" and not all of them in each row.
And I can't figure out how to search for the column(5) of that selected row.
Any help would be greatly appreciated.
Thank you.
Sub ConvertTo_3MM()
Dim oTable As Table
Dim stT As Long, enT As Long
Dim stS As Long, enS As Long
With Selection.Find
.Forward = True
.MatchPhrase = True
.Execute FindText:="0.118"
End With
For Each oTable In ActiveDocument.Tables
Do While Selection.Find.Execute = True
stT = oTable.Range.Start
enT = oTable.Range.End
stS = Selection.Range.Start
enS = Selection.Range.End
If stS < stT Or enS > enT Then Exit Do
Selection.Collapse wdCollapseStart
If ActiveDocument.Tables.Count >= 1 Then
With ActiveDocument.Tables(1).Cell(nRow, 2).Range
.Text = "3 MM" & vbCrLf & "-" & vbCrLf & "6 MM"
End With
End If
Selection.MoveRight Unit:=wdCell
If ActiveDocument.Tables.Count >= 1 Then
With ActiveDocument.Tables(1).Cell(nRow, 3).Range
.InsertAfter Text:=vbCrLf & "-" & vbCrLf & "SHANK"
End With
End If
Selection.MoveRight Unit:=wdCell
Selection.MoveRight Unit:=wdCell
response = InputBox("Cut Length For 3 MM")
If ActiveDocument.Tables.Count >= 1 Then
With ActiveDocument.Tables(1).Cell(nRow, 5).Range
.Text = response & vbCrLf & "-" & vbCrLf & (column(5).value - response)
End With
End If
Selection.Find.Execute Replace:=wdReplaceAll
Loop
Selection.Collapse wdCollapseEnd
Next
Application.ScreenUpdating = True
End Sub
I would be very surprised if the code in your question actually does anything as it doesn't even compile.
Your code is rather a confused mess so I'm not entirely certain that I have correctly understood what you are attempting to do, but try this:
Sub ConvertTo_3MM()
Application.ScreenUpdating = False
Dim oTable As Table
Dim response As String
For Each oTable In ActiveDocument.Tables
With oTable.Range
With .Find
.Forward = True
.MatchPhrase = True
.Text = "0.118"
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found = True
.Text = "3 MM" & vbCr & "-" & vbCr & "6 MM"
With .Rows(1)
.Cells(3).Range.InsertAfter Text:=vbCr & "-" & vbCr & "SHANK"
response = Val(InputBox("Cut Length For 3 MM"))
With .Cells(5).Range
.Text = response & vbCr & "-" & vbCr & (Val(.Text) - response)
End With
End With
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Next
Application.ScreenUpdating = True
End Sub
Thi may not be a solution, but I do see some problems:
You do:
For Each oTable In ActiveDocument.Tables
Then you do inside that loop:
Do While Selection.Find.Execute = True
but this Find will not be limited to the table of the For Each loop.
Though harmless, inside this Do While loop you do:
If ActiveDocument.Tables.Count >= 1 Then
but of course this is true because the For Each already determined there is at least 1 table.
I suggest you lookup the documentation of Find, rethink the logic and then run it step by step in the debugger to see what the code is doing.
Try this code:
Sub ConvertTo_3MM()
Dim oTable As Table, rng As Range
Dim nRow As Long, response As String
For Each oTable In ActiveDocument.Tables
With oTable
Set rng = .Range
Do
If rng.Find.Execute("0.118") Then
If rng.Information(wdEndOfRangeColumnNumber) = 2 Then
nRow = rng.Information(wdEndOfRangeRowNumber)
.Cell(nRow, 2).Range.Text = "3 MM" & vbCrLf & "-" & vbCrLf & "6 MM"
.Cell(nRow, 3).Range.InsertAfter Text:=vbCrLf & "-" & vbCrLf & "SHANK"
response = Val(InputBox("Cut Length For 3 MM"))
.Cell(nRow, 5).Range.Text = response & _
vbCrLf & "-" & vbCrLf & (Val(.Cell(nRow, 5).Range.Text) - response)
End If
Else
Exit Do
End If
rng.Collapse wdCollapseEnd
Loop
End With
Next
Application.ScreenUpdating = True
End Sub
Before
After

Macro (VBA) crashing Microsoft word (Find and replace)

I using a VBA code to batch find and replace highlighted text. The macro finds and replaces the words in the document. It works well with a few number of highlighted text on a small document (1-2 pages). However, when I use this macro on a large documents which has over a 100 pages, Microsoft word crashed and becomes unresponsive so I have to forced to quit.
The code is to help make it easy to redact information. I am replacing the highlight text which occur also in tables with XXXXX and highlighted black.
Does anyone have any tips to make the code more efficient?
Here is the code
Sub FindandReplaceHighlight()
Dim strFindColor As String
Dim strReplaceColor As String
Dim strText As String
Dim objDoc As Document
Dim objRange As Range
Application.ScreenUpdating = False
Set objDoc = ActiveDocument
strFindColor = InputBox("Specify a color (enter the value):", "Specify Highlight Color")
strReplaceColor = InputBox("Specify a new color (enter the value):", "New Highlight Color")
strText = InputBox("Specify a new text (enter the value):", "New Text")
With Selection
.HomeKey Unit:=wdStory
With Selection.Find
.Highlight = True
Do While .Execute
If Selection.Range.HighlightColorIndex = strFindColor Then
Set objRange = Selection.Range
objRange.HighlightColorIndex = strReplaceColor
objRange.Text = strText
objRange.Font.ColorIndex = wdBlack
Selection.Collapse wdCollapseEnd
End If
Loop
End With
End With
Application.ScreenUpdating = True
End Sub
Try:
Sub FindandReplaceHighlight()
Application.ScreenUpdating = False
Dim ClrFnd As Long, ClrRep As Long, strTxt As String
Const StrColors As String = vbCr & _
" 1 Black" & vbCr & _
" 2 Blue" & vbCr & _
" 3 Turquoise" & vbCr & _
" 4 Bright Green" & vbCr & _
" 5 Pink" & vbCr & _
" 6 Red" & vbCr & _
" 7 Yellow" & vbCr & _
" 8 White" & vbCr & _
" 9 Dark Blue" & vbCr & _
"10 Teal" & vbCr & _
"11 Green" & vbCr & _
"12 Violet" & vbCr & _
"13 Dark Red" & vbCr & _
"14 Dark Yellow" & vbCr & _
"15 Gray 50" & vbCr & _
"16 Gray 25%"
ClrFnd = InputBox("Specify the old color (enter the value):" & StrColors, "Specify Highlight Color")
ClrRep = InputBox("Specify the new color (enter the value):" & StrColors, "New Highlight Color")
strTxt = InputBox("Specify the new text (enter the value):", "New Text")
With ActiveDocument
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Highlight = True
.Forward = True
.Wrap = wdFindStop
End With
Do While .Find.Execute
If .HighlightColorIndex = ClrFnd Then
.HighlightColorIndex = ClrRep
.Text = strTxt
.Font.ColorIndex = wdBlack
.Collapse wdCollapseEnd
End If
Loop
End With
End With
Application.ScreenUpdating = True
End Sub

VBA font and bolding text?

I'm trying to make the "number of occurrences" either be written in red or in bolded red. Can someone please point me in the right direction. I'm new to coding. This is a word-counter, and when 2+ words are found...it displays the number of words found at the bottom of the word document.
Sub a3()
Dim Word As String
Dim wcount As Integer
Word = InputBox("Search for a word")
If (Word <= "") Then
MsgBox ("Did not enter word")
End If
If (Word > "") Then
wcount = 0
With Selection
.HomeKey Unit:=wdStory
With ActiveDocument.Content.Find
.Text = Word
Do While .Execute
wcount = wcount + 1
Selection.MoveRight
Loop
End With
MsgBox ("The word: '" & Word & "' shows up " & wcount & " times in the document")
End With
End If
If (wcount <= 2) Then
ActiveDocument.Content.InsertAfter Text:=(vbCrLf & "Number occurrences: " & wcount)
Selection.Font.ColorIndex = wdRed
ElseIf (wcount <= 3) Then
ActiveDocument.Content.InsertAfter Text:=(vbCrLf & "Number occurrences: " & wcount)
Selection.Font.ColorIndex = wdRed
Selection.Font.Bold = True
Else
ActiveDocument.Content.InsertAfter Text:=(vbCrLf & "Number occurrences: " & wcount)
Selection.Font.ColorIndex = wdBlack
Selection.Font.Bold = False
End If
End Sub
Working with Word Range objects will help with this. Think of a Range like an invisible selection, except that code can work with multiple Range objects, while there can be only one Selection.
Assign the document's content to a Range, then perform the Find and extension on that. Then the formatting can also be applied to the Range. I've altered (but not tested) the code in the question to demonstrate.
In the last part, where text is written at the end of the document, the Range object is set to the entire document, then collapsed (think of it like pressing the right-arrow key with a selection). Then the new text is assigned to the range and formatting applied. Because the range will contain only the new text, the formatting is applied to that, only.
(Additional notes: I've changed the Word variable name to sWord because "Word" could be misunderstood to mean the Word application. I've also changed the comparison to check whether sWord contains something to Len(sWord) > 0 because the "greater than """ comparison is not guaranteed.)
Sub a3()
Dim sWord As String
Dim wcount As Integer
Dim rng as Word.Range
Set rng = ActiveDocument.Content
sWord = InputBox("Search for a word")
If (sWord <= "") Then
MsgBox ("Did not enter word")
End If
If (Len(sWord) > 0) Then
wcount = 0
With Selection
.HomeKey Unit:=wdStory
With rng.Find
.Text = sWord
Do While .Execute
wcount = wcount + 1
rng.Collapse wdCollapseEnd
Loop
End With
MsgBox ("The word: '" & sWord & "' shows up " & wcount & " times in the document")
End With
End If
Set rng = ActiveDocument.Content
rng.Collapse wdCollapseEnd
If (wcount <= 2) Then
rng.Text = (vbCrLf & "Number occurrences: " & wcount)
rng.Font.ColorIndex = wdRed
ElseIf (wcount <= 3) Then
rng.Text = (vbCrLf & "Number occurrences: " & wcount)
rng.Font.ColorIndex = wdRed
rng.Font.Bold = True
Else
rng.Text = (vbCrLf & "Number occurrences: " & wcount)
rng.Font.ColorIndex = wdBlack
rng.Font.Bold = False
End If
End Sub
There are many ways to do this, some of them are based on a preference for ranges or selections and also the structure of the Find statement. Here is my preference.
Sub a3()
Dim wrd As String
Dim wcount As Integer
Dim rng As Word.Range
wrd = InputBox("Search for a word")
If wrd = vbNullString Then
MsgBox ("Did not enter word")
Exit Sub
End If
Set rng = ActiveDocument.Content
wcount = 0
With rng.Find
.ClearFormatting
.Format = False
.Forward = True
.MatchWholeWord = True
.Text = wrd
.Wrap = wdFindStop
.Execute
Do While .found
wcount = wcount + 1
rng.Collapse Word.WdCollapseDirection.wdCollapseEnd
.Execute
Loop
End With
MsgBox ("The word: " & "" & wrd & "" & " shows up " & wcount & " times in the document")
ActiveDocument.Content.InsertParagraphAfter
Set rng = ActiveDocument.Content
rng.Collapse Word.WdCollapseDirection.wdCollapseEnd
rng.Text = "Number occurrences: " & wcount
If wcount < 3 Then
rng.Font.ColorIndex = wdRed
ElseIf wcount < 4 Then
rng.Font.ColorIndex = wdRed
rng.Font.Bold = True
Else
rng.Font.ColorIndex = wdAuto
rng.Font.Bold = False
End If
End Sub

Word Macro to Count Words in Quotation Marks

I am writing my essays for university and I am not allowed to include words used in quotes toward my total word count. As Word does not have a feature to do this i was hoping that someone would be able to help me by creating a macro. I have used macros before, but I have very, very little experience into something as complex as this (if it's even that complex).
I already have something similar to work with citations throughout a document and so having both of these will be a great help. I will copy this code below so you can get a rough idea of what I need, except with quotes instead of citations.
So I was wondering if someone would be able to produce a macro that counted the number of words used in quotes throughout a document?
Sub CitationWordCount()
Dim Fld As Field, l As Long, StrTmp As String
For Each Fld In ActiveDocument.Fields
With Fld
If .Type = wdFieldCitation Then
StrTmp = .Result
l = l + UBound(Split(StrTmp, " ")) + UBound(Split(StrTmp, "-")) + 1
StrTmp = .Code.Text
l = l + Len(StrTmp) - Len(Replace(StrTmp, "\n", "\"))
End If
End With
Next
MsgBox "There are " & l & " words in citations in this document.", , "Citation Word Count"
End Sub
Paul Edstein (macropod) wrote a solution to this issue months ago on http://www.msofficeforums.com/word-vba/33866-count-words-between-quotation-marks.html
Sub Demo()
Application.ScreenUpdating = False
Dim i As Long, j As Long
With ActiveDocument
j = .ComputeStatistics(wdStatisticWords)
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[“" & Chr(34) & "]*[" & Chr(34) & "”]"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
i = i + .ComputeStatistics(wdStatisticWords)
.Collapse wdCollapseEnd
.Find.Execute
Loop
MsgBox "This document contains " & j & " words ," & vbCr & _
"of which " & i & " (" & Format(i * 100 / j, "0.00") & _
"%) are in quotes."
End With
End With
Application.ScreenUpdating = True
End Sub
This will give you your total word count and the total amount of words in quotation marks. To get your total number, just subtract the words in quotes from the total words.

Insert bold text into Word using VBA

I wrote a little script that exports certain Excel cell values into Word. However, certain inserts need to be bold. And there doesn't seem to be an easy way to do this.
This code loops through the records and adds them to the Word document
Do While intRow < intTotalRows + 1
strTemp = " ;b;" & Range("G" & intRow).FormulaR1C1 & " " & Range("I" & intRow).FormulaR1C1 & ";e; "
If strTemp <> strCur Then
strCur = strTemp
.Content.Font.Bold = True
.Content.InsertAfter strCur
End If
.Content.Font.Bold = False
.Content.InsertAfter Range("A" & intRow).FormulaR1C1 & " - " & Range("C" & intRow).FormulaR1C1 & " " & Range("E" & intRow).FormulaR1C1 & " * "
intRow = intRow + 1
Loop
Turning on bold before inserting text and turning it off again afterwards seems like the most logical solution, so it does not work.
I then tried to find and replace the text, but that also did not work:
.Content.Find.ClearFormatting
With .Content.Find
.Text = ";b;" 'Look for
.Replacement.Text = ";bbb;" 'Replace with
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
.Content.Find.Execute Replace:=wdReplaceAll
Replace .InsertAfter with .TypeText. Inserting works like pasting whereas TypeText works like if you would actually type the text on the keyboard.