Hello.

I'm trying to align all table cell contents to the bottom of the cell if
they are "Table Heading Style".

I've written the following macro to do this.

Sub AlignTables()
'Aligns table headings
Dim Table, aRow, aCell, myRange
For Each Table In ActiveDocument.Tables
For Each aRow In Table.Rows
For Each aCell In aRow.Cells
myRange = aCell
If myRange.Style = "Table Heading" Then
aCell.VerticalAlignment = wdAlignVerticalBottom
End If
Next aCell
Next aRow
Next Table
End Sub


This doesn't work though. I get an error - "Object variable or With block
variable not set".

Any ideas how I can get this working. Thanks in advance.

Dave.

Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Tue May 10 09:38:59 CDT 2005

david_alex_smith was telling us:
david_alex_smith nous racontait que :

> Hello.
>
> I'm trying to align all table cell contents to the bottom of the cell
> if they are "Table Heading Style".
>
> I've written the following macro to do this.
>
> Sub AlignTables()
> 'Aligns table headings
> Dim Table, aRow, aCell, myRange
> For Each Table In ActiveDocument.Tables
> For Each aRow In Table.Rows
> For Each aCell In aRow.Cells
> myRange = aCell
> If myRange.Style = "Table Heading" Then
> aCell.VerticalAlignment = wdAlignVerticalBottom
> End If
> Next aCell
> Next aRow
> Next Table
> End Sub
>
>
> This doesn't work though. I get an error - "Object variable or With
> block variable not set".
>
> Any ideas how I can get this working. Thanks in advance.
>

Five comments:

1) It is not a good idea to use a variable name that happens to be a
constant, an object name, a method name or a property name in the Object
model. Table is an object name.

2) It is much better practice to explicitly cast the variable to a type.
When you do that, you and the compiler both know what you are dealing with
anywhere in the code. This way you don't need to let the compiler decide for
you and then produce funny results...as you have experienced. As a big plus
to this practice, Intellisense will work when you write your code, so if you
try to use a method/property with an object that does not support it, you
will know right away.

3) It is also much better not to use default assignment ("myRange = aCell"
You want myRange to be a range object, but have not said so anywhere in your
code, and you want aCell to be the range in the cell represented by aCell
which the compiler had to infer...) Also, we do not know if in future
versions of the Word object model if the default will remain the same, or
even be allowed to be used.

4) It is recommended not to use the object in the Next statement.
For Each myThingy In ActiveDocument.Thingies
Test myThingy
Next
If you want, you can comment it so that you know what each next is referring
to:
For Each myThingy In ActiveDocument.Thingies
Test myThingy
Next 'myThingy

5) Finally, and this is where you had the problem generating the error
message, you need a "Set" statement to assign a document range to a range
object in the code.

Here is a revised version of your code.

'_______________________________________
Sub AlignTables()
'Aligns table headings
Dim aTable As Table
Dim aRow As Row
Dim aCell As Cell
Dim myRange As Range

For Each aTable In ActiveDocument.Tables
For Each aRow In aTable.Rows
For Each aCell In aRow.Cells
Set myRange = aCell.Range
If myRange.Style = "Table Heading" Then
aCell.VerticalAlignment = wdAlignVerticalBottom
End If
Next
Next
Next

End Sub
'_______________________________________

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org




Re: Aligning table cell contents based on style by davidalexsmith

davidalexsmith
Wed May 11 03:26:04 CDT 2005

Merci Jean-Guy,

Thanks for the tips on good practice. I still get the same error though.
- "Object variable or With block variable not set".

Dave.




"Jean-Guy Marcil" wrote:

> david_alex_smith was telling us:
> david_alex_smith nous racontait que :
>
> > Hello.
> >
> > I'm trying to align all table cell contents to the bottom of the cell
> > if they are "Table Heading Style".
> >
> > I've written the following macro to do this.
> >
> > Sub AlignTables()
> > 'Aligns table headings
> > Dim Table, aRow, aCell, myRange
> > For Each Table In ActiveDocument.Tables
> > For Each aRow In Table.Rows
> > For Each aCell In aRow.Cells
> > myRange = aCell
> > If myRange.Style = "Table Heading" Then
> > aCell.VerticalAlignment = wdAlignVerticalBottom
> > End If
> > Next aCell
> > Next aRow
> > Next Table
> > End Sub
> >
> >
> > This doesn't work though. I get an error - "Object variable or With
> > block variable not set".
> >
> > Any ideas how I can get this working. Thanks in advance.
> >
>
> Five comments:
>
> 1) It is not a good idea to use a variable name that happens to be a
> constant, an object name, a method name or a property name in the Object
> model. Table is an object name.
>
> 2) It is much better practice to explicitly cast the variable to a type.
> When you do that, you and the compiler both know what you are dealing with
> anywhere in the code. This way you don't need to let the compiler decide for
> you and then produce funny results...as you have experienced. As a big plus
> to this practice, Intellisense will work when you write your code, so if you
> try to use a method/property with an object that does not support it, you
> will know right away.
>
> 3) It is also much better not to use default assignment ("myRange = aCell"
> You want myRange to be a range object, but have not said so anywhere in your
> code, and you want aCell to be the range in the cell represented by aCell
> which the compiler had to infer...) Also, we do not know if in future
> versions of the Word object model if the default will remain the same, or
> even be allowed to be used.
>
> 4) It is recommended not to use the object in the Next statement.
> For Each myThingy In ActiveDocument.Thingies
> Test myThingy
> Next
> If you want, you can comment it so that you know what each next is referring
> to:
> For Each myThingy In ActiveDocument.Thingies
> Test myThingy
> Next 'myThingy
>
> 5) Finally, and this is where you had the problem generating the error
> message, you need a "Set" statement to assign a document range to a range
> object in the code.
>
> Here is a revised version of your code.
>
> '_______________________________________
> Sub AlignTables()
> 'Aligns table headings
> Dim aTable As Table
> Dim aRow As Row
> Dim aCell As Cell
> Dim myRange As Range
>
> For Each aTable In ActiveDocument.Tables
> For Each aRow In aTable.Rows
> For Each aCell In aRow.Cells
> Set myRange = aCell.Range
> If myRange.Style = "Table Heading" Then
> aCell.VerticalAlignment = wdAlignVerticalBottom
> End If
> Next
> Next
> Next
>
> End Sub
> '_______________________________________
>
> --
> Salut!
> _______________________________________
> Jean-Guy Marcil - Word MVP
> jmarcilREMOVE@CAPSsympatico.caTHISTOO
> Word MVP site: http://www.word.mvps.org
>
>
>
>

Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Wed May 11 08:58:24 CDT 2005

david_alex_smith was telling us:
david_alex_smith nous racontait que :

> Merci Jean-Guy,
>
> Thanks for the tips on good practice. I still get the same error
> though. - "Object variable or With block variable not set".

Have you tried the code I posted?

It worked without any problems on many test runs on my machine.

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org




Re: Aligning table cell contents based on style by Greg

Greg
Wed May 11 09:16:03 CDT 2005

JGM,

I read with great interest. Thank you.

David's orginal code worked in the limited testing I did.

Can you shed a little insight on why you use the Rows statement and why
you use the myRange statement. Seems to me that both can be
eliminated.


Sub AlignTables()
Dim aTable As Table
Dim aCell As Cell

For Each aTable In ActiveDocument.Tables
For Each aCell In aTable.Range.Cells
If aCell.Range.Style = "Table Heading" Then
aCell.VerticalAlignment = wdAlignVerticalBottom
End If
Next
Next

End Sub

Thanks.


Re: Aligning table cell contents based on style by davidalexsmith

davidalexsmith
Wed May 11 09:32:16 CDT 2005

Yes - I'm using the code exactly as you posted. I'm still getting the same
error. Am going to try Greg's solution now.

Re: Aligning table cell contents based on style by davidalexsmith

davidalexsmith
Wed May 11 09:38:14 CDT 2005

Greg,

I orignally tried to do something very like your suggestion but couldn't
make it work.

I've just tried your code and i get the same error as i get when i run mine
or JGM's.

Am running Word 2003 on XP. Is it possible there is something wrong with my
installation? Am puzzled if these work on your machines but not mine.

Dave.

Re: Aligning table cell contents based on style by Greg

Greg
Wed May 11 09:58:14 CDT 2005

JGM,

Runnig a test on a table with 6300 rows. The method that you posted
took 34.63 seconds. The method I posted took 3.375 seconds.

