如何根据未出现在 Select 子句中的连接表列向表单添加过滤器?

发布于 2024-11-30 04:08:03 字数 2398 浏览 0 评论 0原文

我有一个显示公司的表单和一个显示联系人的子表单。每个公司都有多个联系人。

我有一个在组合框上工作的过滤器,它仅选择与所选职责有联系的公司;

Sub SetFilter()    
    Dim ASQL As String        
    If IsNull(Me.cboshowcat) Then
    ' If the combo and all check boxes are Null, use the whole table as the 
    ' RecordSource.
        Me.RecordSource = "SELECT company.* FROM company"        
    Else        
        ASQL = "SELECT DISTINCTROW company.* " & _
                "FROM company INNER JOIN Contacts " & _
                    "ON company.company_id = Contacts.company_id " & _
                "WHERE Contacts.responsibility= '" & cboshowcat & "' " & _
                "ORDER BY Company.company_id"
        Me.RecordSource = ASQL        
    End If        
End Sub

我还有 3 个复选框,可进一步细化记录,这些记录只有在选择工作职责后才能使用。单击按钮后将运行过滤器和复选框;

Private Sub Command201_Click()

If Nz(Me.cboshowcat) = "" _
        And Me.Check194 = True _
    Or Nz(Me.cboshowcat) = "" _
        And Me.Check199 = True _
    Or Nz(Me.cboshowcat) = "" _
        And Me.Check205 = True _
    Then
        MsgBox "Please Select a Job Responsibility"
        Cancel = True
    Else    
        SetFilter
        If Me.Check194 = True _
            And Me.Check199 = True _
            And Me.Check205 = True _
            Then
            Me.Filter = "[contacts].[edit] <=Date()-90 " & _
                "and [contact].[opt out]='No' " & _
                "and [company].[exclude site] is null"
            Me.FilterOn = True
        Else
            If Me.Check194 = True _
                And Me.Check199 = True _
                And Me.Check205 = False _
                Then
                Me.Filter = "[contacts].[edit] <=Date()-90 " & _
                    "and [contact].[opt out]='No'"
                Me.FilterOn = True
            Else
'................(repeated for each combination)
                                    Me.Filter = ""
                                    Me.FilterOn = False
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
    Me.Repaint
End Sub

上面的查询不起作用,因为它找不到我在联系人表中引用的字段名称。如果我在过滤器查询选择语句中包含该字段,它确实可以工作,但是它会根据每个公司返回的联系人数量向我显示每个公司的多个实例。

我需要根据联系人表中的信息过滤公司,而不重复公司信息。

如果有人知道如何解决这个问题,我将不胜感激。

I have a form which displays companies and a subform which displays contacts. There are multiple contacts per company.

I have a filter which works off of a combo box, which selects companies only where they have contacts with the selected responsibility;

Sub SetFilter()    
    Dim ASQL As String        
    If IsNull(Me.cboshowcat) Then
    ' If the combo and all check boxes are Null, use the whole table as the 
    ' RecordSource.
        Me.RecordSource = "SELECT company.* FROM company"        
    Else        
        ASQL = "SELECT DISTINCTROW company.* " & _
                "FROM company INNER JOIN Contacts " & _
                    "ON company.company_id = Contacts.company_id " & _
                "WHERE Contacts.responsibility= '" & cboshowcat & "' " & _
                "ORDER BY Company.company_id"
        Me.RecordSource = ASQL        
    End If        
End Sub

I also have 3 checkboxes which further refine the records which can only be used once a job responsibility has been selected. The filter and checkboxes are ran after clicking a button;

Private Sub Command201_Click()

If Nz(Me.cboshowcat) = "" _
        And Me.Check194 = True _
    Or Nz(Me.cboshowcat) = "" _
        And Me.Check199 = True _
    Or Nz(Me.cboshowcat) = "" _
        And Me.Check205 = True _
    Then
        MsgBox "Please Select a Job Responsibility"
        Cancel = True
    Else    
        SetFilter
        If Me.Check194 = True _
            And Me.Check199 = True _
            And Me.Check205 = True _
            Then
            Me.Filter = "[contacts].[edit] <=Date()-90 " & _
                "and [contact].[opt out]='No' " & _
                "and [company].[exclude site] is null"
            Me.FilterOn = True
        Else
            If Me.Check194 = True _
                And Me.Check199 = True _
                And Me.Check205 = False _
                Then
                Me.Filter = "[contacts].[edit] <=Date()-90 " & _
                    "and [contact].[opt out]='No'"
                Me.FilterOn = True
            Else
