Отличительные или уникальные значения из CSV с использованием VBA - PullRequest
0 голосов
/ 24 октября 2018

Сегодня меня спросил один из друзей, который использует макросы и электронные таблицы Excel, есть ли способ преобразовать целочисленную строку csv в csv с разными значениями.Будучи из современной эры linq и fancy huha, я думал, что это будет прямо вперед, но я потратил хороший час, чтобы найти свое собственное решение после того, как Google и ТАК не появились.Я хотел бы знать, есть ли лучшее решение для этого.Вот входные данные: «1,45,2,4,5,2,3,5» Ожидаемый результат: «1,45,2,4,5,3»

Я выложу свое решениескоро, но я надеюсь услышать лучшее решение SO.

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Я бы использовал словарь как быстрый и простой способ сделать это.Добавьте значения в словарь, используя синтаксис перезаписи для обработки дубликатов.Затем используйте .Keys для генерации массива, который можно вернуть в виде строки, используя Join с разделителем ",".

Option Explicit
Public Sub Test()
    Dim inputValue As String, outputValue As String, arr() As String, i As Long, dict As Object
    inputValue = "1,45,2,4,5,2,3,5"
    arr = Split(inputValue, ",")
    Set dict = CreateObject("Scripting.Dictionary")
    For i = LBound(arr) To UBound(arr)
        dict(arr(i)) = vbNullString
    Next
    outputValue = Join(dict.keys, ",")
    Debug.Print outputValue
End Sub
0 голосов
/ 24 октября 2018

Это было решение, которое я придумал

Function GetUnique(notUnique As String) As String

    ar = Split(notUnique, ",")
    Dim result As String
    Dim retVal As New Collection

    For Each a In ar
     If HasKey(retVal, a) Then
      ' do nothomg
     Else
      retVal.Add a, a
     End If
    Next
    result = ""
    For Each r In retVal
     result = result + r + ","
    Next

    GetUnique = Mid(result, 1, Len(result) - 1)

End Function

Function HasKey(coll As Collection, strKey) As Boolean
    Dim var As Variant
    On Error Resume Next
    var = coll(strKey)
    HasKey = (Err.Number = 0)
    Err.Clear
End Function
0 голосов
/ 24 октября 2018

Вы можете использовать это как основу для того, что вы хотите сделать - есть некоторые шаги, чтобы помочь продемонстрировать то, что я сказал в своем комментарии - возможно, вместо того, чтобы создать коллекцию и затем преобразовать ее в массив, который объединен в msgboxВы могли бы написать это в ячейку - или сделать все, что вы хотите с ним вниз по течению.Это уменьшит потребность в функции collectionToArray.

В качестве альтернативы вы можете сделать это с массивами, но я считаю, что коллекции будут более аккуратными.

Public Sub GetDistinctCommaSeparated()

Dim values As String
Dim valuesArr() As String
Dim DistinctCol As New Collection

' Get an array from the comma separated field
values = Range("A1").Value
valuesArr = Split(values, ",")

' get a distinct collection
Set DistinctCol = MakeCommaArrayDistinct(valuesArr)

' convert to array - and join (demonstration purposes)
MsgBox Join(CollectionToArray(DistinctCol), ",")


End Sub

Private Function MakeCommaArrayDistinct(valuesArr() As String) As Collection

Dim output As New Collection

 ' Loop through your array and push items to a secondary collection only if they are not already there
 For Each x In valuesArr
        If IsInCollection(CStr(x), output) <> True Then
          output.Add CStr(x)
        End If
    Next x

Set MakeCommaArrayDistinct = output

End Function

' Checks if the current item exists within the collection
Public Function IsInCollection(stringToBeFound As String, col As Collection) As Boolean

    Dim x As Variant

    ' Empty Collection
    If col.Count = 0 Then
        IsInCollection = False
        Exit Function
    End If

    ' Loop and Check
    For Each x In col
        If CStr(x) = stringToBeFound Then
            IsInCollection = True
            Exit Function
        End If
    Next x

End Function

' Used to convert the collection to an array to easily display in the msgbox - Demonstration only
Public Function CollectionToArray(myCol As Collection) As Variant

    Dim result  As Variant
    Dim cnt     As Long

    ReDim result(myCol.Count - 1)

    For cnt = 0 To myCol.Count - 1
        result(cnt) = myCol(cnt + 1)
    Next cnt

    CollectionToArray = result

End Function

output;

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...