Excel-如何查找字符串在列中出现的次数

Excel-如何查找字符串在列中出现的次数,excel,algorithm,excel-2016,Excel,Algorithm,Excel 2016,这是我的第一篇文章,我还是excel的初学者 我创建了一个python脚本,它可以刮取布告牌Hip-Hop/R&B图表,并将数据填充到excel电子表格中。我的数据如下所示: 标题为广告牌编号、艺术家姓名和歌曲标题 我想计算艺术家在艺术家名下出现的总次数,包括他们是否出现在歌曲中,以及是否显示最热门的图表歌曲。例如: 标题包括艺术家姓名、广告牌外观和热门歌曲 我怎样才能做到这一点呢?如果您已经有了所有艺术家的名字,请使用countif和vlookup和通配符 另外,确保你的艺术家名字是正确的。

这是我的第一篇文章,我还是excel的初学者

我创建了一个python脚本,它可以刮取布告牌Hip-Hop/R&B图表,并将数据填充到excel电子表格中。我的数据如下所示:

标题为广告牌编号、艺术家姓名和歌曲标题

我想计算艺术家在艺术家名下出现的总次数,包括他们是否出现在歌曲中,以及是否显示最热门的图表歌曲。例如:

标题包括艺术家姓名、广告牌外观和热门歌曲


我怎样才能做到这一点呢?

如果您已经有了所有艺术家的名字,请使用
countif
vlookup
通配符


另外,确保你的艺术家名字是正确的。您的示例数据
J.cole
不包含空格,它将返回错误的结果。

首先,您需要进行所谓的数据清理,以获得广告牌上艺术家的列表

要获得独特艺术家的列表,请将数据列表复制到电子表格上的新空间。然后选择所有数据并运行“删除重复项”功能(在“数据”选项卡下),选择“艺术家”列。这将给你一个所有独特艺术家的名单,并给你他们的顶级歌曲引导

现在,所有这些X和Y艺术家的“名字”都是唯一的,所以你需要进一步过滤。使用Find函数搜索“featured”链接器单词,并将其与Left函数结合使用,仅获取第一个艺术家。类似这样的东西,
=IFERROR(左(I3,查找(“特色”,I3)-2),I3)
此函数使用iferror函数传递没有“特征”字的名称。然后在&和|的结果列上做同样的事情,这将为您提供一个非常清晰的单身艺术家列表

要获得特色艺术家,请使用右函数而不是左函数执行类似操作

在你得到一个干净的列表后,再做一次独特的艺术家过滤,将其浓缩。从那里,您可以将其与vlookup或find函数一起使用以开始计数。

您可以使用Power Query(获取和转换数据)来操作您的表:

let

    Source = Excel.CurrentWorkbook(){[Name="tbInput"]}[Content],

    #"Changed Type" = Table.TransformColumnTypes(
        Source,
        {{"Billboard Number", Int64.Type}, 
         {"Artist Name", type text}, 
         {"Song Title", type text}}),

    #"Split Column by Delimiters" = Table.ExpandListColumn(
        Table.TransformColumns(
            #"Changed Type",
            {{"Artist Name", Splitter.SplitTextByAnyDelimiter({"Featuring","|","&"}, QuoteStyle.None), 
            let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), 
            "Artist Name"),

    #"Trimmed Text" = Table.TransformColumns(
        #"Split Column by Delimiters",
        {{"Artist Name", Text.Trim, type text}}),

    #"Artist Highest Position" = Table.Group(
        #"Trimmed Text", 
        {"Artist Name"}, 
        {{"Highest Position", each List.Min([Billboard Number]), 
        type number}}),

    #"Merge 1" = Table.NestedJoin(
        #"Artist Highest Position",
        {"Artist Name", "Highest Position"},
        #"Trimmed Text",
        {"Artist Name", "Billboard Number"},
        "Merged",
        JoinKind.LeftOuter),

    #"Highest Song" = Table.ExpandTableColumn(
        #"Merge 1", "Merged", {"Song Title"}, {"Song Title"}),

    #"Artist Count" = Table.Group(
        #"Trimmed Text", 
        {"Artist Name"}, 
        {{"Count", each Table.RowCount(_), type number}}),

    #"Merge 2" = Table.NestedJoin(
        #"Artist Count",
        {"Artist Name"},
        #"Highest Song",
        {"Artist Name"},
        "Merged",
        JoinKind.LeftOuter),

    #"Expanded Merged" = Table.ExpandTableColumn(
        #"Merge 2", "Merged", {"Song Title"}, {"Song Title"}),

    #"Sorted Rows" = Table.Sort(#"Expanded Merged",{{"Count", Order.Descending}})

in

    #"Sorted Rows"
它给出了输出:


最难的部分是清理数据以获得艺术家姓名的唯一列表

