Combobox 因必须根据 500,000 条记录验证条目而挂起。可以预载吗?需要一个组合框,因为我在您键入时使用自动填充

问题描述 投票:0回答:1

我还是 Access 的新手,已经奋斗了两天了。请参阅下面我使用过的代码。它有点啰嗦,我不确定这是否会导致我的问题(需要很长时间才能运行,有时组合框会挂起 2-3 秒),因为它运行代码以及 ListParts 查询.

我想知道的是,有没有办法让组合框预加载查询,这样当我开始输入数字时它就不会挂起?请注意,我发现了一些类似的代码,但已添加到其中以尝试改进程序。

以下是 PartType 组合框的代码,它是记录中的第一个字段。一旦从下拉菜单中选择了此选项,则

Private Sub PartType_AfterUpdate()
If Me!PartType.Value = "PARTS" Then
Me!PartNumber.RowSource = "ListPART"
Me!UnitPrice.Locked = True
ElseIf Me!PartType.Value = "LABOUR" Then
Me!PartNumber.RowSource = "ListLABOUR"
Me!UnitPrice.Locked = True
ElseIf Me!PartType.Value = "SUNDRIES" Then
Me!PartNumber.RowSource = "ListSUNDRIES"
Me!UnitPrice.Locked = False
ElseIf Me!PartType.Value = "SUBLET" Then
Me!PartNumber.RowSource = "ListBLANK"
Me!UnitPrice.Locked = False
End If

End Sub

我还在 Forms Change() Sub 中使用了此代码

Private Sub Partnumber_Change()
'filter dropbox as you type
    'If Len(PartNumber.Text) > 6 Then
    'Dim rs As Recordset
    'Set rs = CurrentDb.OpenRecordset(RecordSQL & " WHERE Code = '" & PartNumber.Text & "' ORDER BY [Code]")
     
    'If (rs.BOF And rs.EOF) Then 'only requery on no exact match
     '   PartNumber.RowSource = RecordSQL & " WHERE Code Like '*' & PartNumber.text & '*' ORDER BY [Code]"
      '  PartNumber.Dropdown
    'End If
    'End If
End Sub

添加的亮点是我正在运行以下代码,因为我需要检查并查看该部分是否已被取代。它的工作原理是,它打开另一个填充数据的表单,然后查看是否有“S”是替代文本框。有时某个部分可能被替换了三四次。

Private Sub PartNumber_AfterUpdate()

If Me!PartType.Value = "PARTS" Then
'FilterComboAsYouType Me.PartNumber, "SELECT * FROM ListParts", "Code"
'PartNumber.LimitToList = False
DoCmd.GoToRecord , , acNext
DoCmd.GoToRecord , , acPrevious
'DoCmd.Requery "ListParts"
'PartNumber.LimitToList = True
'DoCmd.GoToRecord , , acNext
'DoCmd.GoToRecord , , acPrevious
DoCmd.Close acForm, "PartPricesSUB"
DoCmd.OpenForm "PartPricesSUB"
Forms!PartPricesSUB.Visible = False
'supercede 1
    If Forms!PartPricesSUB!Supercede.Value = "S" Then
    Me!PartNumber.Value = Forms!PartPricesSUB!SupercedeCode.Value
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.SetWarnings False
    DoCmd.OpenQuery "UpdateSupercede1"
    DoCmd.SetWarnings True
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    Forms!PartPricesSUB.Visible = False
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    MsgBox "This part number is a supercession here is the new code", vbOKOnly
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
        'supercede 2
    If Forms!PartPricesSUB!Supercede.Value = "S" Then
    Me!PartNumber.Value = Forms!PartPricesSUB!SupercedeCode.Value
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.SetWarnings False
    DoCmd.OpenQuery "UpdateSupercede1"
    DoCmd.SetWarnings True
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    Forms!PartPricesSUB.Visible = False
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    MsgBox "This part number is a supercession here is the new code", vbOKOnly
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
    End If
        
    'supercede 3
    If Forms!PartPricesSUB!Supercede.Value = "S" Then
    Me!PartNumber.Value = Forms!PartPricesSUB!SupercedeCode.Value
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.SetWarnings False
    DoCmd.OpenQuery "UpdateSupercede1"
    DoCmd.SetWarnings True
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    Forms!PartPricesSUB.Visible = False
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    MsgBox "This part number is a supercession here is the new code", vbOKOnly
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
    End If
        
    'Supercede 4
    If Forms!PartPricesSUB!Supercede.Value = "S" Then
    Me!PartNumber.Value = Forms!PartPricesSUB!SupercedeCode.Value
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.SetWarnings False
    DoCmd.OpenQuery "UpdateSupercede1"
    DoCmd.SetWarnings True
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    Forms!PartPricesSUB.Visible = False
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    MsgBox "This part number is a supercession here is the new code", vbOKOnly
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
    End If
            
    'Supercede 5
    If Forms!PartPricesSUB!Supercede.Value = "S" Then
    Me!PartNumber.Value = Forms!PartPricesSUB!SupercedeCode.Value
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.SetWarnings False
    DoCmd.OpenQuery "UpdateSupercede1"
    DoCmd.SetWarnings True
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    Forms!PartPricesSUB.Visible = False
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    MsgBox "This part number is a supercession here is the new code", vbOKOnly
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
    End If
            
 Else
    DoCmd.GoToRecord , , acNext
    DoCmd.GoToRecord , , acPrevious
    DoCmd.Close acForm, "PartPricesSUB"
    DoCmd.OpenForm "PartPricesSUB"
    Forms!PartPricesSUB.Visible = False
    Me!Description.Value = Forms!PartPricesSUB!Description.Value
    Me!UnitPrice.Value = Forms!PartPricesSUB!UnitPrice.Value
    Me!DscCode.Value = Forms!PartPricesSUB!DscCode.Value
    Me!Qty.Value = "1"
    DoCmd.GoToControl "Qty"
    Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value *           Me!UnitPrice.Value) * Me![Discount])
    End If

