在表中使用切片器/过滤器

时间:2016-03-31 08:20:02

标签: excel

示例我将使用的是我购买甜食,按优先顺序排列并按类别排序的人员列表。我有一个格式的值表:

Option 1|Option 2|Option 3|Catagory 1 | Category 2 |
--------|--------|--------|-----------|------------|
Bob     |  Mary  | Jane   | Candy     | Sherbert   |
James   |  Bob   | Jane   | Choc      | Cadbury Bar|
Jane    |        |        | Candy     | Haribo     |
Jane    |  Mary  | James  | Candy     | Millions   |
...     | ...    | ...    | ...       | ...        |

我希望能够使用下拉框或切片器来选择名称和第一类,并显示最终类别(2)的过滤列表和基于它们是主要,次要或第三选项的“排名”,例如,我选择Jane:

Name |^| Catagory 1|^| Category 2 | Rank  |
-------|-------------|------------|-------|
 Jane  | Candy       | Sherbert   | 3     |
                     | Haribo     | 1     |
                     | Millions   | 1     |

或:

Name |^| Catagory 1|^| Category 2 | Rank  |
-------|-------------|------------|-------|
 Jane  | Choc        | Cadbury Bar| 3     |

(取决于如何挑选)

评论问题:

  • 您使用的是什么Excel版本?的 2013
  • 这是非vba任务吗? 最好不要使用vba,如果你选择在VBA中回答,请考虑它需要量身定制,以解释如何为有限的excel-vba经验的人实施解决方案。
  • 您可以使用两个表(1个输入,1个输出),还是希望布局动态更改? 使用2个表格很好,如果您愿意,可以使用动态表格留下深刻印象(动态表格可以在没有它们的情况下赢得奖励)
  • 你能解释一下如何计算田野等级吗?例如,在Jane |的情况下Rank = 3 Choc |吉百利酒吧? 在吉百利酒吧排,Jane是第3选项,因此排名3.如果她是第二名,她将排名第2或排名第一。
  • 前三列中有姓名(简)。可以在三列中的任何一列中出现相同的名称(Jane)吗?你能解释一下三列名字的原因吗?如果名称可能出现在任何列中,那么它们必须是唯一的 - 就是这样吗? 首先将数据视为行,也许从右向左阅读可能有所帮助。 类别2 列是唯一包含唯一值的列。任何名称都可以在前3列中出现任意次数,但不能在同一行中复制任何名称:Jane不能是单个项目的选项1,2和3(例如)

3 个答案:

答案 0 :(得分:1)

如果您熟悉在Excel中使用SQL语句,则非常容易。您可以使用我在此处提供的方法Filter ShowDetails of PivotTable。如果您不这样做,请不要担心,只需download my file,就可以提供您的餐桌并使用它。

SQL中的想法是:

Select Name=[Option 1],[Category 1],[Category 2],Rank=1 union all
Select Name=[Option 2],[Category 1],[Category 2],Rank=2 union all
Select Name=[Option 3],[Category 1],[Category 2],Rank=3 

*我更改了在Excel中使用SQL语句的标题不允许以数字结尾的列名 - 愚蠢的bug很难学到。

它产生以下输出表:

enter image description here

使用这样的输出表,以下部分非常容易。你甚至不需要切片机。只需使用表格的过滤器即可获得所需的结果:

enter image description here

您可能愿意让输出表没有不包含名称的行(即第7行或第11行)。然后只需使用SQL子句:

WHERE Name is not null

您可以调整此代码,以便在打开文件时自动生成输出表。

答案 1 :(得分:1)

这是一个使用标准Excel组件的VBA解决方案

您的工作簿应该有两张名为SourceDataCalculation的工作表,其中两个表的名称与下图相同:

enter image description here enter image description here

现在添加将处理您的数据的VBA代码。按 Alt + F11 打开代码编辑器。添加一个新模块:

enter image description here

现在在该模块中插入此代码:

Const SOURCE_DATA_SHEET As String = "SourceData"
Const SOURCE_DATA_TABLE As String = "SourceData"

Const CALCULATION_SHEET As String = "Calculation"
Const CALCULATION_TABLE As String = "Calculation"

Const S_OPTION_1 As Integer = 1
Const S_OPTION_2 As Integer = 2
Const S_OPTION_3 As Integer = 3
Const S_CATEGORY_1 As Integer = 4
Const S_CATEGORY_2 As Integer = 5

