【问题标题】:MS Access Form Bind to ADO RecordsetMS Access 表单绑定到 ADO 记录集
【发布时间】:2019-12-27 22:19:18
【问题描述】:

把我逼疯了……

问题是速度之一。

我有一个链接到客户端可访问网站的有效 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 这对于理解为什么不支持的人来说非常好,因为它与我没有什么不同可以查看我复制的示例。

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

感谢您的帮助

【问题讨论】:

  • 为什么要使用记录集来设置表单的数据集?我从来没有这样做过。为什么不用 SQL 语句设置 RecordSource 属性?
  • 好的,刚刚注意到您的后端是 SQLServer。我也没用过。
  • 您缺少 Set 关键字:Set Me.Recordset = Rs1

标签: sql ms-access ado


【解决方案1】:

好吧,加载 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 后端,而且我们都非常经常动态加载子表单并且在您查看子表单之前不加载它们说在选项卡控件后面。

【讨论】:

  • 感谢 Albert...您可能需要显示所有子表单。因此,您可以将所有子表单 RecordSource 留空,然后将其作为主表单加载事件,只需将 sql 填充到每个子表单。这可能会稍微提高速度,并且由于连接速度较慢,这将是最少的工作量。 ...我正在这样做。记录实际上只是一个记录,取决于视角。数据结构为 Client -
  • 在加载事件中,我将 SQL 提供给子表单,并且我已索引 SQL 以匹配并将加载时间设置为大约 9 秒,这可能没问题。不确定只是想更接近说 3 秒。我只是在打开数据库时加载表单。它反映了我所做的工作。在任何给定的电话或询问中,我可能需要知道任何或所有这些。
  • 有趣..删除除客户端记录之外的所有其他子表单,计时器显示 4-5 秒来加载记录...也许 8 或 9 秒是可以的
  • 这是很大的进步。然后,技巧和问题就变成了您想要在动态(按需加载)子表单方面付出多少努力。所以你很可能可以进一步减少它。不清楚表单上是否有选项卡控件 - 如果没有这样的选项,那么动态加载子表单可能不是一个实用的 UI 选择。如果子表单可以放置在选项卡控件上,那么您可以选择仅在用户单击选项卡控件时设置/加载数据。总而言之,如果你编写了 ADO reocrdsets 并绑定到子表单,你无论如何都不会在这里获得任何性能。
猜你喜欢
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
  • 2011-05-04
相关资源
最近更新 更多