从一个范围内的单元格中读取所有的唯一值,并从它们中创build一个逗号分隔的string?
我已经写了下面的函数来读取范围内单元格的所有唯一值,并从它们中创build一个逗号分隔的string? 有没有更好,更简单的方法来做到这一点?
Private Sub CsvUniqueValues(r As Excel.Range) Dim c As Excel.Range Dim s As String = "" For Each c In r.Cells If ExcelApp.WorksheetFunction.CountIf(r, c.Value) = 1 Then s = s & "," End If Next If s.Length > 0 Then s = s.Substring(0, s.Length - 1) End If End Sub
您可以使用LINQ来获取唯一值的列表,如下所示:
Dim uniqueValues As IEnumerable = r.Cells.Where(Function(x) ExcelApp.WorksheetFunction.CountIf(r, x.Value) = 1))
然后,您可以使用LINQ将所有这些唯一值转换为string:
Dim uniqueStrings As IEnumerable(Of String) = uniqueValues.Select(Of String)(Function(x) x.ToString())
然后,您可以使用LINQ将结果列表转换为数组:
Dim uniqueArray() As String = uniqueStrings.ToArray()
然后,您可以使用String.Join
方法将它们合并为一个CSVstring:
Dim csv As String = String.Join(",", uniqueArray)
当然,你可以用一个命令来完成所有这些工作,例如:
Dim csv As String = String.Join(",", r.Cells.Where(Function(x) ExcelApp.WorksheetFunction.CountIf(r, x.Value) = 1)) .Select(Of String)(Function(x) x.ToString()) .ToArray())
但问题是,你是否会称之为“更容易”。 LINQ是有用的,因为它使得代码更易于读写,但是当它太过于可读时,可读性就会变差,从而导致使用它的目的。 至less,为了使你的代码更加清晰,我将把第一部分移动到一个命名的函数中,以便更自我logging:
Public Function GetUniqueCellValuesAsString(r As Excel.Range) As IEnumerable(Of String) Return r.Cells.Where( Function(x) ExcelApp.WorksheetFunction.CountIf(r, x.Value) = 1)) .Select(Of String)(Function(x) x.ToString()) End Function
那么你可以像这样构buildCSVstring:
Dim csv As String = String.Join(",", GetUniqueCellValuesAsString(r).ToArray())
我会利用collection
对象。 由于集合只能包含唯一值,因此尝试将所有input数据添加到集合将导致一组唯一值。 以下修改让CsvUniqueValues
从任何给定范围的值中返回逗号分隔的string。
'Test function and return result in MsgBox Sub ReturnUnique() MsgBox CsvUniqueValues(Selection) End Sub 'Function will return csv-string from input range Function CsvUniqueValues(r As Range) As String Dim Cell As Range Dim i As Integer Dim DistCol As New Collection Dim s As String 'Add all distinct values to collection On Error Resume Next For Each Cell In r DistCol.Add Cell.Value, Cell.Value Next Cell On Error GoTo 0 'Write collection to comma seperated list For i = 1 To DistCol.Count s = s & DistCol.Item(i) & "; " Next i s = Left(s, Len(s) - 2) CsvUniqueValues = s End Function