There is an even faster method that Steve Hudson showed me.

Public Sub AlignTables3()
Dim aTable As Table
Dim myRange As Range
Dim oCell As Cell
Dim StartTime As Single

StartTime = Timer

For Each aTable In ActiveDocument.Tables
With aTable.Range
Set myRange = .Cells(1).Range
Do
If myRange.Style = "Table Heading" Then
Set oCell = myRange.Cells(1)
oCell.VerticalAlignment = wdAlignVerticalBottom
End If
myRange.Collapse wdCollapseEnd
myRange.MoveEnd wdParagraph, 1
Loop Until myRange.End = .End
End With
Set myRange = Nothing
MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
Next
End Sub

There isn't must difference with a 6300 cell table, (less than 1/2 a
second) but the difference grows as the number of cells increases.

Again, my purpose for pointing this out is to see if there is some
stability issues that I am not aware by using either of these faster
methods.


Re: Aligning table cell contents based on style by davidalexsmith

davidalexsmith
Wed May 11 10:10:05 CDT 2005

I still get the same error when running this code. What on earth is wrong
with my Word?

Dave.

Re: Aligning table cell contents based on style by Greg

Greg
Wed May 11 11:38:20 CDT 2005

I meant 6300 cells not rows.


Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Wed May 11 12:31:43 CDT 2005

Greg was telling us:
Greg nous racontait que :

> JGM,
>
> I read with great interest. Thank you.
>
> David's orginal code worked in the limited testing I did.
>
> Can you shed a little insight on why you use the Rows statement and
> why you use the myRange statement. Seems to me that both can be
> eliminated.

I was not really thinking about streamlining the code. I just took the
poster's code and rewrote it.
pointing out where he went wrong with the assignment.

You are right that myRange/myRow are not necessary in this case because we
are not doing anything else with it.

> Sub AlignTables()
> Dim aTable As Table
> Dim aCell As Cell
>
> For Each aTable In ActiveDocument.Tables
> For Each aCell In aTable.Range.Cells
> If aCell.Range.Style = "Table Heading" Then
> aCell.VerticalAlignment = wdAlignVerticalBottom
> End If
> Next
> Next
>
> End Sub
>
> Thanks.

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org




Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Wed May 11 12:34:48 CDT 2005

Greg was telling us:
Greg nous racontait que :

> JGM,
>
> Runnig a test on a table with 6300 rows. The method that you posted
> took 34.63 seconds. The method I posted took 3.375 seconds.
>
> There is an even faster method that Steve Hudson showed me.
>
> Public Sub AlignTables3()
> Dim aTable As Table
> Dim myRange As Range
> Dim oCell As Cell
> Dim StartTime As Single
>
> StartTime = Timer
>
> For Each aTable In ActiveDocument.Tables
> With aTable.Range
> Set myRange = .Cells(1).Range
> Do
> If myRange.Style = "Table Heading" Then
> Set oCell = myRange.Cells(1)
> oCell.VerticalAlignment = wdAlignVerticalBottom
> End If
> myRange.Collapse wdCollapseEnd
> myRange.MoveEnd wdParagraph, 1
> Loop Until myRange.End = .End
> End With
> Set myRange = Nothing
> MsgBox "Time taken was: " & (Timer - StartTime) & " seconds"
> Next
> End Sub
>
> There isn't must difference with a 6300 cell table, (less than 1/2 a
> second) but the difference grows as the number of cells increases.
>
> Again, my purpose for pointing this out is to see if there is some
> stability issues that I am not aware by using either of these faster
> methods.

Thanks for reminding me about the speed factor...
--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org




Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Wed May 11 12:38:31 CDT 2005

david_alex_smith was telling us:
david_alex_smith nous racontait que :

> I still get the same error when running this code. What on earth is
> wrong with my Word?
>

Describe you document content.
Also, are you running any code before the code Greg posted?
How are you calling the code?

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org




Re: Aligning table cell contents based on style by Greg

Greg
Wed May 11 15:55:21 CDT 2005

Dave,

As I mentioned, I ran the original code you posted with no problem.

Have you tried stepping through the code one line at a time with the F8 key?
What line is generating the error?


--
Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.