'................(repeated for each combination)
                                    Me.Filter = ""
                                    Me.FilterOn = False
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
    End If
    Me.Repaint
End Sub

The above query does not work as it does not find the field name that I am referencing in the contact table. If I include the field in the filter query select statement it does work, however it shows me multiple instances of each company depending on how many contacts are returned for each company.

I need to filter the companies based on information in contact table without duplicating the company information.

If someone knows how to get around this problem I would be very grateful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兔姬 2024-12-07 04:08:03

首先是一些样式方面的事情:

1)如果您使用 ElseIf 而不是

Else
    If '...

2),将复选框重新命名为比 Check194 更有意义的名称,这将是一种很好的形式> (至少对于下一个接触此代码的开发人员而言 - 即使那是 4 年后的你)。当然,假设这不是一个为了稍微匿名化代码而设计的示例。

3)同样,列名和表名中存在空格可能会很麻烦。同样,“编辑”看起来像是一个保留字(也可能不是),并且可能会导致心碎。

4)我不确定你的第一个 IF 语句的逻辑。您的操作顺序可能不是您所期望的。它基本上相当于“

If Nz(Me.cboshowcat) = "" _
    And (Me.Check194 = True _
        Or Me.Check199 = True _
        Or Me.Check205 = True) _
    then

如果这就是你想要的,那就没问题”。

5) 如果您即时构建过滤器字符串,则无需遍历所有八种组合(也许会错过其中一种)。想象一下,如果您有 4、5 或 10 个复选框。通常,我会做这样的事情

dim strFilter as string

strFilter = "(1 = 1) " ' so we don't have to decide whether to put `and` or not.
If Nz(Me.cboshowcat) = "" then
    if Me.Check194 = then
        strFilter = strFilter & "and [contacts].[edit] <=Date()-90 "
    end if
    if Me.Check199 = then
        strFilter = strFilter & "and [contacts].[opt out]='No' "
    end if
    if Me.Check199 = then
        strFilter = strFilter & "and [company].[exclude site] is null "
    end if
    me.filter = strFilter
    me.filteron = true
else
    me.filter = ""
    me.filteron = false
end if

第二个解决您的问题的方案:

每个公司的多行是由于联接而产生的,并且查询现在被迫为每个联系人显示一行,其中具有不同的“编辑”值组合或“选择退出”。

由于您已经在动态更新记录源,因此我只需将过滤器推入记录源的 where 子句中即可完成。这实际上就是过滤器正在做的事情(仅针对查询的结果,这就是它无法查看联系人表的原因)。

再次,动态构建 where 子句,而不是执行 8 种不同的组合。

First some style things:

1) You probably have less nesting if you use ElseIf instead of

Else
    If '...

2) It would be good form to re-name the check boxes something more meaningful that Check194 (at least for the next developer who touches this code - even if that is you 4 years down the line). That is, of course, assuming that this is not a contrived example to anonymise the code a little bit.

3) Like wise having space in column and table names can be a pain in the butt. Likewise "Edit" looks like a reserved word (it may not be), and can lead to heart break.

4) I'm not sure of the logic of your 1st IF statement. You may not have the order of operation may not be what you expect. It's basically the equivalent of

If Nz(Me.cboshowcat) = "" _
    And (Me.Check194 = True _
        Or Me.Check199 = True _
        Or Me.Check205 = True) _
    then

If that's what you wanted, then it is fine.

5) If you build up the filter string on the fly, you won't have to go through al eight combinations (and perhaps miss one). Imagine if you had 4, 5 or 10 check boxes. Typically, I would do something like this

dim strFilter as string

strFilter = "(1 = 1) " ' so we don't have to decide whether to put `and` or not.
If Nz(Me.cboshowcat) = "" then
    if Me.Check194 = then
        strFilter = strFilter & "and [contacts].[edit] <=Date()-90 "
    end if
    if Me.Check199 = then
        strFilter = strFilter & "and [contacts].[opt out]='No' "
    end if
    if Me.Check199 = then
        strFilter = strFilter & "and [company].[exclude site] is null "
    end if
    me.filter = strFilter
    me.filteron = true
else
    me.filter = ""
    me.filteron = false
end if

Second the solution to your problem:

The multiple rows for each company are because of the join, and the query is now forced to show a row for each contact with a different combination of values for "Edit" or "Opt out".

Since you are already updating the record source on the fly, I'd just shove the filter into the where clause of the record source and be done with it. That's effectively what the filter is doing anyway (only on the result of the query, that's why it can't see into the contacts table).

Again, build up the where clause on the fly, instead of doing 8 different combinations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文