【问题标题】:ADODb connection refresh after Insert/Update/Delete statement (Excel/Access linkage)插入/更新/删除语句后 ADODb 连接刷新(Excel/Access 联动)
【发布时间】:2021-10-16 10:53:56
【问题描述】:

我制作了一个 Excel 界面来与 Access 数据库进行交互。目标是多人可以在只读模式下打开 Excel 界面,但仍使用 ActiveX 控件同时对数据库进行操作。

我有 3 个按钮显示 3 个用户窗体:一个用于“插入条目”,一个用于“删除条目”,一个用于“修改条目”。在这些用户表单中,我们可以分别输入新条目的值,然后通过 VBA 代码检查其有效性、确认删除一行或修改用户在表格显示上选择的条目的值。数据输入+确认后,与Access db建立ADO连接,执行sql查询。

例如,这里是“删除”用户表单的代码,其他的都是基于相同的模型。

Private Sub CommandButton1_Click()

    Dim lineArr() As Variant
    
    lineArr = returnSelectedLine
    
    Call doSqlInsert(CStr(lineArr(1)))
    Unload Me
        
End Sub

Private Sub CommandButton2_Click()
    Unload Me
End Sub


Private Sub UserForm_Terminate()
    Selection.ListObject.QueryTable.Refresh BackgroundQuery:=False
End Sub


Private Sub UserForm_Activate()
    Dim lineArr() As Variant
    
    lineArr = returnSelectedLine
    
    Me.Label8.Caption = "Are you sure you want to delete the article number " & lineArr(1) & " ? This action is irreversible."

End Sub


Sub doSqlInsert(art As String)

    Dim cn As Object
    Dim strFile As String
    Dim strCon As String
    Dim quer As String

    
    
    strFile = ThisWorkbook.Path + "\etwDb.accdb"
        
    strCon = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & strFile
        
    Set cn = CreateObject("ADODB.Connection")
    cn.Open strCon
    
    quer = "DELETE FROM Dvpt WHERE [Article] = " & art & ";"
    
    cn.Execute quer

    cn.Close
    
    Set cn = Nothing
    
End Sub

Function returnSelectedLine()

    Dim rw As Integer
    Dim res(0 To 7) As Variant
    Dim i As Integer
    
    
    
    rw = ActiveCell.Row
    
    With ThisWorkbook.Worksheets("Liste dvpt")
        For i = 0 To 7
            res(i) = .Cells(rw, i + 2)
        Next i
    End With
    
    returnSelectedLine = res
End Function

这很好用,并且可以正确影响数据库中的数据。但是,此数据库也使用 QueryTable 对象(连接处于读取模式)显示在 Excel 文件中,我尝试在每个用户窗体终止时刷新它(请参阅Private Sub UserForm_Terminate),但这并不能始终如一地工作。有时,我需要再执行一两个操作(或再刷新一次或两次)才能显示更改,有时它会立即显示。

指示:工作表被编程,因此只能选择一个唯一的单元格,并且只能在 QueryTable 区域中选择。如果用户尝试选择表格之外的内容,则选择会返回到表格,因此我可以毫无歧义地使用Selection.ListObject.QueryTable.Refresh

ADO 连接是否有执行时间?我是否以错误的方式刷新了我的 QueryTable?造成这种延迟的原因是什么?

感谢您的帮助

【问题讨论】:

  • 您可以尝试在销毁之前关闭连接。所以cn的open-update-close-destroy。不确定我会做一些测试。
  • 我刚看到那个,我在其他用户表单中正确地做到了,我认为这只是一个复制错误。感谢您关注@Nathan_Sav!
  • 为什么使用 Excel 作为 GUI 而不是 Access 前端?

标签: sql excel vba ms-access


【解决方案1】:

不是一个答案,而是一个想法,太大而无法评论。您可以使用连接的事件,因此创建一个类 clsCustomConnection。像这样

 Private WithEvents cn As ADODB.Connection

Public Sub Initialise(strConnectionString As String)
    Set cn = New ADODB.Connection
    cn.ConnectionString = strConnectionString
    cn.Open
End Sub

Public Sub Execute(strSQL As String)
    cn.Execute strSQL
End Sub

Private Sub cn_ExecuteComplete(ByVal RecordsAffected As Long, ByVal pError As ADODB.Error, _
    adStatus As ADODB.EventStatusEnum, ByVal pCommand As ADODB.Command, ByVal pRecordset As ADODB.Recordset, ByVal pConnection As ADODB.Connection)
    '   Refresh any query tables of interest, based on the Error/Status
End Sub

然后在一个模块中有这样的东西:

Sub Testing()

Dim cnCustom As clsCustomConnection
Dim strConnectionString As String
Dim strSQL As String

Set cnCustom = New clsCustomConnection

cnCustom.Initialise strConnectionString
cnCustom.Execute strSQL

End Sub

这将使用连接来告诉其余代码它的成功/失败,通过使用连接的事件。

【讨论】:

  • 好的,我试了一下。一开始我要感谢你,因为我不知道我们可以实例化对象以在应用程序级别处理它们的事件,你提醒我 VBA 是一种 OO 语言(这很讽刺,因为我来自 Java作为初级 OO 应用程序开发人员)。结论是它的作用相同,所以我很确定 ADO 查询与 Excel 前端对驱动数据的可用性之间存在延迟。但我将使用我的 customSQL 对象来尝试测量它,并稍后在此处报告它。非常感谢!
  • @MirageHF 我会玩一会,看看我能不能看到。是否只是删除导致问题?数据库是独立的还是链接的?一次可以有多个用户吗?在更新之前和之后尝试从数据库中计算行数,检查 sql 是否按预期工作。所以计数,删除,再计数。
【解决方案2】:

在运行了一些测试之后,延迟似乎来自 OLE 连接,或者来自我公司的网络性能。在第一种情况下,它可能可以通过更改后端和/或前端技术(从 Access/Excel 切换到具有硬编码 C# 前端的 Oracle db)来解决,而在第二种情况下,什么也做不了。

感谢 Nathan_Sav 的帮助!

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 2013-10-21
    相关资源
    最近更新 更多