Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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.
VBA Hacker
This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.
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