Страницы: 1 2 След.
RSS
Перенос данных с одной таблицы в другую с суммированием (макрос)
 
Здравствуйте.  
Вопрос видимо простой, но решения не знаю.  
Есть две таблицы. Надо перенести данные с исходной в конечную (см. вложение), при этом просуммировав данные по второму столбцу в случае нескольких одинаковых данных в первом.  
Короче, с помощью формул все легко  
 
=СУММЕСЛИ($B$20:$B$31;I20;$C$20:$C$31)  
 
А как с помощью макроса - не заю.  
Пример с формулами и недоделанным макросом во вложении.  
Заранее спасибо.
 
Макрос тут:  
 
http://www.planetaexcel.ru/forum.php?thread_id=26105
 
Используйте коллекцию или словарь.  
 
Алгоритм (приблизительно) следующий (на примере коллекции):  
Цикл по таблице с добавлением элементов в коллекцию.  
With New collection  
.add 1,064, cstr(1)  
End with  
Если элемент уже есть в коллекции, сложить значение с уже имеющимся в коллекции.  
По окончанию обхода таблицы, выгрузить все это дело на лист.
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
{quote}{login=Hugo}{date=31.08.2011 01:41}{thema=}{post}Макрос тут:  
 
http://www.planetaexcel.ru/forum.php?thread_id=26105{/post}{/quote}  
Видать плохо искал я.  
Большое спасибо Всем за подсказку!
 
Тот код примерно так и делает, плюс накрутки на универсальность и проверки данных.  
Но есть один момент - если данных много, то может глючить выгрузка из словаря/коллекции с использованием Transpose.  
Тогда или нужно выгружать циклом, или сперва перекладывать в массив.  
Я сделал иначе - сразу собираем данные в массив, заодно там можно и ещё что-нибудь держать - вот тут например вариации этого кода:    
http://www.programmersforum.ru/showthread.php?t=164454
 
{quote}{login=Hugo}{date=31.08.2011 01:57}{thema=}{post}Тот код примерно так и делает, плюс накрутки на универсальность и проверки данных.  
Но есть один момент - если данных много, то может глючить выгрузка из словаря/коллекции с использованием Transpose.  
Тогда или нужно выгружать циклом, или сперва перекладывать в массив.  
Я сделал иначе - сразу собираем данные в массив, заодно там можно и ещё что-нибудь держать - вот тут например вариации этого кода:    
http://www.programmersforum.ru/showthread.php?t=164454{/post}{/quote}  
Спасибо, буду изучать.
 
{quote}{login=Hugo}{date=31.08.2011 01:41}{thema=}{post}Макрос тут:  
 
http://www.planetaexcel.ru/forum.php?thread_id=26105{/post}{/quote}  
Hogo, смотрю на макрос с http://www.planetaexcel.ru/forum.php?thread_id=26105 как баран на новые ворота.  ;(  
С массивами еще не общался совсем, к сожалению.  
Прилепил к своему примеру, работает.  
Уточню задачу:  
- реальные таблицы до несколько тысяч строк.  
- первый столбец конечной таблицы нельзя менять.  
- проверяется весь первый столбец исходной таблицы на наличие каждого пункта первого столбца в исходной.  
- макросом формируется только второй столбец конечной таблицы (как в моем макросе, но с суммированием).  
Помогите, пожалуйста, а то "приперло". :)
 
Но ведь прилепили правильно :)  
Только строка Columns(9).NumberFormat = "@" тут лишняя - это было думано для данных типа "000123"  
Ну а под Вашу задачу этот код нужно на части разобрать и собрать наоборот :)  
Т.е. сперва набираем в словарь исходные фамилии второй таблицы, потом по словарю сверяем первую таблицу и суммируем.  
Отсутствующие судя по всему не учитываем.  
Но мне сейчас некогда...
 
Хотя нет, лучше другой алгоритм, я сегодня на работе с утра такой реализовал на основе того кода:  
 
а) если данных во второй таблице в пределе тысячи штук -  
1. в начале отбираем в словарь и массив суммы по уникальным первой таблицы.  
2. потом проходим циклом for each по диапазону второй таблицы и извлекаем из словаря-массива суммы к текущему значению, помещаем в таблицу через оффсет.  
Небыстро, ибо работа с ячейками.  
 
б) если данных намного больше, то вероятно можно так - =  
1. -//-  
2. берём вторую таблицу в массив, создаём параллельный такой же массив  
3. потом проходим циклом по массиву из второй таблицы и извлекаем из словаря-массива суммы к текущему значению, помещаем в параллельный (новый) массив.  
4. выгружаем этот новый массив рядом во вторую таблицу.  
Быстро.
 
Знающие люди, помогите...  
Пожалуйста...
 
{quote}{login=Hugo}{date=31.08.2011 08:07}{thema=}{post}Хотя нет, лучше другой алгоритм, я сегодня на работе с утра такой реализовал на основе того кода:  
 
а) если данных во второй таблице в пределе тысячи штук -  
1. в начале отбираем в словарь и массив суммы по уникальным первой таблицы.  
2. потом проходим циклом for each по диапазону второй таблицы и извлекаем из словаря-массива суммы к текущему значению, помещаем в таблицу через оффсет.  
Небыстро, ибо работа с ячейками.  
 
