How do i get Word to check Integrity of my text? - vba

i want to automatically check my document for certain properties:
a space before a parenthesis
look for weasel words, that is specified in a list
Unprintable characters (I set a lot of equations and then changed the type - not good)
Ideally I would like word to marker all these with a comment, so i can fix them later.
Is this testing of text possible/feasible/already existing in word?

Unfortunately, you can't run it at once as it's not possible to highlight hidden document marks if you need some. Try this two subs for different goals (read some comments inside subs, too)
Sub Searching_For_Text()
'will highlight all options added with .HitHighlight method
With ActiveDocument.Content.Find
.ClearHitHighlight
'words
.HitHighlight "Variant" 'any word this way
'any text
.HitHighlight " (" 'this for spaces before parenthesis
'partially specified text
.HitHighlight "doc" 'simply this for words like: _
document, documents
'option 2- this can't be highlighted but no error returned
.HitHighlight "^p" 'paragraph mark
.HitHighlight "^l" 'soft line mark
End With
End Sub
And for special document marks:
Sub Searching_Special_marks()
'for paragraph marks you need to search each separately
'each time you call it you will find next one, next to current selection point
With Selection.Find
'some cleaning
.ClearFormatting
'searching each separately
.Text = "^p" '^l for soft lines, _
^t for tabs, etc.
.Forward = True
.Execute
End With
End Sub
I think you need to make some experiments with these possible solutions.

Related

Finding by style and selecting next table

I've been tasked with writing VBA code to automate Word. I have no idea about VBA.
What is needed:
There is a standard Word document based on a template, which has a section for writing issues. Each section has a heading, and below the heading there is a table with a couple of rows.
Sections view
The overall document layout with the different sections.
Issue view
A standard issue, with a Heading for the issue title, then a table to be filled, and then a description.
How do I write a macro that will:
Review ALL the issues in the document to see if the issue has a list of "Affected Hosts" in the table below the heading that contains more than 10 hosts
If this is not the case, ignore and move on to the next one.
If this is the case, that list should be replaced with some generic text such as "See Appendix G", and then add to that Appendix G the issue title and below it the list of all those hosts.
Where I am at:
I looked for examples of code snippets, looked at the documentation, etc. This is all I have:
Sub TidyAffectedSystems()
'
' TidyAffectedSystems Macro
'
'
' Loop over all issues by finding the appropriate style (IssueHeading)
With ActiveDocument.Range
With .Find
.ClearFormatting
.Forward = True
.Format = True
.Style = "Issue Heading" ' Heading style to find
.Wrap = wdFindStop
.Execute
End With
Do While .Find.Found
MsgBox .Text
' If it is the last one, then finish looping over
If .End = ActiveDocument.Range.End Then Exit Do
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
End Sub
This code tries to find the headings based on the style ("Issue Heading"), and then print that heading. I'm doing this to make sure that at least I am finding the right sections, but that's it.
I don't know how to for example select the table below the current found item to then see if that table has more than 10 hosts and all that, and of course no idea how to then replace, take it to an Appendix and repeat.

Word VBA - format and re-link footnotes and endnotes in hyperlinks

I need to find footnote and endnote marks (in the body, to format them and re-link them) etc, in a macro I have written to clean up documents imported from the web.
My macro works fine, except where part of the find string is hyperlink display text and part is not.
Searching for ([a-z])([0-9]) (to locate endnote marks in the body, as they are not formatted as endnotes) does not find them because [0-9] is hyperlink display text and [a-z] is not.
My question here: how to search for [normal string] adjacent to [hyperlink display text string]?
If found, the next step is how to replace the hyperlink display text (format endnotes superscript, delete the para mark) keeping it in the hyperlink (I can work on that - maybe the subject of another question?)
You could, of course, simply convert your hyperlinks to superscripted numbers then use whatever other code you have to replace the superscripted numbers with endnotes.
Sub Demo()
Dim h As Long
With ActiveDocument
For h = .Hyperlinks.Count To 1 Step -1
With .Hyperlinks(h)
If IsNumeric(.TextToDisplay) = True Then
With .Range
If .Characters.First.Previous Like "[a-z]" Then
.Fields.Unlink
.Font.Reset
.Font.Superscript = True
End If
End With
End If
End With
Next
End With
End Sub
Depending on what you're doing, you could simply insert your endnoting code into the inner If ... End If construct in place of the font manipulations.

