Ms Access数据库在使用vba打开时是否可以创建自己的备份?

时间:2017-08-16 15:56:42

标签: vba ms-access

后台:我有一个将Quickbooks链接到Ms Access的流程。如果按下某个按钮,将从Quickbooks中查询一些信息,然后更新Ms Access。如果电源耗尽,或者用户强制Ms Access在同步过程中关闭,则可能导致某些信息被破坏。

目标:我希望在表单上有一个用户可以按下的按钮,它会将当前数据库保存到预定义位置,并将日期和时间附加到文件名。

我一直在阅读如何备份其他已关闭的数据库(使用FileCopy),但是您需要一个hacky-workaround解决方案来在开放数据库上执行此操作,这可能会导致数据损坏。我并不完全相信,因为用户可以随时使用“另存为”。

有没有办法备份当前打开的Ms Access数据库,或者满足我需求的东西?

3 个答案:

答案 0 :(得分:3)

用户"另存为"与复制文件不同,它实际上创建了一个新数据库,并将所有内容导出到该数据库。如果您愿意,您也可以这样做(如果没有锁定的记录),但它确实需要一些编码。

"备份数据库"如果文件由其他用户打开(并在使用时关闭所有打开的对象),则从保存菜单中不可用。

当然,您可以创建一个新文件,然后遍历所有表,查询,表单,报表,宏和模块以复制它们,然后遍历所有关系以将它们添加到副本中。然后,您可以将所有数据库属性复制到新数据库。但这需要一些工作。

请参阅以下代码以创建忽略关系和数据库属性的备份

Public Sub BackupDatabase(newLocation As String)
    'Make sure there isn't already a file with the name of the new database
    If Dir(newLocation) <> "" Then Kill newLocation
    'Create a new database using the default workspace
    'dbVersion30 = Jet 3, dbVersion40 = Jet4, dbVersion120 = 2007 accdb, dbVersion150 = 2013 accdb
    DBEngine.Workspaces(0).CreateDatabase newLocation, dbLangGeneral, Option:=dbVersion150

    'Iterate through common object collections, put the files in
    Dim iterator As Variant
    For Each iterator In CurrentDb.TableDefs
        If Not iterator.Name Like "MSys*" Then
            DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acTable, iterator.Name, iterator.Name
        End If
    Next iterator
    For Each iterator In CurrentDb.QueryDefs
        If Not iterator.Name Like "~sq_*" Then
            DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acQuery, iterator.Name, iterator.Name
        End If
    Next iterator
    For Each iterator In CurrentProject.AllForms
         DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acForm, iterator.Name, iterator.Name
    Next iterator
    For Each iterator In CurrentProject.AllReports
        DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acReport, iterator.Name, iterator.Name
    Next iterator
    For Each iterator In CurrentProject.AllMacros
        DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acMacro, iterator.Name, iterator.Name
    Next iterator
    For Each iterator In CurrentProject.AllModules
        DoCmd.TransferDatabase acExport, "Microsoft Access", newLocation, acModule, iterator.Name, iterator.Name
    Next iterator
End Sub

请注意,根据您的安全设置,您可能会获得大量安全弹出窗口。

答案 1 :(得分:0)

您可以使用以下代码行,假设您有一个拆分数据库:

Public sub CompactDB()
dim rst as dao.recordset
dim strSQL as string
dim strLocation as string
Dim strDestination as string

strsql = "SELECT * " & _
         "FROM DestinationTable;"
set rst = currentdb.openrecordset(strsql)
strlocation = rst![DestinationFrom]
strdestination = rst![DestinationTo]
rst.close
set rst = nothing

DBEngine.CompactDatabase rst![DestinationFrom] , rst![DestinationTo]

if not rst is nothing then
rst.close
set rst = nothing
end if
End Sub

注意这不会压缩您当前的后端(strFrom),这会使位于strFrom的后端副本到新位置(strTo)。

只需按一下按钮点击或来自另一个人的事件就可以调用此子。

但是,我处理这个的方法是制作一个存储2个字段的表。字段1命名为&#34; DestinationFrom&#34;,字段2命名为&#34; DestinationTo&#34;。然后我存储如下记录:

DestinationFrom = C:\当前后端的目的地

DestinationTo = C:\备份目标

然后使用以下代码:

TO_CHAR(Month(t.TRANDATE,'YYYY-MM-DD')) AS CreatedMonth

这样,如果我的代码失败导致文件夹被删除或移动,我可以更改表格字段中的字符串位置,而无需更改任何硬编码并需要发布新副本的内容。在分割数据库中允许多个用户时非常有用

答案 2 :(得分:0)

您可以尝试像这样使用FileSystemObject:

"Answer 1"