为什么列表/组合框有时会在表单刷新之前清空?

时间:2014-04-02 11:07:40

标签: vba access-vba

我正在Access 2010中开发一个数据库,多个用户一次访问(分离的前端/后端)。现在有更多的用户开始使用它,我偶然发现了一个非常不一致的问题: 有些用户看到空的列表框/组合框,直到他们关闭当前表单并再次打开它,或按f5。这不会发生在所有用户身上,并且并非总是发生(意味着用户有时会出现此问题,有时甚至没有)。 我已经设法发现,这只发生在使用VBA填充的控件上 - 如果我在属性选项卡中指定了一个查询,它就能正常工作。

以下是我填充控件的方法:

Dim sQuery As String
Dim rs As DAO.Recordset

sQuery = "SELECT ID, Name FROM Users WHERE ID <> 1"

Set rs = CurrentDB.OpenRecordset (sQuery)
Set listBox.Recordset = rs

Set rs = Nothing

在开发过程中,这种情况发生在我身上几次,我可以使用Me.Refresh或Me.Repaint(有时一个工作,有时另一个工作)绕过它。

当我看到一个应该填充的emtpy列表时,我个人并不难发现只按F5,但是随着越来越多的用户使用它,这对他们来说非常不方便。

这种行为正常吗?填充控件时我错过了什么吗?这可能是计算机性能的问题(因为控件是在填充之前绘制的)?

5 个答案:

答案 0 :(得分:0)

列表框或组合框不会自动刷新。正如您所说,以编程方式使用控件的Refresh方法。

这是设计使得表单不会不断地重新运行不必要的查询。

您的选择就我所知:

在需要刷新的控件旁边创建一个按钮。然后在按钮的click事件中调用控件的Refresh Method。

在控件的got focus事件中编写代码以调用refresh方法。

设置表单计时器事件以按设定的时间间隔刷新控件。

我认为按钮是最好的方法,因为它为用户提供了一个视觉提示,只有在绝对必要时才会运行查询。

请注意,使用控件的刷新方法和表单之间存在细微差别。当您使用表单的刷新方法时,您正在刷新表单记录源而不是列表框或ComboBox行源。例如:

Me.Requery ' this is refreshing form
Me.ListBox1.Requery 'this is refreshing a individual control

答案 1 :(得分:0)

您是否在VBA代码中使用该记录集做了一些特别的事情?如果您只是像这样运行静态SQL,则可以将rowsource类型设置为Table / Query并将SELECT ID, Name FROM Users WHERE ID <> 1粘贴到RowSource属性中 - 它不必是已保存查询的名称。

答案 2 :(得分:0)

在MS Access中,没有任何事件在加载完所有内容后发生。在我的情况下,我遇到类似的问题,列表框控件返回空查询,因为该查询引用了我尚未完全加载的表单源字段之一。有一个事件可以帮助我们,Form_Timer()事件。

请注意,您需要将表单Timer Interval属性更改为一个值(500 ms应该这样做)。如果将其保留为0则不会运行。 Pro-tip,在设计视图中设置定时器延迟。

Private Sub Form_Timer()

    'Use 0 for TimeInterval so that it only runs the event once. 
    'Don't forget to set your Timer Interval property on your form. 

    Me.TimerInterval = 0
    Me.listAddresses.Requery
    Debug.Print "Timer Ran"

End Sub

答案 3 :(得分:0)

我找到了一个不同的,更优选的解决方案来解决我的问题。

这里我将列表框的行源设置为查询。两个查询在我的表单上完成相同的操作。第一个查询是可重用的,但代价是不刷新并且通常是错误的。

第二个查询特定于我的frmJobView,但在表单加载时加载并且没有错误或需要额外的计时器/刷新代码。

只关注每个WHERE子句的最后一部分。

Screen.ActiveForm!。[Job_ID] - 可以在任何表单上使用,但不会加载表单/需要刷新。如果您绝对必须这样做,请参阅我关于刷新的其他答案。

[Forms]![frmJobView]。[Job_ID] - 仅适用于frmJobView,但加载了表单。

//This SQL statement will require a refresh if you set it to a listbox
    SELECT [tblJobAddresses].ID, 
    FROM tblJobAddresses
    WHERE [tblJobAddresses].Job_ID=Screen.ActiveForm![Job_ID];

//This SQL statement will not require a refresh after loading the form.
    SELECT *
    FROM tblJobContacts
    WHERE [tblJobContacts].Job_ID=[Forms]![frmJobView].[Job_ID];

答案 4 :(得分:0)

我在Access 2010中尝试了所有解决此问题的方法,但ListBox在启动时保持空白。

最后,在绝望的情况下,我尝试将其添加为表单加载中的第一项:

Me.Dirty = False

有效!我不关心如何或为什么,但现在我的ListBox在启动时填充自己。以前,在发生明确事件之前,它拒绝显示任何内容,例如重新选择组合框中的项目。