Word VBA: Replace the space at the end of a line if the preceding character is a digit

I've found this similar issue here, but I don't know how to make it work for what I need.
I need to replace the space (" ") at the end of a line if it's preceded by a digit ("[0-9]"). Replacement text will be a non-breaking space ("^s"). So for example, throughout my document I might have dates written in this format "24 September 2019", phone numbers, phrases like "in 8 days" etc. I need to ensure the line doesn't break between the digit and the following word, hence replacing the space with a non-breaking space.
My code is on a different PC so it's not easy for me to include it, and all I've done so far is copy the one linked above but it doesn't work because I'm not sure which parts I need to amend. So please see the link above for what I've got so far, alternatively any new code that might be more effective is of course welcome.
Thank you in advance :)
This should resolve your issue:
Sub testNBS()
Dim myRange As Range
Set myRange = ActiveDocument.Range(ActiveDocument.Range.Start, ActiveDocument.Range.Start)
myRange.Select
Selection.Expand wdLine
While Selection.End < ActiveDocument.Range.End
If Right(Selection.Text, 1) = " " And IsNumeric(Left(Selection.Words.Last, 1)) = True Then
Selection.Characters.Last = Chr(160)
End If
Selection.MoveDown wdLine, 1
Selection.Expand wdLine
Wend
End Sub
I changed Left to Right, added the check for a numeric string, and added in the addition of a non-breaking space (NBS) in place of the last character in the line, which should be a space. I added the And clause just to double-check/verify.

Word VBA - Ignore punctuation while counting/selecting X number of "Words" or "Sentences"

