Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Generating shapes

Hi folks, I am new to VB6. As part of my assignment I am supposed to generate an MS Word document at the click of a command button. I have been able to code for the same.

But what I am unable to do is generate regular shapes like rectangles, lines, arrow, etc., in that word document generated. Have been googling for the last 3 days without success. Since I am new to VB not sure if I am searching using appropriate keywords. So far searched under automation and OLE.
[477 byte] By [KiranM] at [2007-11-11 10:17:07]
# 1 Re: Generating shapes
You might try turning on Word's macro recorder, then manually perform the action you'd like to automate, and finally look at the recorded macro. For more information, see http://wordprocessing.about.com/od/workingwithmacro1/l/blmacrorecord.htm
Phil Weber at 2007-11-11 17:22:53 >
# 2 Re: Generating shapes
Hi, Phil. What you are referring to is drawing shapes on the Word document after it has generated.

What I want is along with the creation of MS Word doc, the required regular shapes must also be generated on the document.

My assignment involves generation of some data on MS Word. However, this data must be accompanied by certain schematic diagrams, for which I need the VB code to generate shapes on MS Word.

Thanks and regards.
KiranM at 2007-11-11 17:23:56 >
# 3 Re: Generating shapes
Hi Phil I tried out the Macro and I realised that on opening a recorded macro I get the VB code. Please deem fit to ignore my previous post and thanks for your help.

But there is a small problem. I am unable to draw shapes when a macro is being recorded. I can only type. Assistance in this regard is very much required.

Thanks and regards.
KiranM at 2007-11-11 17:24:49 >
# 4 Re: Generating shapes
Folks, I need help and I need it fast. Don't anyone have a solution for my problem?? :(
KiranM at 2007-11-11 17:25:55 >
# 5 Re: Generating shapes
Here is one I did and then cleaned up the excess options:Sub Macro1()
'
' Macro1 Macro
' Macro recorded 1/31/2007 by Ronald A Weller
'
'msoShapeHeart
'msoShapeHexagon
'msoShapeOval
'msoShapeMoon
'msoShapeOctagon
'msoShapePentagon
'msoShapeRectangle
'msoShapePlaque
'msoShapeSun
'msoShapeWave
'msoShape5pointStar
'msoShapeDiamond
'msoShapeExplosion1
'msoShapeDonut

