首页 > 解决方案 > MS Access 表单绑定到 ADO 记录集

问题描述

让我发疯...

问题是速度之一。

我有一个链接到客户端可访问网站的工作 SQL Server,我想添加一个 Access 前端,以使我们办公室工作人员能够更好地支持客户和现场工作人员。

我构建的当前表单是一个主表单,其中包含五个子表单,在一个视图中为我们提供了所有相关的客户信息。但是,此方法需要 24 秒才能加载单个客户端的完整记录。

我查看了 SQL Server,发现没有索引,修复了这个问题并将时间缩短到 24 秒,随后的负载接近 18 秒,具体取决于客户端(有些记录更多)。这可能没问题,因为虽然这是现实世界时间中计算时间的相对永恒,但它还可以……但不是很好。我想看看是否可以通过更改连接方式以及表单与记录的绑定方式等来获得更好的负载。

在查看各种想法并阅读了很多我发现: https ://docs.microsoft.com/en-us/office/vba/access/concepts/activex-data-objects/bind-a-form-to-an -ado-recordset?source=docs

这对我很有吸引力,因为我更倾向于使用 ADO,而我很少使用 DAO。原来我理解的 ADO 是打算和 SQL 等一起使用的,这似乎是一个明智的想法。

再次,据我所知,如果我能让它工作,它将作为一个通过查询,在网络上只返回一条记录,因此应该会大大加快我的表单速度。然而它不会工作。

我的代码是:

Private Sub cssSetForm(lngID As Long)
Dim cnn As New ADODB.Connection
Dim Rs1 As New ADODB.Recordset
Dim strSQL As String
Dim strR As String  

cnn = "Provider=MSOLEDBSQL;Server=Server;Database=DatabaseName;UID=UserName; PWD=Password;"   
cnn.Open

  strSQL = "SELECT Clients.Clientid, Clients.AccountContact, Clients.AccountEmail, Clients.Address, Clients.Name, Clients.OfficePhone, Clients.PostCode, " & _
           "Clients.ShentonAcc, Clients.Suburb FROM Clients WHERE (((Clients.Clientid)=" & lngID & "));"



    With Rs1

        Set .ActiveConnection = cnn
        .Source = strSQL
        .LockType = adLockPessimistic
        .CursorType = adOpenKeyset
        .Open

    End With


     Debug.Print Rs1.RecordCount

   Me.Recordset = Rs1

  End sub

现在我没有收到任何错误,直到 Me.Recordset=rs1 生成错误 3251 Operation is not supported for this type of object 这对于理解为什么不支持的人来说非常好,因为它与我看到的没有什么不同我正在复制的示例。

我不明白为什么我正在处理的表单根据错误消息不支持记录集?我的代码有错误吗?我对链接站点的破坏的理解有误吗?错误是别的吗?

谢谢您的帮助

标签: sqlms-accessado

解决方案


好吧,加载 5 个子表单需要大量数据。转换为 ado reocdsets 不会加快速度。

您在这里要做的不是加载子表单,直到用户说单击相应的选项卡以加载一个给定的子表单。

只要有问题的表单是用一个 were 子句打开的,那么一个主表单只会从 sql server 中提取一个主记录。所以做各种花哨的 reocrdsets 等会让你几乎一无所获。所以,总是——但总是将你的主表单启动到一个记录。如果该主表单绑定到 5,000 行或 100 万行的表,它将立即加载,尽管该表单直接绑定到具有 100 万行的链接表。

使用这个主窗体,您可以编辑或执行任何操作,然后将其关闭。然后,您当然会回到搜索表单/提示,您必须询问用户要处理的记录。那么,会计包是如何工作的,甚至是谷歌?您搜索、显示搜索结果并选择一件要查看的东西。这种方法应该使您的主表单加载时间减少到大约 1 秒。同样,打开该表单时只需使用“where”子句:例如:

dim strInv   as string
strInv = InputBox("Enter invoice number to view")
docmd.OpenForm "frmInvoice",,,"InvoiceNum = " & strInv

当然上面是空气代码,你可能会构建一些搜索表单,如下所示:

在此处输入图像描述

所以在上面,用户输入了一些名称。然后我们用一个简单的 where 子句填写表格,或者

me.MySubForm.RecordSource = "select * from tourCust where LastName like '" & sTextbox & "*'"

当用户点击眼镜图标来编辑 + 查看 ONE 行时,我们使用这个:

docmd.OpenForm "frmDetails",,,"id = " & me!id

同样,所有绑定的表格,尽管表格有 500,000 多行,但表格的加载是即时的——即使后端是 SQL 服务器也是如此。

所以,采用提示+搜索结果+编辑/查看设计模式。每个单一的软件系统都有这个循环或设计模式。它不仅对用户友好,而且性能也很好,因为访问不会拉取整个表,而只有你告诉表单通过使用上面的 where 子句加载的记录。

现在,对于子表单(子表单)。如前所述,在用户实际单击给定选项卡之前不要加载它们。

因此,在选项卡的 on-change 事件中,您可以执行以下操作:

If Me.TabMainpage.Pages(Me.TabMainpage).Name = Me.pgeDocs.Name Then

'' the tab been changed to show past tours
dim strSQL as string
strSQL = "select * from tblPastTours where tour_ID = " & me!ID
me.
' dynamic load the sub form
If Me.frmSubPastTours .SourceObject = "" Then
     Me.frmSubPastTours.SourceObject  = "Forms.frmPastTours"
End If
' now load sql into form
 me.frmSubPastTours.Form.RecordSource = strSQL

上面主要是空气代码,但这里的想法是:

在需要之前不要加载子表单。或者您可以加载子表单,但在单击选项卡时将其 RecordSource 留空并在您需要显示的 sql 中保留 STUFF。

您可能需要显示所有子表单。因此,您可以将所有子表单 RecordSource 留空,然后将其作为主表单加载事件,只需将 sql 填充到每个子表单。这可能会稍微提高速度,并且由于连接速度较慢,这将是最少的工作量。

您“未能”提及您如何启动 + 加载主表单,但如前所述,它应该向 ONE reocrd 打开。数据的链接主/子拉动可能有点慢,我不能说只是在这些表单中使用上面的 sql 内容会有很大帮助。我会先尝试,因为这是最少的工作量。如果加载时间仍然太慢,则将子表单放在选项卡控件后面并仅加载子表单,然后设置数据源将是最快的。

尝试构建所有这些记录集,然后将它们绑定到表单?它不会加快速度,只是将一个 sql 字符串推入表单(或子表单)recordSource 就相当于实际上相同的东西和相同的性能。因此,您节省了大量的工作和代码,并且上述想法不仅适用于 sql server 后端,而且我们都非常经常动态加载子表单并且在您查看子表单之前不加载它们说在选项卡控件后面。


推荐阅读