在列中以CSV格式的文本查找唯一变量

时间:2018-07-31 07:13:04

标签: excel vba hashmap keyvaluepair

image 列A包含所有计数器的列表,列D(往后)包含我从表单XML中提取的一些相关信息。现在,我想返回B列中的变量,这些变量在D列中有多个值,并且超出范围

例如:

  • 对于counter1,什么也不应该退回
  • 对于counter2,“ D”应为 返回,因为它有2个唯一值(4和5)
  • 对于counter3,应返回“ B,C,D”,因为这3个变量有多个值。

格式是标准格式,变量值对用逗号分隔,变量和值之间有等号,但是可以有许多对和键对实例(一个计数器最多可以有100个) +前面的此类单元格

1 个答案:

答案 0 :(得分:0)

假设您要

  

搜索对形式为X=n的变量的多个分配,并返回至少分配了2个不同值的所有变量名称。一个单元格内的多个分配由定义的定界符分隔。多个包含或不包含一个或多个分配的单元格可以用作输入。

以下函数FindDuplicateAssignmentsInCSVRange(inputRange, listDelimiter, assignmentOperator接受一定范围的单元格,并可以选择定义备用列表分隔符(默认值:逗号)和备用赋值运算符(默认值:相等符号)。
它输出以逗号分隔的列表(或传递了任何其他分隔符)的形式,这些变量的名称至少分配了2个不同的值。如果没有任何变量名称满足该要求,则返回一个空字符串。


Option Explicit

Private Type TKeyValuePair
    key As String
    val As String
End Type

Private Function FindDuplicateAssignmentsInCSVRange(inpRange As Range, _
                                                    Optional ByVal listDelimiter As String = ",", _
                                                    Optional ByVal assingmentOperator As String = "=") As String
    ' this function needs a reference to the Microsoft Scripting Runtime to work

    Const ReturnIndicator As String = "Return this value's key when done"
    Dim dic As Scripting.Dictionary
    Set dic = New Scripting.Dictionary

    ' Go into each cell in the given range
    Dim c As Range
    For Each c In inpRange.Cells

        ' split cell contents and iterate over each particle
        Dim particle As Variant
        For Each particle In Split(c.Value, listDelimiter)

            ' split each fragment "A=1" into variable and value; kvp = key-value pair
            Dim kvp As TKeyValuePair
            kvp.key = Split(particle, assingmentOperator)(0)
            kvp.val = Split(particle, assingmentOperator)(1)

            If Not dic.Exists(kvp.key) Then
                ' add new keys/variables to dictionary to keep track
                dic.Add kvp.key, kvp.val
            Else
                ' check values of existing keys and mark key if values differ ( = there are 2 or more different values)
                Dim AlreadyMarkedForReturn As Boolean
                AlreadyMarkedForReturn = (dic(kvp.key) = ReturnIndicator)
                If dic(kvp.key) <> kvp.val And Not AlreadyMarkedForReturn Then
                    dic(kvp.key) = ReturnIndicator
                End If
            End If

        Next particle

    Next c

    ' clean up dictionary to only contain the return entries
    Dim k As Variant
    For Each k In dic.Keys
        If dic(k) <> ReturnIndicator Then dic.Remove k
    Next k

    ' return remaining keys as comma(or whatever)-separated list
    FindDuplicateAssignmentsInCSVRange = Join(dic.Keys, listDelimiter)

End Function

用法示例:

Public Sub SO_51607467()
    Debug.Print "D2:D2 Variables: '" & FindDuplicateAssignmentsInCSVRange(ThisWorkbook.Sheets(1).Range("D2")) & "'"
    Debug.Print "D3:E3 Variables: '" & FindDuplicateAssignmentsInCSVRange(ThisWorkbook.Sheets(1).Range("D3:E3")) & "'"
    Debug.Print "D4:F4 Variables: '" & FindDuplicateAssignmentsInCSVRange(ThisWorkbook.Sheets(1).Range("D4:F4")) & "'"
End Sub

从您显示的工作簿的近似副本中(由于复制类型)运行SO_51607467的输出:

D2:D2 Variables: ''
D3:E3 Variables: 'D'
D4:F4 Variables: 'B,C'