PDA

View Full Version : Solved: justify paragraph via VBA



white_flag
01-05-2010, 05:16 AM
Hello
I have the following code (see code). My question is: Why the

oPara1.Range.ParagraphFormat.Alignment = wdAlignParagraphJustify
dasn't work.It is ignored and the text is all the time Align to the left (Default).
Thank you


Private Sub CommandButton1_Click()


Dim oPara1 As Word.Paragraph

'Start Word and open the document template.
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Add

'Insert a paragraph at the beginning of the document.

Set oPara1 = oDoc.Content.Paragraphs.Add
oPara1.Range.ParagraphFormat.Alignment = wdAlignParagraphJustify
oPara1.Range.InsertParagraphAfter
oPara1.Range.Font.Name = "Trebuchet MS"
oPara1.Range.Font.Size = "10"
oPara1.Range.Font.Bold = False
'oPara1.Format.SpaceAfter = 5 '5 pt spacing after paragraph.
oPara1.Range.Text = "INSERT TEXT that has to be justify ..................."


End Sub

Tinbendr
01-05-2010, 05:41 AM
It appears you are starting an incidence of Word from another program.

Set oWord = CreateObject("Word.Application")
Perhaps the problem is Word's predefined properties (the wd* properties).

So change.. oPara1.Range.ParagraphFormat.Alignment = wdAlignParagraphJustify to oPara1.Range.ParagraphFormat.Alignment = 3

white_flag
01-05-2010, 05:56 AM
Tinbendr, thx for reply. it is VBA for Word (ALT+F11)
your code is acting correct but was to be put after the "INSERT TEXT"
and also the

oPara1.Range.ParagraphFormat.Alignment = wdAlignParagraphJustify is working, but has to be put after the oPara1.Range.Text
Now the code it is going like I want.

fumei
01-06-2010, 01:58 PM
"Tinbendr, thx for reply. it is VBA for Word (ALT+F11)"

What does that mean?

Surely (I hope) it does not mean you are executing the code from Word. Because Tinbendr is correct. Normally:
Set oWord = CreateObject("Word.Application")
means you are executing the VBA from some other application (Excel, PowerPoint, Access...). If you are actually in Word, there is never a need to make an instance of Word.

I have some suggestions.

1. Use With statements. That means:
oPara1.Range.ParagraphFormat.Alignment = wdAlignParagraphJustify
oPara1.Range.InsertParagraphAfter
oPara1.Range.Font.Name = "Trebuchet MS"
oPara1.Range.Font.Size = "10"
oPara1.Range.Font.Bold = False
'oPara1.Format.SpaceAfter = 5 '5 pt spacing after paragraph.
would be written as:

With oPara1.Range
.ParagraphFormat.Alignment = wdAlignParagraphJustify
.InsertParagraphAfter
With .Font
.Name = "Trebuchet MS"
.Size = "10"
.Bold = False
End With
End With


2. Use Styles rather than manually setting properties like Font.Size, or Bold...whatever. If all of those characteristics are in the Style (say named "Whatever"), then you could:

Set oDoc = oWord.Documents.Add
oDoc.Paragraphs(1).Range.Style = "Whatever"

Done.

3. Technically this comment:
'Insert a paragraph at the beginning of the document.
should not be needed, as ALL Word documents have a paragraph to start with. It is not possible to have a Word document with zero paragraphs. They all have at least one.

white_flag
01-07-2010, 02:35 PM
@fumei .. thx for the correction, you are correct.But my experience is zero, compare with you guys. I will putted in the correct VBA sentence.
I just need to made an automation form + bookmarks in word. But for the moment it is ok, the script.

Antoniu

fumei
01-07-2010, 03:03 PM
I am not actually trying to "correct". I am trying to help. Could you please answer the question though...what application are you running this VBA code from?

white_flag
01-11-2010, 08:00 AM
Application will be (it is) MS Word. I am doing this, wen I have some free time (to gain more free time :P)..

...so thx for the help :)
ps. the start example was take it from Microsoft (Vba for Word)

fumei
01-11-2010, 10:46 AM
"Application will be (it is) MS Word. "

If that is so, then there is no need to create another instance of Word. In other words, you do NOT need to do:

'Start Word and open the document template.
Set oWord = CreateObject("Word.Application")

You do not need to "start" Word, as it is already started. The above code makes a NEW instance4 of the Word application itself, which - if you are running the code from Word, is both not required, and not a good idea.

