问题:
如何恢复已经删除的记录;如何恢复已经删除的表、窗体等等对象
1、我用DELETEFROMTABLE删除了一些记录,现在发现误删除了,该如何恢复?
2、我直接手动删除或者用DROPTABLE删除了一个表,现在发现是误删除了,该如何恢复?
3、我手动删除了一个窗体,该如何恢复?
4、我删除了记录,可是数据库体积并没有减小,那么是否能找回记录呢?
回答:
1、已经删除的记录是无法恢复的,ACCESS不是FOXPRO,MDB格式不是DBF格式,没有逻辑删除和物理删除的概念,一旦删除就无法恢复了。
2、无法恢复,但是你可以查看一下,有没有隐藏的以"~"符号开头的表,更改该表的名称有可能找回你需要的表。
3、无法恢复,但是你可以查看一下有没有系统隐藏的对象,有时候对象被删除时系统并不直接删除,而是更改对象名后隐藏它。
4、数据库体积的确没有变小,你压缩修复数据库后体积就会变小了。那是因为在二进制上你的数据的确没有被删除,仍然存放在磁盘的某个扇区,但是微软没有提供MDB格式二进制组织方式的参考资料(微软也不会提供,其他第三方公司也没有权利直接反编译MDB格式)。至今为止,中国大陆我也没有看到过相关的参考资料。所以目前为止,你已经删除的数据是无法恢复的。但是你可以尝试使用磁盘恢复软件来找到恢复数据的方法,但是该方法不在本文讨论范围。
建议:在建立数据库结构时,可以在各个表中再多加一个ISDEL字段,删除记录时不使用DELETEFROM,而使用UPDATETABLESETISDEL=TRUE这样的语句,然后在界面上不显示ISDEL=TRUE的记录即可。
复制代码 代码如下:
如果还没有被压缩理论上可以。试试这段代码吧。加在access模组中
恢復刪除的工作表(未被壓縮)
PublicFunctionFnUndeleteObjects()AsBoolean
OnErrorGoToErrorHandler:
DimstrObjectNameAsString
DimrsTablesAsDAO.Recordset
DimdbsDatabaseAsDAO.Database
DimtDefAsDAO.TableDef
DimqDefAsDAO.QueryDef
DimintNumDeletedItemsFoundAsInteger
SetdbsDatabase=CurrentDb
ForEachtDefIndbsDatabase.TableDefs
'Thisisactuallyusedasa'DeletedFlag'
IftDef.AttributesAnddbHiddenObjectThen
strObjectName=FnGetDeletedTableNameByProp(tDef.Name)
strObjectName=InputBox("AdeletedTABLEhasbeenfound."&_
vbCrLf&vbCrLf&_
"Toundeletethisobject,enteranewname:",_
"AccessUndeleteTable",strObjectName)
IfLen(strObjectName)>0Then
FnUndeleteTableCurrentDb,tDef.Name,strObjectName
EndIf
intNumDeletedItemsFound=intNumDeletedItemsFound+1
EndIf
NexttDef
ForEachqDefIndbsDatabase.QueryDefs
'Note'Attributes'flagisnotexposedforQueryDefobjects,
'WecouldlookuptheflagbyusingMSysObjectsbut
'newqueriesdon'tgetwrittentoMSysObjectsuntil
'Accessisclosed.Thereforewe'lljustcheckthe
'startofthenameis'~TMPCLP'...
IfInStr(1,qDef.Name,"~TMPCLP")=1Then
strObjectName=""
strObjectName=InputBox("AdeletedQUERYhasbeenfound."&_
vbCrLf&vbCrLf&_
"Toundeletethisobject,enteranewname:",_
"AccessUndeleteQuery",strObjectName)
IfLen(strObjectName)>0Then
IfFnUndeleteQuery(CurrentDb,qDef.Name,strObjectName)Then
'We'llrenamethedeletedobjectsincewe'vemadea
'copyandwon'tbeneedingtore-undeleteit.
'(Tobreakthecondition"~TMPCLP"infuture...)
qDef.Name="~TMPCLQ"&Right$(qDef.Name,Len(qDef.Name)-7)
EndIf
EndIf
intNumDeletedItemsFound=intNumDeletedItemsFound+1
EndIf
NextqDef
IfintNumDeletedItemsFound=0Then
MsgBox"Unabletofindanydeletedtables/queriestoundelete!"
EndIf
SetdbsDatabase=Nothing
FnUndeleteObjects=True
ExitFunction:
ExitFunction
ErrorHandler:
MsgBox"ErroroccuredinFnUndeleteObjects()-"&_
Err.Description&"("&CStr(Err.Number)&")"
GoToExitFunction
EndFunction
PrivateFunctionFnUndeleteTable(dbDatabaseAsDAO.Database,_
strDeletedTableNameAsString,_
strNewTableNameAsString)
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
DimtDefAsDAO.TableDef
SettDef=dbDatabase.TableDefs(strDeletedTableName)
'RemovetheDeletedFlag...
tDef.Attributes=tDef.AttributesAndNotdbHiddenObject
'Renamethedeletedobjecttotheoriginalornewname...
tDef.Name=strNewTableName
dbDatabase.TableDefs.Refresh
Application.RefreshDatabaseWindow
SettDef=Nothing
EndFunction
PrivateFunctionFnUndeleteQuery(dbDatabaseAsDAO.Database,_
strDeletedQueryNameAsString,_
strNewQueryNameAsString)
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
'Wecan'tjustremovetheDeletedflagonqueries
'('Attributes'isnotanexposedproperty)
'SoinsteadwecreateanewquerywiththeSQL...
'Note:Can'tuseDoCmd.CopyObjectasitcopiesthedbHiddenObjectattribute!
IfFnCopyQuery(dbDatabase,strDeletedQueryName,strNewQueryName)Then
FnUndeleteQuery=True
Application.RefreshDatabaseWindow
EndIf
EndFunction
PrivateFunctionFnCopyQuery(dbDatabaseAsDAO.Database,_
strSourceNameAsString,_
strDestinationNameAsString)
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
OnErrorGoToErrorHandler:
DimqDefOldAsDAO.QueryDef
DimqDefNewAsDAO.QueryDef
DimFieldAsDAO.Field
SetqDefOld=dbDatabase.QueryDefs(strSourceName)
SetqDefNew=dbDatabase.CreateQueryDef(strDestinationName,qDefOld.SQL)
'Copyrootqueryproperties...
FnCopyLvPropertiesqDefNew,qDefOld.Properties,qDefNew.Properties
ForEachFieldInqDefOld.Fields
'Copyeachfieldsindividualproperties...
FnCopyLvPropertiesqDefNew.Fields(Field.Name),_
Field.Properties,_
qDefNew.Fields(Field.Name).Properties
NextField
dbDatabase.QueryDefs.Refresh
FnCopyQuery=True
ExitFunction:
SetqDefNew=Nothing
SetqDefOld=Nothing
ExitFunction
ErrorHandler:
MsgBox"Errorre-creatingquery'"&strDestinationName&"':"&vbCrLf&_
Err.Description&"("&CStr(Err.Number)&")"
GoToExitFunction
EndFunction
PrivateFunctionPropExists(PropsAsDAO.Properties,strPropNameAsString)AsBoolean
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
'Ifpropertiesfailtobecreated,we'lljustignoretheerrors
OnErrorResumeNext
DimPropAsDAO.Property
ForEachPropInProps
IfProp.Name=strPropNameThen
PropExists=True
ExitFunction'Shortcircuit
EndIf
NextProp
PropExists=False
EndFunction
PrivateSubFnCopyLvProperties(objObjectAsObject,OldPropsAsDAO.Properties,NewPropsAsDAO.Properties)
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
'Ifpropertiesfailtobecreated,we'lljustignoretheerrors
OnErrorResumeNext
DimPropAsDAO.Property
DimNewPropAsDAO.Property
ForEachPropInOldProps
IfNotPropExists(NewProps,Prop.Name)Then
IfIsNumeric(Prop.Value)Then
NewProps.AppendobjObject.CreateProperty(Prop.Name,Prop.Type,CLng(Prop.Value))
Else
NewProps.AppendobjObject.CreateProperty(Prop.Name,Prop.Type,Prop.Value)
EndIf
Else
WithNewProps(Prop.Name)
.Type=Prop.Type
.Value=Prop.Value
EndWith
EndIf
NextProp
EndSub
PrivateFunctionFnGetDeletedTableNameByProp(strRealTableNameAsString)AsString
'Module(c)2005WaynePhillips(http://www.everythingaccess.com)
'Written18/04/2005
'Ifanerroroccurshere,justignore(userwilloverridetheblankname)
OnErrorResumeNext
DimiAsLong
DimstrNameMapAsString
'LookuptheUnicodetranslationNameMappropertytotrytoguessthe
'originaltablename...(Access2000+only-anddoesn'talwaysexist?!)
strNameMap=CurrentDb.TableDefs(strRealTableName).Properties("NameMap")
strNameMap=Mid(strNameMap,23)'Offsetofthetablename...
'Findthenullterminator...
i=1
IfLen(strNameMap)>0Then
While(i<Len(strNameMap))And(Asc(Mid(strNameMap,i))<>0)
i=i+1
Wend
EndIf
FnGetDeletedTableNameByProp=Left(strNameMap,i-1)
EndFunction