How do I convert this Excel macro for use in Word? - excel

I have found a macro written for Excel that has the exact function that I need but I don't know how to convert it for use in Word - I'm fairly new to scripting and the only language/syntax that I'm familiar with is the Aspect scripting language that I've been learning from working with Procomm Plus. I found the Excel macro here:
Find specific text and delete three rows above it
Sub Delete()
Dim find As String: find = "TOT"
Dim rng As Range
Set rng = Sheets("Sheet1").Cells.find(What:=find, After:=Sheets("Sheet1").Cells(1, 1), LookIn:=xlValues, Lookat:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=True)
If Not rng Is Nothing Then
rng.EntireRow.Delete
rng.Offset(-1).EntireRow.Delete
rng.Offset(-2).EntireRow.Delete
rng.Offset(-3).EntireRow.Delete
End If
End Sub
I need the macro to look for the the text "% Invalid input detected at ‘^’ marker" and then delete it, as well as the two lines above that phrase:
Router#show environment all ;(let's call this "line -2")
^ ;(and this would be "line -1")
% Invalid input detected at ‘^’ marker ;(and "line 0")
This is the console output from a Cisco router (copy/pasted to Word) and the phrase "% Invalid input detected at ‘^’ marker" is always the same but the two lines above it can vary, depending on what Cisco command I have used that has not been recognised.
I think the solution is probably quite simple but I'm stuck!
I found another macro for Word that performs a similar function and - it looks for a key phrase and deletes the line containing that phrase but again, I'm not sure how to extend it to include the preceding two lines of text:
Sub InvalidInput()
Dim oRng As Word.Range
Set oRng = ActiveDocument.Range
With oRng.Find
.Text = "Invalid input detected"
While .Execute
oRng.Paragraphs(1).Range.Delete
Wend
End With
End Sub
Would anyone be able to suggest some edits that could solve my problem? Thank you very much in advance.

Assuming your 'lines' are separate paragraphs, try:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[!^13]#^13[!^13]#^13% Invalid input detected at ‘^94’ marker^13"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute Replace:=wdReplaceAll
End With
End With
Application.ScreenUpdating = True
End Sub
Otherwise, you'll have to provide a more meaningful description of what delineates your 'lines'.

This is a longshot but have a go at this macro in Word ...
Public Sub RemoveUnwantedParagraphs()
Dim objParagraph As Paragraph, arrToRemove() As Long, lngIndex As Long
Dim i As Long, x As Long, strSearchFor As String
strSearchFor = "% Invalid input detected at '^' marker"
lngIndex = -1
For i = 1 To ThisDocument.Paragraphs.Count
Set objParagraph = ThisDocument.Paragraphs(i)
If Left(objParagraph.Range.Text, Len(strSearchFor)) = strSearchFor Then
For x = 2 To 0 Step -1
lngIndex = lngIndex + 1
ReDim Preserve arrToRemove(lngIndex)
arrToRemove(lngIndex) = i - x
Next
End If
Next
On Error GoTo ExitGracefully
For i = UBound(arrToRemove) To 0 Step -1
ThisDocument.Paragraphs(arrToRemove(i)).Range.Delete
Next
ExitGracefully:
End Sub
... do yourself one favour though before you run it, BACKUP YOUR DOCUMENT!!!.
I make no guarantees that it won't inadvertently stuff up the entire thing. I've done limited development in Word but that code above did work for me.
The only thing to note is that if the text you're searching for is contained in the 1st or 2nd row, it may break. I figure that's not expected though so didn't cater for it.

Related

Find and replace, excel macro that opens word document