white_flag
01-12-2010, 03:00 AM
I understand
now the code is like this:



Private Sub CommandButton1_Click()


Dim oPara1 As Word.Paragraph

'Start Word and open the document template.
Set oWord = CreateObject("Word.Application")
oWord.Visible = True
Set oDoc = oWord.Documents.Add

'Insert an text

Set oPara1 = oDoc.Content.Paragraphs.Add
With oPara1.Range
.InsertParagraphAfter
.Text = "Text to be inserted"
.ParagraphFormat.Alignment = wdAlignParagraphJustify
With .Font
.Name = "Trebuchet MS"
.Size = "10"
.Bold = True
End With
End With


End Sub
how will be look better from your point of view? Yes the world is allready open and it is not necessary to be reopen. But I do not know how to do it.

white_flag
01-12-2010, 03:00 AM
double post

TonyJollans
01-12-2010, 03:13 AM
I understand
Clearly you don't.

If you are running from Word to begin with, you can start your code like this ...

Private Sub CommandButton1_Click()

Dim oPara1 As Word.Paragraph

Set oDoc = Documents.Add

'Insert an text

What the point of the rest of it is, I do not know. It can surely be better done, but how depends on your ultimate aim.

white_flag
01-12-2010, 04:03 AM
That "understand" was: I understand that is not good what I am doing and I have to change it (because is better).

your code, create an new document (it is possible to be done this text in the actual world file):



Private Sub CommandButton1_Click()


Dim oPara1 As Word.Paragraph

Set oDoc = Documents.Add

Set oPara1 = oDoc.Content.Paragraphs.Add
With oPara1.Range
.InsertParagraphAfter
.Text = "This an text"
.ParagraphFormat.Alignment = wdAlignParagraphJustify
With .Font
.Name = "Trebuchet MS"
.Size = "10"
.Bold = True
End With
End With


End Sub

TonyJollans
01-12-2010, 05:28 AM
I appreciate that English is not your first language, but I am not understanding what question you have.

The code you have just posted works but it doesn't do anything useful. What are you trying to do?

white_flag
01-12-2010, 07:07 AM
ok :) thx for understanding..I put in attachment what I try to do (like this is better to understand).

This is an document with bookmarks. In those bookmarks will be fill in, some text via an user form. and some standard text via drop list validated by an checkbottom.

TonyJollans
01-12-2010, 10:37 AM
And what, if anything, now, isn't working for you?

fumei
01-12-2010, 11:35 AM
I agree. The attached document has no userform, therefore no
Sub CommandButton1_Click()


There is no code at all.

Regarding the use CreatObject, I will reiterate.

If you are in Word (and you are), then you do NOT need to create a Word application object. You can use the one you are already using.

I would strongly recommend you use Styles. I am sure it would help a great deal. Having existing paragraphs starting with a Tab (in your header) is not good.

white_flag
01-13-2010, 12:51 AM
I made an mistake (wen I attach the file) and wen I was at home, I didn't have the file with me. Please look in attachment and tell me yours point of view.

thx

white_flag
01-13-2010, 04:30 AM
I have the following error


Private Sub Insulation()
With ComboBox_Insulation1
Select Case .Value
Case Is = "Rockwool"
Range.Text = "txt Rockwool"
Else
Range.Text = "JUST TEXT"
End Select
End With

With ComboBox_Insulation2
Select Case .Value
Case Is = "Rockwool"
Range.Text = "txt Rockwool"
Else
Range.Text = "JUST TEXT"
End Select
End With

End Sub
Private Sub CommandButton1_Click()

If CheckBox_Insulation1 = True Then
ActiveDocument.Bookmarks("Insulation1").Range.Text = Insulation

End If

Application.ScreenUpdating = False
Unload Me

End Sub

Private Sub UserForm_Initialize()
With ComboBox_Insulation1
.AddItem "Rockwool"
.AddItem "Rockwool DK"
.AddItem "Armaflex"
.AddItem "Armaflex HT"
.AddItem "PIR"
.AddItem "PUR"
.AddItem "PUR SCH"
.AddItem "JitraBand"
.AddItem "Sound"
End With
With ComboBox_Insulation2
.AddItem "Rockwool"
.AddItem "Rockwool DK"
.AddItem "Armaflex"
.AddItem "Armaflex HT"
.AddItem "PIR"
.AddItem "PUR"
.AddItem "PUR SCH"
.AddItem "JitraBand"
.AddItem "Sound"
End With
End Sub



