从范围中的单元格中读取所有唯一值并从中创建逗号分隔的字符串?

时间:2015-03-12 13:15:46

标签: vb.net excel

我编写了以下函数来读取范围中单元格的所有唯一值,并从中创建逗号分隔的字符串?是否有更好,更简单的方法来做到这一点?

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

2 个答案:

答案 0 :(得分:1)

您可以使用LINQ获取仅包含唯一值的列表,如下所示:

Dim uniqueValues As IEnumerable = r.Cells.Where(Function(x) ExcelApp.WorksheetFunction.CountIf(r, x.Value) = 1))

然后,您可以使用LINQ将所有这些唯一值转换为字符串:

Dim uniqueStrings As IEnumerable(Of String) = uniqueValues.Select(Of String)(Function(x) x.ToString())

然后,您可以使用LINQ将结果列表转换为数组:

Dim uniqueArray() As String = uniqueStrings.ToArray()

然后,您可以使用String.Join方法将它们合并为一个CSV字符串:

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非常有用,因为它使代码更易于读写,但是当它占用太多时,它的可读性就会降低,从而无法使用它。至少,为了使你的代码更清晰,我会将第一部分移动到一个命名函数中,因此它更自我记录:

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

然后您可以像这样构建CSV字符串:

Dim csv As String = String.Join(",", GetUniqueCellValuesAsString(r).ToArray())

答案 1 :(得分:1)

我会使用collection对象。由于集合只能包含唯一值,因此尝试将所有输入数据添加到集合中将导致一组唯一值。以下修改允许CsvUniqueValues从任何给定范围内的值返回逗号分隔的字符串。

'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