Changing paragraph alignment of word document through VBA - vba

I Have excel workbook which maintains data of my customers Like address & Due amount. I am writing a VBA code in excel which will generate letter to each of the customer for the due amounts. I cannot use mailmerge because of the complexity of the letter. I am using following codes to add paragraphs
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Add
wrdDoc.content.InsertAfter "----------"
wrdDoc.content.InsertParagraphAfter
Now I need to change alignment of paragraphs. The paragraphs in body of letter are to be justified while some paragraphs like subject line are to be center aligned. I tried this code but its not working
1.
wrdDoc.Paragraphs(8).Range.ParagraphFormat.Alignment = wdAlignParagraphCenter
also
2.
wrdDoc.Paragraphs(8).Alignment = wdAlignParagraphCenter
What is the correct way doing this?
Regards
Shekhar

This worked for me:
objselection.Paragraphs.Alignment = 3
Numbers:
3 Justify
2 Center
1 Right Justify

Related

How can I search for text, select the line it's on, and bold it in Word VBA?

I have created a word VBA system that takes information from excel spreadsheets and creates a word document. The document each time is a proposal for a job, so there is typically at least 1, often multiple lines that have a subtotal:
Sub-Total $1,000.00
I want to write a piece of code (to fit in a button) that finds "Sub-Total" in the document, selects the entire line, and makes it bold. It will always be on 1 line and the line will always start with "Sub-Total".
I tried to work with finding text, but the dollar amount changes with any new data import; only the word "Sub-Total" itself is static. Any help is appreciated. Thanks!
Note that its good practice to include a minimum, viable code sample which shows what you've tried when you're asking a stackoverflow question.
The first question is, if you're generating the Word document from Excel, why don't you format the "Sub-Total" line as you create the Word document(?); its probably easier than trying to find and format the text afterwards.
However, assuming you can't for some reason, here is a working example which opens a Word document, loops through all sentences, checks if the sentence starts with "Sub-Total ", and if it does, makes it bold. It assumes that the text (e.g. "Sub-Total $1500.00") is a complete sentence and the whole sentence needs to be bold.
Option Explicit
Public Sub FindAndBold()
Dim WordApp As Word.Application
Dim MyWordDocument As Word.Document
Dim Counter As Long
Set WordApp = New Word.Application
Set MyWordDocument = Word.Application.Documents.Open("C:\test.docx")
For Counter = 1 To MyWordDocument.Sentences.Count
With MyWordDocument.Sentences(Counter)
If Left$(.Text, 11) = "Sub-Total: " Then
.Bold = True
End If
End With
Next
End Sub

How to bold only a portion of Word paragraph in Visual Studio (VB)