I am trying to make a macro to open a word document and make track changes in accordance with column A and B.
I got this to work, but only if the document that is opened in the track changes mode "Simple Markup".
If it is in any other mode, and I have the following search sentences.
A1: al anden personer B1: alle andre mennesker
A2: anden personer B2: andre mennesker
And the text in the word document is "al anden personer".
The text will be "alle andre menneskerandre mennesker" in other world it will search in the track changes.
Therefore, I am trying to make the Word document always open in simple markup. I have tried using iteration of
ActiveWindow.View.RevisionsFilter.Markup = wdRevisionsMarkupSimple
but could not get it to work.
Hope you can help.
PS: I am fairly new to VBA so if you have any other improvement or hint the I'm all ears.
My code right now is:
Option Explicit
Const wdReplaceAll = 2
Sub FindReplace()
Dim wordApp As Object
Dim wordDoc As Object
Dim myStoryRange As Object
Dim cell As Range
Dim Find1 As String
Dim Replace1 As String
Const wdRevisionsMarkupSimple As Integer = 1
'Dim oRevision As Revision
If Not FileIsOpen("H:\Til excel replace test ark" & ".docx") Then
Set wordApp = CreateObject("Word.Application")
wordApp.Visible = True
Set wordDoc = wordApp.Documents.Open("H:\Til excel replace test ark.docx")
wordDoc.trackrevisions = True
'ActiveWindow.View.RevisionsFilter.Markup = wdRevisionsMarkupSimple cannot get it to work
Else
On Error GoTo ExitSub
End If
With Worksheets("sheet1")
For Each cell In Range("A2:A" & .Cells(.Rows.Count, "A").End(xlUp).Row)
Find1 = cell.Value
Replace1 = cell.Offset(0, 1).Value
For Each myStoryRange In wordDoc.StoryRanges
With myStoryRange.Find
.MatchCase = True
.matchwholeword = True
.Text = Find1
.Forward = True
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Replacement.Text = Replace1
.Execute Replace:=wdReplaceAll
End With
Next myStoryRange
Next cell
End With
Exit Sub
ExitSub:
MsgBox "Luk word document før du benytter denne macro"
End Sub
Public Function FileIsOpen(FullFilePath As String) As Boolean
Dim ff As Long
On Error Resume Next
ff = FreeFile()
Open FullFilePath For Input Lock Read As #ff
Close ff
FileIsOpen = (Err.Number <> 0)
On Error GoTo 0
End Function
Your issue is a result of your use of late binding.
When using late binding you cannot use the enums or constants from the Word object library, e.g. wdRevisionsMarkupSimple, as Excel doesn't know what those represent. You either have to declare those constants yourself or use their underlying values.
So to activate revisions with simple markup your code needs to be:
ActiveWindow.View.RevisionsFilter.Markup = 1 'wdRevisionsMarkupSimple
EDIT: I also missed something else obvious - Excel also has ActiveWindow in its object model. When writing code across applications you need to be absolutely scrupulous in specifying which application/object the line of code refers to. In this case it should be:
WordApp.ActiveWindow.View.RevisionsFilter.Markup = 1 'wdRevisionsMarkupSimple
You can avoid these errors by adding Option Explicit at the top of the code module. This will prevent your code from compiling when you have undeclared variables. To add this automatically open the VBE and go to Tools | Options. In the Options dialog ensure that Require Variable Declaration is checked.

Extract text between two words within a Larger Query

Thank you for taking the time to read my request. I have tried using a few answers on this site and I am not getting what I want. (I tried this: Word VBA how to select text between two substrings and assign to variable?)
I am trying to select a number that is ALWAYS between the two same words. It is between "Account No.:" and "IMPORTANT" (yes in all caps, unsure if caps/ no-caps matters for denoting it).
I am creating a macro where I open a word document with say 200 pages. I want to open and save EACH PAGE as it's own pdf with a specific name. I have gotten the code to run where I open and save as PDF. What I want to do, is with in that code, have something that finds the text between "Account No.:" and "IMPORTANT", selects it and copies it. This text is an account number.
Then, when I go to save the file, I want it to paste the account number as the file name. Or have a reference that when it finds the account number it assigns it to a variable. I am new to VBA, so if you can please be descriptive, and put instructions in laymans terms. THANK YOU!
My macro:
Sub CutePDFWriter()
Dim FName, FPath, username, LoanNo As String
Dim wordapp As Word.Application
Dim wordDoc As Word.Document
Dim i As Integer
Dim rngParagraphs As Range
'open doc and export as a pdf
Set wordapp = CreateObject("word.Application")
Set wordDoc = wordapp.Documents.Open("G:\test.doc")
For i = 1 To wordDoc.BuiltinDocumentProperties("Number of Pages")
**Here is where I want to add the “Find and Select” code**
'set variable strings
FPath = "G:\Excel Doc Tests\"
FName = "___**Here is where I want the acct nbr to go_______"** & i & ""
wordDoc.ExportAsFixedFormat FPath & FName & "-escrtax", ExportFormat:=wdExportFormatPDF, Range:=wdExportFromTo, From:=i, To:=i
Next i
'empty word doc objects
wordDoc.Close (False)
wordapp.Quit
End Sub
I added a comment to the question at that link which makes his code work. But I spent time on this: (tested with "blah blah Account No.:123-456IMPORTANT blah blah"):
Option Explicit
Sub Sub1()
Dim i&, FName$ ' I presume
Dim i1&, i2&, s1$, rngDoc As Range
Selection.HomeKey wdStory ' ?
i1 = getPoint("Account No.:", 1) ' get start
i2 = getPoint("IMPORTANT", 2) ' get end
Set rngDoc = ActiveDocument.Range(i1, i2)
s1 = rngDoc.Text
FName = "Prefix" & s1 & "Postfix" & Str$(i)
Stop ' and hover over FName
End Sub
Function getPoint&(sText$, iStart&) ' 1 for start, 2 for end
With Selection.Find
.Text = sText
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = True
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.Execute
End With
If iStart = 1 Then
getPoint = Selection.End
Else
getPoint = Selection.Start
End If
End Function

