Tables Disappeared

S

Swarfmaker

Access2003 on XPproSP2.

All of the tables and queries in my database have suddenly disappeared, but
the forms can still see the data.
I've tried closing and repairing, I've tried importing into a new database -
the forms and reports can be imported but the tables and queries are
invisible. The database is set to show hidden and system objects.
Can anyone throw a bit of light on this?

Iain, Pudsey UK
 
S

Swarfmaker

Danny J. Lesandrini said:
Did you have their attributes set to hidden before they disappeared?
No. I never hide tables until ready for deployment.

Iain, Pudsey UK
 
D

Danny J. Lesandrini

What do you get when you run this SQL ...

SELECT MSysObjects.Name FROM MSysObjects WHERE Type=4

Are these tables prefixed with USYS, making them, effectively, system
tables and hidden unless the option is selected to show system tables.

Can you create a new Access MDB and import tables from the one where
they were deleted? (Be sure to have the options to see hidden and system
tables made visible.)

Are the tables really gone, or simply not visible? If they are gone, then it's
simply a corruption and the question is, "How did they get whacked?"

If you set the property of a table to hidden (maybe only through code, I
forget) and then run Compact, the process will dump the tables.

Maybe somebody else knows of another reason why tables would disappear,
but that's the only scenario I'm aware of.
 
D

Danny J. Lesandrini

Iain:

I don't mean to frustrate you with these questions, but sometimes people complain
of missing tables and then they say, "Ooops, there they are. Sorry, my bad."

I just wanted to make sure the tables were actually *gone* and not just hiding.
From what you've said, they are gone. I've _never_ seen this happen and I've
worked with hundreds, if not thousands of databases over the last dozen years.

What do you think triggered the disappearance?
What was the last thing you did before missing them?
Could a user have deleted them?

Have you googled the question?

I googled it against one newsgroup and got a number of posts. Try this out ...
http://groups.google.com/groups/search?safe=off&q=missing+tables+group:comp.databases.ms-access
 
S

Swarfmaker

Danny,
Please see inline comments
I don't mean to frustrate you with these questions, but sometimes people
complain
of missing tables and then they say, "Ooops, there they are. Sorry, my
bad."
I hope I didn't give the impression of being frustrated. I'm grateful for
any help in solving this puzzle
I just wanted to make sure the tables were actually *gone* and not just
hiding.
From what you've said, they are gone. I've _never_ seen this happen and
I've
worked with hundreds, if not thousands of databases over the last dozen
years.

What do you think triggered the disappearance?
I'd been thinking of putting an Audit Trail on this database and had just
loaded the following into the modules tab, and then compiled the database.
*****Code Start*******


' Author: Allen Browne, (e-mail address removed), 2006.

' Purpose: Audit trail, to track Deletes, Edits, and Inserts.
' Does not audit any Cascading Updates/Deletes.

' Requirements: The table to be audited must have an AutoNumber primary key.
' Data entry must be through a form.

' Method: Makes a copy of the record in a temp table, and logs the
' change when it is guaranteed. The temp table copes with:
' - multiple deletes at once (continuous/datasheet view)
' - cancelled deletes or failed updates.
' - requirement for sequential numbering in the audit table.
' On a multi-user split (front-end/back-end) database, the
' temp table may reside in the front end, and the audit log
' in the back-end.

' Result: The audit table will contain one record for each deletion or
' insertion, and two records for each edit (before and after).
' Delete Copy of the deleted record, marked "Delete".
' Insert Copy of the new record, marked "Insert".
' Change: Copy of the record before change, marked "EditFrom".
' Copy of the record after change, marked "EditTo".
' This approach, together with the sequential numbering of the
' AutoNumber in the audit table makes tampering with the audit
' log more detectable.

'Note: Record confirmations need to be on. When opening the database:
' If Not Application.GetOption("Confirm Record Changes") Then
' Application.SetOption ("Confirm Record Changes"), True
' End If

