【问题标题】:VBA: How to filter through a sheet based on a checkbox?VBA:如何根据复选框过滤工作表?
【发布时间】:2019-11-09 13:30:50
【问题描述】:

我是 VBA 新手,我正在尝试设置一个可自定义的工作表,允许用户根据我设置的复选框过滤某些列。到目前为止,我了解复选框的工作原理以及如何将它们集成到代码中,但我认为我的自动筛选功能存在问题。具体来说,我认为我为 Criteria1 设置了错误的值。

我一直在寻找类似的编码问题,但它们似乎都不适用于我正在尝试做的事情。

TL;DR 我认为我的问题在于如何格式化数组以放入 AutoFilter() 的 Criteria1

Sub Auto_filter()

'variables are for checkboxes'
    Dim VC1500 As Shape 
    Dim VC7500 As Shape
    Dim VC144024 As Shape

'initiates to check for the checkboxes'
   Set VC1500 = Sheets("Sheet7").Shapes("Check Box 4")
   Set VC7500 = Sheets("Sheet7").Shapes("Check Box 5")
   Set VC144024 = Sheets("Sheet7").Shapes("Check Box 6")

'if statement that will add a string to strCriteria if checkbox is true'
    If VC1500.OLEFormat.Object.Value = 1 Then
       strCriteria = strCriteria & ", VC1500"
    End If

    If VC7500.OLEFormat.Object.Value = 1 Then
       strCriteria = strCriteria & ", VC7500"
    End If

    If VC144024.OLEFormat.Object.Value = 1 Then
       strCriteria = strCriteria & ", 144024"
    End If

'with statement that finds for column vendor then filter it based on 
strCriteria, I think this is where my issue is'

    With Worksheets("Open Purchase Orders")
        With .Range("A1", .Cells(1, Columns.Count).End(xlToLeft))
            Set vendorfind = .Rows(1).Find("Vendor")
            If Not vendorfind Is Nothing Then
                .AutoFilter Field:=vendorfind.Column, 
           Criteria1:=Split(strCriteria, ", "), Operator:=xlFilterValues
            End If
        End With
         .AutoFilterMode = False
   End With

End Sub

我希望根据复选框过滤工作表。 我收到运行时错误 9 错误:下标超出范围