VBA search for string in document and check its color

I tried to make a function to search for a string in a document and check what is the first char in the string that is colored in red.
for example I know that my document contains the string "bread water juice peach wine". Imagine that the bold text is red colored. I want the function to return the int 19 (first red char - p).
Function check(stringToCheck As String) As Integer
Dim oRng As Word.Range
Set oRng = ActiveDocument.Content
With oRng.Find
' to ensure that unwanted formats aren't included as criteria
.ClearFormatting
'You don't care what the text is
.Text = stringToCheck
'Loop for each match and set a color
While .Execute
MsgBox (oRng.Text)
For i = 1 To 40
'take the Nth char of the string an check if it's red
'the following msgBox is working
MsgBox (Mid(oRng, i, 1))
If Mid(Orng, i, 1).Font.Color = wdColorRed Then
'the following msgBox is not working which means the error is in the last line.
MsgBox ("made it")
check = i
Exit Function
End If
Next i
Wend
End With
End Function
every time I try to call the function I have the error "run time error 424 - object required".
I added some msgboxes to see when is the function interrupted and added a comment in that place.
what is the problem? how can I fix it?
First thing's first: Use Option Explicit at the beginning of your module. You'll quickly find that your code has compilation issues.
Do you mean to use oRng or myRange? This should be consistent.
Once you've done that...
Mid(myRange, i, 1) returns a string, not an object.
You may want to use If oRng.Characters(1).Font.Color = wdColorRed Then instead.
Here's your code modified that returns correctly:
Function check(stringToCheck As String) As Integer
Dim oRng As Word.Range
Set oRng = ActiveDocument.Content
Dim i As Integer
With oRng.Find
' to ensure that unwanted formats aren't included as criteria
.ClearFormatting
'You don't care what the text is
.Text = stringToCheck
'Loop for each match and set a color
While .Execute
MsgBox (oRng.Text)
For i = 1 To 40
'take the Nth char of the string an check if it's red
'the following msgBox is working
MsgBox oRng.Characters(i)
If oRng.Characters(i).Font.Color = wdColorRed Then
'the following msgBox is not working which means the error is in the last line.
MsgBox ("made it")
check = i
Exit Function
End If
Next i
Wend
End With
End Function

Excel VBA Macro Find and Format

I am trying to create a macro that can find a particular string in a header, then format the cells in that column. For an example, I have a header called "Purchase Date", "Cap Date", and "Exp Date". I want to be able to find the first instance of "Date" used, format them as text, then find the next occurance and format, etc.
I have created one that will find only the first instance, then not look for any further. Any idea? I have looked up "Find" and "After", but cannot get them to function correctly.
Thanks for any help.
I also struggled moving past the first find. ook at the last part fo the code below from Do While. Maybe you can work something from it.
Sub HyperLinking()
Call HyperLink("Text TO Hyperlink", "C:\Document.docx")
End Sub
Private Function HyperLink(LinkName As String, LinkAddress As String)
Dim WDApp As Object, wd As Object, rn As Long
On Error Resume Next
Set WDApp = GetObject(, "Word.Application")
If Err.Number <> 0 Then
Set WDApp = CreateObject("Word.Application")
End If
On Error Goto 0
Set wd = WDApp.Documents.Open(LinkAddress)
WDApp.Visible = True
Set objWdRange = wd.Content
objWdRange.Find.ClearFormatting
With objWdRange.Find
.Text = LinkName
.Forward = True
.Wrap = wdFindContinue
End With
Do While objWdRange.Find.Execute = True
objWdRange.Hyperlinks.Add Anchor:=objWdRange, Address:=LinkAddress, SubAddress:="", ScreenTip:="Linked Document", TextToDisplay:=LinkName
objWdRange.Find.Execute
Loop
wd.Save
wd.Close
Set wd = Nothing
Set WDApp = Nothing
End Function
One problem is that sometimes, I guess due to formatting, all the words are not found. Maybe someone can help with why this happens?
You can adapt this code to your requirements.
It's not particularly elegant, but this will most likely do the trick for you. Just edit some of the hardcoded values like sheetname and make sure that you don't have more than 99 columns or 999 rows.
Public Sub FormatRowsInDateColumns()
Dim header As String
Worksheets("Sheet1").Activate
'loop through columns
For col = 1 To 99
'check if header cell contains word date
header = Cells(1, col).Value
If InStr(1, header, "date", vbTextCompare) <> 0 Then
'convert cell values to string
For Row = 1 To 999
'Formats value and perserves as text with an apostrophe
Cells(Row, col).Value = "'" & Format(Cells(Row, col).Value, "yyyy/mm/dd")
Next Row
'set column format as text
Columns(col).NumberFormat = "#"
End If
Next col
End Sub

