MS Access:搜索表单中的外部联接

时间:2013-04-19 13:28:13

标签: ms-access

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

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

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

对象不一定拥有所有者。

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

我想做什么:

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

到目前为止我做了什么:

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

对于用例1和2工作正常,但在案例3中没有所有者过滤

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

我怎么能解决这个问题?

1 个答案:

答案 0 :(得分: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

表格打开时会显示所有记录......

FirstOpened.png

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

ObjectFilter.png

......或由所有者......

OwnerFilter.png

......或两者兼而有之。

修改

Subforms的类似技术是将上面的查询保存为[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属性似乎会产生更好的结果。)