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