2

我有一个带有搜索表单的访问数据库。

我有一个“对象”表,其中包括一个“名称”字段,以及一个带有“名称”字段的“所有者”表。

在两者之间,我有一个连接表,所以我有一个多对多的关系

对象不一定有所有者。

在我的搜索表单中,我有两个未绑定的字段:“对象名称”和“所有者名称”。

我想做的事:

  • 当用户将两个字段都留空时,他会获得所有对象的列表(包括那些没有所有者的对象),如果该对象有所有者,它也会显示在列表中。
  • 当用户在“对象名称”字段中填写内容时,他会得到一个包含输入子字符串的所有对象的列表(包括那些没有所有者的对象)。
  • 当用户在“所有者名称”字段中填写内容时,他会获得所有者名称包含输入的子字符串的所有对象的列表(忽略 NULL 所有者)。

到目前为止我做了什么:

我使用“对象名称”文本字段的值使用左外连接和 Object.name 上的条件进行了查询

这适用于用例 1 和 2,但在用例 3 中没有所有者过滤

但是,如果我根据“所有者名称”文本字段在 Owner.name 上添加条件,案例 3 工作正常,但案例 1 和 2 不再工作(使左外连接过时)

我该如何解决这个问题?

4

1 回答 1

3

在我看来,您可以使用带有以下记录源的连续表格...

SELECT Objects.ObjectName, ObjectOwners.OwnerName
FROM (ObjectOwnership INNER JOIN ObjectOwners ON ObjectOwnership.OwnerID = ObjectOwners.OwnerID) INNER JOIN Objects ON Objects.ObjectID = ObjectOwnership.ObjectID
UNION ALL
SELECT Objects.ObjectName, NULL AS OwnerName
FROM ObjectOwnership RIGHT JOIN Objects ON Objects.ObjectID = ObjectOwnership.ObjectID
WHERE ObjectOwnership.ObjectID IS NULL
ORDER BY 1, 2;

...然后在表单标题中放置几个​​文本框和一个“过滤器”命令按钮,以更新表单.Filter属性以根据需要过滤记录,如下所示:

Private Sub cmdFilter_Click()
Dim sFilter As String
If IsNull(Me.txtObjectFilter.Value) And IsNull(Me.txtOwnerFilter.Value) Then
    Me.FilterOn = False
Else
    If IsNull(Me.txtObjectFilter.Value) Then
        sFilter = ""
    Else
        sFilter = "ObjectName LIKE ""*" & Me.txtObjectFilter.Value & "*"""
    End If
    If Not IsNull(Me.txtOwnerFilter.Value) Then
        If Len(sFilter) > 0 Then
            sFilter = sFilter & " AND "
        End If
        sFilter = sFilter & "Ownername LIKE ""*" & Me.txtOwnerFilter.Value & "*"""
    End If
    Me.Filter = sFilter
    Me.FilterOn = True
End If
End Sub

当表单打开时,它会显示所有记录...

首次打开.png

...然后我们可以按对象过滤...

对象过滤器.png

...或由所有者...

所有者过滤器.png

...或两者兼而有之,就此而言。

编辑

子表单的类似技术是将上面的查询另存为[ObjectOwner_base_query]并将其指定为Record Source子表单的,然后稍微更改 VBA 代码,以

Private Sub cmdFilter_Click()
Dim sFilter As String, sSQL As String
sFilter = ""

If Not IsNull(Me.txtObjectFilter.Value) Then
    sFilter = "ObjectName LIKE ""*" & Me.txtObjectFilter.Value & "*"""
End If

If Not IsNull(Me.txtOwnerFilter.Value) Then
    If Len(sFilter) > 0 Then
        sFilter = sFilter & " AND "
    End If
    sFilter = sFilter & "Ownername LIKE ""*" & Me.txtOwnerFilter.Value & "*"""
End If

sSQL = "SELECT * FROM ObjectOwner_base_query"
If Len(sFilter) > 0 Then
    sSQL = sSQL & " WHERE " & sFilter
End If
Me.RecordSource = sSQL
End Sub

(似乎修改.Filter子窗体的属性会导致 Access 行为异常;更新.RecordSource属性似乎会产生更好的结果。)

于 2013-04-19T15:32:17.050 回答