查询更改后访问报告未更新

时间:2017-08-28 19:27:55

标签: sql vba ms-access

我在下面有一个表单,允许用户以多种方式过滤数据库。当他们按下表单上的过滤器按钮时,将根据过滤器查询填充报告。问题是如果我再次过滤数据库,即使报告代码中包含.requery,报告也不会更新到新的查询结果。我知道如果我手动关闭它可以工作的报告,但是当我将其编码为DoCmd.Close时,它实际上并不关闭报告。如果我显示它 acViewPreview每当我在表单上使用重新过滤器按钮时它都会更新,但我无法使用报表上的按钮。我试图让它像一个售货亭,所以我不希望导航标签显示。

过滤表格

enter image description here

报告

enter image description here

表单代码:

Private Sub btnFilter_Click()
    Dim db As DAO.Database
    Dim qdf As DAO.QueryDef
    Dim SQL2 As String
    Dim ToDate As Date
    Dim FromDate As Date

    SQL2 = ""

    Set db = CurrentDb()
    Set qdf = db.QueryDefs("Filter")

If cmbFilter.Value = "Vended Date" Then

    ToDate = Format(DTPickerTo.Value, "YYYY-MM-DD")
    FromDate = Format(DTPickerFrom.Value, "YYYY-MM-DD")

SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
        " FROM CribMaster_Quality" & _
        " WHERE CribMaster_Quality.[Vended Date]" & _
        " BETWEEN #" & FromDate & "# AND #" & ToDate & "#" & _
        " ORDER BY CribMaster_Quality.[Vended Date] DESC;"
ElseIf ckbDateConst = True Then

    ToDate = Format(DTPickerTo.Value, "YYYY-MM-DD")
    FromDate = Format(DTPickerFrom.Value, "YYYY-MM-DD")

    SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
        " FROM CribMaster_Quality" & _
        " WHERE CribMaster_Quality." & Me!cmbFilter.Value & " = '" & Me!cmbFilterBy.Value & "' And CribMaster_Quality.[Vended Date] " & _
        " BETWEEN #" & FromDate & "# AND #" & ToDate & "#" & _
        " ORDER BY " & Me.cmbFilter.Value & " DESC;"
    Else
    SQL2 = "SELECT CribMaster_Quality.Line,CribMaster_Quality.[Vended Date],CribMaster_Quality.PartNumber,CribMaster_Quality.Group,CribMaster_Quality.ItemNumber,CribMaster_Quality.Amount,CribMaster_Quality.Description,CribMaster_Quality.Cost,CribMaster_Quality.[Extended Cost],CribMaster_Quality.User " & _
            " FROM CribMaster_Quality" & _
            " WHERE CribMaster_Quality." & Me!cmbFilter.Value & " = '" & Me!cmbFilterBy.Value & "'" & _
            " ORDER BY " & Me.cmbFilter.Value & " DESC;"
    End If

    qdf.SQL = SQL2
    Set db = Nothing
    Set qdf = Nothing

    DoCmd.OpenReport "CribMasterReport", acViewReport
End Sub

报告代码:

Private Sub btnReFilter_Click()
    DoCmd.Close , acSaveNo
    DoCmd.OpenForm "Filter Database Form"
End Sub

Private Sub Report_Load()

Me.Requery

With VendedDatetxt
    .Requery
End With

With ItemNumbertxt
    .Requery
End With

With Linetxt
    .Requery
End With

With PartNumbertxt
    .Requery
End With

With Usertxt
    .Requery
End With

With Amounttxt
    .Requery
End With

With Costtxt
    .Requery
End With

With ExtendedCosttxt
    .Requery
End With

End Sub

1 个答案:

答案 0 :(得分:1)

问题1:重新报告报告

使用标准技术打开报表时,例如单击导航窗格中的报表或使用DoCmd.OpenReport打开报表时,Access会创建报表的默认实例可以通过Application.Reports集合访问。在首次打开报告之前或者默认报告实例完全关闭(即从内存中删除)之前,Application.Reports集合将不包含报告的实例。在访问默认实例之前,请确保报告已打开。

与其他MS Office对象模型集合一样,Application.Reports没有“包含”方法或其他直接方法来测试报表是否已打开,只能通过循环数字索引并测试每个报表对象。虽然对我来说似乎很草率,但最简单的方法是使用错误处理来尝试直接获取报告,然后捕获错误,如果找不到:

On Error Resume Next
Set frm = Application.Reports("CribMasterReport")
If err.Number <> 0 Then
  'Default instance not open
End If

注意:不要使用类名称作为对象引用报告,如Report_CribMasterReport.Requery中所示。如果这样做,VBA将自动创建一个新的,隐藏的报表实例,但它不是如上所述的默认实例,并且无法通过Application.Reports集合访问此新实例。同样,在这样的对象上使用属性和调用方法将在很大程度上无效。 (可以创建和使用这样的独立实例,但这是一种充满自身陷阱和挑战的先进技术。)

正如问题描述的那样,其他在线资源也证实了这一点,Report.Requery在基础查询或数据发生变化后刷新报告无效。但是,在正常的报表视图中,重置Report.RecordSource会强制完全刷新报表。

问题2:报告未结束

DoCmd.Close命令缺少逗号。它应该是DoCmd.Close , , acSaveNo。更好的是总是使用显式名称作为可选参数。在一个含糊不清的逗号列表中输入一个额外的参数绝对值得省去挫折和拼写错误的时间:

DoCmd.Close Save:=acSaveNo

问题3:不必要的电话

完全没必要在报表和Report_Load事件中的每个控件上调用Requery。我得到你试图调试情况,但这种行为应该自动发生。此外,Form_Load事件仅在首次加载表单时发生一次,因此除非报告完全关闭并重新打开,否则不会再次调用代码。

最后一些替代代码

Private Sub btnFilter_Click()
    '... Include previous code to reset report query

    '* Call DoCmd.OpenReport every time to
    '* 1) Ensure default report is open 
    '* 2) Automatically activate the report (even if it was already open)
    DoCmd.OpenReport "CribMasterReport", acViewReport

    On Error Resume Next
    Dim frm As Report_CribMasterReport
    Set frm = Application.Reports("CribMasterReport")
    If Err.Number = 0 Then
        '* Force the Report object to re-run query and recreate report
        frm.RecordSource = frm.RecordSource
    End If
End Sub

不再需要完全关闭报告。

Private Sub btnReFilter_Click()
    ''DoCmd.Close Save:=acSaveNo
    DoCmd.OpenForm "Filter Database Form"
End Sub

Private Sub Report_Load()
    '* Eliminated unnecessary Requery calls
End Sub