VBA Excel - Word Wrap

I'm creating a small piece of VBA code with a specific formula, however it has a couple of if statements, one of which originates a double-line string (with vbNewLine)
The issue is that I can't see the text.
So I wanted to word wrap it, but each time I set the ActiveCell.WrapText = True, nothing happens.
I checked with a message box. I set the WrapText to True, I return the property value with the MessageBox to confirm, and it's still False.
I've been told to use ActiveCell.Rows.AutoFit as well, but AutoFit does nothing if the text isn't wrapped.
Any idea what I might be doing wrong here?
try:
Sub WrapandFit()
ActiveCell.WrapText = True
ActiveCell.EntireRow.AutoFit
End Sub
It worked for me. Make sure that your screenupdating is also set to true.
For me, the code below worked. (only set to change header row, (change range))
ActiveSheet.Range("A1:R1").Select
With Selection
.WrapText = True
End With
UDFs (procedures that use the keyword Function) only return values. They cannot change other parts of the Excel object model, like cell formatting. Only Subroutines (procedures that use the keyword Sub) can do that.
You need to have your cells formatted properly before you enter your UDF. Or you could use a worksheet change event sub to format them after the fact.
Turn off/On word wrap for whole sheet row can be done by VB code shown below:
If the first row is set true, excel inherits that property for whole sheet, unless you specifically turned it off using another code.
MyWorkSheet.Rows.WrapText = True
To turn off wrapping property of a specific row:
MyWorkSheet.Rows(8).WrapText = False
I suspect that you are trying to wrap text in merged cells. If yes, you cannot simply call:
MyWorkSheet.Rows.WrapText = True
Instead, you have to simulate the wrapping operations. I found the code from http://blog.contextures.com/archives/2012/06/07/autofit-merged-cell-row-height/ helped me last year.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim MergeWidth As Single
Dim cM As Range
Dim AutoFitRng As Range
Dim CWidth As Double
Dim NewRowHt As Double
Dim str01 As String
str01 = "OrderNote"
If Not Intersect(Target, Range(str01)) Is Nothing Then
Application.ScreenUpdating = False
On Error Resume Next
Set AutoFitRng = Range(Range(str01).MergeArea.Address)
With AutoFitRng
.MergeCells = False
CWidth = .Cells(1).ColumnWidth
MergeWidth = 0
For Each cM In AutoFitRng
cM.WrapText = True
MergeWidth = cM.ColumnWidth + MergeWidth
Next
'small adjustment to temporary width
MergeWidth = MergeWidth + AutoFitRng.Cells.Count * 0.66
.Cells(1).ColumnWidth = MergeWidth
.EntireRow.AutoFit
NewRowHt = .RowHeight
.Cells(1).ColumnWidth = CWidth
.MergeCells = True
.RowHeight = NewRowHt
End With
Application.ScreenUpdating = True
End If
End Sub
This may not be exactly what the OP had in mind but I figured I'd share my VBA Word Wrap function since I couldn't find anything on the web to do what I wanted.
This function insert CR+LF's into the string in order to wrap it, so the word wrap is maintained if the text is copied to another application, text-based or otherwise.
Function wrapText(strIn As String, Optional maxLen As Long = 110) As String
Dim p As Long: wrapText = strIn
Do
p = InStrRev(wrapText, " ", p + maxLen) - 1
wrapText = Left(wrapText,p) & vbCrLf & Right(wrapText, Len(wrapText)-p-1)
Debug.Print Mid(Replace(wrapText, vbCrLf, "||"), p - 20)
'Stop
Loop While p + maxLen < Len(wrapText)
End Function
It defaults to maximum width of 115 characters but can optionally be changed to anything. It only breaks on spaces (the last one that appears on/before position #115), and it only inserts CR + LF's (with the constant vbCrLf), but they can be adapted as required.
As an example of application, I was building complex SQL queries in Excel and wanted to copy the SQL over to the server app neat & tidy, instead of one giant line.

Resources