david_alex_smith wrote:
> Greg,
>
> I orignally tried to do something very like your suggestion but
> couldn't make it work.
>
> I've just tried your code and i get the same error as i get when i
> run mine or JGM's.
>
> Am running Word 2003 on XP. Is it possible there is something wrong
> with my installation? Am puzzled if these work on your machines but
> not mine.
>
> Dave.



Re: Aligning table cell contents based on style by davidalexsmith

davidalexsmith
Thu May 12 04:00:04 CDT 2005

Thanks for your continued help on this guys.

The word documented is created by AuthorIT (a single-souce publishing
solution) http://www.author-it.com/.

This populates a Word template with content from a database when publishing
a particular document. This template includes an AfterPublish macro which is
run when AuthorIT has finished building the document. I'm using this to call
my code (however, I get the same error if I call it manually from the VB
editor).

The line that causes the error is indicated below:

Sub AlignTables()
Dim aTable As Table
Dim aCell As Cell

For Each aTable In ActiveDocument.Tables
For Each aCell In aTable.Range.Cells
If aCell.Range.Style = "Table Heading" Then '***This one causes error***
aCell.VerticalAlignment = wdAlignVerticalBottom
End If
Next
Next

End Sub


The error is:

Run-time error '91'

Object variable or With block variable not set.


I could send a sample document by email if anyone would like to try and
discover a solution.

Thanks

Dave.

Re: Aligning table cell contents based on style by Greg

Greg
Thu May 12 06:48:14 CDT 2005

Dave,

Hmm. Here is what help says about Error 91:

Object variable or With block variable not set (Error 91):

There are two steps to creating an object variable. First you must
declare the object variable. Then you must assign a valid reference to
the object variable using the Set statement. Similarly, a With...End
With block must be initialized by executing the With statement entry
point. This error has the following causes and solutions:

You attempted to use an object variable that isn't yet referencing a
valid object.
Specify or respecify a reference for the object variable. For example,
if the Set statement is omitted in the following code, an error would
be generated on the reference to MyObject:

Dim MyObject As Object ' Create object variable.
Set MyObject = Sheets(1) ' Create valid object reference.
MyCount = MyObject.Count ' Assign Count value to MyCount.

You attempted to use an object variable that has been set to Nothing.
Set MyObject = Nothing ' Release the object.
MyCount = MyObject.Count ' Make a reference to a released object.

Respecify a reference for the object variable. For example, use a new
Set statement to set a new reference to the object.

The object is a valid object, but it wasn't set because the object
library in which it is described hasn't been selected in the References
dialog box.
Select the object library in the Add References dialog box.

The target of a GoTo statement is inside a With block.
Don't jump into a With block. Make sure the block is initialized by
executing the With statement entry point.

You specified a line inside a With block when you chose the Set Next
Statement command.
The With block must be initialized by executing the With statement.

For additional information, select the item in question and press F1
(in Windows) or HELP (on the Macintosh).

Lets try:
Sub AlignTables()
Dim aTable As Table
Dim aCell As Cell
Dim oStyle As Style

Set oStyle = ActiveDocument.Styles("Table Heading")

For Each aTable In ActiveDocument.Tables
For Each aCell In aTable.Range.Cells
'On Error Resume Next
If aCell.Range.Style = oStyle Then

aCell.VerticalAlignment = wdAlignVerticalBottom
End If
'On Error Goto 0
Next
Next
Exit Sub

End Sub

If nothing changes, then try uncommenting the On Error lines.


Re: Aligning table cell contents based on style by Jean-Guy

Jean-Guy
Thu May 12 08:42:12 CDT 2005

david_alex_smith was telling us:
david_alex_smith nous racontait que :

> Thanks for your continued help on this guys.
>
> The word documented is created by AuthorIT (a single-souce publishing
> solution) http://www.author-it.com/.
>
> This populates a Word template with content from a database when
> publishing a particular document. This template includes an
> AfterPublish macro which is run when AuthorIT has finished building
> the document. I'm using this to call my code (however, I get the same
> error if I call it manually from the VB editor).


Without knowing what this other code that runs first does, it is difficult
to find the problem.
Can you post the relevant bits of code (The part about calling your code
from the other code)
Alternatively, can you set up a sample document somewhere that we can look
at?

--
Salut!
_______________________________________
Jean-Guy Marcil - Word MVP
jmarcilREMOVE@CAPSsympatico.caTHISTOO
Word MVP site: http://www.word.mvps.org