ElseIf Me!PartType.Value = "LABOUR" Then
DoCmd.GoToRecord , , acNext
DoCmd.GoToRecord , , acPrevious
DoCmd.Close acForm, "PartPricesSUB"
DoCmd.OpenForm "PartPricesSUB"
Forms!PartPricesSUB.Visible = False
Me!Description.Value = Forms!PartPricesSUB!Description.Value
Me!UnitPrice.Value = Forms!PartPricesSUB!UnitPrice.Value
Me!DscCode.Value = Forms!PartPricesSUB!DscCode.Value
Me!Qty.Value = "1"
DoCmd.GoToControl "Qty"
Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])
        
    
ElseIf Me!PartType.Value = "SUNDRIES" Then
DoCmd.GoToRecord , , acNext
DoCmd.GoToRecord , , acPrevious
DoCmd.Close acForm, "PartPricesSUB"
DoCmd.OpenForm "PartPricesSUB"
Forms!PartPricesSUB.Visible = False
Me!Description.Value = Forms!PartPricesSUB!Description.Value
Me!UnitPrice.Value = Forms!PartPricesSUB!UnitPrice.Value
Me!DscCode.Value = Forms!PartPricesSUB!DscCode.Value
Me!Qty.Value = "1"
DoCmd.GoToControl "Qty"
Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])

    
ElseIf Me!PartType.Value = "SUBLET" Then
DoCmd.GoToRecord , , acNext
DoCmd.GoToRecord , , acPrevious
DoCmd.Close acForm, "PartPricesSUB"
DoCmd.OpenForm "PartPricesSUB"
Forms!PartPricesSUB.Visible = False
Me!Description.Value = Forms!PartPricesSUB!Description.Value
Me!UnitPrice.Value = Forms!PartPricesSUB!UnitPrice.Value
Me!DscCode.Value = Forms!PartPricesSUB!DscCode.Value
Me!Qty.Value = "1"
DoCmd.GoToControl "Description"
Me!TotalPrice.Value = (Me!Qty.Value * Me!UnitPrice.Value) - ((Me!Qty.Value * Me!UnitPrice.Value) * Me![Discount])

Else

End If
DoCmd.GoToControl "Qty"
'PartNumber.RowSource = RecordSQL
End Sub
vba ms-access combobox
1个回答
0
投票

一个组合框适合大约 1000 行,也许 5,000 行,仅此而已。

因此,请记住,如果您允许在表单上进行记录导航(通常您不应该这样做),那么当您移动到下一条记录时,对于 Access 显示/更新/维护组合框,它必须获取从组合框的数据源中获取组合框的一条记录。

当然,如果您打开(放下)组合框,那么它需要加载并显示 500,000 行 - 该设计根本无法处理那么多行。正如我所指出的,即使 5,000 行也可能太多了。

您只看到 3-5 秒的延迟这一事实证明了我们今天在计算机处理方面享有的惊人速度。但是,您的设置可能在您的计算机上运行 100%,并且如果您计划拥有多个用户,那么数据库的副本可能不会位于计算机上,而是位于共享文件夹中,或者更好的是,您可以使用 SQL Server 作为后端数据库。无论哪种方式,一旦您在表单和数据源之间引入网络,那么这样的设计的运行速度将比您现在的慢很多倍(慢 100 倍)。这意味着 3-5 秒的延迟将变成 400 秒的延迟(6 分钟,甚至更长!!!)。

因此,那个 500,000 行组合框必须被删除,而且它根本行不通——从 UI 角度来看这根本不是一个可行的选择,从技术角度来看也不是一个可行的选择。

我的意思是,用户如何滚动浏览并从 500,000 行中选择一行?这根本不是一个可行的解决方案。

所以,一些解决方案是:

如果这是发票编号、报价编号、产品 ID 等,则让用户只需输入该值。如果需要某种类型的搜索,那么当然需要弹出某种类型的搜索表单供用户使用,他们可以通过允许这种搜索的好表单来搜索并找到一个产品行ID。关闭后,一行 PK id(主键)值就可以保存到您的表中。

现在,当您加载表单或导航记录时,您可以保存组合框面临的 500,000 行加载和搜索。

因此,您需要构建一个漂亮(但非常好)的表单,允许用户搜索和查找产品 - 远远超过组合框可以提供的功能,但更重要的是不要拉出 500,000 行,然后呈现一个列表选择。

所以,假设我的表格上有一个城市选择选项。我的城市表大约有 150,000 行。因此,如上所述,组合框不起作用。

因此,我们构建了这样的 UI:

enter image description here

请注意,虽然我们有 150,000 行,但只需单击几下鼠标即可选择城市。

因此,您需要一些搜索表单来代替组合框,并且需要一个非常好的搜索表单来允许用户选择该产品。也许您有一些类别,例如产品类型、库存类型、位置等等。通过添加几个简单的过滤器和向下钻取类别,这样的搜索对于用户来说变得很容易,而且对数据库也很友好,因为从数据库中提取的记录很少。

© www.soinside.com 2019 - 2024. All rights reserved.