and there

ActiveDocument.Bookmarks("Insulation1").Range.Text = Insulation
tell me that "Expected Function or variable". what I did wrong?

white_flag
01-13-2010, 06:27 AM
update. Please tell me if the construction of this VBA code is correct (I mean in the healthy VBA code). Thank you :)

fumei
01-13-2010, 11:49 AM
So many things...

1. I strongly suggest you use Option Explicit in your code modules. In the VBE, go Tools > Options and under the Editor tab, check "Require Variable Declaration".

2. The reason you had the ealier error was indeed the line:
ActiveDocument.Bookmarks("Insulation1").Range.Text = Insulation
VBA is expecting a string (or a string variable), but the code is not a string. You fixed that with the later version of (for example):
ActiveDocument.Bookmarks("Insulation1").Range.Text = "put PIR TXT"


3. However, using the above code, you will notice that "put PIR TXT" is placed after the bookmark. In other words:

put the Rockwool TXT (after the bookmark Insulation1)

becomes:

put PIR TXTput the Rockwool TXT

Do you want to replace "put the Rockwool TXT" with "put PIR TXT"?

4. Why do you have a MultiPage with only one tab ("General")? Are you going to end with more tabs?

5. Why do you have both the combobox to select an item, and a checkbox?

Small points.

6. It is normally a good thing to have a combobox have an item displayed, rather than blank. To do this, use ListIndex.
With ComboBox_Insulation1
.AddItem "Rockwool"
.AddItem "Rockwool DK"
.AddItem "Armaflex"
.AddItem "Armaflex HT"
.AddItem "PIR"
.AddItem "PUR"
.AddItem "PUR SCH"
.AddItem "JitraBand"
.AddItem "Sound"
.ListIndex = 0
End With
will display the combox with Rockwool displayed.

7. You do not need to use Case Is =
Case Is = "Rockwool"
This can be:
Case "Rockwool"


Like this:
Option Explicit

Private Sub Insulation()
With ComboBox_Insulation1
Select Case .Value
Case "Rockwool"
Call FillBM("Insulation1", "put the Rockwool TXT")
Case "Rockwool DK"
Call FillBM("Insulation1", "put the Rockwool DK TXT")
Case "Armaflex"
Call FillBM("Insulation1", "put Armaflex DK TXT")
Case "Armaflex HT"
Call FillBM("Insulation1", "put Armaflex HT TXT")
' etc. etc


The Call FillBM passes the bookmark name, and text content to the Sub FillBM. This is in a standard module. This procedure inserts the text into the bookmark, not after it. Although technically, it actually inserts the text 9which deletes the bookmark) and then re-creates the bookmark.

Amended doc attached. Click "Show The Form" on the top toolbar.

TonyJollans
01-13-2010, 12:51 PM
Agree with everything Gerry says, and ..

I don't like that you hard code "Rockwool" (and all the other options) twice - it's just asking for trouble. One way to avoid this is to store the document text in the combobox. I have copied Gerry's document and done this (see attached).

fumei
01-13-2010, 01:28 PM
I was going to do that for the OP...but am too busy to do other than what I did. I only corrected/amended part of the commandbutton Click event.

I absolutely agree. It is NOT a good idea to hard code values twice. It is indeed asking for trouble.

Very nice coding Tony.

white_flag, it is also a good and polite thing to respond to user choices. As you have the requirement to select an item from the combobox AND check the checkbox (something I am not sure I agree with), it would be good to give the user a second chance if they selected an item, but forgot to check the checkbox. I amended the commandbuton code.Private Sub CommandButton1_Click()
Dim whatever As VbMsgBoxResult

If CheckBox_Insulation1 = True Then
Insulation
Else
whatever = MsgBox("You are clicking OK with no checkbox checked. " & _
vbCrLf & _
"Do you really wish to do nothing?" & vbCrLf & _
vbCrLf & vbCrLf & _
"Click Yes to exit and do nothing." & vbCrLf & _
"Click No to try again.", vbYesNo)
If whatever = vbYes Then
GoTo Finish:
Else
Exit Sub
End If
End If

Finish:
Application.ScreenUpdating = False
Unload Me