I am trying to export a Word document from a Visual Basic program. Different parts of the document will need different formatting.
I have several paragraphs, and I need to bold only portions of each of those paragraphs. I am trying to set the range within each paragraph that needs to be bolded, but no matter what I do, it only seems to want to to bold the entire paragraph.
I want to do something like this:
Dim Para1 As Word.Paragraph
Para1 = WordDoc.Content.Paragraphs.Add
Para1.Range.Start = 1
Para1.Range.End = 14
Para1.Range.Font.Bold = True
Para1.Range.Text = "Job number is: " + myJobID
... so that it bolds from the 'J' to the ':' (in Para1.Range.Text) but does not bold the myJobID (which is a variable I'm getting from the user). However, no matter what I do, it bolds the entire paragraph, including the myJobID.
I've also tried creating a Range variable that sets a range based on the entire document, but the problem with that is, the lengths of several variables I'm outputting on the Word document are going to be varying sizes, and thus there's no way to know where the start of the next section I want to bold will start at. So basically, I have to work within the Paragraph object rather than iterating through all of the characters in the entire document.
Hope that made sense. Any ideas?
In order to format individual text runs it's necessary to break the text down into individual runs when inserting. Also, it's best to work with an independent Range object. Between formatting commands the Range needs to be "collapsed" - think of it like pressing the right (or left) arrow of a selection to make it a blinking cursor. Something along these lines
Dim Para1 As Word.Paragraph
Dim rng as Word.Range
Para1 = WordDoc.Content.Paragraphs.Add
rng = Para1.Range
rng.Text = "Job number is: "
rng.Font.Bold = True
rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
rng.Text = myJobID
rng.Font.Bold = False
rng.Collapse Word.WdCollapseDirection.wdCollapseEnd
If it's really necessary to insert the full text in one go, then Find/Replace to locate the text that should be formatted differently is one way to format after-the-fact, although less efficient.
Another possibility is to use string manipulation functions, such as Instr (or Contains), Left, Mid etc. to determine where in a longer string the substring is located. Then Range.Start and Range.End can work with those values. But generally it's better to not rely on the start and end values since Word can insert non-visible characters that can throw this numbering off.
Create another Range object that only covers the characters that you want to bold.
The code below is not tested (don't have full VS set up on this machine), but should give you an idea:
Dim para1 As Word.Paragraph
Dim textToBeBolded As Word.Range
para1 = WordDoc.Content.Paragraphs.Add 'ThisDocument.Paragraphs.Add in VBA
para1.Range.Text = "Job number is: " + myJobID
para1.Range.SetRange 1, 14
textToBeBolded = para1.Range
textToBeBolded.SetRange 1, 14
textToBeBolded.Font.Bold = True

Word/VBA: How to set an other column count for a special page?

I am trying something with Word and VBA, but i have a little problem:
I currently have 3 pages, all of them with 2 columns but I would like to have the first page, and only the first page, with 1 column.
Does someone knew how to solve this?
my code:
Set appWord = CreateObject("Word.Application")
appWord.DisplayAlerts = False
Set wordDoc = appWord.Documents.Open(Application.GetOpenFilename("Word-Dateien (*.doc;*.docx;),*.doc;*.docx"))
wordDoc.Activate
wordDoc.Sections(1).PageSetup.TextColumns.SetCount NumColumns:=2
Here is where I currently stopped because I don't know how to make it right.
With best regards, and big thanks for answering
Assuming you have a paragraph in your document or created by you code. e.g. you know that your first page ends after the 4th paragraph of your document.
Sub reportCreation()
Dim myRange As Range
'Place where your report is generated - include wordApp activation etc. according to your needs.
'Define the range after which you want to add your page break section - here paragraph 4
Set myRange = ActiveDocument.Paragraphs(4).Range
'Add the Next Page section Break
ActiveDocument.Sections.Add Range:=myRange, _
Start:=wdSectionContinuous
'Now your report is separated in two sections: 1st section-> 1st page, 2nd section->rest of the report
wordDoc.Sections(2).PageSetup.TextColumns.SetCount NumColumns:=2
End Sub

Insert text after numbers and before words in a Word hierarchical heading

I am working my way through two books (Roman's Writing Word Macros, Mansfield's Mastering VBA for MS Office). In my work environment, I use both Word 2007 and Word 2010.
My issue is that I want to use VBA to insert a very brief amount of standardized text before the English-language string in my numbered hierarchical headings. For instance, I have:
1.1.1 The Quick Brown Fox.
What I want is:
1.1.1 (XXxx) The Quick Brown Fox.
I guess my most basic issue is that I don't know how to approach the situation. I have hierarchical headings yet I don't know how to say, in effect, "Go to each hierarchical heading regardless of level. Insert yourself in front of the first English language word of the heading. Paste the text "XXxx" in front of the first word in the heading. Go on to the next heading and all remaining headings and do the same. My document is over 700 pages and has hundreds of hierarchical headings.
I see that paragraphs are objects and that hierarchical headings are paragraphs. However, I can't see any way to make VBA recognize what I am talking about. I haven't been able to use Selection approaches successfully. I've tried using the Range approach but just have not been able to phrase the VBA code intelligently. I haven't been able to specify a range that includes all and only the hierarchical headings and, especially, I don't understand how to get the insertion to happen in front of the first English-language word of the heading.
I have just begun to look at using Bookmarks. However, don't bookmarks require me to go to every heading and enter them? I may as well just paste my content if that is the case. I'm stumped. It is interesting that in no way, as might have been expected, does this appear to be a simple matter
Assuming you are using Word's outline levels (I think this is what you mean by hierarchical headings), you can check a paragraph for this state. For example, assuming I have a paragraph in my document that has the Heading 1 style applied to it:
Sub PrintHeadings()
Dim objDoc as Document
Dim objPara as Paragraph
Set objDoc = ActiveDocument
For each objPara in objDoc.Content.Paragraphs
If objPara.OutlineLevel <> wdOutlineLevelBodyText then
Debug.Print objPara.Range.Text
End If
Next objPara
End Sub
This code would print the contents of any paragraph that has an outline level above body text to the VBA Immediate Window. There are other approaches as well; you could use Find and Replace to search for each of the Outline Levels. This gives you a bit less control; you'd want your change to be something that could be encapsulated in a Word Find and Replace. But, it would be faster if you have a long document and not too many heading levels. A basic example:
Sub UnderlineHeadings()
Dim objDoc as Document
Set objDoc = ActiveDocument
With objDoc.Content.Find
.ClearFormatting
.ParagraphFormat.OutlineLevel = wdOutlineLevel1
With .Replacement
.ClearFormatting
.Font.Underline = wdUnderlineSingle
End With
.Execute Forward:=True, Wrap:=wdFindContinue, Format:=True, Replace:=wdReplaceAll
End With
End Sub
That would underline all of your text of Outline Level 1.
Perhaps that will get you started.
I asked this question some months ago: "My issue is that I want to use VBA to insert a very brief amount of standardized text before the English-language string in my numbered hierarchical headings." By "numbered hierarchical headings" I meant Word multilevel lists. The answers I received were appreciated but did not respond effectively to my question or guide me to a resolution. I pass this along in the hope it may be of use to others.
First, the "number" part of the Word heading is irrelevant. In writing your code, there is NO need to think of a "number" portion and a "text" portion of the heading. I was afraid that any text I was trying to insert would be inserted BEFORE the multilevel numbering rather than BEFORE the English language text. The multilevel numbering is apparently automatically ignored. Below are two solutions that worked.
This first macro succeeded in producing the desired result: 1.1.1 (FOUO). I used this macro to create individual macros for each order of heading. I haven't learned how to combine them all into one macro. But they work individually (but not without the flaw of taking too much time ~5 to 10 minutes for a complex, paragraph-heavy 670 page document).
Public Sub InsertFOUOH1()
Dim doc As Document
Dim para As Paragraph
Dim paraNext As Paragraph
Dim MyText As String
Dim H1 As HeadingStyle
Set doc = ActiveDocument
Set para = doc.Paragraphs.First
Do While Not para Is Nothing
Set paraNext = para.Next
MyText = "(U//FOUO) "
If para.Style = doc.Styles(wdStyleHeading1) Then
para.Range.InsertBefore (MyText)
End If
Set para = paraNext
Loop
End Sub
THIS WORKS ON ALL FIRST ORDER HEADINGS (1, 2, 3 ETC.)
I used the macro below to add my security marking all body paragraphs:
Public Sub InsertFOUObody()
'Inserts U//FOUO before all body paragraphs
Dim doc As Document
Dim para As Paragraph
Dim paraNext As Paragraph
Dim MyText As String
Set doc = ActiveDocument
Set para = doc.Paragraphs.First
Do While Not para Is Nothing
Set paraNext = para.Next
MyText = "(U//FOUO) "
If para.Style = doc.Styles(wdStyleBodyText) Then
para.Range.InsertBefore (MyText)
End If
Set para = paraNext
Loop
End Sub
These macros are running slowly and, at the end, generating Error 28 Out of stack space errors. However the error is displayed at the end of running the macros and after the macros have successfully performed their work.

In vbs/hta how do I tell if I reach the end of a word document?

I am currently creating a large script to automate a Microsoft word document to pull out tables and put them into a new document. But I need to know when I reach the end of the document so I can move on to the next document.
Set objWord = CreateObject("Word.Application")
Set objNewDoc = objWord.Documents.Add()
Set objNewSelection = objWord.Selection
Set objDoc = objWord.Documents.Open( C:/Users/blahdoc.doc )
Set objSelection = objWord.Selection
This isn't the script but its how I defined and opened the documents for reading. I will happily insert more details if and when there needed.
I did look around for similar questions but didn't find any that apply. If you do sorry ahead of time ;)
You actually don't need to worry about "reaching the end of the document." Thankfully, the tables are stored in a Tables collection which is a property of a Word.Document. You can iterate through all the tables like so:
For Each oTable In objNewDoc.Tables
If Left(oTable.Cell(1, 1).Range.Text, Len(oTable.Cell(1, 1).Range.Text) - 2) = "Some string" Then
MsgBox "Found one!"
End If
Next
One issue I ran into when putting this together is that all Cells' Text have an End-of-Cell Marker composed of two characters: a Carriage Return (ascii 13) followed by a BELL (ascii 7). I used Left to strip those off so I could compare the text against a string value, which is what I understand you are trying to do.