在Excel 2010中,如何删除包含多个值单元格的单元格范围内的重复项和连接值?
我在Excel 2010中创build了一个文档,但是我希望从中获得的function似乎是不可能的(至less不能使用默认的Excel函数),而且我对VB编程还不太了解。 UDF。 (我实际上使用的是我在网上find的一部分是我想要的,但并不能满足我所有的需求。)
让我分解一下:
-
我有多个用户可以添加数字的字段组(一些将是空白的,一些将包含一个单一的数字,一些将包含多个逗号分隔的数字)
-
我有一个“概述”表,我想要连接这些数字(并删除任何重复)在几个不同的部分(只看特定的字段组)。
我发现了一个ConcatIf UDF,它可以很好地工作,但是它不能处理非连续的单元格(例如,我想连接和删除单元格D30,G30,J30和M30中的重复项)(这里是UDF 🙂
Function ConcatIf(ByVal compareRange As Range, ByVal xCriteria As Variant, Optional ByVal stringsRange As Range, _ Optional Delimiter As String, Optional NoDuplicates As Boolean) As String Dim i As Long, j As Long With compareRange.Parent Set compareRange = Application.Intersect(compareRange, Range(.UsedRange, .Range("a1"))) End With If compareRange Is Nothing Then Exit Function If stringsRange Is Nothing Then Set stringsRange = compareRange Set stringsRange = compareRange.Offset(stringsRange.Row - compareRange.Row, _ stringsRange.Column - compareRange.Column) For i = 1 To compareRange.Rows.Count For j = 1 To compareRange.Columns.Count If (Application.CountIf(compareRange.Cells(i, j), xCriteria) = 1) Then If InStr(ConcatIf, Delimiter & CStr(stringsRange.Cells(i, j))) <> 0 Imp Not (NoDuplicates) Then ConcatIf = ConcatIf & Delimiter & CStr(stringsRange.Cells(i, j)) End If End If Next j Next i ConcatIf = mid(ConcatIf, Len(Delimiter) + 1) End Function
它也不能作为单独的数字处理“在一个单元中的多个数字”。
有没有办法让一个连接UDF“parsing”它正在查找的单元格以查找多个数字单元格和单个数字单元格之间的重复项,然后输出结果? 优选地允许它拍摄一系列不连续的单元格(在不同的片材上)工作。
对不起,如果解释有点复杂,这是我第一次要求这样的帮助。 :X
这是一个例子:
如果我有单元格:
- 2,4,6
- 2,6
- 2
- 4
- 6
- 6,8
我想要能够简单地得到:
- 2,4,6,8
现在,我会得到:
- 2,4,6,2,6,6,8
试试下面。 如果您需要更改分隔符等,您可以适当地调整它。我已经logging了它在做什么以及为什么。
示例公式: =blah(A1:A7,A8,C9)
(也可以从代码调用)
示例输出: 2,4,6,8
Public Function Blah(ParamArray args()) As String 'Declarations Dim uniqueParts As Collection Dim area As Range Dim arg, arr, ele, part Dim i As Long 'Initialisations Set uniqueParts = New Collection 'Enumerate through the arguments passed to this function For Each arg In args If TypeOf arg Is Range Then 'range so we need to enumerate its .Areas For Each area In arg.Areas arr = area.Value 'for large ranges it is greatly quicker to load the data at once rather than enumerating each cell in turn For Each ele In arr 'enumerate the array addParts CStr(ele), uniqueParts 'Call our sub to parse the data Next ele Next area ElseIf VarType(arg) > vbArray Then 'an array has been passed in For Each ele In arg 'enumerate the array addParts CStr(ele), uniqueParts 'Call our sub to parse the data Next ele Else 'assume can be validly converted to a string. If it cannot then it will fail fast (as intended) addParts CStr(arg), uniqueParts 'Call our sub to parse the data End If Next arg 'process our results If uniqueParts.Count > 0 Then ReDim arr(0 To uniqueParts.Count - 1) For i = 1 To uniqueParts.Count arr(i - 1) = uniqueParts(i) Next i 'we now have an array of the unique parts, which we glue together using the Join function, and then return it Blah = Join(arr, ",") End If End Function 'Sub to parse the data. In this case the sub splits the string and adds the split elements to a collection, ignoring duplicates Private Sub addParts(partsString As String, ByRef outputC As Collection) 'ByRef is unecessary but I use it to document that outputC must be instantiated Dim part For Each part In Split(partsString, ",") On Error Resume Next 'existing same key will raise an error, so we skip it and just carry on outputC.Add part, part On Error GoTo 0 Next part End Sub