Handling a selecion via OLE

D

David Clark

Hi

I have a Lotus application that creates a Word 2003 document via OLE.
It's almost complete, much to my surprise as I don't really know what
I'm doing (as will become apparent) and I've only got this far by
finding code snippets, recording macros and using the object browser.
Anyway I just have 2 remaining issues, the first is more important
than the second.

1. I need to insert a tick symbol in a table cell. I found that I need
use the insertsymbol method and that needs to be on a selection but
how do I get that 'selection'? My function that inserts text in a
call uses a range. Here's my failing code - the errors I see vary
from 'insertsymbol is not a property' (yes, that I know) to something
about whatever I've tried the method on not being a simple selection.

Function addticktocell(table As Variant, rowNum As Integer, colNum As
Integer) As Variant
Dim cell As Variant
Dim lastParagraph As Variant
Dim newRangeStart As Long
Dim selection As Variant
Set cell = GetTableCell(table, rowNum, colNum)
Set lastParagraph = Nothing
If Not cell Is Nothing Then
Set lastParagraph =
cell.Range.Paragraphs(cell.Range.Paragraphs.Count).Range

lastparagraph.select
Call lastparagraph.select.insertSymbol("Wingdings 2", -4014, True)
'Call selection.insertSymbol("Wingdings 2", -4014, True)
newRangeStart = lastParagraph.End-1

Set lastParagraph =
cell.Range.Paragraphs(cell.Range.Paragraphs.Count).Range
Call lastParagraph.SetRange(newRangeStart, lastParagraph.End)
Call lastparagraph.select
'Call lastparagraph.insertSymbol("Wingdings 2", -4014, True)
End If

End Function


2. I'd like to be able to create a table inside the cell of an
existing table but I can't see how to navigate to the cell. My current
createtable works at the document level....

Function CreateTable(doc As Variant, numRows As Integer, numCols As
Integer, pwidth) As Variant
Dim lastParagraph As Variant
Dim range As Variant
Dim table As Variant
Set lastParagraph = doc.Paragraphs(doc.Paragraphs.Count).Range
Set range = doc.Range(lastParagraph.Start, lastParagraph.End)
Set table = doc.Tables.Add(range, numRows, numCols)
table.PreferredWidthType = 2
table.PreferredWidth = pwidth
Set CreateTable = table
End Function

Any guidance gratefully received
 
D

Doug Robbins - Word MVP

You code is horribly complex. To insert a check mark into the first cell in
the first row of the first table on the document, use:

Dim myrange As Range
Set myrange = ActiveDocument.Tables(1).Cell(1, 1).Range
myrange.Collapse wdCollapseStart
myrange.InsertSymbol CharacterNumber:=252, Font:="Wingdings", Unicode:=False


The following will add a 2 x 2 table to the first cell in the first row of
the first table in the document:

Dim myrange As Range
Set myrange = ActiveDocument.Tables(1).Cell(1, 1).Range
myrange.Collapse wdCollapseStart
ActiveDocument.Tables.Add Range:=myrange, Numrows:=2, NumColumns:=2



--
Hope this helps.

Please reply to the newsgroup unless you wish to avail yourself of my
services on a paid consulting basis.

Doug Robbins - Word MVP
 
S

Shauna Kelly

Hi David

I assume you're developing a Lotus app to create a Word document for
professional use, not just as a quick fix for personal use. So it might
be worth considering a few more general things before we get to the
specifics.

1. You have used a lot of reserved words as the names of variables. I
don't know how Lotus does this stuff, so maybe it doesn't matter. But
it's unlikely to be good practice. The following are reserved words:
Cell, Selection, Range, Table. I suggest you find variable names that
avoid the reserved words.

2. Unless there's something about Lotus that requires it, you're much
better off declaring variables with an appropriate type. A Variant is a
useful thing, but not all the time. So:

Dim oCell As Word.Cell
Dim lastParagraph As Word.Paragraph
Dim newRangeStart As Long
'Dim selection As Variant - not needed, because it's not used

Dim lastParagraph As Word.Range
Dim oRange As Word.Range
Dim oTable As Word.Table

Similarly, make sure that all the parameters of a Sub or Function have
explicit types. In this:
Function CreateTable(doc As Variant, numRows As Integer, numCols As
Integer, pwidth) As Variant
pwidth is a Variant.

And finally, declare the return type for a function as an appropriate
type. So the CreateTable function might be:

Function CreateTable(doc As Word.Document, numRows As Integer,
numCols As Integer, pwidth as Single) As Word.Table

Note that I made pwidth a Single because you use it for the
..PreferredWidth of a table, and VBA Help tells me that .PreferredWidth
takes a Single.


3. Use VBA Help to get the right variable types where you can. I'm
assuming that your GetTableCell function does something like
Set GetTableCell = oTable.Rows(rowNum).Cells(colNum)
with a bit of error checking wrapped around it.

If that's the case, then rowNum and colNum need to be Longs, not
Integers. While VBA will convert from one type to another whereever it
can, it's not generally good practice to let it do so.



4. Use VBA Help to investigate each of the objects you're using (there
are only about half a dozen in your code), and have a look at their
methods and properties. You'll find, for example, that you can do this:

set paraLast = doc.Paragraphs.Last
or
set rngParaLast = doc.Paragraphs.last.range

In the following,
Set lastParagraph = doc.Paragraphs(doc.Paragraphs.Count).Range
sets lastParagraph to be the range of the last paragraph, and
Set range = doc.Range(lastParagraph.Start, lastParagraph.End)
just sets another variable to the same range. You don't need both.


5. You never *need* to use Call. If you do, only use it when you are
Call-ing a Sub of your own. You don't use it when using an object and
method from Word.