End Sub
NOTE: this does NOT cover the same situation for the second combobox....hey, we can not do all your coding for you. But it does show the process for some error-trapping and/or user interface.

I also made the comboboxes bigger so you can see both columns (as Tony coded them) better.

fumei
01-13-2010, 01:30 PM
BTW: it is also a good idea to have a Cancel mechanism.

fumei
01-13-2010, 01:35 PM
Lastly, the reason I liked Tony's code so much is that it makes it impossible for the user to make their own alterations of the combobox items.

As it stands, the user can put "yaskahks shdklq2648adha" into a combobox. This obviously is likely not a correct value. Tony's code, by using
.List(.ListIndex, 1)

will error out, as that is NOT an item on the List.

Properly speaking, this should ALSO be error-trapped and dealt with. With something like:

Option Explicit

Public ItIsOK As Boolean

Private Sub Insulation()
On Error GoTo Gibberish:
With ComboBox_Insulation1
Call FillBM("Insulation1", .List(.ListIndex, 1))
End With
With ComboBox_Insulation2
If .ListIndex >= 0 Then
Call FillBM("Insulation2", .List(.ListIndex, 1))
End If
End With
ItIsOK = True
GoTo MyEnd:

Gibberish:
If Err.Number = 381 Then
MsgBox "Huh???? INVALID INPUT! Please try again."
ComboBox_Insulation1.ListIndex = 0
ItIsOK = False
End If

MyEnd:
End Sub
for the Insulation procedure, and of course you would have to amend the commandbutton procedure as well....
Private Sub CommandButton1_Click()
Dim whatever As VbMsgBoxResult

If CheckBox_Insulation1 = True Then
Insulation
' everything is OK
If ItIsOK = True Then
GoTo Finish
' it is NOT OK, so simply exit
Else
Exit Sub
End If
Else
whatever = MsgBox("You are clicking OK with no checkbox checked. " & _
vbCrLf & _
"Do you really wish to do nothing?" & vbCrLf & _
vbCrLf & vbCrLf & _
"Click Yes to exit and do nothing." & vbCrLf & _
"Click No to try again.", vbYesNo)
If whatever = vbYes Then
GoTo Finish:
Else
Exit Sub
End If
End If

Finish:
Application.ScreenUpdating = False
Unload Me

End Sub

fumei
01-13-2010, 01:57 PM
We are a heck a long way from the Subject: justify paragraph with VBA

white_flag
01-13-2010, 04:17 PM
fumei, thank you! (that you are spending your time to help me)

1. I did that (now)(Option explicit). Can you tell me what is the reason (for my understanding).
2. Thx for the explanation
3. I like that but I didn't know how to do it (can you point me the idea, a bit explicit)
4. You are correct. I will do more tabs but this one (whit the combobox I didn't know to solve it).
5. The reason is that is necessary to be sure that type of insulation that I am choosing it is the right one (the checkbox make me more attention).
6. Good to know, that is better.
7. I will correct in the future "Case . Value"

the Call FillBM is a nice function. Because some time the bookmark was erase by code (I think)

thx for the attachment.
Another question:
It is possible to insert an imagine (picture) via bookmarks? I will like to attach in this document also some technical drawings if I will check one checkbox. I search on the forum, but most issue are related with: insert an picture in an user form.

one more time: thank you for your time :)

have a nice day. Here it is night (so I am going to sleep)

white_flag
01-13-2010, 04:26 PM
I just saw now that are more pages in this thread.
I will read it tomorrow ..Today was a long day. so, lovely people thank you for your time and for the help.

ps1. I think I will lost in those codes
ps2. Correct (the Subject for this thread is far away from the first post)

TonyJollans
01-13-2010, 05:16 PM
Gerry .. you said you were busy!

White_flag .. sleep well! Where in the world are you? Your early attachments were in Dutch but I don't think your time zone is European.

white_flag
01-14-2010, 12:57 AM
Good morning TonyJollans
I am in Flanders (Belgium) were for the moment, it is fogy and gray.

TonyJollans
01-14-2010, 02:19 AM
It is also foggy here (in the UK) so now we can't see the snow :)

white_flag
01-14-2010, 03:07 AM
here, the snow from yesterday is gone. But at least, we had some snow in this winter (an that was so cool).
so ..can you help me (again)? I will like to add in the world file via bookmarks an picture (imagine). This is possible?

