VBA to Cleanup A2007 DB Extra Objects (1 Viewer)

mdlueck

Sr. Application Developer
Local time
Today, 12:09
Joined
Jun 23, 2011
Messages
2,631
Greetings,

In an Access 2007 application, I accidentally double-linked some table to the SQL BE DB, thus Access named the dupe links with a 1 appended to the dupe object. I deleted those.

While checking the MSysObjects table, I saw yet remaining all of those orphaned objects, even thought they were deleted from the Access UI \ Navigation Pane.

So I worked up the following code, stuck it in a new button on my admin/cleanup form.

The code logs its progress to the Immediate window.

Code:
Private Sub btnDeleteADOXNonsense_Click()
On Error GoTo Err_btnDeleteADOXNonsense_Click

  Dim adoCat As Object
  Dim lngStep As Long
  Dim lngMaxCount As Long
  Dim strThisObjectName As String

  'Define attachment to FE database
  Set adoCat = CreateObject("ADOX.Catalog")
  Set adoCat.ActiveConnection = CurrentProject.Connection

  'Process "~" named Tables
  lngMaxCount = adoCat.Tables.Count
  If lngMaxCount > 0 Then
    'It is necessary to subtract 1 from what is shown in the watches window
    'The watches window shows numbers starting with 1
    'The numbers actually start with 0
    For lngStep = lngMaxCount - 1 To 0 Step -1
      strThisObjectName = adoCat.Tables.Item(lngStep).Name
      'Debug.Print "Considering adoCat.Tables: " & strThisObjectName
      If InStr(1, strThisObjectName, "~", vbTextCompare) <> 0 Then
        Debug.Print "Call adoCat.Tables.Delete(" & strThisObjectName & ")"
        Call adoCat.Tables.Delete(strThisObjectName)
      End If
    Next lngStep
  End If

  'Process Procedures
  lngMaxCount = adoCat.Procedures.Count
  If lngMaxCount > 0 Then
    'It is necessary to subtract 1 from what is shown in the watches window
    'The watches window shows numbers starting with 1
    'The numbers actually start with 0
    For lngStep = lngMaxCount - 1 To 0 Step -1
      strThisObjectName = adoCat.Procedures.Item(lngStep).Name
      Debug.Print "Call adoCat.Procedures.Delete(" & strThisObjectName & ")"
      Call adoCat.Procedures.Delete(strThisObjectName)
    Next lngStep
  End If

  'Process Views
  lngMaxCount = adoCat.Views.Count
  If lngMaxCount > 0 Then
    'It is necessary to subtract 1 from what is shown in the watches window
    'The watches window shows numbers starting with 1
    'The numbers actually start with 0
    For lngStep = lngMaxCount - 1 To 0 Step -1
      strThisObjectName = adoCat.Views.Item(lngStep).Name
      Debug.Print "Call adoCat.Views.Delete(" & strThisObjectName & ")"
      Call adoCat.Views.Delete(strThisObjectName)
    Next lngStep
  End If

Exit_btnDeleteADOXNonsense_Click:
  'Clean up the connection to the database
  Set adoCat = Nothing

  Exit Sub

Err_btnDeleteADOXNonsense_Click:
  Call errorhandler_MsgBox("Form: " & TypeName(Me) & ", Subroutine: btnDeleteADOXNonsense_Click()")
  Resume Exit_btnDeleteADOXNonsense_Click

End Sub
Perhaps this helps someone else.
 
Last edited:

mdlueck

Sr. Application Developer
Local time
Today, 12:09
Joined
Jun 23, 2011
Messages
2,631
I will point out... evidently DAO.QueryDef objects are considered by ADO to be Views. Thus the part of code cleaning up ADO Views also cleans up DAO.QueryDef objects.

Saves me the trouble of pushing the button which cleans up DAO.QueryDef objects! :D

Code:
Call adoCat.Views.Delete(frmqryclsObjProjectsTbl_RefreshLocalTmpTbl)
Call adoCat.Views.Delete(frmqryclsObjProductsTbl_RefreshLocalTmpTbl)
Call adoCat.Views.Delete(frmqryclsObjPartsTbl_RefreshLocalTmpTbl)
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 12:09
Joined
Feb 19, 2002
Messages
43,296
1. Deleting a table from the relationship window does not delete the relationship. It just hides it. You must delete the relationship line first. Then you can get rid of the table.

2. When deleting objects, the record counter gets out of sync. That's why you had to run the delete multiple times. If you work backwards and delete the last item each time rather than the next item, you only have to run the loop once.
 

mdlueck

Sr. Application Developer
Local time
Today, 12:09
Joined
Jun 23, 2011
Messages
2,631
1. Deleting a table from the relationship window does not delete the relationship. It just hides it. You must delete the relationship line first. Then you can get rid of the table.

I do not ever open / use the relationships window.

Which ADO object type is it that you are talking about being linked to tables?

Temp tables in the FE DB I merely empty out, and leave there. I do not see benefit on recreating those, just empty and be done with it.

