【发布时间】:2021-04-20 11:52:48
【问题描述】:
我在 Excel 上制作了一个多用户界面,以便使用 ADO Connection 在一个常见的 Excel 文件中写入记录。
我有四个用户在使用这个界面(每个用户使用不同的界面文件)。
它一直有效,直到两个或更多用户尝试同时添加或编辑一条记录。
在这种情况下,VBA 会在尝试为最后一个用户打开 ADO 连接后立即以只读模式打开 Excel 文件。
我的解决方法是使用 ISWORKBOOKOPEN() 函数来识别何时发生并发,然后关闭文件,关闭连接,等待一秒钟,然后重试:
Application.ScreenUpdating = False
Dim ADODBCONNECT As New ADODB.Connection
Dim RECORDSET As New ADODB.RECORDSET
Dim SQL_FILTER As String
Dim DATABASE As String
' -------- BACKUP --------
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
Call oFSO.CopyFile(Range("SLITTING_DATABASE"), Range("BACKUP_FILENAME"))
' -------- ADIÇÃO DO REGISTRO --------
DATABASE = Workbooks("S41 - Deacro.xlsm").Sheets("DATA SOURCES").Range("SLITTING_DATABASE")
OPEN_CONN:
ADODBCONNECT.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source ='" & DATABASE & "';
Extended Properties='Excel 12.0'"
ADODBCONNECT.Open
If ISWORKBOOKOPEN(DATABASE) = True Then
ADODBCONNECT.Close
Workbooks(DATABASE).Close False
newHour = Hour(Now())
newMinute = Minute(Now())
newSecond = Second(Now()) + 1
WAITTIME = TimeSerial(newHour, newMinute, newSecond)
Application.Wait WAITTIME
GoTo OPEN_CONN
End If
SQL_FILTER = "Select * From [SLIT_INCOME$]"
RECORDSET.Open SQL_FILTER, ADODBCONNECT, adOpenKeyset, adLockOptimistic
RECORDSET.AddNew
RECORDSET!SlittingWO = Workbooks("S41 - Deacro.xlsm").Sheets("INTERFACE").Range("OP_Corte")
RECORDSET!ReelUD = CADASTRO_DE_BOBINAS.REEL_UD_ENTRY
RECORDSET!ReelLenghtm = CADASTRO_DE_BOBINAS.REEL_MTS_IN_ENTRY
RECORDSET!Date = Now
RECORDSET.UPDATE
RECORDSET.Close
ADODBCONNECT.Close
' -------- ATUALIZAÇÃO DOS DADOS NA INTERFACE --------
Call UPDATE_DATA
Application.ScreenUpdating = True
这里还有两个问题:
1 - 当文件打开时,workbooks.close 似乎不起作用,原因是:
错误9,下标超出范围
2 - 如果在打开 ADO 连接后使用该函数,即使该连接已被检查文件可用性的同一用户打开,它也会返回 true。
我在这里复制了另一个问题的函数:
Function ISWORKBOOKOPEN(FileName As String)
Dim ff As Long, ErrNo As Long
On Error Resume Next
ff = FreeFile()
Open FileName For Input Lock Read As #ff
Close ff
ErrNo = Err
On Error GoTo 0
Select Case ErrNo
Case 0: ISWORKBOOKOPEN = False
Case 70: ISWORKBOOKOPEN = True
Case Else: Error ErrNo
End Select
End Function
有没有办法检测到文件正在被另一个用户通过 ADO 连接访问,所以我可以做一个循环来强制最后一个用户等到第一个用户的连接关闭?
我知道 Excel 在用作数据库文件时有很多限制,但它是我公司提供的唯一工具。
【问题讨论】:
标签: sql excel vba concurrency ado