Microsoft Office Forums

Go Back   Microsoft Office Forums > >

Reply
 
Thread Tools Display Modes
  #1  
Old 03-30-2018, 05:44 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default Testing for 'Object has been deleted' error

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
Reply With Quote
  #2  
Old 03-30-2018, 06:50 PM
eduzs eduzs is offline Testing for 'Object has been deleted' error Windows 10 Testing for 'Object has been deleted' error Office 2010 32bit
Expert
 
Join Date: May 2017
Posts: 260
eduzs is on a distinguished road
Default

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
Reply With Quote
  #3  
Old 03-30-2018, 07:14 PM
macropod's Avatar
macropod macropod is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2010 32bit
Administrator
 
Join Date: Dec 2010
Location: Canberra, Australia
Posts: 21,956
macropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond repute
Default

Quote:
Originally Posted by Cosmo View Post
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.
How about posting the code that's doing the row deletion? It seems that's the logical place to test the status of oTbl.
__________________
Cheers,
Paul Edstein
[Fmr MS MVP - Word]
Reply With Quote
  #4  
Old 03-31-2018, 02:55 AM
slaycock slaycock is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

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
Reply With Quote
  #5  
Old 03-31-2018, 04:01 AM
slaycock slaycock is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

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
Reply With Quote
  #6  
Old 03-31-2018, 05:08 AM
eduzs eduzs is offline Testing for 'Object has been deleted' error Windows 10 Testing for 'Object has been deleted' error Office 2010 32bit
Expert
 
Join Date: May 2017
Posts: 260
eduzs is on a distinguished road
Default

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
Backup original files before test, test before use, use at your own.
Reply With Quote
  #7  
Old 04-04-2018, 05:12 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default

Quote:
Originally Posted by macropod View Post
How about posting the code that's doing the row deletion? It seems that's the logical place to test the status of oTbl.
Here is the code I'm using, the issue is that if all rows are deleted, the table no longer exists, but the reference to oTable is not 'Nothing'. There are other steps which need to be performed to the table after deleting the rows, but I need to be able to test to see if the table has been deleted so I can skip those steps.
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...
For now, I am using the 'tableExists' function I originally posted to test for the table, but I'd prefer to use a valid test, not testing for error.
Reply With Quote
  #8  
Old 04-04-2018, 05:59 AM
macropod's Avatar
macropod macropod is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2010 32bit
Administrator
 
Join Date: Dec 2010
Location: Canberra, Australia
Posts: 21,956
macropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond repute
Default

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]
Reply With Quote
  #9  
Old 04-04-2018, 07:09 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default

Quote:
Originally Posted by macropod View Post
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
That won't help me, since it will always set the table to nothing if the first row is empty. There may be other rows that were not deleted, and the table will need further processing.

Edit:
I could set a flag if the rowcount is 1 before deleting the row. That might work. Seems a bit hackish, though.
Reply With Quote
  #10  
Old 04-04-2018, 07:28 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default

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.
Reply With Quote
  #11  
Old 04-04-2018, 08:32 AM
slaycock slaycock is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

'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
Applying the same approach to you code gives

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...
Reply With Quote
  #12  
Old 04-04-2018, 10:17 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default

Quote:
Originally Posted by slaycock View Post
'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
Applying the same approach to you code gives

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...
Thanks, I see what you are saying now about using the range (didn't quite pick up your meaning in your original post).

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)
Reply With Quote
  #13  
Old 04-04-2018, 10:43 AM
Cosmo Cosmo is offline Testing for 'Object has been deleted' error Windows Vista Testing for 'Object has been deleted' error Office 2007
Competent Performer
Testing for 'Object has been deleted' error
 
Join Date: Mar 2012
Posts: 240
Cosmo is on a distinguished road
Default

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.
Reply With Quote
  #14  
Old 04-04-2018, 11:30 AM
slaycock slaycock is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2016
Expert
 
Join Date: Sep 2013
Posts: 256
slaycock is on a distinguished road
Default

Good luck whichever approach you take.
Reply With Quote
  #15  
Old 04-04-2018, 01:58 PM
macropod's Avatar
macropod macropod is offline Testing for 'Object has been deleted' error Windows 7 64bit Testing for 'Object has been deleted' error Office 2010 32bit
Administrator
 
Join Date: Dec 2010
Location: Canberra, Australia
Posts: 21,956
macropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond reputemacropod has a reputation beyond repute
Default

Quote:
Originally Posted by Cosmo View Post
That won't help me, since it will always set the table to nothing if the first row is empty. There may be other rows that were not deleted, and the table will need further processing.
In that case, try:
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]
Reply With Quote
Reply

Thread Tools
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
set row object variable error CLoos Excel Programming 6 03-10-2017 04:48 PM
Testing for 'Object has been deleted' error Run-time error '424': Object required zlodeh Excel Programming 1 02-24-2016 01:58 AM
Testing for 'Object has been deleted' error Run Time Error 424 - Object Required Doug Needham Excel Programming 4 01-12-2015 10:54 PM
Testing for 'Object has been deleted' error 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

Other Forums: Access Forums

All times are GMT -7. The time now is 01:58 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Search Engine Optimisation provided by DragonByte SEO (Lite) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
MSOfficeForums.com is not affiliated with Microsoft