2. When deleting objects, the record counter gets out of sync. That's why you had to run the delete multiple times. If you work backwards and delete the last item each time rather than the next item, you only have to run the loop once.

My code uses FOR EACH / NEXT based looping, so how would I go backwards through the collection?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 12:09
Joined
Feb 19, 2002
Messages
43,296
1. If deleted items are showing in MSysObjects, compact the database and they should disappear.
2. Count the items in the collection. Change your loop to start with the last item and decrement as you loop. I think this might be a zero-based array so if there are 9 items, the "last" one may be #8. So check the code carefully.
 

Galaxiom

Super Moderator
Staff member
Local time
Tomorrow, 02:09
Joined
Jan 20, 2009
Messages
12,852
Temp tables in the FE DB I merely empty out, and leave there. I do not see benefit on recreating those, just empty and be done with it.

Whether you simply delete the records from them or delete the object entirely, temporary tables will bloat the front end and require compacting. It also increases the risk of corruption.

I strongly believe that temporary data should be written to tables in a separate local database rather than writing to the Front End. I call this database the Side End.

The FE is an application file and should be treated as such. You wouldn't expect to write data to an exe file would you? So why would you write data to an Access application file?

It just doesn't make sense to write temporary data to the FE unless of course you think it makes sense to write your shopping lists in the margins of an encyclopedia.
 

mdlueck

Sr. Application Developer
Local time
Today, 12:09
Joined
Jun 23, 2011
Messages
2,631
1. If deleted items are showing in MSysObjects, compact the database and they should disappear.

My DB cleanup:

NT Command Script and Documented Steps to Decompile / Compact / Compile an Access DB
http://www.access-programmers.co.uk/forums/showthread.php?t=219948

... would not remove the Table objects with the ~ in their name. This is the only way I have found to blast away the orphan Table objects with ~'s in their name.

2. Count the items in the collection. Change your loop to start with the last item and decrement as you loop. I think this might be a zero-based array so if there are 9 items, the "last" one may be #8. So check the code carefully.

Indeed I was able to finally find syntax to step through numerically backwards, and indeed between the VBA watches window and the way the code actually works there is a 0/1 starting number difference... which I noted in source code comments.

Thank for your suggestions - much appreciated! :D
 

mdlueck

Sr. Application Developer
Local time
Today, 12:09
Joined
Jun 23, 2011
Messages
2,631
I strongly believe that temporary data should be written to tables in a separate local database rather than writing to the Front End. I call this database the Side End.

...

It just doesn't make sense to write temporary data to the FE unless of course you think it makes sense to write your shopping lists in the margins of an encyclopedia.

Galaxiom, You and I discussed the topic of SE's long ago, and I decided against their use for the following reasons...

"Why not to use a side-end (SE) database with a front-end (FE) database"
http://www.access-programmers.co.uk/forums/showthread.php?p=1107063#post1107063

I will not be revisiting that topic.
 

Galaxiom

Super Moderator
Staff member
Local time
Tomorrow, 02:09
Joined
Jan 20, 2009
Messages
12,852
Galaxiom, You and I discussed the topic of SE's long ago, and I decided against their use for the following reasons...

Clearly I overlooked the end of that conversation or I would have answered your objections. I have posted a reply now.
 

Thales750

Formerly Jsanders
Local time
Today, 12:09
Joined
Dec 20, 2007
Messages
2,120
Whether you simply delete the records from them or delete the object entirely, temporary tables will bloat the front end and require compacting. It also increases the risk of corruption.

I strongly believe that temporary data should be written to tables in a separate local database rather than writing to the Front End. I call this database the Side End.

The FE is an application file and should be treated as such. You wouldn't expect to write data to an exe file would you? So why would you write data to an Access application file?

It just doesn't make sense to write temporary data to the FE unless of course you think it makes sense to write your shopping lists in the margins of an encyclopedia.

I do the same thing with the exception of the Local Version table, and local Objects; which never change again after compiling.

We keep running version records on a server and insert local records as we develop. That way once a system is compiled and the version form is removed there is no way to change the version number.
 

Thales750

Formerly Jsanders
Local time
Today, 12:09
Joined
Dec 20, 2007
Messages
2,120
I actually gave this some more thought.
My previous post is not entirely accurate.
Very often we build front ends to very large databases; our current Point of Sale system will scale to thousands of locations using both Access or PHP with Java, and a combination of both.
1. This requires us to synchronize versions across wide geographic areas.
2. Point of Sales generally works better if the local machine temperately stores data locally, and then replicates it to server data.
3. Often a machine will require unique data at the same time other machines need the same “unique” data. So some form of local storage is required.
4. On local systems, data that will never change. Like store location, cash requester number, tax rates etc. is always stored in a “side end” file. So updates to the local point of sale will not change the info about that machine.
5. Salt is stored in the local machine client.
In other words data that will never or rarely change are stored in “side ends”, data that is ephemeral is stored in the local (client) especially if it may be part of a possible upgrade in the future.
 

Users who are viewing this thread

Top Bottom