查看您的列表,似乎当一首歌中列出了多个艺术家姓名时,他们将被
特征
|

如果总是这样,您可以使用VBA宏来分隔名称,然后使用字典来收集名称列表

在创建该列表时,还可以获得艺术家出现的次数,以及最高级别的歌曲(即与该名称的第一个实例关联的歌曲),这很简单

我们使用一个用户定义的对象(类)来保存信息,并将这些对象收集到一个与艺术家姓名相匹配的字典中

还要注意的是,我们将工作表数据读入VBA数组,并遍历该数组。这通常比在实际工作表中迭代快一个数量级

为了获得报告,我们将结果输出到工作表上

课程模块

Option Explicit
'Class module **RENAME**: cArtist
Public Cnt As Long
Public Song As String
Option Explicit
Option Compare Text
Sub Artists()
    Dim dA As Dictionary, cA As cArtist
    Dim vSrc, vRes
    Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
    Dim V, W, X, Y, Z, A, B
    Dim I As Long
    Dim sKey As String

Set wsSrc = Worksheets("sheet6")
With wsSrc
    vSrc = .Range(.Cells(2, 2), .Cells(.Rows.Count, 2).End(xlUp)).Resize(columnsize:=2)
End With

Set wsRes = Worksheets("sheet6")
    Set rRes = wsRes.Cells(1, 6)

Set dA = New Dictionary
For I = 1 To UBound(vSrc, 1)
    W = Split(vSrc(I, 1), "Featuring")
        For Each X In W
            Y = Split(X, "|")
                For Each Z In Y
                    A = Split(Z, "&")
                        For Each B In A
                            sKey = Trim(B)
                            Set cA = New cArtist
                            With cA
                                .Cnt = 1
                                .Song = Trim(vSrc(I, 2))
                            End With
                            If Not dA.Exists(sKey) Then
                                dA.Add Key:=sKey, Item:=cA
                            Else
                                dA(sKey).Cnt = dA(sKey).Cnt + 1
                            End If
                        Next B
                Next Z
        Next X
Next I

ReDim vRes(0 To dA.Count, 1 To 3)
    vRes(0, 1) = "Artist Name"
    vRes(0, 2) = "Billboard Appearances"
    vRes(0, 3) = "Top Song"

I = 0
For Each V In dA.Keys
    I = I + 1
    With dA(V)
        vRes(I, 1) = V
        vRes(I, 2) = .Cnt
        vRes(I, 3) = .Song
    End With
Next V

Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
    .EntireColumn.Clear
    .Value = vRes
    .Sort key1:=rRes(1, 2), order1:=xlDescending, key2:=rRes(1, 1), order2:=xlAscending, MatchCase:=False, Header:=xlYes
    .Style = "Output"
    With .Columns(2)
        .ColumnWidth = .ColumnWidth / 2
        .WrapText = True
        .HorizontalAlignment = xlCenter
    End With
    With .Rows(1)
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
    .EntireColumn.AutoFit
End With
End Sub
常规模块

Option Explicit
'Class module **RENAME**: cArtist
Public Cnt As Long
Public Song As String
Option Explicit
Option Compare Text
Sub Artists()
    Dim dA As Dictionary, cA As cArtist
    Dim vSrc, vRes
    Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
    Dim V, W, X, Y, Z, A, B
    Dim I As Long
    Dim sKey As String

Set wsSrc = Worksheets("sheet6")
With wsSrc
    vSrc = .Range(.Cells(2, 2), .Cells(.Rows.Count, 2).End(xlUp)).Resize(columnsize:=2)
End With

Set wsRes = Worksheets("sheet6")
    Set rRes = wsRes.Cells(1, 6)

Set dA = New Dictionary
For I = 1 To UBound(vSrc, 1)
    W = Split(vSrc(I, 1), "Featuring")
        For Each X In W
            Y = Split(X, "|")
                For Each Z In Y
                    A = Split(Z, "&")
                        For Each B In A
                            sKey = Trim(B)
                            Set cA = New cArtist
                            With cA
                                .Cnt = 1
                                .Song = Trim(vSrc(I, 2))
                            End With
                            If Not dA.Exists(sKey) Then
                                dA.Add Key:=sKey, Item:=cA
                            Else
                                dA(sKey).Cnt = dA(sKey).Cnt + 1
                            End If
                        Next B
                Next Z
        Next X
Next I

ReDim vRes(0 To dA.Count, 1 To 3)
    vRes(0, 1) = "Artist Name"
    vRes(0, 2) = "Billboard Appearances"
    vRes(0, 3) = "Top Song"

I = 0
For Each V In dA.Keys
    I = I + 1
    With dA(V)
        vRes(I, 1) = V
        vRes(I, 2) = .Cnt
        vRes(I, 3) = .Song
    End With