б) если данных намного больше, то вероятно можно так - =  
1. -//-  
2. берём вторую таблицу в массив, создаём параллельный такой же массив  
3. потом проходим циклом по массиву из второй таблицы и извлекаем из словаря-массива суммы к текущему значению, помещаем в параллельный (новый) массив.  
4. выгружаем этот новый массив рядом во вторую таблицу.  
Быстро.{/post}{/quote}  
Спасибо, что откликнулись.  
Посты загрузились одновременно )  
Но масивы пока мне не под силу самому сотворить...  ;(
 
Я через час-полтора только до своего компа доберусь, может тогда сделаю, если раньше вариантов не будет.
 
{quote}{login=Hugo}{date=31.08.2011 08:14}{thema=}{post}Я через час-полтора только до своего компа доберусь, может тогда сделаю, если раньше вариантов не будет.{/post}{/quote}  
Спасибо, буду ждать.  )))
 
попробуйте так
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
совсем забыл, вариант Hugo значительно быстрее : )
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
диапазоны можно заменить на что-то вроде Usedrange.Columns(1).Cells - 1-ый столбец
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Спасибо, счас буду изучать.
 
Пока Игорь не доехал :-)
 
Ну вот, уже мне писать и не нужно.  
На массивах конечно быстрее, но кода больше, и чуть сложнее.  
А на пару тысяч строк и как у nerv нормально, напрягать не будет.  
Я тут подумал - можно для результата не создавать пустой массив, а брать массив с листа, уже с значениями, и или плюсовать к тому, что уже есть, или дополнять пустые ячейки. Можно брать сразу пару колонок - с фамилиями и суммами, и потом выгрузить оба столбца назад - так будет на один массив меньше.  
P.S. Юрий, я уже доехал - сейчас твой вариант полюбопытствую :)
 
{quote}{login=Юрий М}{date=31.08.2011 09:24}{thema=}{post}Пока Игорь не доехал :-){/post}{/quote}  
Спасибо, Юрий М.  
В посте выше post_255119.xls задачу немного уточнил.  
Все равно, спасибо, буду переваривать Ваши примеры.
 
Юрий М, ключевую часть кода по добавлению в коллекцию с сортировкой можно записать так  
 
For i = 1 To .Count  
                   If s < .Item(i) Then  
                       .Add s, s, Before:=i: Exit For  
                   End If  
               Next  
               .Add s, s  
 
 
вместо  
 
For i = 1 To .Count  
                       If s < .Item(i) Then Exit For  
                   Next  
                   If i > .Count Then .Add s, s Else .Add s, s, Before:=i  
 
если я не ошибаюсь...
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Кто посмел корректировать ZVI?
 
^_^ it's me ... Повторюсь, я могу ошибаться. Но, как мне кажется, не в этот раз : )
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
ну что бы старттопику было что выбрать, и мой вариант :)с сортировкой
Спасибо
 
{quote}{login=nerv}{date=31.08.2011 09:54}{thema=}{post}^_^ it's me ... Повторюсь, я могу ошибаться. Но, как мне кажется, не в этот раз : ){/post}{/quote}Александр, все-таки в это раз - да :-)  
В Вашем варианте элемент, для которого s < .Item(i), добавится дважды: один раз внутри For-Next цикла, и еще раз - после. Ну, и не понятна цель изменения.  
 
> Кто посмел корректировать ZVI?  
 
Юрий, спасибо, но я тоже люблю ошибаться, к сожалению, в этот раз не получилось :-)  
По поводу одного важного нюанса работы с коллекцией, пожалуй, найду исходную тему с NoDups и там кое-что расскажу.
 
Всем доброго времени суток : )  
 
>>По поводу одного важного нюанса работы с коллекцией, пожалуй, найду исходную тему с NoDups и там кое-что расскажу.  
Может быть эта? http://www.planetaexcel.ru/forum.php?thread_id=12736  
 
>>В Вашем варианте элемент, для которого s < .Item(i), добавится дважды:  
На первый взгляд, так оно и есть. Но, если рассматривать данный кусок в рамках контекста всей функции/процедуры, то:  
 
on error resume next  
For i = 1 To .Count  
If s < .Item(i) Then.Add s, s, Before:=i: Exit For ' Допустим, в этой строке добавили элемент в коллекцию.  
Next  
.Add s, s ' Следовательно, здесь будет ошибка. И этот же элемент повторно добавлен не будет.  
 
>>Ну, и не понятна цель изменения.  
Меньше на одно условие (на больше на одну ошибку ^_^). Сл-но, код выполняется быстрее. Ну и меньше букаф, если на то пошло : )  
 
=24742=
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Всем, здраствуйте.  
Ребят!  
Не дам дупля.  
Вариант от nerv прилепил, работает, но проблема с объявлением диапазона  
For Each x In [B3:B15]
диапазон мне надо типа такого  
For Each x In Range(Cells(6,i),Cells(2000,i))  
но что-то не получается  ;(  
И ещё, обратите внимание на мой пост от 31.08.2011, 17:20, мне не нужна ни какая сортировка и первую колонку в конечной таблице (список клиентов) трогать нельзя ни в коем случае.  
Помогите, кто чем может...     )
 
Vovan RU, а вот если бы Вы обратили внимание на то, что я пытался донести до вас в сообщениях выше то:  
 
вместо [B3:B15] - Usedrange.Columns(2).Cells
вместо [I3:I15] - Usedrange.Columns(9).Cells
 
=50011=
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
{quote}{login=nerv}{date=01.09.2011 10:19}{thema=}{post}Vovan RU, а вот если бы Вы обратили внимание на то, что я пытался донести до вас в сообщениях выше то:  
 
вместо [B3:B15] - Usedrange.Columns(2).Cells
вместо [I3:I15] - Usedrange.Columns(9).Cells
 
=50011={/post}{/quote}  
Да нет, пробовал.  
Конкретно ставлю  
UsedRange.Columns(102).Cells  
и не фуричит   ;(
 
кидайте файл мне на почту
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
Страницы: 1 2 След.
Читают тему (гостей: 1)
Наверх