Word Macro To Delete Pages With Specific Text - string

I'm trying to delete any page that contains a specific text such as the sentence below (strSearch =). But I get a 5904 Error when I try running my macro... Any clue?
Sub DeletePages()
Dim strSearch As String
Dim rgeStart As Range
Set rgeStart = Selection.Range
strSearch = "Report the content of the ""StatusBar"" status bar message to the results."
With ActiveDocument.Range.Find
.Text = strSearch
Do While .Execute
With .Parent
.Select With Selection
.Bookmarks("\Page").Range.Delete
End With
End With
Loop
End With
rgeStart.Select
Application.Browser.Target = wdBrowsePage
End Sub

I get a syntax error on .Select With Selection, and there is no intellisense with this line...it seems that objects are not able to access properties and methods because with statements are embedded in one another.
The following worked for me...I had to delete the last page differently
Sub DeletePages()
'source1 http://stackoverflow.com/questions/13465709/repeating-microsoft-word-vba-until-no-search-results-found
'source2 https://msdn.microsoft.com/en-us/library/bb208876(v=office.12).aspx
Dim strSearch As String
strSearch = "GoodBye"
With Selection.Find
.Forward = True
.Wrap = wdFindStop
.Text = strSearch
.Execute
End With
Do While Selection.Find.Found = True And iCount < 1000
iCount = iCount + 1
Selection.HomeKey Unit:=wdStory
Selection.Find.Execute
If Selection.Find.Found Then
'Get Current page
CurPage = Selection.Information(wdActiveEndAdjustedPageNumber)
'Check if current page is the last page
If CurPage = FindLastPage Then
ActiveDocument.Range(Selection.Start, ActiveDocument.Range.End).Delete
Else
ActiveDocument.Bookmarks("\Page").Range.Delete
End If
End If
Loop
End Sub
Function FindLastPage()
'Source https://support.microsoft.com/en-us/kb/293861
'Iterate each section in the document to retrieve the end page of the
'document and compute the page count in that section. The results are
'displayed in the Immediate window.
Dim oSec As Object
Dim nStartPg As Integer, nEndPg As Integer, nSecPages As Integer
Dim NumSections As Integer
NumSections = ActiveDocument.Sections.Count
nStartPg = 1
For Each oSec In ActiveDocument.Sections
nEndPg = oSec.Range.Information(3) - 1 'wdActiveEndPageNumber=3
'Account for the last page.
If oSec.Index = NumSections Then nEndPg = nEndPg + 1
nSecPages = nEndPg - nStartPg + 1
FindLastPage = nSecPages
Next
End Function

Related

Find and copy numbered paragraphs into individual cells in Excel

I want to copy numbered paragraphs from Word to Excel.
I want to copy below paragraphs into individual cells in Excel
heading
this is paragraph
heading 2
this is paragraph
heading 3
this is paragraph
this is itself a paragraph
I am able to count the number of numbered items via below function but stuck in copy and break till another numbered item.
count_observations = ActiveDocument.Content.ListFormat.CountNumberedItems(Level:=1)
Thanks, I finaly figured it out by researching and searching the other posts. here's the below solution i've come up with.
Sub AutoDatabase()
excel_path = "D:/test.xlm"
Dim obs_range1 As Word.Range
Dim obs_range2 As Word.Range
Dim response_range1 As Word.Range
Dim response_range2 As Word.Range
Dim obs As String
Dim response As String
Dim Z As Integer
Set obs_range1 = ActiveDocument.Range
Set obs_range2 = ActiveDocument.Range
Set response_range1 = ActiveDocument.Range
Set response_range2 = ActiveDocument.Range
x = ActiveDocument.Content.ListFormat _
.CountNumberedItems(Level:=1)
For y = 1 To x
If obs_range1.Find.Execute(FindText:="CopyThis") Then
Set obs_range2 = ActiveDocument.Range(obs_range1.End, ActiveDocument.Range.End)
If obs_range2.Find.Execute(FindText:="CopyThis") Then
obs = ActiveDocument.Range(obs_range1.End, obs_range2.Start).Text
If response_range1.Find.Execute(FindText:="Branch Comments") Then
Set response_range2 = ActiveDocument.Range(response_range1.End, ActiveDocument.Range.End)
If response_range2.Find.Execute(FindText:="CopyThis") Then
response = ActiveDocument.Range(response_range1.End, response_range2.Start).Text
'MsgBox (response)
With ActiveDocument.Tables(1).Rows.Add
With ActiveDocument.Tables(1).Cell(y, 1).Range
.Text = obs
End With
With ActiveDocument.Tables(1).Cell(y, 2).Range
.Text = response
End With
End With
End If
End If
End If
End If
'MsgBox (obs)
Next y
' Remove ^p from table(1)
With ActiveDocument.Tables(1).Range
.Find.Execute FindText:="^p", ReplaceWith:="", Replace:=wdReplaceAll
End With
End Sub