【问题讨论】:

    标签: excel vba checkbox autofilter


    【解决方案1】:

    在我看来,该代码的某些部分就像用右手在头上抓挠左耳一样。但我并不完全清楚它的实际外观(样本会有所帮助) - 每个供应商都有一些单独的指示列吗?如果是这样,你在那里过滤什么?看起来是供应商标签?

    例如,这是针对可能包含 3 个名称的单个供应商列 (D) 的解决方案。它基本上应用了值列表的自动过滤器。 (我使用下面的 activex 复选框,因为它们的属性可以直接访问。)

    Private Sub VC1500_Click()
    Update_Filter
    End Sub
    
    Private Sub VC7500_Click()
    Update_Filter
    End Sub
    
    Private Sub VC144024_Click()
    Update_Filter
    End Sub
    
    Private Sub Update_Filter()
    Dim varr_filter(3) As String
    Dim indshow As Boolean
    indshow = True
    If VC1500 Then
        varr_filter(0) = VC1500.Caption
        indshow = False
    End If
    If VC7500 Then
        varr_filter(1) = VC7500.Caption
        indshow = False
    End If
    If VC144024 Then
        varr_filter(2) = VC144024.Caption
        indshow = False
    End If
    If indshow Then
        Range("$A:$D").AutoFilter
    Else
        Range("$A:$D").AutoFilter field:=4, Criteria1:=varr_filter, Operator:=xlFilterValues
    End If
    End Sub
    

    注意:选择正确的列作为“字段”值进行过滤,如果您出于某种原因希望将复选框与表单分开,请添加“”“sheets(“sheetname”).{each checkbox}” “”。

    或者,如果每个 vcs 都有一个单独的列,并寻找字面上说“供应商”的行,我会将它们合并到工作表中,如下所示:

    E2=if(cond1)*checkbox1 + if(cond2)*checkbox2 + if(cond3)*checkbox3 ; E > 0.
    Cond1 could be b2="Vendor", for example.
    To make the sheet display all cols when no ticks are selected,
    I've added another value: 1 - max(checkboxes).
    E6=1-MAX($H$4:$H$6) + IF(AND(B2="Vendor"),1,0)*$H$4 +
       IF(AND(C2="Vendor"),1,0)*$H$5 + IF(AND(D2="Vendor"),1,0)*$H$6
    

    这是一个隐藏工作表值有帮助的示例,因为您实际上可以在没有 vb 的情况下定义这样的列。然后,代码本身被简化了一点。

    Private Sub VC1500_Click()
    If VC1500.Value Then
        Range("$H$4").Value = 1
    Else
        Range("$H$4").Value = 0
    End If
    Update_Filter
    End Sub
    
    Private Sub VC7500_Click()
    If VC7500.Value Then
        Range("$H$5").Value = 1
    Else
        Range("$H$5").Value = 0
    End If
    Update_Filter
    End Sub
    
    Private Sub VC144024_Click()
    If VC144024.Value Then
        Range("$H$6").Value = 1
    Else
        Range("$H$6").Value = 0
    End If
    Update_Filter
    End Sub
    
    Private Sub Update_Filter()
    Range("$A:$E").AutoFilter field:=5, Criteria1:=">0", Operator:=xlFilterValues
    End Sub
    

    通过在单击期间检查范围值而不是复选框,并隐藏 H 列,转换到表单控件也更容易。对于普通用户来说,这并不完全防弹但足够。要么阅读你写的形状。


    编辑:为以上两种情况(单列、多列)添加了经过测试的代码,包括在没有选中复选框而不是没有选中复选框时显示所有行。这是演示照片。

    Single col code

    Single col sample sheet

    Single col filtered

    Multicol code

    Multicol sample

    Multicol filtered

    【讨论】:

    • 我实际上在使用表单控件,但就像我之前所说的那样,我仍然掌握了这个窍门。我不太了解您提供的代码 - 如果您不介意将其分解,将不胜感激。
    • 至于这个过滤器的用途,我可以尝试详细说明。因此,工作表包含了我工作中每个人的信息,但他们对他们的特定供应商负责。我正在尝试根据供应商代码和制造商 # 制作一个可自定义的过滤器,然后为他们认为有用的特定列制作另一个过滤器(这部分将很容易,因为它应该只是与他们每列的复选框绑定的单独查找功能想)。我实际上让原始代码可以工作,但发现自己遇到了另一个运行时错误 5 的问题。
    • 对,我误解了——这就是所有形状和 ole 摆弄的原因。该代码只是将过滤器应用于具有所选供应商值的单个列。我已经为它添加了一个演示和一个完整的 multicol 路线指南,让我知道这是否足以澄清事情。如果对您来说都一样,那么示例我的意思是您拥有的工作表的几行,以及您希望输出的样子。仅从解释中我看不到细节。
    • 哇,你的代码似乎比我的更干净。我也怀疑它是实时过滤的?因为,通过单击复选框,它会运行过滤器代码。另外,感谢您的解释和示例!有其他(更好的)方法可以解决这个问题,这很酷。我实际上让我的工作,只是字符串数组的一些间距问题。这只是一个麻烦,因为大约有 150 个供应商代码,所以我编写了一个代码来为我编写所有代码。
    • 是的,它是实时的。我对最小化用户工作量要求严格;对于 150 家供应商,我肯定会尝试与客户一起制定策略以减少单调乏味。但如果你最终设法让它发挥作用,那将是一个重要的里程碑。干得好。
    【解决方案2】:

    您是否尝试过使用切片? 它很容易,应该在没有宏的情况下做简单的过滤器。

    选择您的数据 > 插入表格。 表格完成后,您可以从“设计”选项卡中选择“插入切片器”。 试试这是否能解决您的问题。

    【讨论】:

    • 我只是查看了 Slices,但我认为这不是我正在寻找的所有数据。不过,感谢您的意见。
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    相关资源
    最近更新 更多