Table Styles
This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.
.gif)
VBA Hacker
Creating Consistent Tables with Named Formats
By Romke Soldaat
Styles have been with Word from its earliest MS-DOS
versions in the mid eighties. They've become such an integrated part of
this word processor that you can't even create a document without them.
According to Microsoft: "A style is a set of formatting characteristics
that you can apply to text in your document to quickly change its
appearance. When you apply a style, you apply a whole group of formats in
one simple task."
Sure, styles are great. They're so powerful and flexible
that I've often wondered why our friends in Redmond never thought of
applying the style concept to Word's table feature. The closest you can
get to easy table formatting is by using the options in the Table
AutoFormat dialog box. But the silly names used for the formats don't make
them easy to remember and use. Would you know the difference between
"Classic 1" and "Classic 4"? What makes the "Elegant" format elegant, and
what's so professional about the "Professional" format? And do the three
"Colorful" formats still deserve their name if they turn into shades of
gray when you clear the Colors checkbox in the AutoFormat dialog box?
In this article I'll introduce a way to personalize your
table formatting by creating Table Styles. With the application in the
download file (see end of article for download details), you can format
your tables using styles that have names that make sense to you, such as
"Sales report," "Zebra stripes," or "Black header above white rows" (see
FIGURE 1). There's even an option to apply an identical style to all
tables in a document, so you don't have to format each table separately.
FIGURE
1: The official format names (clockwise from top left) are Simple 3,
Colorful 1, Columns 5, and List 8. By creating Table Styles, you could
name them "Black Header," "Pistachio," "White and gray columns," and
"Symphony in Pink and Yellow."
AutoFormatting Tables
When you select Table AutoFormat from the Table menu
(while the insertion point is inside a table), the dialog box shown in
FIGURE 2 is displayed. This dialog box lets you choose from no fewer than
42 predefined formats, and within each format, you can apply or remove up
to nine sub-formats. Since the preview is fully interactive, you can see
the effect of your choice immediately. After clicking the OK button, the
selected formats are applied to the underlying table.
FIGURE
2: Powerful formatting, but silly format names.
The VBA way. Although Microsoft doesn't
explicitly say so, there are two ways to AutoFormat tables from a macro.
VBA Help only mentions the AutoFormat method, which uses the
following syntax:
expression.AutoFormat(Format, ApplyBorders, ApplyShading, _
ApplyFont, ApplyColor, ApplyHeadingRows, ApplyLastRow, _
ApplyFirstColumn, ApplyLastColumn, AutoFit)
In this syntax, expression must return a Table
object, and all other (optional) parameters are treated as Variants. The
Format parameter must be one of the WdTableFormat constants,
or its matching numeric value (see FIGURE 3).
|
WdTableFormat constants |
Value |
|
wdTableFormatNone |
0 |
|
wdTableFormatSimple1 |
1 |
|
wdTableFormatSimple2 |
2 |
|
wdTableFormatSimple3 |
3 |
|
wdTableFormatClassic1 |
4 |
|
wdTableFormatClassic2 |
5 |
|
wdTableFormatClassic3 |
6 |
|
wdTableFormatClassic4 |
7 |
|
wdTableFormatColorful1 |
8 |
|
wdTableFormatColorful2 |
9 |
|
wdTableFormatColorful3 |
10 |
|
wdTableFormatColumns1 |
11 |
|
wdTableFormatColumns2 |
12 |
|
wdTableFormatColumns3 |
13 |
|
wdTableFormatColumns4 |
14 |
|
wdTableFormatColumns5 |
15 |
|
wdTableFormatGrid1 |
16 |
|
wdTableFormatGrid2 |
17 |
|
wdTableFormatGrid3 |
18 |
|
wdTableFormatGrid4 |
19 |
|
wdTableFormatGrid5 |
20 |
|
wdTableFormatGrid6 |
21 |
|
wdTableFormatGrid7 |
22 |
|
wdTableFormatGrid8 |
23 |
|
wdTableFormatList1 |
24 |
|
wdTableFormatList2 |
25 |
|
wdTableFormatList3 |
26 |
|
wdTableFormatList4 |
27 |
|
wdTableFormatList5 |
28 |
|
wdTableFormatList6 |
29 |
|
wdTableFormatList7 |
30 |
|
wdTableFormatList8 |
31 |
|
wdTableFormat3DEffects1 |
32 |
|
wdTableFormat3DEffects2 |
33 |
|
wdTableFormat3DEffects3 |
34 |
|
wdTableFormatContemporary |
35 |
|
wdTableFormatElegant |
36 |
|
wdTableFormatProfessional |
37 |
|
wdTableFormatSubtle1 |
38 |
|
wdTableFormatSubtle2 |
39 |
|
wdTableFormatWeb1 |
40 |
|
wdTableFormatWeb2 |
41 |
|
wdTableFormatWeb3 |
42 |
FIGURE 3: WdTableFormat constants.
If no format is specified, Word assumes
wdTableFormatSimple1 (value 1). All other nine parameters must be
set to True or False, corresponding to the status of the
checkboxes in the dialog box. If omitted, these values default to
True, except ApplyLastRow and ApplyLastColumn, which
are assumed to be False if no value is specified. The instruction
in FIGURE 4 demonstrates the AutoFormat method.
With Selection.Tables(1) ' First table in the selection.
.AutoFormat _
Format:=wdTableFormat3DEffects1,_
ApplyBorders:= True, _
ApplyShading:= True, _
ApplyFont:= True, _
ApplyColor:= True, _
ApplyHeadingRows:= True, _
ApplyLastRow:= True, _
ApplyFirstColumn:= True, _
ApplyLastColumn:= True, _
AutoFit:= True
End With
FIGURE 4: The AutoFormat method.
The second method to AutoFormat a table is by directly
communicating with the Table AutoFormat dialog box. Like all Word's dialog
boxes, it's part of the Dialogs collection, so you can set its
arguments from VBA code, and use the Execute method to make the
settings active without displaying the dialog box. The code in FIGURE 5
applies the same table formatting as the instruction in FIGURE 4.
With Dialogs(wdDialogTableAutoFormat)
.Format = wdTableFormat3DEffects1
.Borders = True
.Shading = True
.Font = True
.Color = True
.HeadingRows = True
.LastRow = True
.FirstColumn = True
.LastColumn = True
.AutoFit = True
.Execute ' Apply the settings.
End With
FIGURE 5: The Dialog method.
The difference between these two methods is that the
AutoFormat method can be applied to any table in any open document,
no matter where the insertion point is. The Dialog method can only
be used if the insertion point is inside a table.
On the other hand, the first method doesn't allow you to
retrieve a table's AutoFormat
settings, with the exception of the main format itself, which you can
obtain using the AutoFormatType property of the Table
object. That's a serious omission. Microsoft could have done a better job
if AutoFormat had been an
object with read/write properties, just as the CalloutFormat,
ParagraphFormat, and PictureFormat objects.
Fortunately, the Dialog method is more generous
with information, even though you can only use it if the insertion point
is in a table. FIGURE 6 demonstrates how you can get the status of any AutoFormat setting in the active
table. (Note that, unlike checkboxes in Microsoft forms, checkboxes in
Word's internal dialog boxes return 1 if they are checked, not -1.)
With Dialogs(wdDialogTableAutoFormat)
FormatChosen = .Format ' 0 - 42
BordersActivated = .Borders ' 0 or 1
ShadingActivated = .Shading ' 0 or 1
FontActivated = .Font ' 0 or 1
ColorActivated = .Color ' 0 or 1
HeadingRowsActivated = .HeadingRows ' 0 or 1
LastRowActivated = .LastRow ' 0 or 1
FirstColumnActivated = .FirstColumn ' 0 or 1
LastColumnActivated .LastColumn ' 0 or 1
AutoFitActivated = .AutoFit ' 0 or 1
End With
FIGURE 6: You can obtain the status of any AutoFormat
setting in the active table.
Defining Table Styles
The table styles we'll be using in this project must be
based on one of the 43 predefined formats; any additional manual
formatting isn't taken into account. If this sounds like a limitation,
remember that you can apply up to nine sub-formats within each main
format, so you have around 3,000 variations at your disposal. Just
experiment a bit with the Borders, Color, and Shading checkboxes in the
dialog box, and you'll see how versatile table auto-formatting can be.
Once you've found the right combination of main format
and sub-formats, you can assign a meaningful name to the result, just as
you would do with paragraph and character styles. After that, you can
re-apply your table style, simply by selecting its name from your list of
available styles. (We'll look at the interface later.)
Retrieving table style definitions. After you've
used the Table AutoFormat dialog box or VBA code to format a table, Word
"remembers" your settings. If you select the table again, and redisplay
the dialog box, you'll see that your original format and sub-formats are
pre-selected. This must mean that Word saves the AutoFormat information
inside the table. You can get part of this information by looking at the
table's AutoFormatType property. This read-only property returns a
Long value in the range 0-42, corresponding to the values shown in
FIGURE 3.
However, there are no documented table properties that
tell you which of the nine sub-formats are applied. The only clue I see in
the Object Browser is a series of WdTableFormatApply constants;
their values are shown in FIGURE 7. This is an interesting range. If
you're familiar with the binary system, you'll see immediately that these
values are bit settings. If this sounds foreign to you, read on for a
simplified explanation.
|
WdTableFormatApply constants |
Value |
|
wdTableFormatApplyBorders |
1 |
|
wdTableFormatApplyShading |
2 |
|
wdTableFormatApplyFont |
4 |
|
wdTableFormatApplyColor |
8 |
|
wdTableFormatApplyAutoFit |
16 |
|
wdTableFormatApplyHeadingRows |
32 |
|
wdTableFormatApplyLastRow |
64 |
|
wdTableFormatApplyFirstColumn |
128 |
|
wdTableFormatApplyLastColumn |
256 |
FIGURE 7: WdTableFormatApply constants. The
values represent bit settings.
Hacking Bits
Computers don't know anything about our decimal system
(which is based on the fact that humans happen to have 10 fingers).
Computers can only think in two values - 0 and 1 - so numbers must be
expressed as a combination of 0s and 1s. For example, the decimal number
343 is expressed as the binary number 101010111. Each element of this
number represents a bit, so this number is a nine-bit binary value.
Because binary numbers are read from right to left, the first three bits
have a value of 1; bits four, six, and eight are 0; and bits five, seven,
and nine are 1. Each bit represents an integer value that's twice as large
as the value of the previous bit. To be more precise: The integer value
represented by a bit is the same as 2 to the power of the bit position
(see FIGURE 8).
FIGURE
8: How bits are organized and interpreted. This range covers decimal
values that can be expressed in 15 bits.
Row 1 represents the positions of bits in a 15-bit
number (counting starts at zero, and bits are arranged from right to
left). Row 2 lists the decimal value associated with each bit. Row 3 shows
the same values as row 2, but are expressed as values in which 2 is raised
to the power of the bit position. The gray part of row 4 shows the binary
representation of our example (the decimal value 343).
Now, look at the WdTableFormatApply constants in
FIGURE 7. They're exactly the same as the values in the gray part of the
second row in FIGURE 8 - ranging from 1 to 256.
Next, look at the checkbox settings in FIGURE 2 in the
following order: Borders, Shading, Font, Color, AutoFit, Heading rows,
Last row, First column, and Last column. Compare their values (0 for
unchecked, 1 for checked) with the ones in the fourth row in FIGURE 8,
starting from the right. As you'll see, they match, too.
Finally, multiply the bit values in row 4 with their
corresponding decimal values in row 2, and add them up. What you get is
(1x1) + (1x2) + (1x4) + (0x8) + (1x16) + (0x32) + (1x64) + (0x128) +
(1x256) = 343. If all nine bits were set (meaning that all checkboxes are
checked in the dialog box), you would end up with a value of 511; if none
were set, you would get zero.
This binary arithmetic demonstrates that we can store
all nine sub-format settings of the Table AutoFormat dialog box in a
single numeric value. We already know how to get the main format: either
by evaluating the AutoFormatType property of the Table
object, or by looking at the value of the Format argument in the
Table AutoFormat dialog box, each of which gives us one of the
WdTableFormat values shown in FIGURE 3.
We could of course save both values separately as part
of our table style definition, but there's a more interesting way. How
about combining them in a single numeric value?
Shifting Bits
Since we've stored the nine sub-formats in the first
nine bits, we can't cram the main format in the same bits. So we have to
go higher up. Literally. The WdTableFormat constants cover
values from 0 to 42, which can be represented in a six-bit binary number.
What we'll do is elevate that value so that its bits are stored in
positions nine through 14. In programmer's jargon this is called "bit
shifting." We can do that by multiplying the WdTableFormat value
with the value that's associated with the first bit position we want to
use, in this case 2^9, or 512 (see the right-most yellow column in FIGURE
8). So, if the main format is wdTableFormat3DEffects2 (decimal 33,
binary 100001), we save it as 33 * 512 = 16896, and then add the value we
retrieved for the sub-formats (which was 343). This gives us a total of
16896 + 343 = 17239. Row 5 in FIGURE 7 shows that the result is a binary
value of 100001101010111.
FIGURE 9 lists a function that combines all these
calculations, and returns the unique numeric style definition for the
table that contains the insertion point.
Function GetTableFormat()As Long
If Selection.Information(wdWithInTable) Then
With Dialogs(wdDialogTableAutoFormat)
GetTableFormat = _
.Borders * wdTableFormatApplyBorders + _
.Shading * wdTableFormatApplyShading + _
.Font * wdTableFormatApplyFont + _
.Color * wdTableFormatApplyColor + _
.AutoFit * wdTableFormatApplyAutoFit + _
.HeadingRows * wdTableFormatApplyHeadingRows + _
.LastRow * wdTableFormatApplyLastRow + _
.FirstColumn * wdTableFormatApplyFirstColumn + _
.LastColumn * wdTableFormatApplyLastColumn + _
.Format * 2 ^ 9
End With
End If
End Function
Sub SetTableFormat(ByVal objTable As Table, _
ByVal iDef As Long)
If Not objTable Is Nothing Then
With objTable
.AutoFormat _
Format:=iDef \ 512, _
ApplyBorders:= CBool(iDef And _
wdTableFormatApplyBorders), _
ApplyShading:= CBool(iDef And _
wdTableFormatApplyShading), _
ApplyFont:= CBool(iDef And _
wdTableFormatApplyFont), _
ApplyColor:= CBool(iDef And _
wdTableFormatApplyColor), _
AutoFit:= CBool(iDef And _
wdTableFormatApplyAutoFit), _
ApplyHeadingRows:= CBool(iDef And _
wdTableFormatApplyHeadingRows), _
ApplyLastRow:= CBool(iDef And _
wdTableFormatApplyLastRow), _
ApplyFirstColumn:= CBool(iDef And _
wdTableFormatApplyFirstColumn), _
ApplyLastColumn:= CBool(iDef And _
wdTableFormatApplyBorders)
End With
End If
End Sub
FIGURE 9: The GetTableFormat function returns a
unique value, representing all Table AutoFormat settings. The
SetTableFormat subroutine applies a table style value to a given
table.
Recreating the Table Format
Once we've stored a table format as a number, we should
be able to use that value to apply the same format to another table. Let's
assume we have a table style definition, stored as 17239. Since we
multiplied the original main format with 512, we can get that value back
by reversing the process. So, we divide the table style value by 512, and
use the integer part of the result. The formula is (note the use of the
backslash as the "integer division" symbol):
OriginalFormat = StyleDef \ 512
If StyleDef
equals 17239, this calculation gives us a value of 33, which is the value
of the wdTableFormat3DEffects2 constant.
To extract the settings of the nine sub-formats, we have
to perform some bit manipulation. The way to do this is by using the
logical And operator. And compares identically positioned
bits in two numbers. If the bit in each number has a value of 1, the
corresponding integer value is returned; otherwise you'll get a 0 value.
The trick is to ensure that at least one of the values has the specified
bit set, so we get only a non-zero result if the same bit is also set in
the other value. The formula is:
BitValue = StyleDef And 2^BitPos
For example, to check the bit status of the fifth bit in
the value 17239, which represents the AutoFit setting of the table format,
you use this VBA statement:
' 4 is the number of the fifth bit.
AutoFitSetting = (17239 And 2 ^ 4)
But there's a more user-friendly way. The value 2^4 is
the same as the value of the wdTableFormatApplyAutoFit constant
(16). Our code becomes more readable if we use the following instruction:
AutoFitSetting = (17239 And wdTableFormatApplyAutoFit)
If the table style definition has its fifth bit set
(which it has; see FIGURE 8), this instruction returns the decimal value
(16) associated with bit position 4; otherwise we get a 0. Since the
AutoFormat method wants its parameters as Boolean values, we can
use the CBool function and change the instruction so we get a
"real" True or False value:
AutoFitSetting = CBool(17239 And wdTableFormatApplyAutoFit)
For purists, we can also use the following Boolean
comparison to get the same result:
AutoFitSetting = (17239 And wdTableFormatApplyAutoFit) = _
wdTableFormatApplyAutoFit
The SetTableFormat routine in FIGURE 9 uses all
these formulas to apply a given style to a given table. For example, to
apply style definition 17239 to the table that contains the insertion
point, you use the following instruction:
SetTableFormat Selection.Tables(1), 17239
To create consistently formatted tables throughout a
document, the code is equally simple:
For Each objTable In ActiveDocument.Tables
SetTableFormat objTable, 17239
Next
The Application
The accompanying download file contains a ready-to-use
Word 2000 template that uses the code shown in Listing
One and Listing
Two. The application creates a new menu item on the Table menu (see
FIGURE 10), that lets you create, apply, rename, and delete table styles.
Each style definition is stored in the Windows registry under the section
HKEY_CURRENT_USER\Software\VB and VBA Program Settings\Tweak Office
2000\Word\Table Styles. The interface is deliberately kept simple, and
uses standard VBA input boxes and message boxes when it enters into a
dialog with the user. The project is unprotected, so you can study and
customize the code.
FIGURE
10: The Table Styles application in action.
Conclusion
The purpose of this series is to demonstrate that there
is a lot more to VBA programming than you may think. With a bit of
hacking, you can greatly enhance your Office environment. In this
installment, I showed you how you can use Word's Table AutoFormat feature
to create table styles that can be applied just like paragraph and
character styles. Watch this space for more VBA hacks!
Dutchman Romke Soldaat was hired by Microsoft in 1988 to
co-found the Microsoft International Product Group in Dublin, Ireland.
That same year he started working with the prototypes of WinWord, writing
his first macros long before the rest of the world. In 1992 he left
Microsoft, and created a number of successful add-ons for Office. Living
in Italy, he divides his time between writing articles for this magazine,
enjoying the Mediterranean climate, and steering his Land Rover through
the world's most deserted areas. Romke can be contacted at romke@soldaat.com.
Begin Listing One -
TableStylesInterface.bas
Option Explicit
Dim objContext As Template
Dim varAllStyles As Variant
Const BAR_TABLE As String = "Table"
Const MNU_STYLE As String = "Table St&yle"
Public Const REG_APP As String = "Tweak Office 2000\Word"
Public Const REG_SEC As String = "Table Styles"
Sub AutoExec()
' This macro runs when the add-in is loaded.
InitializeContext
If objContext Is Nothing Then Exit Sub
CreateInterface
CleanUpContext
End Sub
Sub AutoExit()
' This macro runs when the add-in is unloaded.
DeleteInterface
End Sub
Sub InitializeContext()
' This routine makes sure that all changes are
' made in this add-in template.
On Error Resume Next
With MacroContainer
Set objContext = Templates(.Path & _
Application.PathSeparator & .Name)
End With
CustomizationContext = objContext
' Bail out if the template isn't a loaded add-in.
If Err Then
MsgBox UCase(MacroContainer) & _
" is an addin template that " & vbCr & _
"must be placed in the Word Startup Path:" & vbCr & _
UCase(Options.DefaultFilePath(wdStartupPath)), _
vbCritical, "Initialization aborted"
Set objContext = Nothing
End If
End Sub
Sub CleanUpContext()
' Set the Saved status of this add-in to True.
If objContext Is Nothing Then
InitializeContext
End If
If Not (objContext Is Nothing) Then
objContext.Saved = True
End If
End Sub
Sub CreateInterface()
' Create the menu item in the Table menu.
On Error Resume Next
With CommandBars(BAR_TABLE)
.Controls(MNU_STYLE).Delete
With .Controls.Add(Type:=msoControlPopup, _
Before:=.Controls("Table Autoformat...").Index + 1)
.BeginGroup = False
.Caption = MNU_STYLE
.OnAction = "InitTableStyleMenu"
' Parameter contains name of OnAction macro
' in submenu.
.Parameter = "ApplyToThisTable"
End With
End With
End Sub
Sub DeleteInterface()
' Delete the menu item from the Table menu.
On Error Resume Next
InitializeContext
CommandBars(BAR_TABLE).Controls(MNU_STYLE).Delete
CleanUpContext
End Sub
Sub InitTableStyleMenu()
' Create object for control that triggers this routine.
Dim ActiveCtl As CommandBarControl
Dim Ctl As CommandBarControl
Set ActiveCtl = CommandBars.ActionControl
' Start with a clean slate, deleting all current items.
For Each Ctl In ActiveCtl.Controls
Ctl.Delete
Next
If Documents.Count = 0 Then
' No tables available.
With ActiveCtl.Controls.Add()
.Caption = "(No documents open)"
.Enabled = False
End With
Exit Sub
End If
' Get all style definitions from the Registry.
varAllStyles = GetAllSettings(REG_APP, REG_SEC)
' Create style list on main menu.
If Selection.Information(wdWithInTable) Then
AddStylesToMenu
End If
With ActiveCtl.Controls.Add(Type:=msoControlPopup)
.Caption = "Apply to &All Tables"
.Visible = (ActiveDocument.Tables.Count > 0)
' Parameter contains name of OnAction macro in submenu.
.Parameter = "ApplyToAllTables"
.OnAction = "AddStylesToMenu"
.BeginGroup = True
End With
' Add the other menu items.
With ActiveCtl.Controls.Add()
.Caption = "&Create Table Style..."
.BeginGroup = True
.OnAction = "CreateTableStyle"
End With
With ActiveCtl.Controls.Add(Type:=msoControlPopup)
.Caption = "&Delete Table Style"
.Parameter = "DeleteStyle"
.OnAction = "AddStylesToMenu"
' Don't show this item if there are no styles yet.
.Visible = VarType(varAllStyles) <> vbEmpty
End With
With ActiveCtl.Controls.Add(Type:=msoControlPopup)
.Caption = "&Rename Table Style"
.Parameter = "RenameStyle"
.OnAction = "AddStylesToMenu"
.Visible = VarType(varAllStyles) <> vbEmpty
End With
CleanUpContext
End Sub
Sub
AddStylesToMenu()
' This routine creates a list of available styles.
Dim Ctl As CommandBarControl
Dim strOnAction As String
Dim iCount As Integer
With CommandBars.ActionControl
' Clear the menu.
For Each Ctl In .Controls
Ctl.Delete
Next
If VarType(varAllStyles) <> vbEmpty Then
' We have at least one style.
If Selection.Information(wdWithInTable) Then
' See if the table has a style attached.
Dim iCurDef As Long
iCurDef = GetTableFormat
End If
' Parameter contains name of OnAction macro.
strOnAction = .Parameter
' Loop through the list of styles.
For iCount = LBound(varAllStyles, 1) To _
UBound(varAllStyles, 1)
' Create an item for each style.
With .Controls.Add()
.Caption = varAllStyles(iCount, 0)
' Parameter gets the numeric style definition.
.Parameter
= varAllStyles(iCount, 1)
' Use Face ID of Table AutoFormat item.
.FaceId = 107
' Highlight if these values are the same.
.State = (.Parameter = iCurDef)
.OnAction = strOnAction
End With
Next iCount
Else
' No styles defined yet.
With .Controls.Add()
.Caption = "(no styles defined)"
.Enabled = False
End With
End If
End With
CleanUpContext
End Sub
Sub ApplyToAllTables()
' Apply selected style to all tables in active document.
If (ActiveDocument.Tables.Count > 0) Then
Dim objTable As Table
For Each objTable In ActiveDocument.Tables
SetTableFormat objTable, _
CommandBars.ActionControl.Parameter
Next
End If
End Sub
Sub ApplyToThisTable()
' Apply selected style to active table.
If Selection.Information(wdWithInTable) Then
SetTableFormat Selection.Tables(1), _
CommandBars.ActionControl.Parameter
End If
End Sub
Sub DeleteStyle()
' Delete selected style.
On Error Resume Next
Dim iReply As Integer
With CommandBars.ActionControl
iReply = MsgBox( _
"Please confirm that you want to delete ' " & _
.Caption & "'", vbOKCancel + vbExclamation, _
"Delete Table Style")
' We have an OK, so we can delete the style.
If iReply = vbOK Then
DeleteSetting REG_APP, REG_SEC, .Caption
End If
End With
End Sub
Sub RenameStyle()
' Rename selected style.
Dim strName As String
With CommandBars.ActionControl
strName = InputBox("Type a New name for: '" & _
.Caption & "'", "Rename Table Style", .Caption)
If strName <> vbNullString Then
Dim strCurrentDef As String
Dim strExistingDef As String
' Get current value of this style.
strCurrentDef = _
GetSetting(REG_APP, REG_SEC, .Caption)
' See if we already have this style.
strExistingDef = _
GetSetting(REG_APP, REG_SEC, strName)
' No? Delete the old style, save the new one.
If strExistingDef = vbNullString Then
DeleteSetting
REG_APP, REG_SEC, .Caption
SaveSetting REG_APP, REG_SEC, strName, _
strCurrentDef
Else
' Name already exists;
' ask for overwrite permission.
Dim iReply As Integer
iReply = MsgBox("'" & strName & _
"' already exists. " & _
"Do you want to replace the existing style?", _
vbYesNoCancel + vbExclamation, _
"Rename Table Style")
Select Case iReply
Case vbYes ' Overwrite old style.
DeleteSetting REG_APP, REG_SEC, .Caption
SaveSetting REG_APP, REG_SEC, strName, _
strCurrentDef
Case vbNo ' Start again.
RenameStyle
Case vbCancel
Exit Sub ' Don't do anything.
Case Else:
End Select
End If
End If
End With
End Sub
End Listing One
Begin Listing Two -
TableStylesLib.bas
Option Explicit
Const MSG_PROMPT As String = "Table Styles"
Sub CreateTableStyle()
' Intro messages.
If Not Selection.Information(wdWithInTable) Then
MsgBox "Please select or create a table first.", _
vbExclamation, MSG_PROMPT
Exit Sub
Else
MsgBox "In the following dialog box, apply a Table" & _
" Format." & vbCr & "When done, you will be " & _
"asked to give a Style name to this format.", _
vbExclamation, MSG_PROMPT
End If
With Dialogs(wdDialogTableAutoFormat)
If .Show Then
' Make sure the dialog wasn't cancelled.
Dim lDef As Long
Dim strName As String
' Create a numeric style definition.
lDef = _
.Borders * wdTableFormatApplyBorders + _
.Shading * wdTableFormatApplyShading + _
.Font * wdTableFormatApplyFont + _
.Color * wdTableFormatApplyColor + _
.AutoFit * wdTableFormatApplyAutoFit + _
.HeadingRows * wdTableFormatApplyHeadingRows + _
.LastRow * wdTableFormatApplyLastRow + _
.FirstColumn * wdTableFormatApplyFirstColumn + _
.LastColumn * wdTableFormatApplyLastColumn + _
.Format * 2 ^ 9
' Ask for a style name.
strName = InputBox( _
"Which Style Name do you want to " & _
"give to this Table Format?", MSG_PROMPT)
If strName <> vbNullString Then
SaveSetting REG_APP, REG_SEC, strName, lDef
End If
End If
End With
End Sub
Function GetTableFormat()As Long
' Make sure the insertion point is inside a table.
If Selection.Information(wdWithInTable) Then
' Get the dialog settings and return a unique
' table style definition.
With Dialogs(wdDialogTableAutoFormat)
.Update
GetTableFormat = _
.Borders * wdTableFormatApplyBorders + _
.Shading * wdTableFormatApplyShading + _
.Font * wdTableFormatApplyFont + _
.Color * wdTableFormatApplyColor + _
.AutoFit * wdTableFormatApplyAutoFit + _
.HeadingRows * wdTableFormatApplyHeadingRows + _
.LastRow * wdTableFormatApplyLastRow + _
.FirstColumn * wdTableFormatApplyFirstColumn + _
.LastColumn * wdTableFormatApplyLastColumn + _
.Format * 2 ^ 9
End With
End If
End Function
Sub SetTableFormat(ByVal objTable As Table, _
ByVal iDef As Long)
' Make sure we have a valid table object, and that the
' table style definition isn't greater than 2^15-1.
If IsObjectValid(objTable) And (iDef <= 32767) Then
' Format the table object.
With objTable
.AutoFormat _
Format:=iDef \ 512, _
ApplyBorders:= CBool(iDef And _
wdTableFormatApplyBorders), _
ApplyShading:= CBool(iDef And _
wdTableFormatApplyShading), _
ApplyFont:= CBool(iDef And _
wdTableFormatApplyFont), _
ApplyColor:= CBool(iDef And _
wdTableFormatApplyColor), _
AutoFit:= CBool(iDef And _
wdTableFormatApplyAutoFit), _
ApplyHeadingRows:= CBool(iDef And _
wdTableFormatApplyHeadingRows), _
ApplyLastRow:= CBool(iDef And _
wdTableFormatApplyLastRow), _
ApplyFirstColumn:= CBool(iDef And _
wdTableFormatApplyFirstColumn), _
ApplyLastColumn:= CBool(iDef And _
wdTableFormatApplyBorders)
End With
End If
End Sub
End Listing Two