MSWord how to unlink/break first link to excel document, without breaking remaining set of hyperlinks

I want to set up a word template, which has a linked excel table via a field with following code:
{LINK Excel.SheetMacroEnabled.12 D:\calendar.xlsm calendar!namedR \f 4 \h \* MERGEFORMAT}
The table resides in excel and is updated daily. The excel has several columns and one of them has a set of hyperlinks to various websites in rows. When I try to break the link to the table, in order to create rest of the document and archive it via the following code, I always get all of the links (including hyperlinks to websites) in the linked table broken.
The funny thing is that when I do it manually and select the table in Word it breaks only the link to the excel table, leaving the hyperlinks in a table column intact. This is the desired programmatic outcome. I tried 2 following macros and none of them works. Is there a way to achieve it via VBA without breaking all the links in a linked table?
Sub ConvertTableLink()
Dim myField As Field
For Each myField In ActiveDocument.Fields
If myField.Type = wdFieldLink Then
myField.Unlink
End If
Next
End Sub
Sub ConvertTableLinkTake2()
ActiveDocument.Fields(1).Update
ActiveDocument.Fields(1).Unlink
End Sub
It's not obvious why your links are remaining when you unlink the LINK field manually but not with VBA. Generally speaking, I see the same behavior whichever way I do it here - the links remain blue so they still look like links, but they aren't.
You can do your own "unlink" that should preserve the hyperlinks using this, assuming the LINK is the first LINK field in the document:
Sub replaceLinkByResult1()
Dim fld As Word.Field
Dim rng As Word.Range
For Each fld In ActiveDocument.Fields
If fld.Type = wdFieldLink Then
Set rng = fld.Result.Tables(1).Range
rng.Copy
fld.Delete
rng.Paste
Exit For
End If
Next
End Sub
If Copy/Paste doesn't work or you prefer to avoid it, the following should also work:
Sub replaceLinkByResult2()
Dim fld As Word.Field
Dim rng1 As Word.Range
Dim rng2 As Word.Range
For Each fld In ActiveDocument.Fields
If fld.Type = wdFieldLink Then
Set rng1 = fld.Result.Tables(1).Range
Set rng2 = rng1.Duplicate
rng2.Collapse wdCollapseEnd
rng2.Start = rng2.Start + 1
rng2.InsertParagraph
rng2.Start = rng2.Start + 1
rng2.FormattedText = rng1.FormattedText
fld.Delete
Set rng2 = Nothing
Set rng1 = Nothing
Exit For
End If
Next
End Sub
For example, assuming the linked object is the first field in the document:
Sub Demo()
Dim Rng As Range, Hlnk As Hyperlink, i As Long
Dim StrDisp As String, StrLink As String, StrFont As String, StrSize As String
With ActiveDocument.Fields(1)
Set Rng = .Result
With Rng
For Each Hlnk In .Hyperlinks
StrDisp = StrDisp & "|" & Hlnk.TextToDisplay
StrLink = StrLink & "|" & Hlnk.Address
StrFont = StrFont & "|" & Hlnk.Range.Font.Name
StrSize = StrSize & "|" & Hlnk.Range.Font.Size
Next
End With
.Unlink
With Rng
For i = 1 To UBound(Split(StrDisp, "|"))
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Format = False
.Text = Split(StrDisp, "|")(i)
.Replacement.Text = ""
.Wrap = wdFindStop
.Execute
End With
Set Hlnk = .Hyperlinks.Add(Anchor:=.Duplicate, Address:=Split(StrLink, "|")(i), TextToDisplay:=Split(StrDisp, "|")(i))
Hlnk.Range.Font.Name = Split(StrFont, "|")(i)
Hlnk.Range.Font.Size = Split(StrSize, "|")(i)
Next
End With
End With
End Sub

How to finda text and get the page no. for acrobat using vba

