I'm trying to create a script in VBA for a Word document that bookmarks and hyperlinks matching strings with numbering to a location later in the document. Right now I have two sets of matching for matching text that looks like this (sometimes with hundreds of more entires):
Contents
'There is a bookmark here named "InpCon"
4326: Info 1
32534: Info 2
7980: Info 3
Body
'There is a bookmark here named "InpBod"
4326: Info 1
32534: Info 2
7980: Info 3
This is what I'm trying to do:
Table of Contents
'There is a bookmark here named "InpCon"
4326: Info 1 'Hyperlink to Bookmark Name: "Info1"
32534: Info 2 'Hyperlink to Bookmark Name: "Info2"
7980: Info 3 'Hyperlink to Bookmark Name: "Info3"
Body
'There is a bookmark here named "InpBod"
4326: Info 1 'Bookmark Name: "Info1"
32534: Info 2 'Bookmark Name: "Info2"
7980: Info 3 'Bookmark Name: "Info3"
I'm trying to implement this at the end of a larger script I have. The larger script copies everything under the "InpBod" bookmark to the "InpCon" bookmark at one point. I don't know if inputting a process there to do this would be more efficient.
Basically, my VBA knowledge is pretty limited. I've tried looking for something that accomplishes this task, but haven't found anything. I'd paste my code, but it's pretty large and on a stand alone system. This would shave hours off my week if I can get it done. Can someone help me out or point me in the right direction? Thanks you in advance.
Don't "manually" generate "InpCon". Use Word to generate the TOC. When generating "InpBod", everytime you come across something you want to link to, mark it and then actomatically generate the TOC. Two possible ways to do so:
Use heading styles and then generate a TOC. Everytime you stumble upon an entry to be marked, mark the paragraph as a heading Selection.Range.Paragraphs.Style = ActiveDocument.Styles(wdStyleHeading1). You may want to change the default heading styles. Then insert a TOC at the beginning.
Use bookmarks if the document uses headers for something else. Everytime you stumble upon an entry to be marked, create a bookmark like this: ActiveDocument.Bookmarks.Add Range:=Selection.Range.Collapse wdCollapseEnd, Name:=**THEBOOKMARKNAME**. Notice that you'll have to remove spaces and that kind of stuff for the bookmark name. Then iterate thorugh all the activedocument.Bookmarks inserting the links using Selection.InsertCrossReference ReferenceType:="Bookmark", ReferenceKind:= _
wdContentText, ReferenceItem:=ITEM, InsertAsHyperlink:=True, _
IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
The macro recorder will expose every object you need to do this.
Using newer info from the comments:
The Word's list object model is pretty well illustrated here: Looping a Word macro over many list paragraphs causes memory issue and here http://oreilly.com/catalog/writewordmacro/chapter/ch17.html with more detail. Here's the proper documentation: http://msdn.microsoft.com/en-us/library/aa223019(v=office.11).aspx
You should loop through the lists collection members (for what I gather you should only have one list, the InpBod list). Then loop through the paragraphs in that list selecting each like this:
Dim para as Range
For Each para In ActiveDocument.Lists(1).ListParagraphs
para.Range.Select
Next para
Related
I suspect my strategy is incorrect as I can't seem to apply my search results for the keywords I've used over the last few days. ( https://stackoverflow.com/questions/54496552] seems to be the closest. )
I am able to populate a single document from the two forms I've built and save it under a new name
...
MsgBox "Saving as " & aFullPath
ActiveDocument.SaveAs FileName:=aFullPath, FileFormat:=wdFormatDocumentDefault
But that changes the name of my parent document that contains my forms (Word2016 document name: waiver.docm). In practice, that won't be a problem because the user will not be saving "waiver.docm" except by accident.
But that's why I think my approach is wrong.
Ideally my VBA code would
Load a protoype waiver template with the page heading, bookmarks and table as I have now in my waiver.docm.
Upon filling that template, append another waiver template as a new page.
And return control to the form
Repeat above two steps of appending of sheets until the user indicates completion (e.g. "Finish" command button). Typically after 1 to 4 pages
Print and save the entire document.
Right now I interrupt the process after each page to force my prospective user to print and save the document (and under a unique name).
I have a table in Word that has column titles. When the page breaks the table rolls over to the next page and the headers repeat. However, I also have section titles that are important to see as well. If you look at the example below, I have the section '2' at the top next to sub-section 'C'.
a) I will be generating MHTML dynamically for import into Word so if it is possible to generate MHTML that will enable the above then that would be great. Otherwise ...
b) Is there any way within Word to manually or using VBA mark up the sections so they know to roll over to the next page automatically, so that the table will update itself if there are any changes to page-break locations. Alternatively...
c) I might have to write some VBA that checks that the section numbers are in the right place every time the VBA code is manually run, although I suspect that might start to get messy as I will also have to remove any existing 'pulled' section numbers that might have been inserted.
Thanks
I am a bit of novice when it comes to VBA (mostly navigate through the code by Recording actions and then altering it accordingly to what I need).
My current problem is the following:
I am going to compile hundreds of word Docs that contain email addresses from clients that I need. In order to make this as easy as possible, I would like to have some code that finds their emails AND additional information that surrounds the email addresses (Name, Location,Job Title,and [possibly] Phone Number) and then copies and pastes the mentioned info to another designated document. The documents and the abovementioned info are formatted as such :
FirstName LastName
Location
Job title # Company
email address - phone number
Now, I believe this will include and IF/THEN statement since not all clients have their email addresses in the documents.
So, IF there is an email address THEN copy it along with the 3 lines above and the phone number that is separated by "a space" "-" "a space"AND paste it on another sheet. IF there is no email address, then keep going.
This query code will probably include a FIND that needs to have a "#" and ".com" attached to the same string. This will be needed since the document also includes other text that has ".com" and "#" but not together.
This sounds harder than what it really is, but again I'm a novice so not completely sure. Feel free to ask any additional questions!
This is an extremely broad question, but I suggest you do the following:
Use a Scripting.FileSystemObject to iterate through files in a folder, looking for Word documents
Open the document using the Word Automation object model
Application object
Application.Documents property, and Documents collection
Documents.Add method, and the Document object, to create the destination document
Documents.Open method, to open existing documents
Find emails within the document (via the Document.Content property, and the Range object)
Range.Find property and the Find object
If the Find.Execute2007 method returns true, then:
Extend the range to the previous 3 paragraphs
Range.MoveStart method
Copy and paste the range to the destination document
You can write only the text to the destination document — Range.Text property, and the Range.Insert-* methods
Or, you can use the clipboard Range.Copy and Range.Paste
Or, you can export to an external file (Range.ExportFragment) and later import from the external file (Range.ImportFragment)
I need to modify a template document (docx) automatically, according to info I've read into some text files and I'm using VBA for this.The template document has a predefined record, which looks like this:
description: first description which can take more rows
...
author: the author
date: the date
...
What I need is copying the previous line below the first one, as many times as many text file I have, and complete each one whit info I've copied into strings. So,for example, if I have 3 text file I'll have the previous line three times, like this:
description: first description
...
author: the first author
date: the date in the first file
description: second description
...
author: the second author
date: the date in the second file
description: third description
...
author: the third author
date: the date in the third file
where the first one is already there and I need to repeat it twice.
How can I tell Word to copy and write in specific points of the document?
I've thought something like the following:(The code probably is not correct, I'll put it there to explaying my idea)
For i = 1 To n(number of text file)
ActiveDocument.Range(Start:=ActiveDocument.Paragraphs(Index).Range.Start
End:=ActiveDocument.Paragraphs(Index+3).Range.End).Select
Selection.Copy
ActiveDocument.Paragraphs(Index+4).Select
Selection.Paste
Next i
the previous was for copying the record.
Now I have to fill that records writing the info after title:, author: and date: of each one, so something like:
For i=1 To n
ActiveDocument.Paragraphs(Index(i)+1).Words(2) = description(i)
ActiveDocument.Paragraphs(Index(i)+2).Words(2) = author(i)
ActiveDocument.Paragraphs(Index(i)+3).Words(2) = date(i)
Next i
where description, author and date are text string I already have.
Does that make any sense or I'm taking a wrong way? Is there any smarter VBA objects I could use?
Unfortunately, I don't have enough points yet to add this as a comment, where it would actually belong...
Which version of Word are you using?
Do you have any influence on the construction of the template, so that you could, for example, add bookmarks such as iDevelop suggests or possibly ContentControls (would be better)?
If you have no influence then it would be better for you to plan entering the data in each "copy" loop.
Note: I hope you're using Documents.Add to create new documents from the template so that you're not actually changing the template?
I have sub sections in a word document which I want to delete based on user inputs in a custom user interface.
For e.g : I want to delete sub section 3.1.1 under the section 3
I used the following code, but it deletes the entire section but I want to delete only a specific sub section:
ActiveDocument.Sections(x).Range.Delete
Here I am not able to give x = 3.1.1, it only accepts just the integer value like 3 and that deletes the entire section.
Word doesn't have nested sections, so you probably need to cycle through the sections until you find one that matches your needs. So, let's say you have a Word document that looks like this:
Title___[continuous section break]
Stuff
Section 1___[continuous section break]
Stuff
Section 1.1___[continuous section break]
Stuff
You could loop through the sections and check the first paragraph of each:
For each objSect in ActiveDocument.sections
if trim(replace(objSect.Range.Paragraphs.First.range.Text, chr(13), "")) like "* 1.1" then objSect.range.delete
Next objSect
Of course, that means if you want to delete section 1 you'll need to delete it along with any sub-sections, one at a time.
If what you really want is something like what the navigation pane gives you, I don't know if that's supported in VBA. There don't appear to be any methods that would mimic the Navigation Pane Delete option.