【问题标题】:RecordSource in Access SQLAccess SQL 中的记录源
【发布时间】:2014-06-17 17:34:26
【问题描述】:

我有一个表单,允许用户查看 LinkRef 字段等于指定值的所有记录,以及 Clearance Applying For 或 Clearance Level 某个值。

LinkRef 是使用 OpenArgs 从之前的表单中提取的用户 ID。我目前的 form_load 代码是:

Private Sub Form_Load()

    'MsgBox Me.OpenArgs

    Me.C_LinKRef = Me.OpenArgs
    Me.chbToggleEdit.Value = False

    'MsgBox Me.C_LinKRef

    Dim mySQL As String
    mySQL = _
    "Select * " & _
    "From TabClearDetail " & _
    "Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
    "And ([Clearance Applying For] = 'BPSS' " & _
          "Or [Clearance Applying For] = 'BPSS (EDF)' " & _
          "Or [Clearance Applying For] = 'BPSS (Magn)' " & _
          "Or [Clearance Applying For] = 'BPSS (Sella)' " & _
          "Or [Clearance Applying For] = 'BPSS Equiv' " & _
          "Or C_ClearanceLevel = 'BPSS' " & _
          "Or C_ClearanceLevel = 'BPSS (EDF)' " & _
          "Or C_ClearanceLevel = 'BPSS (Magn)' " & _
          "Or C_ClearanceLevel = 'BPSS (Sella)' " & _
          "Or C_ClearanceLevel = 'BPSS Equiv' " & _
          "Or C_ClearanceLevel = 'DESTROYED' " & _
          "Or C_ClearanceLevel = 'Lapsed' " & _
          "Or C_ClearanceLevel = 'NOT_FLWDUP' " & _
          "Or C_ClearanceLevel = 'NOT_SPECIFIED' " & _
          "Or C_ClearanceLevel = 'Refused' " & _
          "Or C_ClearanceLevel = 'Withdrawn');"

    Me.RecordSource = mySQL

    'MsgBox Me.RecordsetClone.RecordCount

End Sub

当有匹配的记录时,mySQL 的行为似乎应该如此。但有时不会有任何记录,因为指定的人没有任何这些许可级别并且没有申请,然后我希望表格出现空白或出现一条消息说没有匹配记录。

目前,如果没有匹配的记录,表单将拉入 LinkRef,但使用来自完全不同记录的值填充所有其他文本框(这似乎是我查看的最后一条记录)。不确定如何解决这个问题,我尝试使用 RecordsetClone.RecordCount 来判断它是否等于 0 然后是 msgbox,但这样做似乎为时已晚,因为它似乎总是找到至少 1 个条目,即使有应该是 0 它已经用另一个字段的数据填充了文本框,所以找到了 1。

LinkRef 文本框由 OpenArgs 填充。所有其他文本框都是使用查询来填充的,该查询在 TabClearDetail 表中查找并将值拉入。我开始认为我最好只使用查询或只使用代码,但我不确定如何使用 OpenArgs在查询中,在某些情况下,查询比编写代码要快得多。

这是我在回复@Roland 帖子时提到的保存对话框的代码。此代码在 Form_Close() 子程序中调用。

Private Sub SaveDialog()
Dim Msg, Style, Title As String
    Dim Response As Integer
    Msg = "Would you like to save your changes?"
    Style = vbYesNoCancel
    Title = "Save Changes"

    On Error GoTo Err_BackFromAddBPSSButton_Click
    Response = MsgBox(Msg, Style, Title)
    If Response = vbYes Then
        'DoCmd.Close
        DoCmd.OpenForm ("Basic Personal Information")
    Else
    If Response = vbNo Then
        Me.Undo
        'DoCmd.Close
        DoCmd.OpenForm ("Basic Personal Information")
    End If
    End If


Exit_BackFromAddBPSSButton_Click:
    Exit Sub

Err_BackFromAddBPSSButton_Click:
    MsgBox Err.Description
    Resume Exit_BackFromAddBPSSButton_Click
End Sub

对这个冗长的问题表示歉意,希望所有细节都是必要的,而且是有道理的,任何建议都非常感谢!