Option Compare Database
Option Explicit

Private Const conMod As String = "ajbAudit"
Private Declare Function apiGetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long


Function NetworkUserName() As String
'On Error GoTo Err_Handler
'Purpose: Returns the network login name
Dim lngLen As Long
Dim lngX As Long
Dim strUserName As String

NetworkUserName = "Unknown"

strUserName = String$(254, 0)
lngLen = 255&
lngX = apiGetUserName(strUserName, lngLen)
If (lngX > 0&) Then
NetworkUserName = Left$(strUserName, lngLen - 1&)
End If

Exit_Handler:
Exit Function

Err_Handler:
' Call LogError(Err.Number, Err.Description, conMod & ".NetworkUserName",
, False)
Resume Exit_Handler
End Function


Function AuditDelBegin(sTable As String, sAudTmpTable As String, sKeyField
As String, lngKeyValue As Long) As Boolean
'On Error GoTo Err_AuditDelBegin
'Purpose: Write a copy of the record to a tmp audit table.
' Copy to be written to real audit table in AfterDelConfirm.
'Arguments: sTable = name of table to be audited.
' sAudTmpTable = the name of the temp audit table.
' sKeyField = name of AutoNumber field in table.
' lngKeyValue = number in the AutoNumber field.
'Return: True if successful.
'Usage: Call from a form's Delete event. Example:
' Call AuditDelBegin("tblInvoice", "audTmpInvoice",
"InvoiceID", Me.InvoiceID)
'Note: Must also call AuditDelEnd in the form's AfterDelConfirm
event.
Dim db As DAO.Database ' Current database
Dim sSQL As String ' Append query.

' Append record to the temp audit table.
Set db = DBEngine(0)(0)
sSQL = "INSERT INTO " & sAudTmpTable & " ( audType, audDate, audUser ) "
& _
"SELECT 'Delete' AS Expr1, Now() AS Expr2, NetworkUserName() AS
Expr3, " & sTable & ".* " & _
"FROM " & sTable & " WHERE (" & sTable & "." & sKeyField & " = " &
lngKeyValue & ");"
db.Execute sSQL, dbFailOnError

Exit_AuditDelBegin:
Set db = Nothing
Exit Function

Err_AuditDelBegin:
' Call LogError(Err.Number, Err.Description, conMod & ".AuditDelBegin()",
, False)
Resume Exit_AuditDelBegin
End Function


Function AuditDelEnd(sAudTmpTable As String, sAudTable As String, Status As
Integer) As Boolean
'On Error GoTo Err_AuditDelEnd
'Purpose: If the deletion was completed, copy the data from the
' temp table to the autit table. Empty temp table.
'Arguments: sAudTmpTable = name of temp audit table
' sAudTable = name of audit table
' Status = Status from the form's AfterDelConfirm event.
'Return: True if successful.
'Usage: Call from form's AfterDelConfirm event. Example:
' Call AuditDelEnd("audTmpInvoice", "audInvoice", Status)
Dim db As DAO.Database ' Currrent database
Dim sSQL As String ' Append query.

' If the Delete proceeded, copy the record(s) from temp table to delete
table.
' Note: Only "Delete" types are copied: cancelled Edits may be there as
well.
Set db = DBEngine(0)(0)
If Status = acDeleteOK Then
sSQL = "INSERT INTO " & sAudTable & " SELECT " & sAudTmpTable & ".*
FROM " & sAudTmpTable & _
" WHERE (" & sAudTmpTable & ".audType = 'Delete');"
db.Execute sSQL, dbFailOnError
End If

'Remove the temp record(s).
sSQL = "DELETE FROM " & sAudTmpTable & ";"
db.Execute sSQL, dbFailOnError
AuditDelEnd = True

Exit_AuditDelEnd:
Set db = Nothing
Exit Function