I want to find the text and get the page number of text found in acrobat using VBA, I am able to find the text but not able to get the page number. for that
Sub Main()
Dim acrApp, acrAVDoc
Set acrApp = CreateObject("AcroExch.app")
Set acrAVDoc = CreateObject("AcroExch.AVDoc")
acrApp.Show
If acrAVDoc.Open("FileName", "") Then
Ok = acrAVDoc.FindText("Text to search", 0, 1, 1)
MsgBox (Ok)
End If
Set acrAVDoc = Nothing
Set acrApp = Nothing
End Sub
I am not able to set the object for
Set acrPDDoc = CreateObject("Acrobat.AV_PAGE_VIEW")
I know this is an old question, but it was one of the top search results when I was looking for the same info. I never found anything that truly met my needs so I made something up by combining several different resources.
The function below is acceptably fast, even on very large documents. It searches page by page, not word by word, so it will find multi-word matches and words with dashes (case insensitive). It returns the matches for all pages separated by commas.
Hope this is helpful to someone in the future.
Sub Demo()
Dim SearchResult As String
SearchResult = AdobePdfSearch("my search string", "C:\Demo\Demo.pdf")
MsgBox SearchResult
End Sub
Function AdobePdfSearch(SearchString As String, strFileName As String) As String
'Note: A Reference to the Adobe Library must be set in Tools|References!
'Note! This only works with Acrobat Pro installed on your PC, will not work with Reader
Dim AcroApp As CAcroApp, AcroAVDoc As CAcroAVDoc, AcroPDDoc As CAcroPDDoc
Dim AcroHiliteList As CAcroHiliteList, AcroTextSelect As CAcroPDTextSelect
Dim PageNumber, PageContent, Content, i, j, iNumPages
Dim strResult As String
Set AcroApp = CreateObject("AcroExch.App")
Set AcroAVDoc = CreateObject("AcroExch.AVDoc")
If AcroAVDoc.Open(strFileName, vbNull) <> True Then Exit Function
Set AcroPDDoc = AcroAVDoc.GetPDDoc
iNumPages = AcroPDDoc.GetNumPages
For i = 0 To iNumPages - 1
Set PageNumber = AcroPDDoc.AcquirePage(i)
Set PageContent = CreateObject("AcroExch.HiliteList")
If PageContent.Add(0, 9000) <> True Then Exit Function
Set AcroTextSelect = PageNumber.CreatePageHilite(PageContent)
' The next line is needed to avoid errors with protected PDFs that can't be read
On Error Resume Next
For j = 0 To AcroTextSelect.GetNumText - 1
Content = Content & AcroTextSelect.GetText(j)
Next j
If InStr(1, LCase(Content), LCase(SearchString)) > 0 Then
strResult = IIf(strResult = "", i + 1, strResult & "," & i + 1)
End If
Content = ""
Next i
AdobePdfSearch = strResult
'Uncomment the lines below if you want to close the PDF when done.
'AcroAVDoc.Close True
'AcroApp.Exit
'Set AcroAVDoc = Nothing: Set AcroApp = Nothing
End Function
sub checks each page of pdf, word by word
Sub FindtextandPageNumber()
Dim FindWord 'Word you want to search
Dim acroAppObj As Object
Dim PDFDocObj As Object
Dim myPDFPageHiliteObj As Object
Dim iword As Integer, iTotalWords As Integer
Dim numOfPage As Integer, Nthpage As Integer
Dim word As String, sPath As String
Set acroAppObj = CreateObject("AcroExch.App")
Set PDFDocObj = CreateObject("AcroExch.PDDoc")
Set myPDFPageHiliteObj = CreateObject("AcroExch.HiliteList")
Check3 = myPDFPageHiliteObj.Add(0, 32767)
FindWord = "Hello"
acroAppObj.Show
sPath = "Test.pdf" 'Path of pdf where you want to search
PDFDocObj.Open (sPath)
numOfPage = PDFDocObj.GetNumPages
word = vbNullString
Set PDFJScriptObj = Nothing
For Nthpage = 0 To numOfPage - 1
Set pAcroPDPage = PDFDocObj.AcquirePage(Nthpage)
Set wordHilite = pAcroPDPage.CreateWordHilite(myPDFPageHiliteObj)
Set PDFJScriptObj = PDFDocObj.GetJSObject
iTotalWords = wordHilite.GetNumText
iTotalWords = PDFJScriptObj.getPageNumWords(Nthpage)
''check the each word
For iword = 0 To iTotalWords - 1
word = Trim(CStr(PDFJScriptObj.getPageNthWord(Nthpage, iword)))
If word <> "" Then
If word = FindWord Then
PageNumber = Nthpage
msgbox PageNumber
End If
word = ""
End If
Next iword
Next Nthpage
End Sub

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

