Не получается доработать код макроса под себя, может кто-то из опытных поможет в этом деле!?))
Исходная задача такова: На входе уже есть массив данных из которого надо выбрать уникальные значения.
В процессе, нашел на просторах инета нужный код, но (для меня) проблема в том, что нужная функция принимает в параметре переменную-диапазон, а мне надо передавать i-й элемент массива. Вот сам код макросса:
Код
'Массив FirstArr() определяется выше по коду и содержит 100 элементов
Sub UnikArr()
Dim MyData As Range: Set MyData = Range([A1], Range("A" & Rows.Count).End(xlUp))
Dim ArrRng() As Variant
ArrRng = UniqueValuesFromArray(MyData.Value, 1) 'Тут нужен цикл For и вместо MyData.Value, 1 подставить FirstArr(0, i)
Range("B1").Resize(UBound(ArrRng)).Value = ArrRng
End Sub
Function UniqueValuesFromArray(ByVal ArrTmp, ByVal col As Long) As Variant
Dim i As Long
If Not IsArray(ArrTmp) Then MsgBox "Это не массив!", vbCritical: Exit Function
If col > UBound(ArrTmp, 2) Then MsgBox "Нет такого столбца в массиве!", vbCritical: Exit Function
If col < LBound(ArrTmp, 2) Then MsgBox "Нет такого столбца в массиве!", vbCritical: Exit Function
On Error Resume Next: Dim coll As New Collection, txt$
For i = LBound(ArrTmp) To UBound(ArrTmp)
txt$ = Trim(ArrTmp(i, col)): coll.Add txt$, txt$
Next i
ReDim MyArr(1 To coll.Count, 1 To 1)
For i = 1 To coll.Count: MyArr(i, 1) = coll(i): Next i
UniqueValuesFromArray = MyArr
End Function
2.3. Приложите файл(ы) с примером (общим весом не более 100 Кб) в реальной структуре и форматах данных того, что есть сейчас и того, что хотелось бы на выходе.
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori
Sub UnikArr()
Dim MyData As Range
Dim ArrRng As Variant
Set MyData = Range([A1], Range("A" & Rows.Count).End(xlUp))
With Sheets.Add
With .Range("A1").Resize(MyData.Count)
.Value = MyData.Value
.RemoveDuplicates Array(1)
End With
ArrRng = .Range("A1").CurrentRegion
Application.DisplayAlerts = False
.Delete
Application.DisplayAlerts = True
End With
Range("B1").Resize(UBound(ArrRng)).Value = ArrRng
End Sub
Sub start()
Dim arr
arr = Selection
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
Dim el
For Each el In arr
If Not dic.exists(el) Then dic.Add el, el
Next
arr = dic.keys()
End Sub
Правильно ли я понимаю, что: CreateObject("Scripting.Dictionary") используется только для подключения метода .exists - который удаляет дубли? У массивов такого метода нет? Верно?
Коллекция просто не позволит добавить в себя уже существующий элемент - это вызвало бы ошибку. Но строка On Error Resume Nextприходит на помощь: разрешает продолжить выполнение программы )
Есть строка - нет разницы, чем её обрабатывать )) А с коллекцией есть один немаловажный момент: раньше я всегда перебирал элементы готовой коллекции обычным циклом For-Next. Заметил, что при большом количестве данных скорость катастрофически падает с каждым элементом. По совету ZVI стал использовать For Each-Next - тормоза пропали!
По поводу словарей. Это, можно сказать, основной мой инструмент в работе. Чуть ли не каждый второй мой макрос для заказчиков использует именно словари/многократно вложенные словари (привычка из Python). Для меня словари намного легче громоздких отвлекающих конструкций с "редим презервами". Словари тем более удобны, что методы keys() и items() дают на выходе одномерные массивы, которые потом очень легко выводить в диапазоны. С помощью вложенных словарей очень просто реализуется программируемая сводная таблица. Коллекции - другая опера. По возможности стараюсь использовать как можно реже (хотя иногда и лень). Для некоторых целей не совсем подходит. Только write-once/read-only (название - мое изобретение) чего стоит (в словарях можно менять уже внесенные значения, хотя для вложенных словарей нужно добавлять дополнительную переменную). Это свойство коллекций очень ограничивает.
До сих пор, словари меня не подводили. Надеюсь и не будут.
Да, словари (объект Scripting.Dictionary из WSH) - это, по идее, обязательная тема изучения, для тех, кому требуется массовая обработка данных. Простые коллекции VBA всё же менее функциональны, а для многих задач функционал запросов (сводные/Power*/sql) излишний.
Вопрос, конечно уже выходит за рамки этой темы, но все же (не могу нагуглить) - каково исходное назначение словарей и коллекций? Ведь не зря они существуют как самостоятельные инструменты, и с разными "свойствами", методами....