Err_AuditDelEnd:
' Call LogError(Err.Number, Err.Description, conMod & ".AuditDelEnd()",
False)
Resume Exit_AuditDelEnd
End Function


Function AuditEditBegin(sTable As String, sAudTmpTable As String, sKeyField
As String, _
lngKeyValue As Long, bWasNewRecord As Boolean) As Boolean
'On Error GoTo Err_AuditEditBegin
'Purpose: Write a copy of the old values to temp table.
' It is then copied to the true audit table in AuditEditEnd.
'Arugments: sTable = name of table being audited.
' sAudTmpTable = name of the temp audit table.
' sKeyField = name of the AutoNumber field.
' lngKeyValue = Value of the AutoNumber field.
' bWasNewRecord = True if this was a new insert.
'Return: True if successful
'Usage: Called in form's BeforeUpdate event. Example:
' bWasNewRecord = Me.NewRecord
' Call AuditEditBegin("tblInvoice", "audTmpInvoice",
"InvoiceID", Me.InvoiceID, bWasNewRecord)
Dim db As DAO.Database ' Current database
Dim sSQL As String

'Remove any cancelled update still in the tmp table.
Set db = DBEngine(0)(0)
sSQL = "DELETE FROM " & sAudTmpTable & ";"
db.Execute sSQL

' If this was not a new record, save the old values.
If Not bWasNewRecord Then
sSQL = "INSERT INTO " & sAudTmpTable & " ( audType, audDate,
audUser ) " & _
"SELECT 'EditFrom' AS Expr1, Now() AS Expr2, NetworkUserName()
AS Expr3, " & sTable & ".* " & _
"FROM " & sTable & " WHERE (" & sTable & "." & sKeyField & " = "
& lngKeyValue & ");"
db.Execute sSQL, dbFailOnError
End If
AuditEditBegin = True

Exit_AuditEditBegin:
Set db = Nothing
Exit Function

Err_AuditEditBegin:
' Call LogError(Err.Number, Err.Description, conMod &
".AuditEditBegin()", , False)
Resume Exit_AuditEditBegin
End Function


Function AuditEditEnd(sTable As String, sAudTmpTable As String, sAudTable As
String, _
sKeyField As String, lngKeyValue As Long, bWasNewRecord As Boolean) As
Boolean
'On Error GoTo Err_AuditEditEnd
'Purpose: Write the audit trail to the audit table.
'Arguments: sTable = name of table being audited.
' sAudTmpTable = name of the temp audit table.
' sAudTable = name of the audit table.
' sKeyField = name of the AutoNumber field.
' lngKeyValue = Value of the AutoNumber field.
' bWasNewRecord = True if this was a new insert.
'Return: True if successful
'Usage: Called in form's AfterUpdate event. Example:
' Call AuditEditEnd("tblInvoice", "audTmpInvoice",
"audInvoice", "InvoiceID", Me.InvoiceID, bWasNewRecord)
Dim db As DAO.Database
Dim sSQL As String
Set db = DBEngine(0)(0)

If bWasNewRecord Then
' Copy the new values as "Insert".
sSQL = "INSERT INTO " & sAudTable & " ( audType, audDate, audUser )
" & _
"SELECT 'Insert' AS Expr1, Now() AS Expr2, NetworkUserName() AS
Expr3, " & sTable & ".* " & _
"FROM " & sTable & " WHERE (" & sTable & "." & sKeyField & " = "
& lngKeyValue & ");"
db.Execute sSQL, dbFailOnError
Else
' Copy the latest edit from temp table as "EditFrom".
sSQL = "INSERT INTO " & sAudTable & " SELECT TOP 1 " & sAudTmpTable
& ".* FROM " & sAudTmpTable & _
" WHERE (" & sAudTmpTable & ".audType = 'EditFrom') ORDER BY " &
sAudTmpTable & ".audDate DESC;"
db.Execute sSQL
' Copy the new values as "EditTo"
sSQL = "INSERT INTO " & sAudTable & " ( audType, audDate, audUser )
" & _
"SELECT 'EditTo' AS Expr1, Now() AS Expr2, NetworkUserName() AS
Expr3, " & sTable & ".* " & _
"FROM " & sTable & " WHERE (" & sTable & "." & sKeyField & " = "
& lngKeyValue & ");"
db.Execute sSQL
' Empty the temp table.
sSQL = "DELETE FROM " & sAudTmpTable & ";"
db.Execute sSQL, dbFailOnError
End If
AuditEditEnd = True

