【问题标题】:How can I remove text duplicates in a cell string?如何删除单元格字符串中的重复文本?
【发布时间】:2018-08-14 07:02:16
【问题描述】:

所以想象一下excel的一个单元格中有以下字符串:

A1 = "Company 1 Company 2 Company 1 Company 2 Company 3"

现在想要的结果是删除重复项:

A1 = "Company 1 Company 2 Company 3"(我想这个不需要宏)

理想的做法是将不同的值以垂直方式放在不同的单元格中:

A1 = "Company 1"
A2 = "Company 2"
A3 = "Company 3"

(这肯定需要编程,但由于我从未使用过 vba,所以我没有足够的经验,我认为无法详细说明此类代码)

可行吗?

编辑:分隔符可以从空格“”更改为其他,例如分号“;”以防止错误并更容易解决这个问题。

【问题讨论】:

  • 你的示例数据太简单了,在数据不应该拆分的地方重复使用了分隔符。
  • 谢谢回复,数据简单是什么意思? (不知道我是否应该说,但 A1 发生了数千次,每次都被引用到不同的 id )。另外,您能否澄清一下分隔符的问题?是因为名称和下一个空格中出现了几个空格吗?我想我可以更改用于在 A1 上提供输出的连接函数以用逗号分隔它们......这有帮助吗?
  • 仅当公司名称中没有逗号时。
  • @Jeeped 100% 正确。有时,如果值本身包含空格或逗号,则使用空格或逗号作为分隔符的拆分值可能会导致问题。如果您可以自定义连接,我建议您使用一个非常奇怪的分隔符。例如,使用|| (Alt GR +1) 然后也许我们可以解决一些问题
  • @Jeeped 我查了名字,只有2个公司名字里面有逗号,运​​气不好。尽管如此,鉴于您提供的输入,那么应该使用公司名称中未使用的分隔符......这会有所帮助吗,例如,使用分号? (我检查过他们的名字中没有“;”)

标签: excel duplicates vba


【解决方案1】:

假设你在字符串之间有一个分隔符来区分你可以使用以下代码

Option Explicit

Sub RemoveDuplicates()

Const SEPARATOR = ","
Dim vDat As Variant

    vDat = Split(Range("A1"), SEPARATOR)

    ' remove trailing blanks if necessary
    Dim i As Long
    For i = LBound(vDat) To UBound(vDat)
        vDat(i) = Trim(vDat(i))
    Next i

    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")

    Dim vItem As Variant

    For Each vItem In vDat
        If Not dic.Exists(vItem) Then
            dic.Add vItem, vItem
        End If
    Next

    vDat = dic.Keys

    ' Write data to column B
    Range("B1").Resize(UBound(vDat) + 1) = WorksheetFunction.Transpose(vDat)

    'Debug.Print Join(vDat, SEPARATOR)

End Sub

用以下数据测试

A1 = Company 1,  Company 2, Company 1, Company 2 , Company 3

A1 = IBM,  Apple, Microsoft, Apple , IBM

【讨论】:

    【解决方案2】:

    使用明确的字符串,我的意思是:

    • 子字符串中不包含分隔符,
    • 每个条目都用双引号括起来

    您可以在 Excel 2010、2013 中使用 Power Query 或在 Excel 2016 中使用 Data Get & Transform 来完成所有这些操作。

    • 在分隔符上拆分单元格
      • 如有必要,将引号定义为文本限定符
    • 行 - 删除重复项

    所以数据如下:

    Company 1;Company 2;Company 1;Company 2;Company 3
    

    或(空格分隔符)

    "Company 1" "Company 2" "Company 1" "Company 2" "Company 3"
    

    您无需使用 VBA 即可轻松完成所需的工作。

    如果,如您的示例中那样,数据的开头或结尾有多余的空格,Power Query 有一个有用的Text.Trim 函数。

    【讨论】:

      【解决方案3】:

      使用 UDF 的替代解决方案(为清楚起见进行了注释):

      Public Function UNIQUELIST(ByVal arg_vOriginalList As String, ByVal arg_sDelimiter As String, ByVal arg_lReturnIndex As Long) As Variant
      
          Dim oDict As Object
          Dim vElement As Variant
          Dim i As Long
      
          'Use a dictionary to extract unique elements
          Set oDict = CreateObject("Scripting.Dictionary")
          i = 0   'This is a counter to keep track until we reach the appropriate return index
      
          'Loop through each element
          For Each vElement In Split(arg_vOriginalList, arg_sDelimiter)
              'Check the trimmed, lowercase element against the keys of the dictionary
              If Not oDict.Exists(LCase(Trim(vElement))) Then
                  'Unique element found
                  i = i + 1
                  If i = arg_lReturnIndex Then
                      'Found appropriate unique element, output and exit function
                      UNIQUELIST = Trim(vElement)
                      Exit Function
                  End If
      
                  'Not correct return index, add element to dictionary
                  'Lowercase the key (so uniques aren't case sensitive) and trim both the key and the value
                  oDict.Add LCase(Trim(vElement)), Trim(vElement)
              End If
          Next vElement
      
          'arg_lReturnIndex was less than 1 or greater than the number of unique values, return blank
          UNIQUELIST = vbNullString
      
      End Function
      

      然后在您希望输出开始的单元格中(例如,B1),输入此公式并复制下来(将"," 调整为正确的分隔符):

      =UNIQUELIST($A$1,",",ROW(A1))
      

      【讨论】:

        【解决方案4】:

        使用与 OP 中相同的分隔符的方法

        我假设与您的原始帖子相同的空格分隔符:由于您希望将公司字符串分组为两个,我通过将Split 结果连接到第 2 步,稍微修改了 @Storax 的良好解决方案,并演示了一种将结果写回工作表的更短方法(参见第 [5] 节)。

        示例代码

        Option Explicit                ' declaration head of your code module
        
        Sub SplitCompanies()
        ' [0] declare variables and set objects
          Dim v, vItem
          Dim i As Integer, n As Integer
          Dim s, str As String
          Dim ws As Worksheet
          Set ws = ThisWorkbook.Worksheets("Tabelle5")  ' << change to your sheet name
          Dim dict As Object                            ' late binding of dictionary
          Set dict = CreateObject("Scripting.Dictionary")
        ' [1] get cell value and split it (space delimited as in Original Post)
          str = ws.Range("A1")        ' cell value, e.g. "Company 1 Company 2 Company 1 Company 2 Company 3"
          s = Split(str, " ")         ' split cell value (space delimiter)
        ' [2] count all companies and redimension helper array
          n = Int((UBound(s) + 1) / 2) - 1    ' items counter equals 1/2 of split items
          ReDim v(0 To n)             ' redim zero-based 1-dim helper array
        ' [3] concatenate partial strings in helper array
          For i = 0 To n
            v(i) = s(i * 2) & " " & s(i * 2 + 1)
          Next i
        ' [4] build dictionary with unique items
          For Each vItem In v
            If Not dict.Exists(vItem) Then
                dict.Add vItem, vItem
            End If
          Next
        ' [5] Write data to column B
          ws.Range("B1:B" & dict.Count) = Application.Transpose(dict.Keys)
        ' [6] clear memory
          Set dict = Nothing: Set ws = Nothing
        End Sub
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-04
          • 1970-01-01
          • 2016-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-07
          相关资源
          最近更新 更多