Remove Extra Lines in Excel Sheet Using VB and .cmd

I have a large excel sheet with a log that consists of around 30000 entries.
The programmer before me has created a removeline.cmd file to remove all extra blank lines in a certain column for the excel file.
The code for the RemoveLine.cmd:
cls
cd\
SET vbfile=newlinetest.exe
K:
cd "IPM - CompOps\Ops Docs\avail-stats\Originals"
%vbfile%
exit
The file runs correctly but at the end it displays this error, which is essentially what I'm trying to get rid of:
Run-time error '1004';
Method '~' of object '~' failed
EDIT:
the program newlinetest.exe was written in VB6 (I have access to it on my machine).
The full source-code for newline.frm is:
VERSION 5.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 4500
ClientLeft = 3435
ClientTop = 3585
ClientWidth = 5175
LinkTopic = "Form1"
ScaleHeight = 4500
ScaleWidth = 5175
Begin VB.CommandButton Command1
Caption = "Excel"
Height = 495
Left = 1800
TabIndex = 0
Top = 3720
Width = 855
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Sub Command1_Click()
Dim oXL As Object ' Excel application
Dim oBook As Object ' Excel workbook
Dim oSheet As Object ' Excel Worksheet
Dim oChart As Object ' Excel Chart
Dim year As String
Dim i As Long
Dim MyRowNumber As Long
Dim Row As Long
Dim comment As String, newline As String
Dim curDate As String
Open "K:\IPM - CompOps\Ops Docs\avail-stats\Originals\Inputavailfile.txt" For Input As #1
Input #1, Data
Close #1
'Start Excel and create a new workbook
Set oXL = CreateObject("Excel.application")
Set oBook = oXL.Workbooks.Add
Set oSheet = oBook.Worksheets.Item(1)
oXL.Visible = True
oXL.UserControl = True
year = Format(Now, "yyyy")
curDate = Date - 3
curDate = Format(curDate, "m/d/yyyy")
Application.DisplayAlerts = False
Workbooks.Open FileName:="K:\IPM - CompOps\Ops Docs\avail-stats\Originals\" + Data
Myfile = "K:\IPM - CompOps\Ops Docs\avail-stats\Originals\" + Data
On Error GoTo Handler
vOurResult = Cells.Find(What:=curDate, LookAt:=xlWhole).Select
If (vOurResult = True) Then
MyRowNumber = ActiveCell.Row
Set ExcelLastCell = ActiveSheet.Cells.SpecialCells(xlLastCell)
'MsgBox vOurResult
Row = ExcelLastCell.Row
col = ExcelLastCell.Column
' MsgBox curDate
Cells(ActiveCell.Row, ActiveCell.Column + 6).Select
comment = ActiveCell.Text
newline = Replace(comment, Chr(10), " ")
ActiveCell.Value = newline
For i = MyRowNumber To Row - 1
comment = ""
newline = ""
Cells(ActiveCell.Row + 1, ActiveCell.Column).Select
comment = ActiveCell.Text
newline = Replace(comment, Chr(10), " ")
ActiveCell.Value = newline
Next i
'MsgBox curDate
ActiveWorkbook.SaveAs FileName:=Myfile, FileFormat:=xlNormal
End If
oXL.Quit
Handler:
oXL.Quit
End Sub
Private Sub Form_Load()
Command1_Click
End
End Sub
Private Sub Label1_Click()
End Sub
You have these lines towards the end of the Sub:
oXL.Quit
Handler:
oXL.Quit
The second Quit call fails, generating the error. You need to exit the procedure just before the Handler (which will only be called in the event of an error):
oXL.Quit
Exit Sub
Handler:
oXL.Quit
That's because the code 'falls through' to your line-label called Handler.
Thus when your Handler then tries to call Method 'Quit' of object 'oXL', that will fail because oXL has already quit.
The obvious solution is to Exit Sub before it reaches the Handler.
The general layout for a Sub (from MSDN):
Sub InitializeMatrix(Var1, Var2, Var3, Var4)
On Error GoTo ErrorHandler
. . .
Exit Sub
ErrorHandler:
. . .
Resume Next
End Sub
Hope this helps!
EDIT:
Seems the original question that I was helping the asker with via chat was deleted and later re-posted (I assume to get some fresh page-views).
Although Andy G has already answered this re-post, I figured not to let my answer go to waste and posted it anyway, hoping the explanation and reference might help future readers.

Resources