Here's a fine example of the use of ranges, if I say so myself. Well, OK. It's one of my best efforts to date in weaning me away from Selection.

Ranges is not bad at all, indeed jolly sweet once you cross the river.


The function lngInsertLeftColumn immediately below is a slave utility function from the module U of my Utils.dot.

It satisfies a slew of User Command Macros (posted waaaay below) for those of us who use tables for column alignment. Typically I insert a table, populate it with data, and forget to shunt it over to the right. The associated command macros insert a column and remove unwanted borders.

You'll note that I've maintained my policy of returning a value from a function.

The argument is a range, and this internal function (it's not a user command macro) assumes that who/whatever called it knows what it is doing, and that the range passed is a part of a table. As long as my rngTbl is within the table, I can use the range as the basis for talking about the table, or any row, column or cell of the table. In this example I need to discuss the 1st column, so I refer to it as "rngTbl.Tables(1).Columns(1).Cells".

All my Table Slave utility procedures use this "rngTbl" argument.

I recorded a macro for the .Borders stuff and pasted it in, deleting unwanted stuff.

<pre>Public Function lngInsertLeftColumn(rngTbl As Range) As Long
' Procedure: lngInsertLeftColumn
' Description: Insert one column at the left of the table
' By: Chris Greaves Inc.
' Inputs: RANGE of table.
' Returns: None.
' Assumes: None.
' Side Effects: Page layout may change.
' Tested: By the calls below.
rngTbl.Columns.Add BeforeColumn:=rngTbl.Tables(1).Columns(1)

With rngTbl.Tables(1).Columns(1).Cells
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
.Borders(wdBorderTop).LineStyle = wdLineStyleNone
.Borders(wdBorderBottom).LineStyle = wdLineStyleNone
.Borders(wdBorderHorizontal).LineStyle = wdLineStyleNone
.Borders.Shadow = False
End With

lngInsertLeftColumn = rngTbl.Tables(1).Columns.Count
'Sub TESTlngInsertLeftColumn()
'Documents.Add
'ActiveDocument.Tables.Add Range:=Selection.Range, NumRows:=8, NumColumns:=8
'MsgBox lngInsertLeftColumn(Selection.Tables(1).Range)
'End Sub
End Function
</pre>



Pasted below are two command macros that use the slave procedure above. The slave requires a range-that-is-within-a-table as an argument, so each slave has to determine a suitable range to pass. Some bright spark is going to try calling the slave with a range that starts outside a table and ends inside a table, right?

The macros look similar, right? By design they have the same name. The first macro is stored in my module TAll (operates on all tables of a document) in Under.dot, the second macro is stored in my TSole (operates on a SOLE Table) module of Under.dot. I can have the same command and button but stored on different sub-menus of the toolbar menu "Table" in Under.dot.


The first macro doesn't have to check if we are in a table - the FOR loop takes care of that.

The second macro checks, and calls a temporary error routine (which for now just pops up a MsgBox).


<pre>Public Sub cmd_InsertLeftColumn()
' Procedure: cmd_InsertLeftColumn
' Description: Insert an extra column for all tables in a document.
' Copyright: Chris Greaves Inc.
' Inputs: None.
' Returns: None.
' Assumes: None.
' Side Effects: Page formatting may change.
' Tested: By a call from the user.
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
Call lngInsertLeftColumn(tbl.Range)
Next tbl
End Sub

Public Sub cmd_InsertLeftColumn()
' Procedure: cmd_InsertLeftColumn
' Description: Insert an extra column for all tables in a document.
' By: Chris Greaves Inc.
' Inputs: None.
' Returns: None.
' Assumes: None.
' Side Effects: Page layout may change.
' Tested: By a call from the the user.
If Selection.Information(wdWithInTable) Then
Call lngInsertLeftColumn(Selection.Tables(1).Range)
Else
Call errMustBeInTable
End If
End Sub
</pre>