Exit_AuditEditEnd:
Set db = Nothing
Exit Function

Err_AuditEditEnd:
' Call LogError(Err.Number, Err.Description, conMod & ".AuditEditEnd()",
, False)
Resume Exit_AuditEditEnd
End Function

What was the last thing you did before missing them? See above
Could a user have deleted them?
No, at this point I'm the only user. Also the data is still there as it is
visible in the forms.Regards,
Iain, Pudsey UK
 
S

Swarfmaker

Danny,
I'll have to anonimise the data first then I'll get it to you tomorrow

Iain, Pudsey UK
 
S

Swarfmaker

Not thinking here. I can't anonimise the data as I can't get to the
tables!!!!!!!
 
I

ihawaiian

Check the forms' and report's record source properties. The path to the
tables or queries in the back end should be embedded in the SQL code. If
it's not in the properties, check the VBA modules for procedures that set
the forms' and reports' record source properties at runtime.

The path to the back end table in SQL is commonly written in this format:

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers
 
D

Danny J. Lesandrini

You do realize, that if you use that syntax, you won't see tables
in the Access object explorer, right?

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers

You'll only see table icons if there are linked tables or local tables.
Could that be the issue? It would explain why forms work but no
tables appear. Do they exist in the source described above?
--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


ihawaiian said:
Check the forms' and report's record source properties. The path to the tables or queries in the back end should be embedded
in the SQL code. If it's not in the properties, check the VBA modules for procedures that set the forms' and reports' record
source properties at runtime.

The path to the back end table in SQL is commonly written in this format:

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers


Swarfmaker said:
Access2003 on XPproSP2.

All of the tables and queries in my database have suddenly disappeared, but the forms can still see the data.
I've tried closing and repairing, I've tried importing into a new database - the forms and reports can be imported but the
tables and queries are invisible. The database is set to show hidden and system objects.
Can anyone throw a bit of light on this?

Iain, Pudsey UK
 
I

ihawaiian

I hide the tables and queries in the SQL for the form's record source and
convert the front end to an MDE. Users can't see the form's record source
in design mode and don't see any linked tables or queries, either. Could be
the same thing has been done to Swarfmaker's database.


Danny J. Lesandrini said:
You do realize, that if you use that syntax, you won't see tables
in the Access object explorer, right?

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers

You'll only see table icons if there are linked tables or local tables.
Could that be the issue? It would explain why forms work but no
tables appear. Do they exist in the source described above?
--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


ihawaiian said:
Check the forms' and report's record source properties. The path to the
tables or queries in the back end should be embedded in the SQL code. If
it's not in the properties, check the VBA modules for procedures that set
the forms' and reports' record source properties at runtime.

The path to the back end table in SQL is commonly written in this format:

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers
 
D

Danny J. Lesandrini

If this syntax is being used throughout, then yes, there are no links.
Not a bad idea. Not sure how this style affects performance, if at all.

--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


ihawaiian said:
I hide the tables and queries in the SQL for the form's record source and convert the front end to an MDE. Users can't see the
form's record source in design mode and don't see any linked tables or queries, either. Could be the same thing has been done
to Swarfmaker's database.


Danny J. Lesandrini said:
You do realize, that if you use that syntax, you won't see tables
in the Access object explorer, right?

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers
 
I

ihawaiian

