Я хочу сделать словарь, добавить в него ключ и значение из одного файла и при совпадении выгрузить значения в другой. Как добавить к одному ключу несколько значений для последующей выгрузки при совпадении? Данный код нормально работает на одном ключе и одном значении. Решение в виде 10 словарей думаю в корне неверное.
Код
With Workbooks(WBName).Worksheets(WBList)
vVALs = .Range(.Cells(2, 1), .Cells(Rows.Count, 1).End(xlUp)).Value2
For v = LBound(vVALs, 1) To UBound(vVALs, 1)
dict.Item((vVALs(v, 1))) = vVALs(v, 1)
Next v
End With
Можно сделать элементом словаря какой-нибудь дополняемый объект, например, словарь, или коллекцию, или массив, который потом будете переопределять Redim Preserve.
МатросНаЗебре написал: элементом словаря какой-нибудь дополняемый объект
Серьезно? Так сложно? А нельзя просто item2, 3 и тд. до бесконечности и вытягивать? Реально получается правильный (не лучший, но рабочий) вариант делать 5 словарей для 5 значений?
Sub ddd()
Dim dic As New Dictionary
mas1 = Range("A1:D9").Value
mas2 = Range("G3:J8").Value
For i = 1 To UBound(mas1)
dic(mas1(i, 1)) = mas1(i, 2) & "|" & mas1(i, 3) & "|" & mas1(i, 4)
Next
For k = 1 To UBound(mas2)
If dic.exists(mas2(k, 1)) Then
For n = 2 To 4
mas2(k, n) = Split(dic(mas2(k, 1)), "|")(n-2)
Next
End If
Next
Range("G3:J8").Value = mas2
End Sub
Бахтиёр, Вот, спасибо, я так понимаю это мне подходит. Надо будет только в r1c1 перевести и нужные столбики загнать как в сбор так и выгрузку
doober, нет, к сожалению даже если Ваш совет правильный и лучший, то я не способен его осознать и перевести в код. Но когда я стану умнее, то я вернусь и применю его (надеюсь)
Что говорят тесты. Исследовал вопрос при написании своего аналога «СцепитьЕсли»
При большом количестве ключей, вариант от Бахтиёра (сцеплять в строку и потом делить строку) будет в разы (десятки и более раз) быстрее варианта с массивом в качестве значения. Причиной тому - неоправданно "тупой" ReDim Preserve, который при частом вызове жрёт всё время Я даже пробовал не пресервить каждый раз при добавлении нового элемента по ключу, а объявлять массив с запасом и "пресервить" только в конце по запомненному в отдельный словарь количеству элементов для каждого ключа — всё равно медленно Есть надежда на коллекции (как массив, размер которого не нужно контролировать), но пока не тестил
Можно попробовать массив словарей, но вряд ли будет быстрее одного словаря со сплитом (очень быстрая функция даже в цикле, хотя и её можно "ускорить", заменив на поиск InStr'ом) строки
А так можно (буквально на ровном месте) заметно ускорить вариант от Бахтиёра
Код
' замените этот блок
If dic.exists(mas2(k, 1)) Then
For n = 2 To 4
mas2(k, n) = Split(dic(mas2(k, 1)), "|")(n - 2)
Next
End If
' на этот
Dim x
'…
If dic.exists(mas2(k, 1)) Then
x = Split(dic(mas2(k, 1)), "|")
For n = 2 To 4
mas2(k, n) = x(n - 2)
Next
End If
' или тоже самое, но без цикла и в одну строку
If dic.exists(mas2(k, 1)) Then
x = Split(dic(mas2(k, 1)), "|")
mas2(k, 2) = x(0): mas2(k, 3) = x(1): mas2(k, 4) = x(2)
End If
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
приветствую! Готовы потетстить? Я вот сомневаюсь… Коллекции не тестил, но обёртка в виде класса всегда медленнее (возможно, незначительно) "чистого" кода, хоть и удобнее
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
New: Пример использования классов и коллекции можно взять из моего файла в этой теме
и какая связь между вашим подсчётом повторов и текущим сбором нескольких значений по одному ключу?
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, Алексей, см. файл. А теперь увеличь все данные на листе до 1млн строк и потестируй Dictionary и Коллекцию классов. Я не тестировал, но думаю, что коллекция классов выиграет по скорости, т.к. и ты и я знаем, как Dictionary начинает тормозить после 100К ключей
дык всё то же самое — я не понимаю, ЧТО ты хотел показать
1. Скорость наполнения и поиска ключей становится выше у КОЛЛЕКЦИИ в сравнеии с маасивом ТОЛЬКО ПОСЛЕ 100 тыс ключей (редко) Я это уже тестил и наглядно показал в сравнительных отчётах
2. Ты опять сравнил Словари, но не с Коллекцией, а с коллекцией классов Где тогда сравнение коллекции с коллекцией классов, чтобы было понятно, что классы лучше
3. Ты забыл самое главное Никакие СОТНИ ТЫСЯЧ значений никто и никогда не добавляет к ОДНОМУ КЛЮЧУ, поэтому зачем это всё, если объёмы изначально другие
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack Famous, С 1-м никто и не спорил. 2. Я же в сообщении 8 написал, что для решения задачи ТС можно использовать коллекцию классов, а не просто коллекцию. Так как в классе можно хранить сразу много полей (значений). А так же я написал, что если данных очень много. 3. Я предложил лишь ещё один вариант как можно решить задачу ТС. Когда в других темах на вопрос ТС дают вариант решения и макросом и формулой и PQ это считается нормальным. Коллекция классов универсальнее Dictionary, быстрее на больших объемах данных, чем Dictionary, но больше кода. Так же если макрос работает на Мак (компьютеров от Apple) там нет Dictionary. Там есть только Collection. Согласись, при определенных условиях преимущества у классов есть? Сейчас в этой теме есть 2 решения. Первое от Бахтиёр (с твоим замечанием по улучшению) и мой вариант с коллекцией классов
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