MS Office 365 ProPlus,Access 2007-2016
这是问题所在...
我在共享文件服务器上有一个MS Access DB,来自许多站点的许多用户可以访问该数据库,每周进行一些小的编辑。有时,具有活动连接的用户会突然关闭其客户端服务器(其笔记本电脑),从而使与DB的连接悬空,从而导致DB处于无法打开的状态。消息表明它已损坏,修复选项只是挂起。没什么大不了的,因为我有一个任务调度程序作业,该作业每3小时备份(复制一次)数据库一次,我可以使用最新的备份来还原。但是我什至无法删除/删除具有备份的数据库,因为悬挂的过程已连接并且Windows拒绝让我删除它(这本身就是IMO的问题)。
解决方案是找到连接,将其杀死,删除.accdb和.laccdb,然后将其替换为备份。但是不幸的是,我没有找到/杀死连接的特权,所以我必须让IT部门的人去做(可能要花很长时间,而且我得到的人经常不知道该怎么做)。
真正缓解该问题的方法是自动为空闲时间超过x分钟的客户端进程断开数据库连接。我使用表格看到了与此类似的内容。但是我的用户直接在表格中编辑单元格(就像在窗体上编辑ExCel样式一样)。我搜索了数据库选项,但没有看到通常为数据库设置空闲超时/断开连接的选项。
问题:是否有办法设置像这样的空闲超时,它将在x分钟后关闭数据库连接?
问题:鉴于存在的问题,还有另一种方法可以防止这些数据库“损坏”。我所读到的所有内容都是“教育用户在完成后关闭Access”。用户太多,我怀疑他们会注意的。
问题:为此,Access似乎不是一个那么健壮的数据库,但是用户确实希望使用ExCel样式的界面(无需格式即可编辑记录中的单元格)。记录级别的锁定机制似乎运行良好。我喜欢这样一个事实,我可以轻松地设置触发器和约束来保持数据质量,使用SQL查询事物等(ExCel对此不太好)。但是,如果有比Access更好的替代方案,我将不知所措。
感谢任何想法!
答案 0 :(得分:1)
这是一个非常普遍的问题,没有简单的解决方案。
有两种主要方法可以解决此问题:
使用隐藏的窗体以及在启动时打开的计时器。时不时检查表单,是否打开了表单/数据表,以及该表单/数据表上的活动记录或活动控件是否发生了更改。如果一段时间没有,请关闭Access。
此方法所需的代码在here on MS docs中进行了描述,它仅需要对数据表(表/查询)进行一些补充。
此方法的局限性在于,您正在关闭多任务用户的Access。如果他们一阵子不触摸Access,那就不见了,那就不是很棒的UX。
此处的另一个限制是,用户有可能被不必要地踢出局,例如,因为他正在从另一个应用程序中移动数据,因此在积极使用数据库时总是将光标停留在新记录上。
使用WinAPI在启动时启动计时器(也可以是带有计时器的隐藏表格)。使用GetLastInputInfo
来验证用户在计时器上没有在设置的时间内发送任何输入。如果还没有,请关闭Access。
这有一个局限性,即任何输入(例如,当鼠标经过不稳定的桌子时移动很小的鼠标)都会重置计时器。
如果您在实现这两个方法时遇到困难,我可以提供示例代码。
答案 1 :(得分:1)
由于Erik解释的局限性,您更好的选择是(如果尚未完成)将数据库拆分到前端和后端,转换后端到SQL Server(可以免费使用Express版),然后 distribute 然后使用我在本文中介绍的方法将前端前端到用户的计算机(如果您没有帐户,请浏览链接“阅读全文”):
Deploy and update a Microsoft Access application with one click
这将使您完全摆脱使您忙碌的艰巨任务。
答案 2 :(得分:0)
想法是运行vbs来运行访问权限。如果检测到掉电事件,它将断开数据库的连接,而不会留下悬而未决的过程。
Option Explicit
Dim objAccess, objWMIService, colItems
Set objAccess = CreateObject("Access.Application")
objAccess.Visible = True
objAccess.OpenCurrentDatabase "\\vausamd20\SCBUDV_Infra\dbg_taskdb.accdb"
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set colItems = objWMIService.ExecNotificationQuery("Select * from
Win32_PowerManagementEvent")
Do While True
If colItems.NextEvent.EventType = 4 Then
objAccess.Quit
Set objAccess = Nothing
Set colItems = Nothing
Set objWMIService = Nothing
Exit Do
End If
Loop
如果有人认为这是个好主意,请公开评论!