![]() |
|
|
|
#1
|
|||
|
|||
|
I have a function which needs to perform several operations on a table "oTb", one of them will remove empty rows "oTbl.rows(row).delete".
If the table is completely empty, all rows are deleted, and the table is deleted. But the object is still valid, and I need to be able to test to see if the table has been deleted. "oTbl is Nothing" evaluates false, even though the table doesn't exist. Is there a test that I can do to determine if the object has been deleted, so I can skip any further processing? I'd rather not try accessing a table property and test for an error, I want to do this a proper way (assuming there is a proper way to do so) Example: this does what I need, but I would prefer not to program by error, I'd rather do a valid test if there is one that I can perform instead Code:
Private Function tableExists(ByRef oTbl As Word.Table) As Boolean
On Error Resume Next
tableExists = (oTbl.Rows.count > 0)
End Function
Thanks |
|
#2
|
|||
|
|||
|
Try this:
I don't know how to do this without "on error" but note that in the code below the "on error" works only within the "Set" (because the "On Error Goto 0") line which will not undercover other errors in the code. Code:
Dim oTbl As Table
On Error Resume Next
Set oTbl = ActiveDocument.Tables(1)
On Error GoTo 0
If Not oTbl Is Nothing Then
Exists = "yes"
Else
Exists "No"
End If
|
|
#3
|
||||
|
||||
|
Quote:
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#4
|
|||
|
|||
|
You were very close to a solution by the use of the count property. You just needed to apply it to the table range rather than count rows.
Code:
Sub process_table(this_table As Word.Table)
Dim a_range As Word.Range
Set a_range = this_table.Range
Do While a_range.Tables.Count > 0
'Put your code here
Loop
End Sub
|
|
#5
|
|||
|
|||
|
ON rereading the original post my example might be better as
Code:
Sub process_table(this_table As Word.Table)
Dim a_range As Word.Range
Set a_range = this_table.Range
' Do a process on the table
If a_range.Tables.Count = 0 Then Exit Sub
' Do a process on the table
If a_range.Tables.Count = 0 Then Exit Sub
' Do a process on the table
If a_range.Tables.Count = 0 Then Exit Sub
Loop
End Sub
|
|
#6
|
|||
|
|||
|
Quote:
Code:
' Remove empty rows
rowCount = oTbl.Rows.count
columnCount = oTbl.Columns.count
For row = rowCount To 1 Step -1
delete = True
For column = 1 To columnCount
If Not (oTbl.Cell(row, column).Range.Text = Chr(13) & Chr(7)) Then
delete = False
Exit For
End If
Next column
If (delete) Then
' Remove row
Call oTbl.Rows(row).delete
End If
Next row
' NOTE: Need to check to see if table still exists here (If all rows were deleted)
If (tableExists(oTbl)) Then ' Can't test for Nothing - object has been deleted, but is NOT nothing.
' Do other processing steps to table...
|
|
#7
|
|||
|
|||
|
This works for me in my test, delete all tables in the activedocument with only empty cells at all:
Code:
Sub Test()
Dim oTbl As Table
For Each oTbl In ActiveDocument.Tables
If Len(Replace(Replace(oTbl.Range.Text, Chr(7), ""), Chr(13), "")) = 0 Then oTbl.Delete
Next
End Sub
|
|
#8
|
||||
|
||||
|
Try something based on:
Code:
Dim Tbl As Table, r As Long
' Remove empty rows
For Each Tbl In ActiveDocument.Tables
With Tbl
For r = .Rows.Count To 1 Step -1
With .Rows(r)
If Len(.Range.Text) = .Cells.Count * 2 + 2 Then
.Delete
If r = 1 Then Set Tbl = Nothing
End If
End With
Next
End With
MsgBox Tbl Is Nothing
Next
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#9
|
|||
|
|||
|
Quote:
Edit: I could set a flag if the rowcount is 1 before deleting the row. That might work. Seems a bit hackish, though. |
|
#10
|
|||
|
|||
|
'oTbl is nothing' - you are comparing objects not values.
The 'is' operator is not the same as the '=' operator'. The 'is' operator compares the references to objects, not the content of the objects. Deleting all rows deletes the word object and leaves oTbl in an indeterminate state. Thus you can refer to the VBA object but trying to access its information gives an error because there is no object. If the object has been deleted then oTbl will be nothing. Hence you will be comparing the reference to nothing with the reference to nothing which is always true. One of the little joys of working with objects. The simplest way to deal with this situation is by abstracting the object range (in fact ranges are by far the best way to work in VBA for Word). The following code works without needing an on error statement assuming there is at least one uniform table in the active document. Code:
Sub Macro2()
Dim oTbl As Word.Table
Dim oTbl_range As Word.Range
Set oTbl = ActiveDocument.Tables(1)
Set oTbl_range = oTbl.Range
Do Until oTbl_range.Tables.Count = 0
Debug.Print oTbl.Range.Rows.Count
oTbl.Rows(1).Delete
Loop
End Sub
Code:
Dim oTbl_range As Word.Range
Set oTbl_range = oTbl.Range
' Remove empty rows
With oTble_range.Tables(1)
RowCount = .Rows.Count
columnCount = .Columns.Count
For Row = RowCount To 1 Step -1
Delete = True
For Column = 1 To columnCount
If Not (.Cell(Row, Column).Range.Text = Chr(13) & Chr(7)) Then
Delete = False
Exit For
End If
Next Column
If (Delete) Then
' Remove row
Call .Rows(Row).Delete
End If
Next Row
End With
' NOTE: Need to check to see if table still exists here (If all rows were deleted)
If oTbl_range.Tables.Count > 0 Then ' by abstracting the table range you can subsequently test for the presence of a table in the range
' Do other processing steps to table...
|
|
#11
|
|||
|
|||
|
Quote:
It feels a little more of a round-about way to do it (reading the code months later might not be as easily identifiable as to what is going on as a 'TableExists' function) |
|
#12
|
||||
|
||||
|
Quote:
Code:
Dim Tbl As Table, r As Long
For Each Tbl In ActiveDocument.Tables
With Tbl
If Len(.Range.Text) = .Range.Cells.Count * 2 + .Rows.Count * 2 Then
.Delete: Set Tbl = Nothing
Else
For r = .Rows.Count To 1 Step -1
With .Rows(r)
If Len(.Range.Text) = .Cells.Count * 2 + 2 Then
.Delete
End If
End With
Next
End If
End With
MsgBox Tbl Is Nothing
Next
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#13
|
|||
|
|||
|
2 of the processes which need to be performed after the empty rows are deleted are deleting any empty columns, and resizing the table to the original width (there are more things which will need to be done to some of the tables after those processes too).
I may just keep the tableExists function I have. It may not be proper programming practices, but it is simple, and it works. I was hoping there was a built-in way, similar to testing for Nothing. |
|
#14
|
|||
|
|||
|
I'll try working it out with your method, but I may end up keeping the original function in the long run.
As much as I hate doing it the 'wrong' way, keeping the simplicity and readability may be a preferable option. |
|
#15
|
|||
|
|||
|
Good luck whichever approach you take.
|
|
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| set row object variable error | CLoos | Excel Programming | 6 | 03-10-2017 04:48 PM |
Run-time error '424': Object required
|
zlodeh | Excel Programming | 1 | 02-24-2016 01:58 AM |
Run Time Error 424 - Object Required
|
Doug Needham | Excel Programming | 4 | 01-12-2015 10:54 PM |
Error Message: Could not load an object...
|
simstem | Word | 1 | 10-06-2012 08:44 PM |
| XML parsing & Object variable not set (Error 91) | tinfanide | Excel Programming | 0 | 12-29-2011 08:43 AM |