So, to the specifics:
I need to use the insertsymbol method and that needs to be on a
selection...
Ummmm, no. If you look up VBA Help for insertsymbol and click the
"Applies to" link, you'll see that InsertSymbol applies to a Range or
the Selection.

So, all you need is:

Sub addticktocell(oTable As Word.table, rowNum As Long, colNum As Long)
'Note: This isn't returning a value, so it does not need to be a
Function. It can just be a Sub.

Dim oCell As Word.cell
Dim rngForTick As Word.range

'Get a reference to our cell
Set oCell = GetTableCell(oTable:=oTable, rowNum:=rowNum, colNum:=colNum)

If Not oCell Is Nothing Then
'Get the range of the cell
Set rngForTick = oCell.range

'Omit the end-of-cell character, or we'll end up in the next cell
rngForTick.MoveEnd Unit:=wdCharacter, Count:=-1

'Collapse the range to its end
rngForTick.Collapse Direction:=wdCollapseEnd

'Insert a tick at the end of the cell
rngForTick.InsertSymbol Font:="Wingdings", CharacterNumber:=-3844,
Unicode:=True

End If

End Sub

To nest a table, just specify the range for your new table:

Function CreateNestedTable()

Dim doc As Word.Document
Dim tblExisting As Word.table
Dim tblNew As Word.table
Dim oCell As Word.cell

'Get a reference to the active document
Set doc = ActiveDocument

'Get a reference to the table of interest
'In real life, you'd put error checking in here
Set tblExisting = doc.Tables(1)

'Get a reference to the cell within which we want to nest a table
Set oCell = GetTableCell(oTable:=tblExisting, rowNum:=1, colNum:=1)

'Create a new table in our cell
if not oCell is nothing then
Set tblNew = doc.Tables.Add(range:=oCell.range, numRows:=4,
NumColumns:=3)
end if

End Function


Hope this helps.

Shauna Kelly. Microsoft MVP.
http://www.shaunakelly.com/word
 
D

David Clark

You code is horribly complex.  To insert a check mark into the first cell in
the first row of the first table on the document, use:

Dim myrange As Range
Set myrange = ActiveDocument.Tables(1).Cell(1, 1).Range
myrange.Collapse wdCollapseStart
myrange.InsertSymbol CharacterNumber:=252, Font:="Wingdings", Unicode:=False

Thanks for the very rapid response. Yes, it may be horribly complex -
I wouldn't know.
I'm struggling with translating the last lines into Lotuscript syntax
though. All other uses of the methods appear to require that I use a
function or procedure-like syntax so the third line may would need to
be something like

call myrange.collapse(wdCollapseStart)

...but then that would fail as I have nothing declared called
wdCollapseStart (and, of course, I have no idea what it is or where it
came from).

What does that .collapse method do?

Thanks again
 
D

David Clark

Hi David

I assume you're developing a Lotus app to create a Word document for
professional use, not just as a quick fix for personal use. So it might
be worth considering a few more general things before we get to the
specifics.

1. You have used a lot of reserved words as the names of variables. I
don't know how Lotus does this stuff, so maybe it doesn't matter. But
it's unlikely to be good practice. The following are reserved words:
Cell, Selection, Range, Table. I suggest you find variable names that
avoid the reserved words.

2. Unless there's something about Lotus that requires it, you're much
better off declaring variables with an appropriate type. A Variant is a
useful thing, but not all the time. So:

I see your point but perhaps there is an 'include' that I'm missing as
those data types don't mean anything at the moment. I suspect not
though as the OLE automation help example contains...

Sub GetManagers
' Use Variant variables for objects
Dim appVisioV As Variant, docObjV As Variant
Dim shapesObjV As Variant, shapeObjV As Variant


For that reason I suspect my variable names are not really reserved
words.
 
D

David Clark

Thanks for the very rapid response.  Yes, it may be horribly complex -
I wouldn't know.
I'm struggling with translating the last lines into Lotuscript syntax
though.  All other uses of the methods appear to require that I use a
function or procedure-like syntax so the third line may would need to
be something like

 call myrange.collapse(wdCollapseStart)

...but then that would fail as I have nothing declared called
wdCollapseStart (and, of course, I have no idea what it is or where it
came from).

What does that .collapse method do?

OK - I have the tick working like this ...

Function addticktocell( table As Variant, rowNum As Integer, colNum
As Integer) As Variant
Dim myrange As Variant
Set myrange = table.Cell(1, 1).Range
myrange.Collapse(1)
Call myrange.InsertSymbol(252, "Wingdings", False)
End Function

Oddly enough I have to use 'call' on the insertsymbol otherwise it
won't compile but it's happy with the 'myrange.collapse(1)'. Whatever
it takes though.


Thanks.
 
J

Jonathan West

Hi David

I think these articles will help you. Although they don't specifically
address Notes/Word integration, the lessons are generally applicable to
integration of Word with other apps, and will help you make sense of the
other responses. What Doug and Shauna have told you is entirely correct, but
I suspect they are assuming some knowledge that you don't have at the
moment. These articles will help fill the gaps.

Control Word from Excel
http://www.word.mvps.org/FAQs/InterDev/ControlWordFromXL.htm

Early vs. Late Binding
http://www.word.mvps.org/FAQs/InterDev/EarlyvsLateBinding.htm

Why variables should be declared properly
http://www.word.mvps.org/FAQs/MacrosVBA/DeclareVariables.htm

The art of defensive programming
http://www.word.mvps.org/FAQs/MacrosVBA/MaintainableCode.htm


--
Regards
Jonathan West - Word MVP
www.intelligentdocuments.co.uk
Please reply to the newsgroup
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top