It doesn't affect performance but it can affect form functionality: bound
form v. unbound form. Using SQL as the form's record source makes it an
unbound form. Need a table name or query name in the record source for a
bound form.
 
D

Danny J. Lesandrini

I don't think that's true under any condition. A form is bound whether
it's source is a query or table or a SQL Statement.

I even checked this syntax, and sure enough, it's updatable too.

SELECT * FROM [;DATABASE=\\PHARMATECH2003\Home\dannyl\My Documents\db1.mdb].tblState;
--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


ihawaiian said:
It doesn't affect performance but it can affect form functionality: bound form v. unbound form. Using SQL as the form's
record source makes it an unbound form. Need a table name or query name in the record source for a bound form.
 
C

Chris O'C

It's updateable but it doesn't meet Access's strictest definition of a bound
form. This issue comes up so very rarely that I've forgotten where it
really matters in bound v. unbound forms -- meaning the VBA code won't work
for the specific situation if it's a form using a SQL statement as the
record source instead of the name of a table or query. Except the bug in
Access 2003 when trying to filter a bound subform in an unbound main form.
But that bug doesn't exist in earlier versions and I don't know if it's in
Access 2007 as I haven't tested that situation yet. Like I said, it's very
rare that it matters to the code. Not surprised you haven't run into it.
 
D

Danny J. Lesandrini

I don't even know how to begin to google this issue and I've never heard
about this. It's disingenuinous to say a form is not "bound" if it uses a
SQL Statement as the recordsource.

You may be correct, Chris, but it sounds like double talk to me. If it looks
like a duck and quacks like a duck, in my village we call it a duck.
--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


Chris O'C said:
It's updateable but it doesn't meet Access's strictest definition of a bound form. This issue comes up so very rarely that
I've forgotten where it really matters in bound v. unbound forms -- meaning the VBA code won't work for the specific situation
if it's a form using a SQL statement as the record source instead of the name of a table or query. Except the bug in Access
2003 when trying to filter a bound subform in an unbound main form. But that bug doesn't exist in earlier versions and I don't
know if it's in Access 2007 as I haven't tested that situation yet. Like I said, it's very rare that it matters to the code.
Not surprised you haven't run into it.


Danny J. Lesandrini said:
I don't think that's true under any condition. A form is bound whether
it's source is a query or table or a SQL Statement.

I even checked this syntax, and sure enough, it's updatable too.

SELECT * FROM [;DATABASE=\\PHARMATECH2003\Home\dannyl\My Documents\db1.mdb].tblState;
 
D

Danny J. Lesandrini

I'll have to watch for that. There have been a-many-a wierd thing
I've not been able to explain. Maybe this would account for it.
 
S

Swarfmaker

The Database has not yet been split. I don't normally split until I'm ready
to deploy.

Iain, Pudsey UK

Danny J. Lesandrini said:
You do realize, that if you use that syntax, you won't see tables
in the Access object explorer, right?

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers

You'll only see table icons if there are linked tables or local tables.
Could that be the issue? It would explain why forms work but no
tables appear. Do they exist in the source described above?
--
Danny J. Lesandrini
(e-mail address removed)
www.amazecreations.com


ihawaiian said:
Check the forms' and report's record source properties. The path to the
tables or queries in the back end should be embedded in the SQL code. If
it's not in the properties, check the VBA modules for procedures that set
the forms' and reports' record source properties at runtime.

The path to the back end table in SQL is commonly written in this format:

[;DATABASE=C:\Database\Northwind.mdb;].Suppliers


Swarfmaker said:
Access2003 on XPproSP2.

All of the tables and queries in my database have suddenly disappeared,
but the forms can still see the data.
I've tried closing and repairing, I've tried importing into a new
database - the forms and reports can be imported but the tables and
queries are invisible. The database is set to show hidden and system
objects.
Can anyone throw a bit of light on this?

Iain, Pudsey UK
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top