Const C_WIDTH As Integer = 4

Const C_NAME As Integer = 1
Const C_CATEGORY_1 As Integer = 2
Const C_CATEGORY_2 As Integer = 3
Const C_RANK As Integer = 4

Function GetTable(sheetName As String, tableName As String) As ListObject
    Set GetTable = Worksheets(sheetName).ListObjects(tableName)
End Function

Sub ClearTable(dataTable As ListObject)
    dataTable.AutoFilter.ShowAllData
    dataTable.Sort.SortFields.Clear
    If dataTable.ListRows.Count >= 1 Then
        dataTable.DataBodyRange.Delete
    End If
End Sub

Sub InsertRow(ByRef dataTable As ListObject, ByRef dataRow As Variant)
    dataTable.ListRows.Add
    dataTable.ListRows(dataTable.ListRows.Count).Range = dataRow
End Sub

Sub CalculateRanks(ByRef dataTable As ListObject, ByRef destinationTable As ListObject)
    Dim newRow(1 To C_WIDTH) As Variant
    Dim nameValue As Variant

    For Each dataRow In dataTable.ListRows
        With dataRow
            newRow(C_CATEGORY_1) = .Range(S_CATEGORY_1).Value
            newRow(C_CATEGORY_2) = .Range(S_CATEGORY_2).Value

            For Each optionNumber In Array(S_OPTION_1, S_OPTION_2, S_OPTION_3)
                nameValue = .Range(optionNumber).Value
                If nameValue <> "" Then
                    newRow(C_NAME) = nameValue
                    newRow(C_RANK) = optionNumber
                    InsertRow destinationTable, newRow
                End If
            Next optionNumber

        End With
    Next dataRow
End Sub

Sub Main()
    Dim sourceTable As ListObject
    Dim destinationTable As ListObject
    Set sourceTable = GetTable(SOURCE_DATA_SHEET, SOURCE_DATA_TABLE)
    Set destinationTable = GetTable(CALCULATION_SHEET, CALCULATION_TABLE)
    ClearTable destinationTable
    CalculateRanks sourceTable, destinationTable
End Sub

Calculation表单上,添加一个用于运行代码的按钮。在“开发人员”选项卡下(如果没有看到此选项卡,请转到Excel选项/自定义功能区/选中“主选项卡”列表中的“开发人员”复选框)插入按钮表单控件:

enter image description here

并将您的宏Main链接到按钮:

enter image description here

你已经完成了!现在,每次单击该按钮,Calculation表都会刷新。您可以使用过滤器来显示所需的内容。

答案 2 :(得分:1)

这是您的动态表,没有VBA解决方案。您只需添加一个辅助列。

首先,选择某种分隔符。我选择了 ”!”。

接下来,在相邻列中放入以下大喇叭公式:

Col A  |Col B  |Col C  |Col D    |Col E    |Col F           |
Option1|Option2|Option3|Category1|Category2|[Name of person]|

这样做是告诉你在F1中的值之前连接的名称列表中出现了多少感叹号(在我的工作簿中是我放“Jane”的列标题)。 (然后添加一个,使得最高点为“1”,而不是“0”)。如果未找到标题行中的名称,则该单元格将留空。

完成此操作后,获取已过滤列表的过程为:

1。在F1中输入人员的姓名。

2。过滤掉F1中的空白。

3。根据需要过滤类别1.

请注意,在我的公式中,列匹配如下:

Option 1|Option 2|Option 3|Category 1 | Category 2 |Jane |
--------|--------|--------|-----------|------------|-----|
Bob     |  Mary  | Jane   | Candy     | Sherbert   |3    |
James   |  Bob   | Jane   | Choc      | Cadbury Bar|3    |
Jane    |        |        | Candy     | Haribo     |1    |
Jane    |  Mary  | James  | Candy     | Millions   |1    |
...     | ...    | ...    | ...       | ...        |...  |

这些公式产生以下输出:

Option 1|Option 2|Option 3|Category 1 | Category 2 |James |
--------|--------|--------|-----------|------------|----- |
Bob     |  Mary  | Jane   | Candy     | Sherbert   |      |
James   |  Bob   | Jane   | Choc      | Cadbury Bar|1     |
Jane    |        |        | Candy     | Haribo     |      |
Jane    |  Mary  | James  | Candy     | Millions   |3     |
...     | ...    | ...    | ...       | ...        |...   |

或者,詹姆斯......

grunt.loadTasks