PDA

View Full Version : Solved: Need help with table sizing in document



janaboo13
03-11-2011, 09:29 AM
Hello all!
I'm so excited to have found this forum. My last post was answered really quickly and with such an elegant solution, thanks!

I have a situation that I need help with. I have a multi-column doc with a variety of table widths that I need to standardize. Some are pretty straight-forward, but others have merged cells. Some tables are in my two-column sections and some are in my one-column sections. I have some code (see below) that works on tables greater than the desired column width, but not if they are less than the column width.

Here's what I want to do: step through all tables in the doc and adjust the table width to fit the column width (either greater or less than the desired column width) in the section that they are in to either 3.15" wide or 6.45" wide. I don't really need to have the content adjusted in each cell, however.

The macro code below does most of what I want, but it is targeted to tables greater than column width and I want to add the option to expand the table as well as contracting the size. It also ignores tables with merged cells (not sure why that's a problem as outlined in the comments).

If anyone has a solution, I'd be most appreciative!
janaboo13

Here's the code:

'Select each table in document
For Each myTable In ActiveDocument.Tables

'Tables with merged cells can cause errors in this procedure. Skip them.
If myTable.Uniform = False Then
myTable.Select
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & Chr(13) & _
"Return to the table when this procedure is finished and " & Chr(13) & _
"make the necessary changes manually."
GoTo NextTable
End If
'Apply general auto-content-fitting settings
myTable.AutoFitBehavior wdAutoFitContent
myTable.AllowAutoFit = True
myTable.Rows.HeightRule = wdRowHeightAuto
myTable.Columns.PreferredWidthType = wdPreferredWidthAuto
myTable.PreferredWidthType = wdPreferredWidthAuto
'*******Cell padding settings***************
myTable.RightPadding = 2
myTable.TopPadding = 2
'*******************************************
'Don't change paragraph spacing for borderless tables
'If myTable.Borders.Item(wdBorderTop).Visible = False Then
'Do nothing
'*******Paragraph spacing (tables with borders)***************
Else
myTable.Select
Selection.ParagraphFormat.SpaceAfter = 2
Selection.ParagraphFormat.SpaceBefore = 2
End If
'*************************************************************

myColumnWidth = 0
myTableWidth = 0
i = 1
'Add width of all columns to determine total table width
Do While i <= myTable.Columns.Count
myColumnWidth = myTable.Columns(i).Width
myTableWidth = myTableWidth + myColumnWidth
i = i + 1
Loop
'Make sure table does not go over the margins - if the width goes
'into the margin, then reduce its size to fit
If myTable.Rows.LeftIndent + myTableWidth > 230 Then
If myTable.Rows.LeftIndent + myTableWidth > 475 Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(6.5)
Else
If myTable.Rows.LeftIndent <= InchesToPoints(0) Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
Else
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
End If
End If
End If
NextTable:
Next

Selection.Find.ClearFormatting

ActiveDocument.Paragraphs(1).Range.Select
Selection.Collapse Direction:=wdCollapseStart

Exit Sub

ErrorHandler:
'Catch the error
If Err.Number = 5992 Then
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & _
"Return to the table when this procedure is finished and apply the " & Chr(13) & _
"settings indicated in the Post-processing Help window."
GoTo NextTable
End If
'Display the error
msg = "Ooops! Something didn't work quite right in the ResizeTables macro." & Chr(13) & Chr(13) & _
"Error number: " & Err.Number & Chr(13) & _
"Error message: " & Err.Description
MsgBox msg, vbOKOnly + vbCritical, "AuthorIT Publisher"
End Sub

Frosty
03-11-2011, 09:58 AM
I'm not 100% from reading your question what it is you want. You want to be able to make the tables wider as well? And you want it to work on a table which contains merged cells?

This is your same code, just with a vba tag around it. Makes it a lot easier to read. You can also more immediately see that it has some problems (a commented out beginning of an If statement, no dimensioned variables, etc).

Is this the code you're actually working on? Or did you truncate it for brevity? Would you post the whole procedure, if possible?

'Select each table in document
For Each myTable In ActiveDocument.Tables

'Tables with merged cells can cause errors in this procedure. Skip them.
If myTable.Uniform = False Then
myTable.Select
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & Chr(13) & _
"Return to the table when this procedure is finished and " & Chr(13) & _
"make the necessary changes manually."
GoTo NextTable
End If
'Apply general auto-content-fitting settings
myTable.AutoFitBehavior wdAutoFitContent
myTable.AllowAutoFit = True
myTable.Rows.HeightRule = wdRowHeightAuto
myTable.Columns.PreferredWidthType = wdPreferredWidthAuto
myTable.PreferredWidthType = wdPreferredWidthAuto
'*******Cell padding settings***************
myTable.RightPadding = 2
myTable.TopPadding = 2
'*******************************************
'Don't change paragraph spacing for borderless tables
'If myTable.Borders.Item(wdBorderTop).Visible = False Then
'Do nothing
'*******Paragraph spacing (tables with borders)***************
Else
myTable.Select
Selection.ParagraphFormat.SpaceAfter = 2
Selection.ParagraphFormat.SpaceBefore = 2
End If
'*************************************************************

myColumnWidth = 0
myTableWidth = 0
i = 1
'Add width of all columns to determine total table width
Do While i <= myTable.Columns.Count
myColumnWidth = myTable.Columns(i).Width
myTableWidth = myTableWidth + myColumnWidth
i = i + 1
Loop
'Make sure table does not go over the margins - if the width goes
'into the margin, then reduce its size to fit
If myTable.Rows.LeftIndent + myTableWidth > 230 Then
If myTable.Rows.LeftIndent + myTableWidth > 475 Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(6.5)
Else
If myTable.Rows.LeftIndent <= InchesToPoints(0) Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
Else
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
End If
End If
End If
NextTable:
Next

Selection.Find.ClearFormatting

ActiveDocument.Paragraphs(1).Range.Select
Selection.Collapse Direction:=wdCollapseStart

Exit Sub

ErrorHandler:
'Catch the error
If Err.Number = 5992 Then
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & _
"Return to the table when this procedure is finished and apply the " & Chr(13) & _
"settings indicated in the Post-processing Help window."
GoTo NextTable
End If
'Display the error
msg = "Ooops! Something didn't work quite right in the ResizeTables macro." & Chr(13) & Chr(13) & _
"Error number: " & Err.Number & Chr(13) & _
"Error message: " & Err.Description
MsgBox msg, vbOKOnly + vbCritical, "AuthorIT Publisher"
End Sub

janaboo13
03-11-2011, 10:22 AM
Hi!

Yes, I want to widen tables as well (sorry for the confusion) and also work on tables with merged cells.

Sorry, looks like I did truncate the code, sorry! I did comment out an If statement and found the error right after I posted.

Thanks for your help!

Here is the entire macro:


'This procedure formats all tables in the document that have borders (borderless tables are used for formatting regular text)
Sub ResizeTables()
Dim myTable As Table
On Error GoTo ErrorHandler

'Select each table in document
For Each myTable In ActiveDocument.Tables

'Tables with merged cells can cause errors in this procedure. Skip them.
If myTable.Uniform = False Then
myTable.Select
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & Chr(13) & _
"Return to the table when this procedure is finished and " & Chr(13) & _
"make the necessary changes manually."
GoTo NextTable
End If
'Apply general auto-content-fitting settings
myTable.AutoFitBehavior wdAutoFitContent
myTable.AllowAutoFit = True
myTable.Rows.HeightRule = wdRowHeightAuto
myTable.Columns.PreferredWidthType = wdPreferredWidthAuto
myTable.PreferredWidthType = wdPreferredWidthAuto
'*******Cell padding settings***************
myTable.RightPadding = 2
myTable.TopPadding = 2
'*******************************************
'Don't change paragraph spacing for borderless tables
If myTable.Borders.Item(wdBorderTop).Visible = False Then
'Do nothing
'*******Paragraph spacing (tables with borders)***************
Else
myTable.Select
Selection.ParagraphFormat.SpaceAfter = 2
Selection.ParagraphFormat.SpaceBefore = 2
End If
'*************************************************************

myColumnWidth = 0
myTableWidth = 0
i = 1
'Add width of all columns to determine total table width
Do While i <= myTable.Columns.Count
myColumnWidth = myTable.Columns(i).Width
myTableWidth = myTableWidth + myColumnWidth
i = i + 1
Loop
'Make sure table does not go over the margins - if the width goes
'into the margin, then reduce its size to fit
If myTable.Rows.LeftIndent + myTableWidth > 230 Then
If myTable.Rows.LeftIndent + myTableWidth > 475 Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(6.5)
Else
If myTable.Rows.LeftIndent <= InchesToPoints(0) Then
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
Else
myTable.PreferredWidthType = wdPreferredWidthPoints
myTable.PreferredWidth = InchesToPoints(3.15)
End If
End If
End If
NextTable:
Next

Selection.Find.ClearFormatting

ActiveDocument.Paragraphs(1).Range.Select
Selection.Collapse Direction:=wdCollapseStart

Exit Sub

ErrorHandler:
'Catch the error
If Err.Number = 5992 Then
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & _
"Return to the table when this procedure is finished and apply the " & Chr(13) & _
"settings indicated in the Post-processing Help window."
GoTo NextTable
End If
'Display the error
msg = "Ooops! Something didn't work quite right in the ResizeTables macro." & Chr(13) & Chr(13) & _
"Error number: " & Err.Number & Chr(13) & _
"Error message: " & Err.Description
MsgBox msg, vbOKOnly + vbCritical, "AuthorIT Publisher"
End Sub

Frosty
03-11-2011, 11:36 AM
I'm playing around with this on a slower day for me, but here are two things:
1. Always use Option Explicit
2. Modularize/Encapsulate your code, especially when you're doing big loops. Makes it so much easier to debug and troubleshoot. Also eases the development cycle.

Here is just a slight redo of your code, the only functional changes are that it doesn't go back and put the cursor at the top of the document, and it allows you to stop the execution by selecting the problem table.

But I wanted to give you a sample of how to deal with this. With this structure, it allows you to develop by going to a specific table in your document, putting your cursor in it... and then typing the following in the immediate window...
?fFixUniformTable(Selection.Tables(1))

Not only will you see the return value in the immediate window (so that the calling routine can do various things depending on what you return), but you don't have set up various 1 table test documents to test all the different tables. Just go to whatever table in the document which isn't being dealt with, and modify your code appropriately.

Wanted to give you structural help before I gave you coding help.

Option Explicit
'-----------------------------------------------------------------------------------------------
'This procedure formats all tables in the document that have borders
'(borderless tables are used for formatting regular text)
'-----------------------------------------------------------------------------------------------
Sub ResizeTables()
Dim myTable As Table
Dim msg As String

On Error GoTo ErrorHandler

'Select each table in document
For Each myTable In ActiveDocument.Tables

'Normal tables are fine...
If myTable.Uniform Then
'although if we had an error, we should exit and select
If fFixUniformTable(myTable) <> 0 Then
myTable.Select
Exit For
End If
'but non-uniform tables are a pain...
Else
'deal with non-uniform table, either moving to the next routine or stopping now
If fFixStrangeTable(myTable) = vbyes Then
myTable.Select
Exit For
End If
End If
Next

'leave cursor at top of the document after processing?
' Selection.Find.ClearFormatting
' ActiveDocument.Paragraphs(1).Range.Select
' Selection.Collapse Direction:=wdCollapseStart
'it would be better to leave any "problem" table selected so the user can immediately deal


Done:
Exit Sub

ErrorHandler:
'Catch the error
If Err.Number = 5992 Then
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & _
"Return to the table when this procedure is finished and apply the " & Chr(13) & _
"settings indicated in the Post-processing Help window."
Resume Next
End If
'build the error message
msg = "Ooops! Something didn't work quite right in the ResizeTables macro." & Chr(13) & Chr(13) & _
"Error number: " & Err.Number & Chr(13) & _
"Error message: " & Err.Description
'display it
MsgBox msg, vbOKOnly + vbCritical, "AuthorIT Publisher"
Resume Done
End Sub
'-----------------------------------------------------------------------------------------------
' dealing with uniform tables
'-----------------------------------------------------------------------------------------------
Public Function fFixUniformTable(myTable As Table) As Integer
Dim myColumnWidth As Long
Dim myTableWidth As Long
Dim iColumnCount As Integer

With myTable
'Apply general auto-content-fitting settings
.AutoFitBehavior wdAutoFitContent
.AllowAutoFit = True
.Rows.HeightRule = wdRowHeightAuto
.Columns.PreferredWidthType = wdPreferredWidthAuto
.PreferredWidthType = wdPreferredWidthAuto
'*******Cell padding settings***************
.RightPadding = 2
.TopPadding = 2
'*******************************************
'Don't change paragraph spacing for borderless tables
If .Borders.Item(wdBorderTop).Visible = False Then
'Do nothing
'*******Paragraph spacing (tables with borders)***************
Else
.Select
Selection.ParagraphFormat.SpaceAfter = 2
Selection.ParagraphFormat.SpaceBefore = 2
End If
'*************************************************************

myColumnWidth = 0
myTableWidth = 0
iColumnCount = 1
'Add width of all columns to determine total table width
Do While iColumnCount <= .Columns.Count
myColumnWidth = .Columns(iColumnCount).Width
myTableWidth = myTableWidth + myColumnWidth
iColumnCount = iColumnCount + 1
Loop
'Make sure table does not go over the margins - if the width goes
'into the margin, then reduce its size to fit
If .Rows.LeftIndent + myTableWidth > 230 Then
If .Rows.LeftIndent + myTableWidth > 475 Then
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = InchesToPoints(6.5)
Else
If .Rows.LeftIndent <= InchesToPoints(0) Then
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = InchesToPoints(3.15)
Else
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = InchesToPoints(3.15)
End If
End If
End If
End With
End Function
'-----------------------------------------------------------------------------------------------
' dealing with non-uniform tables
'-----------------------------------------------------------------------------------------------
Public Function fFixStrangeTable(myTable As Table) As Integer

'nothing to do yet, but this can become more robust, it is also very easy to test on an
'individual table, by having it in it's own routine
With myTable
If MsgBox("This table has merged cells and cannot be handled by this procedure." & vbCr & vbCr & _
"Do you wish to deal with this now?", vbYesNo, "Non-uniform Table issue") = vbYes Then
fFixStrangeTable = vbYes
End If
End With
End Function

janaboo13
03-11-2011, 11:45 AM
Hi Frosty!

Thank you again for your help! I'm definitely a newbie to this macro building, but I'd love to learn more...your structural help has been awesome.

I'm going to try this out...I'm sure it'll work and will be so much easier to handling our larger docs with tons of tables.

I'll let you know if I run into more issues.

Janaboo13

Frosty
03-11-2011, 12:04 PM
And now, after playing with the code a bit.. there are too many options. You'll have to try the following, and explain what doesn't work about it. I've taken out everything but the auto-fit items which seem like they would work for your purposes (for both narrowing and widening). This seems to work on non-uniform tables as well, but I'm leaving the structure in place because your original programmer was right: non-uniform tables are VERY problematic when you start to work with them through code. It is best to assume there will be problems.


'-----------------------------------------------------------------------------------------------
'This procedure formats all tables in the document that have borders
'(borderless tables are used for formatting regular text)
'-----------------------------------------------------------------------------------------------
Sub ResizeTables()
Dim myTable As Table
Dim msg As String

On Error GoTo ErrorHandler

'Select each table in document
For Each myTable In ActiveDocument.Tables

'Normal tables are fine...
If myTable.Uniform Then
'although if we had an error, we should exit and select
If fFixUniformTable(myTable) <> 0 Then
myTable.Select
Exit For
End If
'but non-uniform tables are a pain...
Else
'deal with non-uniform table, either moving to the next routine or stopping now
If fFixStrangeTable(myTable) = vbYes Then
myTable.Select
Exit For
End If
End If
Next

'leave cursor at top of the document after processing?
' Selection.Find.ClearFormatting
' ActiveDocument.Paragraphs(1).Range.Select
' Selection.Collapse Direction:=wdCollapseStart
'it would be better to leave any "problem" table selected so the user can immediately deal


Done:
Exit Sub

ErrorHandler:
'Catch the error
If Err.Number = 5992 Then
MsgBox "This table has merged cells and cannot be handled by this procedure." & Chr(13) & _
"Return to the table when this procedure is finished and apply the " & Chr(13) & _
"settings indicated in the Post-processing Help window."
Resume Next
End If
'build the error message
msg = "Ooops! Something didn't work quite right in the ResizeTables macro." & Chr(13) & Chr(13) & _
"Error number: " & Err.Number & Chr(13) & _
"Error message: " & Err.Description
'display it
MsgBox msg, vbOKOnly + vbCritical, "AuthorIT Publisher"
Resume Done
End Sub
'-----------------------------------------------------------------------------------------------
' dealing with uniform tables
'-----------------------------------------------------------------------------------------------
Public Function fFixUniformTable(myTable As Table) As Integer
Dim myColumnWidth As Long
Dim myTableWidth As Long
Dim iColumnCount As Integer

With myTable
'Apply general auto-content-fitting settings
'QUESTION: wdAutoFitWindow doesn't work here?
.AutoFitBehavior wdAutoFitWindow
' .AutoFitBehavior wdAutoFitContent
' .AllowAutoFit = True
' .Rows.HeightRule = wdRowHeightAuto
' .Columns.PreferredWidthType = wdPreferredWidthAuto
' .PreferredWidthType = wdPreferredWidthAuto
' '*******Cell padding settings***************
' .RightPadding = 2
' .TopPadding = 2
' '*******************************************
' 'Don't change paragraph spacing for borderless tables
' If .Borders.Item(wdBorderTop).Visible = False Then
' 'Do nothing
' '*******Paragraph spacing (tables with borders)***************
' Else
' 'don't need selection, do this instead
' .Range.ParagraphFormat.SpaceAfter = 2
' .Range.ParagraphFormat.SpaceBefore = 2
' '.Select
' 'Selection.ParagraphFormat.SpaceAfter = 2
' 'Selection.ParagraphFormat.SpaceBefore = 2
' End If
' '*************************************************************
'
' myColumnWidth = 0
' myTableWidth = 0
' iColumnCount = 1
' 'Add width of all columns to determine total table width
' Do While iColumnCount <= .Columns.Count
' myColumnWidth = .Columns(iColumnCount).Width
' myTableWidth = myTableWidth + myColumnWidth
' iColumnCount = iColumnCount + 1
' Loop
' 'Make sure table does not go over the margins - if the width goes
' 'into the margin, then reduce its size to fit
' If .Rows.LeftIndent + myTableWidth > 230 Then
' If .Rows.LeftIndent + myTableWidth > 475 Then
' .PreferredWidthType = wdPreferredWidthPoints
' .PreferredWidth = InchesToPoints(6.5)
' Else
' If .Rows.LeftIndent <= InchesToPoints(0) Then
' .PreferredWidthType = wdPreferredWidthPoints
' .PreferredWidth = InchesToPoints(3.15)
' Else
' .PreferredWidthType = wdPreferredWidthPoints
' .PreferredWidth = InchesToPoints(3.15)
' End If
' End If
' End If
End With

End Function
'-----------------------------------------------------------------------------------------------
' dealing with non-uniform tables
'-----------------------------------------------------------------------------------------------
Public Function fFixStrangeTable(myTable As Table) As Integer

'nothing to do yet, but this can become more robust, it is also very easy to test on an
'individual table, by having it in it's own routine
With myTable
.AutoFitBehavior wdAutoFitWindow
' If MsgBox("This table has merged cells and cannot be handled by this procedure." & vbCr & vbCr & _
' "Do you wish to deal with this now?", vbYesNo, "Non-uniform Table issue") = vbYes Then
' fFixStrangeTable = vbYes
' End If
End With
End Function

janaboo13
03-11-2011, 12:50 PM
OMG! This is really slick.

I tried the first solution and it didn't work for me. This one, however, is awesome. It happened so fast (all the tables were affected correctly!)

Let me tell you what I think it's doing...each table is selected and if it's uniform, you call the fFixUniformTable function and set the AutoFitBehavior to fit the column (whether it's in a two-column or one-column section); if it's non-uniform, you call the fFixStrangeTable function and set the AutoFitBehavior to fit the column (whether it's in a two-column or one-column section). Is that correct?

Now, let me throw something else in the mix. Is there a way to dictate the width of the table, either 3.15" or 6.55" (depending on whether it's in a one-column or two-column section), instead of making all of them auto fit the column? The reason being is that some tables need to be indented (e.g., indented paragraph following a procedure). Is that really difficult to do or does that make sense???

I can't tell you how much I'm learning...THANK YOU!
janaboo13:bow:

Frosty
03-11-2011, 02:04 PM
You're right that it is doing exactly the same thing for uniform vs. non-uniform tables. However, it is not "selecting" anything (which is why it goes faster).

Once you get into specific widths, you're going to run into issues, especially with non-uniform tables, because the "table indent" property looks like it works on the Rows collection of a table.

The best way to proceed is the following:

Record a macro to adjust a table the way you want to adjust it. Then look at the macro.. you'll end up seeing something like this:

Selection.Tables(1).Rows.LeftIndent = InchesToPoints(0.5)
Selection.Tables(1).PreferredWidthType = wdPreferredWidthPoints
Selection.Tables(1).PreferredWidth = InchesToPoints(6)

If that kind of stuff ends up being what you want... you just need to remove the Selection.Tables(1) stuff, and put everything else into your With myTable... End With block, so that it looks like this:

with myTable
'whatever other code you have in the routine
.Rows.LeftIndent = InchesToPoints(0.5)
.PreferredWidthType = wdPreferredWidthPoints
.PreferredWidth = InchesToPoints(6)
End with

However, I can't say something is easy or not... because I don't know what your actual tables look like, or your actual documents. And, since the table indent works off the .Rows property, you *may* run into issues with non-uniform tables if you have merged cells vertically (i.e., Microsoft isn't indenting the "table" per se... it's indenting each of the rows of the table by the same amount). And merged cells may or may not get referenced properly by the .Rows collection. So you may or may not run into issues. The best way to find out is to test it!

However, you do have the structure to play around and learn what is or is not do-able in your environment with your tables, I think. So... go play and see what works.

From what I can see... it looks like the wdAutoFitWindow doesn't really care about the number of columns you have in that section of the document, so you don't need to worry about overall table width (which is taken care of by the wdAutoFitWindow).

However, if your "table" indent (which is really your .Rows indent) is going to be different depending on whether you're in a two column section or a one column section, you find out what kind of section your current table is in by doing the following test:

If myTable.Range.Sections(1).PageSetup.TextColumns.Count = 2 then
'do whatever your left indent needs to be for 2 column...
Else
'do whatever your left indent needs to be for 1 or 3,4,5 etc column count
End if

janaboo13
03-11-2011, 02:27 PM
Soooo, I think I get it. The good news is, the only tables that I will have to deal with the indentation issue are tables created to handle those times when I have text & a graphic following a procedure/step. There are only a few of those in the entire doc and they are always in the two-column sections. I originally created a macro to "outdent" selected tables and gave me an option of outdenting or not. Now, with your new code, all tables are outdented and I'll have to go back to change those that I didn't want to outdent, but change the width (in this case instead of column width, 2.85" wide..that would be expanding or contracting those tables to the width with an indent).

What's nice about your code is that I don't have to step through ALL the tables and answer y or n, since most of the tables don't need outdenting, and I like that. Now, however, I have to see if I can come up with an If statement to handle the tables I want to indent, right?

Again, thank you! I'll let you know what i come up with and if you have any other ideas, I'd love to hear them.
Janaboo13

Frosty
03-11-2011, 02:53 PM
My pleasure. I think the bigger lesson here is that when you structure the code right, it's a) a lot easier to understand what's going on and b) easier to test.

Like most people, I suspect, I don't have the entire word object model floating around in my head. So I tend to try to figure out what my logic structure should be (which comes with experience) and then I tend to record a macro to see what Word does on a single thing to see what the likely properties I need to work with actually are.

In terms of coming up with the logic, you would do well to look up Working with Ranges in the VBA help... because you already know what your logic is, I think: tables which have a text and a graphic immediately following or proceeding that table. And you know what you want to do: have a left indent of 0 (or, rather, NOT do any indenting at all).

Again, rather than setting up some kind of complex IF routine (the criteria of which may change in the future), you create another function to return your logic:

'-----------------------------------------------------------------------------------------------
' should this table be indented?
'-----------------------------------------------------------------------------------------------
Public Function fIndentThisTable(myTable As Table) As Boolean
Dim rngWorking As Range
Dim bReturn As Boolean

'start with our table
Set rngWorking = myTable.Range
'collapse to the paragraph immediately after our table
rngWorking.Collapse wdCollapseEnd
'now see if we have any shapes in this paragraph
If rngWorking.Paragraphs(1).Range.ShapeRange.Count = 0 Then
bReturn = True
End If

'now return what we've decided
fIndentThisTable = bReturn
End Function

And then you test this function the same way you tested the others... put your cursor in the table, and in the immediate window type:
?fIndentThisTable(selection.tables(1))

Once you've figured out the actual logic (if it's returning True and False in the right scenarios), you can plug it into your actual routine

If fIndentThisTable(myTable) = True then
'do the indent code
End If

Obviously if the test ends up being really simple, you don't necessarily need an external function... and you may end up simply taking the code from the function and putting right into your regular macro... but this makes it easier to test the various bits of your program, rather than keep running the whole thing on all the tables of your document simply to see if you got one bit of logic change.

Hope this helps, and good luck!

Frosty
03-11-2011, 02:56 PM
Also... when you use this structure... you will plug it into your routine, and find out it's working on your document... all except for one table. Then you can go put your cursor into that one table and figure out why your logic test didn't work... and make the test more robust (i.e., .ShapeRange doesn't work if you've got a floating graphic, but it does when you've got an inline graphic, etc... or maybe it's too hard and you end up seeing if the .Style of the paragraph following the table is name "GraphicTitle" and that becomes your test... etc.

Frosty
03-11-2011, 03:07 PM
And one last thought... if you aren't able to come up with the logic on your own...that's an excellent time to post a sample document containing a couple of tables and associated text. And then say you'd like, for example, tables 1 & 4 to return True, while tables 2 & 3 should return false from the "fIndentThisTable" function.

It becomes very easy to help you with that kind of very specific encapsulated question.

Frosty
03-11-2011, 03:39 PM
Darn it... was compiling my normal for another reason, and realized I gave you bad code (although you'd notice if you have Option Explicit on, right?)

Editted that procedure above.

janaboo13
03-14-2011, 06:24 AM
Hi Frosty!
Again, can't thank you enough for all the help! I've learned so much....only makes me want to learn more. Do you know of any online classes that make sense to do? OR other resources?

I'm going to try out your latest code and see if I get it..will let you know.

You're right about me getting the logic and I do try to mentally map out what I'm want to happen. The challenge for me is the code, as you would expect. Oh so much to learn...love it, love it, love it!

Thanks, again.