Does anyone know if there is a VBA statement to recognize successive adjacent characters as "words" rather than counting each and every non-alpha character (as a word) along the way?
My research indicates that most people who want to ignore punctuation and/or non-alpha characters are focused on trimming or deselecting the characters. I want to retain these characters, but I also want the non-alpha character ignored while the macro is determining how many "words" to select.
Consider the following examples of "visual" words versus "Word words":
Ms. Smith-Harris (visually 2; Word 5)
9:00 a.m. (visually 2; Word 7)
and/or (visually 1, Word 3)
I have hundreds of macros that I access easily (with mnemonic shortcuts) via a text expander, among them dozens of macros that will select and perform an action (e.g., highlight, bold, uppercase, italicize, delete, etc.) on varying amounts of text to my left or right - something I do quite often in my transcription and editing work.
So, for example, my cursor might be to the right of Ms. Smith-Harris, and perhaps I want to highlight it or make it uppercase or delete it. It's much easier and faster for my eyes to quickly assess that string of characters as 2 "words" (of adjacent text) rather than stop and perform the tedious task of counting all the disruptive non-alpha characters that Word counts as "words" when selecting text, to figure out that it's 5 "words" by Word standards.
Although the text expander itself is capable of performing all the functions I might want to do to the text directly from within the program, it's much faster and more efficient to have it instead invoke a Word macro to perform the function, especially since the macro can intelligently trim unwanted spaces from the selection
But alas, if I run, for example, the Highlight2PreviousWords macro (shown below) while my cursor is to the right of Ms. Smith-Harris, it would only highlight "-Harris."
Here are two examples of my "select X number of words" macros:
Sub h1lw_HighlightPrevious1Word()
Selection.MoveLeft Unit:=wdWord, Count:=1, Extend:=wdExtend
Dim oRng As Word.Range
Set oRng = Selection.Words(1)
Do While oRng.Characters.Last = " "
oRng.MoveEnd wdCharacter, -1
Loop
oRng.Select
Selection.Range.HighlightColorIndex = wdYellow
Selection.Collapse Direction:=wdCollapseEnd
End Sub
Sub h2lw_HighlightPrevious2Words()
'
Selection.MoveLeft Unit:=wdWord, Count:=2, Extend:=wdExtend
Dim oRng As Range
Set oRng = Selection.Range
Do While oRng.Characters.Last = " "
oRng.MoveEnd wdCharacter, -1
Loop
oRng.Select
Selection.Range.HighlightColorIndex = wdYellow
Selection.Collapse Direction:=wdCollapseEnd
End Sub
All of my "select some words and then do something" macros look the same, except for the "do something" part, of course. So all of the "select 1 word to the left and do something" macros look like the first one, and all of the "select 2+ words to the left and do something" look like the second one. I usually don't go beyond 5 words because in the time it takes to visually count beyond that, I could just manually select the text.
So the macros work great for straight-text words, but not so great when other characters are in the mix. I'd love to be able to ignore the non-alpha characters and define all strings of adjacent text as "words."
Does anyone know of a way to accomplish this?
Two tips first:
To get real information about number of words you could use something like Range.ComputeStatistics() method
To select required part of your document you can trace starting and ending characters which defines range in this way ActiveDocument.Range(startingPosition, EndingPosition)
Here is your first subroutine improved. It could be not 100% of what you need but I believe it is a good starting point (tested with Ms. Smith-Harris :) ).
Sub h1lw_HighlightPrevious1Word()
Dim curSection As Range
Dim curEnd As Long
curEnd = Selection.End
Dim newStart As Long
Do
newStart = Selection.Start
Selection.MoveLeft Unit:=WdUnits.wdWord, _
Count:=1
Set curSection = ActiveDocument.Range(Selection.Start, curEnd)
Debug.Print curSection.Text 'test
Loop While curSection.ComputeStatistics(wdStatisticWords) < 2
Set curSection = ActiveDocument.Range(newStart, curEnd)
Debug.Print curSection.Text 'test
'removing ending spaces
Do While curSection.Characters.Last = " "
Set curSection = ActiveDocument.Range(curSection.Start, curSection.End - 1)
Loop
With curSection
.HighlightColorIndex = wdYellow
ActiveDocument.Range(.End, .End).Select
End With
End Sub
Ps. I believe there is a shorter solution but I could not figure it out. I think one could use RegEx here as an alternative.

Word-Scripting: replace nonbreaking spaces with thin spaces?

I use word to open (special) html documents for printing and want to write a script to fix a small issue:
In the html file I have numbers like '15 cm' written as '15 cm', so there will be no line break between the number '15' and the unit 'cm'.
My problem is: The spacing is too wide, especially when word expands the spaces to fit a sentence to the margins.
So I'd like to replace these with some kind of thin spaces using a word VBA script. I guess I need to enumerate the paragraphs, but I'm not sure how to replace text in there. This is what I came up with so far, but I don't know how to write the html nbsp in word and what to use for thin spaces, maybe someone can help me here?
Sub MakeThinSpaces()
Dim para As Paragraph
For Each para In ActiveDocument.Paragraphs
replace the with some   here?
Next
End Sub
Thin space is Unicode 8201. (A narrow no-break space would be 8239).
It should work with this code using the selection object.
^s is the wildcard for a protected space, you could also use Chr(160)
Selection.WholeStory
With Selection.Find
.Text = "^s"
.Replacement.Text = ChrW(8201)
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
Regarding replacement in the entire text, there is an alternative solution to selecting the whole story.
E.g. following code would replace all non-breaking spaces in the document with normal spaces:
With ActiveDocument.Content.Find
.Execute "^s", replacewith:=" ", Replace:=wdReplaceAll
End With
The wildcard-match parameter, should it really be required, could be packet into the .Execute statement in the same way.