代码之家  ›  专栏  ›  技术社区  ›  Tim Visher

如何编辑要以交互方式选择的VBA表单中的记录?

  •  2
  • Tim Visher  · 技术社区  · 17 年前

    我在MS Access 2003数据库中有一组组合框,它们都绑定到单个表中的字段。但是,它们允许您选择的数据不是来自该表,而是来自其他各种表。这对唱片制作故事来说很好,但现在我希望能够追溯编辑唱片。问题是,我不知道如何在不编写一堆自定义代码的情况下重新填充表单元素。

    我最初的倾向是提供一个组合框,将您的选择限制为记录ID,然后执行自定义查询,并使用它在所有不同的表单元素中设置所选值。然而,我觉得我应该能够做一些简单的事情 DoCmd.GoToRecord , , , ID 表格应该可以重新填充。我并不反对做这些繁忙的工作,但我确信我在VBA和Access方面的知识相对贫乏,只是缺少了一些东西。

    3 回复  |  直到 11 年前
        1
  •  1
  •   David-W-Fenton    17 年前

    为了补充这一点,我将提供两种方法,一种是推荐的,另一种不是。

    方法1:如果已将表单绑定到整个数据表(这是不推荐的方法),则可以使用组合框向导导航到请求的记录,但我不建议在Access的最新版本中使用它:

    a、 它不允许您在创建代码之前正确命名组合框。

    b、 代码就是错了。

    以下是我刚刚在测试数据库中生成的代码:

    Dim rs As Object
    
    Set rs = Me.Recordset.Clone
    rs.FindFirst "[InventoryID] = " & Str(Nz(Me![Combo2], 0))
    If Not rs.EOF Then Me.Bookmark = rs.Bookmark
    

    这在很多方面都是错误的,这很了不起。代码应该是这样的:

    With Me.RecordsetClone
      .FindFirst "[ID]=" & Me!cmbMyComboBox
      If Not .NoMatch Then
         If Me.Dirty Then Me.Dirty = False
         Me.Bookmark = .Bookmark
      Else
         MsgBox "Not Found!"
      End If
    End With
    

    如果RecordsetClone已经存在,则无需克隆窗体的记录集。

    当您可以直接使用预先存在的对象时,没有理由使用对象变量。

    在离开记录之前需要检查脏记录,因为如果不强制保存,保存过程中的错误可能会导致数据丢失。

    但更好的方法是:

    方法2:使用组合框更改窗体的底层记录源。

    组合框的AfterUpdate事件如下所示:

    If Not IsNull(Me!cmbMyComboBox) Then
       Me.Recordsource = Me.Recordsource & " WHERE [ID]=" & Me!cmbMyComboBox
    End If
    

    现在,这只在第一次起作用,就像在第二次重置Recordsource时一样,最终会出现两个WHERE子句,这是不好的。有两种方法:

    a、 假设窗体在没有WHERE子句的情况下打开,将打开的recordsource值存储在窗体的OnLoad事件中的模块级变量中:

       Private Sub Form_Load()
         strRecordsource = Left(Me.Recordsource,Len(Me.Recordsource)-1)
       End Sub
    

    在模块级,相应地定义strRecordsource:

       Dim strRecordsource As String
    

    然后,在组合框的AfterUpdate事件中,您有以下内容:

       Me.Recordsource = strRecordsource & " WHERE [ID]=" & Me!cmbMyComboBox
    

    现在,如果你的表单以一个已经定义的WHERE子句打开,它会变得更复杂,但我不会深入讨论这个问题,并把它作为一个练习留给读者,告诉他们最好的方法可能是什么。

        2
  •  0
  •   BIBD    17 年前

    我假定您已经为每个组合框设置了行源。只要你没有将组合框限制在该列表中;它应该显示您在该列中存储的内容。

    但是,如果组合框更改了每行的列表,则可以在记录的OnCurrent事件或字段的GotFocus事件中执行类似操作:

    Me.combo_box_name.Requery 
    
        3
  •  0
  •   Mike Spross Alex Martelli    15 年前

    在重读你的问题之后,我想我明白了你想要实现的目标。你在正确的轨道上 GotoRecord ,尽管我可能会使用 OpenForm 在这种情况下,因为它有一个 WhereCondition 属性,该属性允许您使用SQL精确指定要打开的记录。听起来您想在表单中实现“跳转到记录”类型的功能,用户从列表中选择一个记录ID,表单会更改以显示所选记录。

    一种可能性是,每当用户在组合框中选择一项时,切换到新记录。你可以在组合框的 Click 事件

    我将使用一个简单的例子:假设你有一个 Students 桌子,还有 StudentForm 用于在中查看/编辑记录 学生 桌子这个 学生表格 有一个组合框 cboStudentID 这是必然的 Students.ID 通过它的 RowSource 所有物在组合框中选择学生ID时 StudentsForm 将切换到显示相应的学生记录。

    点击 对于ComboBox的事件处理程序,您可以使用以下代码编写“跳转到记录”功能:

    Private Sub cboStudentID_Click() 
        Dim recordID As Long
        'The ItemData property will return the value of the bound'
        'column at the specified index.'
        recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
        'Jump to the record. This assumes we want to use the same form.'
        'You can change the form name if you want to open a different form when'
        'the user selects an ID from the ComboBox.'
        DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & recordID
    End Sub
    

    正如David W.Fenton在评论中指出的,您可以缩短以下行:

    recordID = cboStudentID.ItemData(cboStudentID.ListIndex)
    

    为此:

    recordID = Me!cboStudentID
    

    或者只是:

    recordID = cboStudentID
    

    因为在本例中,组合框的默认值将是当前 ListIndex .在这种情况下,你可以移除 recordID 全部,然后编码 点击 活动内容如下:

    Private Sub cboStudentID_Click() 
        DoCmd.OpenForm "StudentForm", WhereCondition:="Student.ID=" & cboStudentID
    End Sub
    
    推荐文章