Next V

Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
    .EntireColumn.Clear
    .Value = vRes
    .Sort key1:=rRes(1, 2), order1:=xlDescending, key2:=rRes(1, 1), order2:=xlAscending, MatchCase:=False, Header:=xlYes
    .Style = "Output"
    With .Columns(2)
        .ColumnWidth = .ColumnWidth / 2
        .WrapText = True
        .HorizontalAlignment = xlCenter
    End With
    With .Rows(1)
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
    .EntireColumn.AutoFit
End With
End Sub
根据以上输入进行输出

Option Explicit
'Class module **RENAME**: cArtist
Public Cnt As Long
Public Song As String
Option Explicit
Option Compare Text
Sub Artists()
    Dim dA As Dictionary, cA As cArtist
    Dim vSrc, vRes
    Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
    Dim V, W, X, Y, Z, A, B
    Dim I As Long
    Dim sKey As String

Set wsSrc = Worksheets("sheet6")
With wsSrc
    vSrc = .Range(.Cells(2, 2), .Cells(.Rows.Count, 2).End(xlUp)).Resize(columnsize:=2)
End With

Set wsRes = Worksheets("sheet6")
    Set rRes = wsRes.Cells(1, 6)

Set dA = New Dictionary
For I = 1 To UBound(vSrc, 1)
    W = Split(vSrc(I, 1), "Featuring")
        For Each X In W
            Y = Split(X, "|")
                For Each Z In Y
                    A = Split(Z, "&")
                        For Each B In A
                            sKey = Trim(B)
                            Set cA = New cArtist
                            With cA
                                .Cnt = 1
                                .Song = Trim(vSrc(I, 2))
                            End With
                            If Not dA.Exists(sKey) Then
                                dA.Add Key:=sKey, Item:=cA
                            Else
                                dA(sKey).Cnt = dA(sKey).Cnt + 1
                            End If
                        Next B
                Next Z
        Next X
Next I

ReDim vRes(0 To dA.Count, 1 To 3)
    vRes(0, 1) = "Artist Name"
    vRes(0, 2) = "Billboard Appearances"
    vRes(0, 3) = "Top Song"

I = 0
For Each V In dA.Keys
    I = I + 1
    With dA(V)
        vRes(I, 1) = V
        vRes(I, 2) = .Cnt
        vRes(I, 3) = .Song
    End With
Next V

Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
    .EntireColumn.Clear
    .Value = vRes
    .Sort key1:=rRes(1, 2), order1:=xlDescending, key2:=rRes(1, 1), order2:=xlAscending, MatchCase:=False, Header:=xlYes
    .Style = "Output"
    With .Columns(2)
        .ColumnWidth = .ColumnWidth / 2
        .WrapText = True
        .HorizontalAlignment = xlCenter
    End With
    With .Rows(1)
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
    End With
    .EntireColumn.AutoFit
End With
End Sub

欢迎来到stack。你能做的最好的事情就是根据你自己的研究来解决你的问题,然后把你尝试过的东西张贴出来,如果它不起作用的话。请回顾-我也支持这项研究。这是一些令人悲伤的数据,音乐行业一个开始可能是创建一个单独的所有艺术家列表,一个单元格一个。这是我第一次使用VBA宏,我注意到在类模块的第二行中,您重命名了文本。是否应将其重命名为excel文档的名称?@Fedolodic No,您需要将类模块重命名:从默认名称(通常为
Class1
)重命名为
cArtist
。检查类模块
属性
,您将看到一行标记为
(名称)
。您可以编辑该行并将名称更改为
cArtist
我将Class1更改为cArtist,并为类模块和常规模块添加了代码,在尝试运行后,我得到错误编译错误:未定义用户定义的类型。然后,在常规模块中,子艺术家()在第3行以黄色突出显示,dA As Dictionary在第4行以蓝色突出显示。我不知道该换什么here@Fedolodic很抱歉忘了提到必须将引用--(请参见菜单栏中的
Tools/References
)设置为
Microsoft脚本运行时
I更改为
Source=Excel.CurrentWorkbook(){[Name=“tbInput”]}[Content],
Source=Excel.CurrentWorkbook(){[Name=“Billboard\u Hip\u Hop\u Charts”]}[Content],
我得到一个错误,上面写着,`Expression.error:找不到表的'Artist Name'列。详情:艺术家姓名'。有办法解决这个问题吗?这是我第一次使用Power Query。您在表
Billboard\u Hip\u Hop\u图表中的列名是什么?我使用了列名
{“公告牌编号”、“艺术家名称”、“歌曲标题”}
-因此,如果您的列名与这些列名不同,您需要相应地更改引用。并且源数据表必须格式化为ListObject表。