【问题讨论】:

  • 生成什么SQL?当您在单独的查询窗口中运行该查询时,您会得到想要的结果吗?如果您在 Open 事件而不是 Load 中运行代码会发生什么?
  • 另外,如果你想要"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _:"And ([Clearance Applying For] IN ('BPSS', 'BPSS (EDF)', 'BPSS (Magn)', 'BPSS (Sella)', 'BPSS Equiv') " & _:"Or C_ClearanceLevel IN ('BPSS' ,'BPSS (EDF)','BPSS (Magn)','BPSS (Sella)','BPSS Equiv'" & _:",'DESTROYED','Lapsed','NOT_FLWDUP','NOT_SPECIFIED','Refused','Withdrawn')" & _:");",你可以像这样简化你的 Where 子句
  • 在 Access 中的何处获得单独的查询窗口?为重写干杯 @Brad,读起来更好。
  • 在功能区上,Create > Query Design > SQL View > paste in the SQL for your mySQL variable
  • 我将 form_load() 更改为 form_open(),现在每次尝试打开表单时都会收到错误消息“OpenForm 操作已取消”

标签: sql ms-access vba openargs


【解决方案1】:

尝试改变事件的顺序:

不要先设置 TextBox 值。将 OpenArgs 传递给 mySql 字符串。使用 mySql 在 VBA (OpenRecordset) 中打开一个记录集并执行 RecordCount。如果为零,则将 Recordsource 设置为 SELECT * FROM TabClearDetail WHERE 1=2 。否则将 mySQl 设置为 Recordsource(或传递 Recordset)。然后才设置TextBox和CheckBox。

Private Sub Form_Load()

    Dim i as Integer
    i = Me.OpenArgs

    Dim mySQL As String
    mySQL = _
    "Select * " & _
    "From TabClearDetail " & _
    "Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
    "And ([Clearance Applying For] IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS Sella)','BPSS Equiv') " & _
          "Or C_ClearanceLevel IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS (Sella)','BPSS Equiv','DESTROYED','Lapsed','NOT_FLWDUP','NOT_SPECIFIED','Refused','Withdrawn'));"

   Dim rst as Recordset
   Set rst = CurrentDB.OpenRecordset(mySQL)
   rst.MoveLast
   rst.MoveFirst
   If rst.RecordCount = 0 then 
       Me.RecordSource = "SELECT * FROM TabClearDetail WHERE 1=2"
       Me.C_LinKRef = ""
       Me.chbToggleEdit.Value = False
   Else
       Me.RecordSource = mySQL
       Me.C_LinKRef = i
       Me.chbToggleEdit.Value = False
   End If

   rst.Close
   Set rst = Nothing

End Sub

抱歉,这里无法测试,所以可能有点问题。如果有什么问题我明天再检查

【讨论】:

  • 这似乎在我第一次这样做时有效,但是当我关闭表单时我有一个保存对话框,因此如果用户检查 chbToggleEdit 他们可以更改记录并保存或不保存保存这些更改。这里表格是空白的,但是保存对话框仍然出现,我按否,但是当我再次打开表格时,所有的文本框都被填满了。此外,当我运行代码 rst.RecordCount = 1 时,即使它应该是 0,但文本框仍然是空白的。如果有帮助,我会将保存对话框附加到我的初始问题代码中。谢谢
  • 我已经注释掉了 rst.MoveLast 和 rst.MoveFirst,还有一些测试要做,但我认为这似乎有效。
  • MoveLast/MoveFirst 确保在计数之前加载完整的记录集。这是2003年的问题,现在可能不是,我只是习惯了。检查空集的另一种方法是检查是否打开rst.EOF。关于保存对话框,您应该只在真正进行更改时才调用它,即设置一个标志(因为未绑定的复选框 Me.Dirty 不起作用)
  • 请注意,一旦我打开表单并且它有记录,当我去找没有任何记录的人时,文本框仍然会填充以前的人记录。设置标志是什么意思?
【解决方案2】:

使用查询并将 [Forms]![BPSS Clearance].[OpenArgs] 以及 C_ClearanceLevel 和 Clearance Applying For 的条件传递给我对我有用。不知道为什么代码不起作用,因为理论上它在做同样的事情,但我有一个解决方案,所以我很高兴。谢谢大家的建议

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多