ActiveDocument.Shapes.AddShape(msoShapeDonut, 162#, 50#, 108#, 108#).Select
Selection.ShapeRange.Fill.Visible = msoFalse
ActiveDocument.Shapes.AddShape(msoShapeHeart, 324#, 50#, 108#, 108#).Select
Selection.ShapeRange.Fill.Visible = msoFalse
End Sub
Ron Weller at 2007-11-11 17:26:54 >
# 6 Re: Generating shapes
Thanks Ron. Can you provide me the links to any online reference material where I can get the code for more such shapes? Will be needing code to generate many other shapes (mostly regular shapes like rectangle, circle and also lines, arrows,etc.).

And also since I am new to VB, a complete tutorial type material will be surely required by me, since I know I can't just copy the code to generate, say a rectangle, and paste it where required. What I am trying to say is there may be initialization parameters involved, if involved, which I don't know about and other such nuances where a comprehensive material will come in handy.

Thanks and regards.
KiranM at 2007-11-11 17:28:01 >
# 7 Re: Generating shapes
Ron regarding the request for comprehensive material what I mean is; for example, consider the below code where I have included your code snippet highlighted in blue:

--------------------

Private Sub Command1_Click()
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim oTable As Word.Table
Dim oPara1 As Word.Paragraph, oPara2 As Word.Paragraph
Dim oPara3 As Word.Paragraph, oPara4 As Word.Paragraph
Dim oRng As Word.Range
Dim oShape As Word.InlineShape
Dim oChart As Object
Dim Pos As Double

'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.Text = "Heading 1"
oPara1.Range.Font.Bold = True
oPara1.Format.SpaceAfter = 24 '24 pt spacing after paragraph.
oPara1.Range.InsertParagraphAfter

'Insert a paragraph at the end of the document.
'** \endofdoc is a predefined bookmark.
Set oPara2 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara2.Range.Text = "Heading 2"
oPara2.Format.SpaceAfter = 6
oPara2.Range.InsertParagraphAfter

'Insert another paragraph.
Set oPara3 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara3.Range.Text = "This is a sentence of normal text. Now here is a table:"
oPara3.Range.Font.Bold = False
oPara3.Format.SpaceAfter = 24
oPara3.Range.InsertParagraphAfter

'Insert a 3 x 5 table, fill it with data and make the first row
'bold,italic.
Dim r As Integer, c As Integer
Set oTable = oDoc.Tables.Add(oDoc.Bookmarks("\endofdoc").Range, 3, 5)
oTable.Range.ParagraphFormat.SpaceAfter = 6
For r = 1 To 3
For c = 1 To 5
oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
Next
Next
oTable.Rows(1).Range.Font.Bold = True
oTable.Rows(1).Range.Font.Italic = True

'Add some text after the table.
'oTable.Range.InsertParagraphAfter
Set oPara4 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara4.Range.InsertParagraphBefore
oPara4.Range.Text = "And here's another table:"
oPara4.Format.SpaceAfter = 24
oPara4.Range.InsertParagraphAfter

'Insert a 5 x 2 table, fill it with data and change the column widths.
Set oTable = oDoc.Tables.Add(oDoc.Bookmarks("\endofdoc").Range, 5, 2)
oTable.Range.ParagraphFormat.SpaceAfter = 6
For r = 1 To 5
For c = 1 To 2
oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
Next
Next
oTable.Columns(1).Width = oWord.InchesToPoints(2) 'Change width of columns 1 & 2.
oTable.Columns(2).Width = oWord.InchesToPoints(3)

'Keep inserting text. When you get to 7 inches from top of the
'document, insert a hard page break.
Pos = oWord.InchesToPoints(7)
oDoc.Bookmarks("\endofdoc").Range.InsertParagraphAfter
Do
Set oRng = oDoc.Bookmarks("\endofdoc").Range
oRng.ParagraphFormat.SpaceAfter = 6
oRng.InsertAfter "A line of text"
oRng.InsertParagraphAfter
Loop While Pos >= oRng.Information(wdVerticalPositionRelativeToPage)
oRng.Collapse (wdCollapseEnd)
oRng.InsertBreak wdPageBreak
oRng.Collapse wdCollapseEnd
oRng.InsertAfter "We're now on page 2. Here's my chart:"
oRng.InsertParagraphAfter

'Insert a chart and change the chart.
Set oShape = oDoc.Bookmarks("\endofdoc").Range.InlineShapes.AddOLEObject( _
ClassType:="MSGraph.Chart.8", FileName _
:="", LinkToFile:=False, DisplayAsIcon:=False)
Set oChart = oShape.OLEFormat.Object
oChart.charttype = 4 'xlLine = 4
oChart.Application.Update
oChart.Application.Quit
'... If desired, you can proceed from here using the Microsoft Graph
'Object model on the oChart object to make additional changes to the
'chart.
oShape.Width = oWord.InchesToPoints(6.25)
oShape.Height = oWord.InchesToPoints(3.57)

'Add text after the chart.
Set oRng = oDoc.Bookmarks("\endofdoc").Range
oRng.InsertParagraphAfter
oRng.InsertAfter "THE END."

'Shape trial
'
' Macro1 Macro
' Macro recorded 1/31/2007 by Ronald A Weller
'
'msoShapeHeart
'msoShapeHexagon
'msoShapeOval
'msoShapeMoon
'msoShapeOctagon
'msoShapePentagon
'msoShapeRectangle
'msoShapePlaque
'msoShapeSun
'msoShapeWave
'msoShape5pointStar
'msoShapeDiamond
'msoShapeExplosion1
'msoShapeDonut

ActiveDocument.Shapes.AddShape(msoShapeDonut, 162#, 50#, 108#, 108#).Select
Selection.ShapeRange.Fill.Visible = msoFalse
ActiveDocument.Shapes.AddShape(msoShapeHeart, 324#, 50#, 108#, 108#).Select
Selection.ShapeRange.Fill.Visible = msoFalse
'All done. Unload this form.
Unload Me
End Sub

----------------------

The above code gives a 4248 run-time error.
I know I am going wrong regarding the shape code but don't know where and how.
KiranM at 2007-11-11 17:28:53 >
# 8 Re: Generating shapes
This will fix your error. I created the macro in word so it knew which application it was in; but your instance of word is accessed through your application object variable called oWord. 'this does a donut
oWord.ActiveDocument.Shapes.AddShape(msoShapeDonut, 162#, 50#, 108#, 108#).Select
'this makes the insides transparent
oWord.Selection.ShapeRange.Fill.Visible = msoFalse
'this makes a heart
oWord.ActiveDocument.Shapes.AddShape(msoShapeHeart, 324#, 50#, 108#, 108#).Select
'this makes the insides transparent
oWord.Selection.ShapeRange.Fill.Visible = msoFalse

Word already has extensive information on this, but it is not always easy to find.
Now that you have some code that shows you some of the objects and properties used by word. Just paste the code into words vb editor, Select a keyword like AddShape and press the F1 key. Word will open the help file to that keyword, from there you can find other links within the help that will give you access to all of the other properties, objects, and methods used by word for creating and manipulating shapes.
When ever I want to automate something in an Office application, I almost always create a macro that in at least some way manipulates or does something similar to what I want to automate. This way when I look at the VBA code for the macro I can see what objects and properties were used. Then I highlight the ones that look promising and hit the F1 key to find it in the help files, once there, if I find what I am looking for I can follow the links to find any additional features and even some examples for a more indepth look at it's capabilities.
Ron Weller at 2007-11-11 17:29:58 >
# 9 Re: Generating shapes
Thanks Ron.

When I run the code after the modifications, it gives a run-time error saying "specified value out of range".

The code:
----------------------

Private Sub Command1_Click()
Dim oWord As Word.Application
Dim oDoc As Word.Document
Dim oTable As Word.Table
Dim oPara1 As Word.Paragraph, oPara2 As Word.Paragraph
Dim oPara3 As Word.Paragraph, oPara4 As Word.Paragraph
Dim oRng As Word.Range
Dim oShape As Word.InlineShape
Dim oChart As Object
Dim Pos As Double

'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.Text = "Heading 1"
oPara1.Range.Font.Bold = True
oPara1.Format.SpaceAfter = 24 '24 pt spacing after paragraph.
oPara1.Range.InsertParagraphAfter

'Insert a paragraph at the end of the document.
'** \endofdoc is a predefined bookmark.
Set oPara2 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara2.Range.Text = "Heading 2"
oPara2.Format.SpaceAfter = 6
oPara2.Range.InsertParagraphAfter

'Insert another paragraph.
Set oPara3 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara3.Range.Text = "This is a sentence of normal text. Now here is a table:"
oPara3.Range.Font.Bold = False
oPara3.Format.SpaceAfter = 24
oPara3.Range.InsertParagraphAfter

'Insert a 3 x 5 table, fill it with data and make the first row
'bold,italic.
Dim r As Integer, c As Integer
Set oTable = oDoc.Tables.Add(oDoc.Bookmarks("\endofdoc").Range, 3, 5)
oTable.Range.ParagraphFormat.SpaceAfter = 6
For r = 1 To 3
For c = 1 To 5
oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
Next
Next
oTable.Rows(1).Range.Font.Bold = True
oTable.Rows(1).Range.Font.Italic = True

'Add some text after the table.
'oTable.Range.InsertParagraphAfter
Set oPara4 = oDoc.Content.Paragraphs.Add(oDoc.Bookmarks("\endofdoc").Range)
oPara4.Range.InsertParagraphBefore
oPara4.Range.Text = "And here's another table:"
oPara4.Format.SpaceAfter = 24
oPara4.Range.InsertParagraphAfter

'Insert a 5 x 2 table, fill it with data and change the column widths.
Set oTable = oDoc.Tables.Add(oDoc.Bookmarks("\endofdoc").Range, 5, 2)
oTable.Range.ParagraphFormat.SpaceAfter = 6
For r = 1 To 5
For c = 1 To 2
oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
Next
Next
oTable.Columns(1).Width = oWord.InchesToPoints(2) 'Change width of columns 1 & 2.
oTable.Columns(2).Width = oWord.InchesToPoints(3)

'Keep inserting text. When you get to 7 inches from top of the
'document, insert a hard page break.
Pos = oWord.InchesToPoints(7)
oDoc.Bookmarks("\endofdoc").Range.InsertParagraphAfter
Do
Set oRng = oDoc.Bookmarks("\endofdoc").Range
oRng.ParagraphFormat.SpaceAfter = 6
oRng.InsertAfter "A line of text"
oRng.InsertParagraphAfter
Loop While Pos >= oRng.Information(wdVerticalPositionRelativeToPage)
oRng.Collapse (wdCollapseEnd)
oRng.InsertBreak wdPageBreak
oRng.Collapse wdCollapseEnd
oRng.InsertAfter "We're now on page 2. Here's my chart:"
oRng.InsertParagraphAfter

'Insert a chart and change the chart.
Set oShape = oDoc.Bookmarks("\endofdoc").Range.InlineShapes.AddOLEObject( _
ClassType:="MSGraph.Chart.8", FileName _
:="", LinkToFile:=False, DisplayAsIcon:=False)
Set oChart = oShape.OLEFormat.Object
oChart.charttype = 4 'xlLine = 4
oChart.Application.Update
oChart.Application.Quit
'... If desired, you can proceed from here using the Microsoft Graph
'Object model on the oChart object to make additional changes to the
'chart.
oShape.Width = oWord.InchesToPoints(6.25)
oShape.Height = oWord.InchesToPoints(3.57)

'Add text after the chart.
Set oRng = oDoc.Bookmarks("\endofdoc").Range
oRng.InsertParagraphAfter
oRng.InsertAfter "THE END."

'Rectangle
oWord.ActiveDocument.Shapes.AddShape(msoShapeDonut, 162#, 50#, 108#, 108#).Select

'All done. Unload this form.
Unload Me
End Sub
KiranM at 2007-11-11 17:31:03 >
# 10 Re: Generating shapes
It is probably the shape constant "msoShapeDonut", sometimes these constants do not get carried over to external applications. They got left out of the libarary. Just go back into word's VB Editor and then in the Immediate window type ?msoShapeDonut and press return. It should print the actual value of the constant. Then simply replace the constant with the actual value. Since the constant was not defined VB thinks it's a variable and variable's are initialized to zero. My guess is that zero in not a valid shape. You can also go into the help file and make yourself a list of all of the shape constants thay you thik you might use,(there are a lot of them), and then get the values for each in the Immediate Window. Once you have the values you could define the constants yourself.
Const msoShapeHeart As Long = 21
Const msoShapeDonut As Long = 18
'''or use ENUM
Enum msoShapeConstants
msoShapeRectangle = 1
msoShapeDiamond = 4
msoShapeOctagon = 6
msoShapeOval = 9
msoShapeHexagon = 10
msoShapeDonut = 18
msoShapeHeart = 21
msoShapeSun = 23
msoShapeMoon = 24
msoShapePlaque = 28
msoShapePentagon = 51
msoShapeExplosion1 = 89
msoShape5pointStar = 92
msoShapeWave = 103
End Enum
Ron Weller at 2007-11-11 17:32:03 >
# 11 Re: Generating shapes
Thanks a lot Ron. You made my day. Issue resolved. On my way to coding glory. :)
KiranM at 2007-11-11 17:33:02 >