确定子表单/子报表是不是在 MS Access 中加载了表单或报表

Posted

技术标签:

【中文标题】确定子表单/子报表是不是在 MS Access 中加载了表单或报表【英文标题】:Determine if Subform/Subreport Has a Form or a Report Loaded in MS Access确定子表单/子报表是否在 MS Access 中加载了表单或报表 【发布时间】:2013-05-23 20:11:09 【问题描述】:

我在 Access 2010 数据库的表单上显示了一个子表单/子报表控件,我用它来显示表单和报表。我有一些事件处理程序,我需要知道报表当前是否已加载到子表单/子报表控件中,或者它是否是已加载的表单。我尝试了以下所有方法均无济于事。

以下任何一种情况

If IsEmpty(NavigationSubform.Form) Then '...
If IsNull(NavigationSubform.Form) Then '...
If IsOject(NavigationSubform.Form) Then '...
If NavigationSubform.Form Is Nothing Then '...
If NavigationSubform.Form Is Null Then '...
If Nz(NavigationSubform.Form) Then '...
If (Not NavigationSubform.Form) = -1 Then '... This is a trick I use to check for uninitialized arrays

结果

运行时错误“2467”:

您输入的表达式引用了一个已关闭或不存在的对象。

有没有什么方法可以检查子表单/子报表控件当前是否加载了表单或报表不会故意导致错误?

【问题讨论】:

【参考方案1】:

我不相信有一种方法可以可靠地执行检查而不会捕获错误,因此您可能希望将代码包装在 Public Function 中并将其放入常规 VBA 模块中:

Public Function CheckSubformControlContents(ctl As SubForm) As String
Dim obj As Object, rtn As String
rtn = "None"
On Error Resume Next
Set obj = ctl.Form
If Err.Number = 0 Then
    rtn = "Form"
Else
    On Error Resume Next
    Set obj = ctl.Report
    If Err.Number = 0 Then
        rtn = "Report"
    End If
End If
Set obj = Nothing
On Error GoTo 0
CheckSubformControlContents = rtn
End Function

那么你的表单代码可以简单地调用CheckSubformControlContents(Me.NavigationSubform)

【讨论】:

谢谢,但正如我在问题中所说,我强烈希望 涉及故意导致错误的选项(即,如果您必须使用 On Error... in你的代码,那么这不是我正在寻找的解决方案)。 @druciferre 让我们看看有没有其他人想出另一个解决方案。您已经尝试了很多,并且我验证了If ... Is Nothing(最有可能的选项)触发了运行时错误,因此错误捕获可能是您唯一的选择。 似乎故意造成错误是唯一的选择。【参考方案2】:

以下是 Access 2013 中用于确定名称是报表还是表单的两个函数。 一旦确定,就可以使用 AllForms 或 AllReports 的 IsLoaded 函数。请注意,dbs 是一个对象,而 rpt 或 frm 是 AccessObjects,而不是表单或报告

Public Function IsForm(FormName As String) As Boolean
    Dim dbs As Object
    Dim frm As AccessObject
    Set dbs = Application.CurrentProject
    IsForm = False
    For Each frm In Application.CurrentProject.AllForms
        If frm.Name = FormName Then
            IsForm = True
            Exit For
        End If
    Next frm
    Set frm = Nothing
    Set dbs = Nothing
End Function
Public Function IsReport(ReportName As String) As Boolean
    Dim dbs As Object
    Dim rpt As AccessObject
    Set dbs = Application.CurrentProject
    IsReport = False
    For Each rpt In Application.CurrentProject.AllReports
        If rpt.Name = ReportName Then
            IsReport = True
            Exit For
        End If
    Next rpt
    Set rpt = Nothing
    Set dbs = Nothing
End Function

这是一个使用上述功能的程序:

Public Sub EnumerateTaggedControls(ReportName As String, MyTag As String) 将 dbs 暗淡为对象 作为报告变暗 以表格形式变暗 暗色作为控件 Dim ctl 作为控件 Dim left As Integer 将顶部调暗为整数 暗淡宽度为整数 暗淡高度为整数 暗淡标签为字符串 将 i 调暗为整数 const format1 As String = "0000"

Set dbs = Application.CurrentProject
If IsForm(ReportName) Then
    If dbs.AllForms(ReportName).IsLoaded Then
        DoCmd.OpenForm ReportName, acViewDesign
        Set frm = Forms(ReportName)
        Set col = frm.Controls
    End If
Else
    If dbs.AllReports(ReportName).IsLoaded Then
        DoCmd.OpenReport ReportName, acViewDesign
        Set rpt = Reports(ReportName)
        Set col = rpt.Controls
    Else
        Debug.Print ReportName & " is not a loaded form or report."
        Exit Sub
    End If
End If
Set dbs = Nothing
Debug.Print Tab(53); "Left   Top    Width  Height"
For Each ctl In col
    With ctl
    left = .Properties("Left")
    top = .Properties("Top")
    width = .Properties("Width")
    height = .Properties("Height")
    tag = Nz(.Properties("Tag"), vbNullString)
    If MyTag = "" Then
        i = 1
    Else
        i = InStr(1, tag, MyTag)
    End If
    If i > 0 Then
        Debug.Print .Name & ">"; Tab(33); tag; Tab(53); Format(left, format1) &         Format(top, format1) & Format(width, format1) & Format(height, format1)
    End If
    End With
Next ctl
Debug.Print "====================================================="
Set ctl = Nothing
Set rpt = Nothing
Set col = Nothing
Set frm = Nothing

结束子

我希望这符合您的要求。

【讨论】:

-1 CurrentProject.AllForms("MySubform").IsLoaded 如果“MySubform”表单作为子表单加载到打开的表单上,将返回 False。

以上是关于确定子表单/子报表是不是在 MS Access 中加载了表单或报表的主要内容,如果未能解决你的问题,请参考以下文章

子表单在 MS Access 中的主表单之前打开

MS Access 2010:是不是可以链接数据表子表单

基于另一个子报表的 MS Access 子报表过滤器

MS Access:将参数传递给不带 SQL 的子报表

在按钮单击 MS Access 2013 VBA 在子窗体中创建新记录

MS Access = 引用子表单中的控件