长期以来,数据库设计的良好实践是将数据库“拆分”为前端(FE)和后端(BE)。 FE包含使数据库正常工作所需的所有查询,表单,报告和模块。 BE包含容纳您的项目数据的所有表。 FE链接到您的BE中的表,因此两者之间似乎无缝集成。 造成这种情况的原因(除其他外)是,大多数情况下,当Access数据库崩溃时,是由于查询,表单,报表和模块无法正常运行,这可能导致程序意外关闭,或者更有可能,无休止地挂起,并要求通过您的任务管理器中止该程序。 如果您的BE发生了这种情况,则丢失数据甚至数据表将被破坏的可能性更高,从而使数据库无法使用。
注意:将数据库分为FE和BE并不排除您需要频繁备份数据文件。 无论您的数据文件有多大,这都是一个好习惯。 假设您每小时备份一次数据。 如果您要进行数千笔交易,则丢失一小时的数据可能看起来很多。 但是,想象一下,丢失了一整天的数据!
请查看
Microsoft有关如何拆分数据库的指南,以详细介绍此过程的基础 。通常(或者至少在许多情况下使用数据库架构师),我们将以一种普通用户无法轻易破解的形式发布最终的FE。 这会将.accdb文件转换为.accde文件。 是的,因为MS Access并不是一个安全的数据库,所以任何具有中等技能的用户都可以找到解决此问题的方法,但是他们需要高级技能才能比查看表更进一步。 因为这个见解是
不是关于安全性,而是关于FE和BE管理,我们会将讨论保留在不同的时间和地点。请查看
Microsoft有关如何创建.accde文件的指南 。而且,通常,在现代工作环境中,数据库通常不是为一个人使用和输入数据而设计的。 它们是供工作组访问和更新的。 这通常需要使用网络文件结构来容纳您的FE和BE。 但是,在网络环境中工作时,当多个人打开并使用同一文件时,MS Access可能会显得有些挑剔。 此外,每当有人打开该特定文件时,该文件都会被锁定,从而阻止数据库管理员对其进行更新或将该文件替换为较新的版本-至少直到每个人都退出数据库为止。
因此,我喜欢将.accde文件发布到共享的网络位置,但是将文件复制到用户的本地计算机上并从本地计算机执行该文件(非常感谢
zmbd,感谢他对此的见识)。 为此,请在记事本中创建一个简短的命令脚本,类似于以下内容:@ECHO OFF
IF NOT EXIST %userprofile%\Documents\DBUser\[DatabaseName].accde MKDIR %userprofile%\Documents\DBUser
COPY \\NetworkLocation\NetworkFolder\DATABASE\[DatabaseName].accde %userprofile%\Documents\DBUser\[DatabaseName].accde /Y
START /I "MSAccess.exe" %userprofile%\Documents\DBUser\[DatabaseName].accde
然后将此文件另存为“ Database.cmd”或有用的文件,然后将该文件保存在与数据库相同的网络位置。
然后,当您设置用户使用数据库时,请创建命令脚本而不是数据库的快捷方式。
这会将数据库复制到本地文件夹并从那里运行它。
我想做的另一件事是尽可能地禁用内置的MS Access用户界面。 我将所有表单设置为模态并弹出,并隐藏“数据库”窗口,禁用菜单并阻止快捷菜单。 用户在我的数据库中可以执行和不能执行的操作受到严格限制,这是设计使然。 我认为,有人独立探索的能力越弱,他们搞砸事情的可能性就越小。 我还具有在执行数据库时打开的指定表单,该表单设置用户权限并将用户定向到数据库的相应部分。 去这里找到我的文章
如何在MS Access中创建用户权限和自定义菜单 。现在,让我们谈谈数据库更新和更改。
假设您的数据库运行良好,但是您的一位用户标识了他们需要添加到数据库中的一项新功能。 您仍应具有.accdb文件的本地副本(或至少您拥有
最好还是拥有它!)。 但是,所有查询,表单,报告和模块的工作副本仍可能链接到网络数据库。 因此,您转到链接表管理器,并让数据库现在指向表的本地保存版本(您也应该随时可以使用它们)。 然后,当您发布更改时,您将返回到链接表管理器并再次进行所有操作。但是,如果您发布数据库并禁用菜单又忘记链接到网络表怎么办? 我想你必须重新开始。 这可能会变得非常乏味,并且如果您碰巧有多个BE,则可能会花费很多时间。 我不想浪费时间,所以我想出了一个解决方案,该解决方案多年来一直为我服务。
我已在数据库中构建了一个管理员表单,该表单除其他外还设置了要在网络上发布的数据库。 将数据库另存为.accde文件后,即可完成所有操作。 这个过程确实如此简单:
以下是我的基本操作:
- 创建.accde文件
- 打开管理员表单,然后运行数据库设置代码
- 关闭数据库并将其复制到网络位置
在独立模块中,我建立了某些全局常量,这些全局常量指示某些文件和文件夹的位置。 因为我们使用数据库来引用网络上的其他文件和文件夹,所以对于网络服务器和数据库路径,我有一个单独的常量。 我还有单独的文件夹用于备份和数据:
Option Compare Database
Option Explicit
'******************************
'* ESTABLISH PUBLIC CONSTANTS *
'* AND GLOBAL VARIABLES *
'******************************
'Database Path constants and variables
Public Const gstrSERVER As String = _
"\\NetworkServer\NetworkFolder\"
Public Const gstrDBASEPATH As String = _
gstrSERVER & "DATABASE\"
Public Const gstrBACKUPPATH As String = _
gstrDBASEPATH & "BACKUP\"
Public Const gstrDBASEDATA As String = _
gstrDBASEPATH & "DATA\"
创建.accde文件之后,我打开该文件,然后打开包含我的代码的Administrator表单。
我要做的第一件事是建立一些特定于Form的变量,这些变量将帮助我更快,更轻松地运行代码。
Option Explicit
Option Compare Database
'Set some Constants and Public Variables
Public dbACC As Database
Public tdfLink As TableDef
我有一个命令按钮,该命令按钮在该命令按钮的OnClick事件中调用RelinkTables过程。
Private Sub RelinkTables()
On Error GoTo EH
Dim tdf As TableDef
Dim strDBName As String
Dim strLink As String
ChangeProperty "StartUpShowDBWindow", dbBoolean, False
ChangeProperty "AllowBuiltInToolbars", dbBoolean, False
ChangeProperty "StartupForm", dbText, "frmSplash"
ChangeProperty "StartUpShowStatusBar", dbBoolean, False
ChangeProperty "AllowSpecialKeys", dbBoolean, False
ChangeProperty "AllowDatasheetSchema", dbBoolean, False
ChangeProperty "AllowFullMenus", dbBoolean, False
ChangeProperty "AllowShortcutMenus", dbBoolean, False
LinkTableStatus "Startup Defaults Set"
strLink = ";DATABASE=" & gstrDBASEDATA
For Each tdf In dbACC.TableDefs
'Filter out system "~",
'non-Access (Excel Spreadsheets="$")
'and non-linked tables ("")
If Not ((Left(tdf.Name, 1) = "~") Or _
(Right(tdf.SourceTableName, 1) = "$") Or _
tdf.Connect = "") Then
strDBName = GetDBName(tdf.Connect)
RelinkTable dbACC, tdf.Name, strLink & strDBName
End If
Next tdf
LinkTableStatus ""
MsgBox "All tables were successfully linked! You are now free to " & _
"move about the Database!", vbOKOnly, "Action Complete"
Exit Sub
EH:
MsgBox "There was an error Relinking the Tables! " & _
"Please contact your Database Administrator.", vbCritical, "Error!"
Resume Next
End Sub
我要做的第一件事是建立一些数据库默认值(如果它们当前有效,这将使使用数据库确实很难)。
然后,它遍历所有表(链接的表),并确定这些表应该是什么源文件。
然后,它将这些表重新链接到那些表的网络版本。
为了使它起作用,我需要创建几个小的函数来帮助我完成此任务。 第一个是实际更改属性的函数:
Private Function ChangeProperty(strPropertyName As String, _
varPropertyType As Variant, varPropertyValue As Variant) As Integer
On Error GoTo Err_ChangeProperty
Dim prpProperty As Property
'Property exists, so set its Value
dbACC.Properties(strPropertyName) = varPropertyValue
ChangeProperty = True
Exit_ChangeProperty:
Exit Function
Err_ChangeProperty:
If Err.Number = 3270 Then 'Property not found
'Since the Property isn't found, create it!
Set prpProperty = _
dbACC.CreateProperty(strPropertyName, _
varPropertyType, varPropertyValue)
dbACC.Properties.Append prpProperty
Resume Next
Else
'Unknown Error
ChangeProperty = False
Resume Exit_ChangeProperty
End If
End Function
接下来,我创建了一个函数(GetDBName)来查找表所链接到的数据库的名称:
Private Function GetDBName(FullPathName As String) As String
On Error GoTo EH
Dim intCharCount As Integer
For intCharCount = Len(FullPathName) To 1 Step -1
If InStr(intCharCount, FullPathName, "\") <> 0 Then
GetDBName = Right(FullPathName, Len(FullPathName) - intCharCount)
intCharCount = -1
End If
Next intCharCount
Exit Function
EH:
MsgBox "There was an error getting the DB Name! " & _
"Please contact your Database Administrator.", vbOKOnly, "WARNING!"
Exit Function
End Function
最后,我需要一个函数,该函数将根据我从当前表中确定的值重新链接表。
Private Function RelinkTable(dbLink As Database, _
strTable As String, strConnect As String)
On Error GoTo EH
LinkTableStatus "Relinking " & strTable
Set tdfLink = dbLink.TableDefs(strTable)
tdfLink.Connect = strConnect
tdfLink.RefreshLink
Exit Function
EH:
MsgBox "There was an error Relinking the Table! " & _
"Please contact your Database Administrator.", vbOKOnly, "WARNING!"
Exit Function
End Function
我还没有弄清楚如何重新链接电子表格,但是我敢肯定我可能不知道有一种方法。
而已! 然后关闭我的管理员表单,关闭数据库并将其复制到网络位置。 一切都很整洁,我不会忘记任何东西。
另外,由于我从未接触过原始的.accdb文件,因此我仍然可以打开它并进行测试(使用本地数据资源),而不必担心会弄乱网络上的任何内容。
我敢肯定,还有其他更好的方法可以完成所有这些工作,但是对于那些觉得有限元分析和BE管理非常繁琐的人来说,这确实节省了时间。 但是,当其他人连接到数据库时,此代码运行速度会很慢,因为它必须重新建立那些链接(我听说有解决方法),但是我的数据库有100多个表,并且没有人连接,整个过程运行不到一分钟!
希望这可以帮助你们中的一些人!
From: https://bytes.com/topic/access/insights/957595-working-front-back-ends