通过公式逻辑通过列表进行Excel筛选

时间:2019-05-08 19:20:04

标签: excel excel-formula

我想滚动浏览成千上万的电子邮件日志列表,找到所有名为“ Yoda”的人,并获取Yoda所在的ID号。

我已经尝试了vlookups和索引匹配的公式,但是它不起作用,因为我得到了重复的ID。我如何才能将列表作为公式过滤,以便仅获取Yoda的所有ID?我将把ID的公式放在另一个工作表中。

电子邮件日志:

Character       ID

Yoda@gmail.com  789
Yoda@yahoo.com  664
Luke@gmail.com  113
Anakin@bing.com 115
Jabba@gmail.com 998
Yoda@wired.com  446
Luke@yahoo.coom 500

我希望在新工作表中看到的是:

Yoda    Luke   Anakin   Jabba

789     113    115      998
664     500
446

3 个答案:

答案 0 :(得分:1)

您可以使用Power QueryGet & Transform相当简单地完成此操作,该功能自2010年以来已在Excel中可用。对于早期版本,VBA是一个不错的选择。

除了创建两个自定义列之外,所有操作都可以从用户界面中完成。自定义列需要在“创建自定义列”对话框中输入公式。

在功率查询中:

  • 添加一个自定义列以删除电子邮件的@domain部分。将列命名为CharName

Text.Start([Character],Text.PositionOf([Character],"@"))

enter image description here

  • 删除原始的Characters
  • CharName分组

enter image description here

  • 添加一个自定义列,该列将结果Table转换为列表

Table.Column([Count],"ID")

enter image description here

  • 在显示的IDs列中,选择该列右上方的双箭头,然后使用逗号定界符选择到Extract Values

  • 用定界符(逗号)分隔该列,然后将创建新列

  • 删除原始的Table

  • 转置整个表格
  • 将第一行的内容升级为标题

这是M代码:

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Character", type text}, {"ID", Int64.Type}}),
    #"Added Custom" = Table.AddColumn(#"Changed Type", "CharName", each Text.Start([Character],Text.PositionOf([Character],"@"))),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Character"}),
    #"Grouped Rows" = Table.Group(#"Removed Columns", {"CharName"}, {{"Count", each _, type table [ID=number, CharName=text]}}),
    #"Added Custom1" = Table.AddColumn(#"Grouped Rows", "IDs", each Table.Column([Count],"ID")),
    #"Extracted Values" = Table.TransformColumns(#"Added Custom1", {"IDs", each Text.Combine(List.Transform(_, Text.From), ","), type text}),
    #"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "IDs", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"IDs.1", "IDs.2", "IDs.3"}),
    #"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"IDs.1", Int64.Type}, {"IDs.2", Int64.Type}, {"IDs.3", Int64.Type}}),
    #"Removed Columns1" = Table.RemoveColumns(#"Changed Type1",{"Count"}),
    #"Transposed Table" = Table.Transpose(#"Removed Columns1"),
    #"Promoted Headers" = Table.PromoteHeaders(#"Transposed Table", [PromoteAllScalars=true]),
    #"Changed Type2" = Table.TransformColumnTypes(#"Promoted Headers",{{"Yoda", Int64.Type}, {"Luke", Int64.Type}, {"Anakin", Int64.Type}, {"Jabba", Int64.Type}})
in
    #"Changed Type2"

这是根据原始数据得出的最终结果:

enter image description here

如果您喜欢VBA方法,则可以为每个字符创建ID集合的字典。您需要通过下面的代码来逐步理解它,并使其适应您的特定工作簿和工作表设置。

Option Explicit
'Set reference to Microsoft Scripting Runtime
Sub charIDs()
    Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
    Dim vSrc As Variant, vRes As Variant
    Dim D As Dictionary, COL As Collection, sKey As String
    Dim I As Long, J As Long
    Dim V As Variant

Set wsSrc = Worksheets("Source")
Set wsRes = Worksheets("Results")
    Set rRes = wsRes.Cells(1, 1)

With wsSrc
    vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 2).End(xlUp))
End With

Set D = New Dictionary
    D.CompareMode = TextCompare

'Create a dictionary of collections of Id's for each character
For I = 2 To UBound(vSrc, 1)
    sKey = Split(vSrc(I, 1), "@")(0)
    If Not D.Exists(sKey) Then
        Set COL = New Collection
        COL.Add vSrc(I, 2)
        D.Add Key:=sKey, Item:=COL
    Else
        D(sKey).Add vSrc(I, 2)
    End If
Next I

'create results array
I = 0
For Each V In D.Keys
    I = IIf(I > D(V).Count, I, D(V).Count)
Next V

ReDim vRes(0 To I, 1 To D.Count)

'Populate
J = 0
For Each V In D.Keys
    J = J + 1
    vRes(0, J) = V
    For I = 1 To D(V).Count
        vRes(I, J) = D(V)(I)
    Next I
Next V

'size and fill results range
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
    .EntireColumn.Clear
    .Value = vRes
    With .Rows(1)
        .Font.Bold = True
        .HorizontalAlignment = xlCenter
    End With
    .EntireColumn.AutoFit
End With

End Sub

答案 1 :(得分:0)

使用the AGGREGATE function吗?您希望Small(15)以升序进行此操作

=IFERROR(INDEX($B$1:$B$8,AGGREGATE(15, 6, ROW($A$1:$A$8)-1+POWER(10,9*--(LEFT($A$1:$A$8,LEN("Yoda"))<>"Yoda")), ROW()-1),1),"")

-1+POWER(10,9*--(LEFT($A$1:$A$8,LEN("Yoda"))<>"Yoda"))位意味着任何非Yoda值都会在INDEX中引发错误,从而导致=""

答案 2 :(得分:0)

我能够找出我的问题!由于Yoda版本过多(请参见错误图片),因此我无法使用“搜索过滤器”为Yoda(以及其他许多名称)记录宏来过滤列表。相反,我记录了一个使用“文本过滤器”的宏,然后过滤了包含“ Yoda”的文本。我为其余的角色做到了这一点,并且能够将过滤后的结果自动化到新的工作表上。

谢谢大家的贡献!

Search Filter

Error Image