TonyJollans
01-14-2010, 04:47 AM
If you just want to add a picture, you can do something like this:

ActiveDocument.Bookmarks("Insulation2").Range.InlineShapes.AddPicture _
"C:\Users\White_Flag\Pictures\Some Kladding.jpg" ' or whatever
which doesn't even destroy the bookmark.

If you want to add mixtures of text and pictures, it is probably worth using Autotexts (or Building Blocks, depending on version).

white_flag
01-14-2010, 05:25 AM
It is working! thx

another question:
I like to add an title before "put technical txt for Rockwool". But the title was to be change in the way the selection will be done.So for every selection it is an title. How can I declare the "titles" to be inserted like it is now ".List(.ListCount - 1, 1) - for insert the text in bookmark but in a different one (Title bookmark)"

.AddItem "Rockwool": .List(.ListCount - 1, 2) = "put the Rockwool TXT": Title - this is asking for an function

white_flag
01-14-2010, 09:06 AM
The reason is that: I like to make an text combination between the first combobox and the second one to be put in the title. Like: Rockwool + Aluminium. Then the rest of the data sheets (like it is now). I do not have anyclue how to make it. any help will be more well appreciated.

fumei
01-14-2010, 11:04 AM
I really AM busy. It did not take me that long to do the changes I did.

white_flag, you need to really spell out EXACTLY your requirements before coding things. As you do not have deep experience I would recommend trying to do simple things first. Adding another variable (this Title) will complicate things a great deal.

Using the FillBM sub routine (it is not a function) is pretty much standard because, yes, just inserting text into a bookmark does delete the bookmark.

Option Explicit is useful as a standard because it forces you to declare variables. It also allows full use of IntelliSense, the syntax helper within the VBE.

TonyJollans
01-14-2010, 11:31 AM
Yes, of course you can do it! At a basic level, you just add whatever text you want to the extra bookmark. Determining the text is up to you - I don't know if you can base it on indexes into the combos, or whether it should include text or what. Here is a quick and dirty amendment to your Insulation routine that should get you started:

Private Sub Insulation()
Dim Title1 As String, Title2 As String
Title1 = "Title .. ": Title2 = "Title .. "
With ComboBox_Insulation1
If .ListIndex >= 0 Then
Call FillBM("Insulation1", .List(.ListIndex, 1))
Title1 = Title1 & .Text & " and "
End If
End With
With ComboBox_Insulation2
If .ListIndex >= 0 Then
Call FillBM("Insulation2", .List(.ListIndex, 1))
Title2 = Title2 & .Text & " and "
End If
End With
With ComboBox_Clading1
If .ListIndex >= 0 Then
Call FillBM("Clading1", .List(.ListIndex, 1))
Title1 = Title1 & .Text
End If
End With
With ComboBox_Clading2
If .ListIndex >= 0 Then
Call FillBM("Clading2", .List(.ListIndex, 1))
Title2 = Title2 & .Text
End If
End With
If Right(Title1, 5) = " and " Then Title1 = Left(Title1, Len(Title1) - 5)
If Right(Title2, 5) = " and " Then Title2 = Left(Title2, Len(Title2) - 5)
Call FillBM("Title1", Title1)
Call FillBM("Title2", Title2)

End Sub

fumei
01-14-2010, 12:11 PM
I hope white_flag is realizing that there has to be the additional bookmark already in the document at the appropriate location....

white_flag
01-14-2010, 01:02 PM
this is so awesome.. what can I say:

fumei and TonyJollans thank you sooooooooooooooo much.
I am so happy.ok, Now, I have to go to make the food :))
I wish you, an lovely day and an lovely evening :)

TonyJollans
01-15-2010, 01:40 AM
Yes, Gerry, white_flag had already added the bookmarks (which I referenced in the last bit of code I posted).

White_flag - I'm glad you are sorted. Graag gedaan.

white_flag
01-25-2010, 06:29 AM
hello lovely people,
I was busy and I can not continued this small project. till now from morning I can not figure out how to do resolve this:

I want to insert an different language text (this selection will be done via option buton). Wen I am doing one selection (Dutch for example) then everything it is acting like I want (put the txt in Dutch language on bookmarks). But after the first option is done and I wanna change the option to an different option, then I received the text from the first option ().

I see that the, function has allready an "text" inside (and that one will be inserted what ever I will select, after the first option). Who can this be made to act correct?

any help will be appreciated