Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.09.2010, 18:07   #1
Nicotinni
 
Регистрация: 07.09.2010
Сообщений: 5
По умолчанию Объединение одинаковых данных и подсчет их(в огромных таблицах)

Как сделать так, чтобы одинаковые данные он объединял, и показывал сколько этих объединений было сделано. например, библиотечный список книг, в нем много авторов и у каждого автора свои книги. сортировку по авторам сделали, сортировку по названиям книг сделали, получилось очень много одинаковых книг. как сделать так, чтобы он обединял эти книги и показывал, сколько их было обединено. вручную делать невозможно. слишком много книг. таблица самая маленькая-4тыс наименований. а в среднем около 120 тыс.
Вот это есть:
!Авторы ! Заголовок !
!автор1 ! заголовок(АА) !
!автор1 ! заголовок(АА) !
!автор1 ! заголовок(ББ) !
!автор1 ! заголовок(ББ) !
!автор2 ! заголовок(жж) !
!автор2 ! заголовок(ээ) !
!автор3 ! заголовок(хх) !
!автор3 ! заголовок(хх) !

Нужно чтобы выглядела вот так:

!Авторы ! Заголовок !количество\шт!
!автор1 ! заголовок(АА) ! 2 !
! ! ! !
!автор1 ! заголовок(ББ) ! 2 !
! ! ! !
!автор2 ! заголовок(жж) ! 1 !
!автор2 ! заголовок(ээ) ! 1 !
!автор3 ! заголовок(хх) ! 2 !
! ! ! !
Nicotinni вне форума Ответить с цитированием
Старый 07.09.2010, 18:30   #2
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Таблицы в 120 тыс. в Экселе?
Сделать несложно, на массиве и Dictionary будет даже очень быстро.
webmoney: E265281470651 Z422237915069 R418926282008
Hugo121 вне форума Ответить с цитированием
Старый 07.09.2010, 22:00   #3
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

Массивы и немного коллекции...
Вложения
Тип файла: zip Книга3 библиотека.zip (78.9 Кб, 56 просмотров)
nilem вне форума Ответить с цитированием
Старый 07.09.2010, 22:06   #4
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Хотел сказать - вот заглянет Николай и сделает. Но воздержался...
Если эти 120 тыс. в текстовом файле лежат (и в старый Эксель не лезут), можно прямо его в массив тянуть, а при выгрузке смотреть - помещается результат на лист или нет. Если нет - выгружать на два.
А я тут после работы в лес по грибы заехал - белых как никогда.... Так что для макроса времени не было
Но обдумал - я бы наверное в словарь грузил и параллельно в другой массив, а номер записи брал из словаря, чтоб суммы подбивать существующим.


P.S. Вот кстати и сделал для параллельной темы - результат с кодом Николая одинаков, можно даже этот код из того файла запускать - только что выгружает правее на одну позицию. Вот на время бы сравнить - сравнил. Я выиграл - 5-10%

Код:
Option Explicit

Sub UniqCount()
    Dim i As Long, ind As Long
    Dim d As Scripting.Dictionary
    Dim arr1, arr2, rng As Range
    
    Set d = New Dictionary

    Set rng = Range("A2:C" & Cells(Rows.Count, 1).End(xlUp).Row)
    arr1 = rng.Value
    ReDim arr2(1 To UBound(arr1), 1 To 3)

    For i = 1 To UBound(arr1, 1)
        If d.Exists(UCase(CStr(arr1(i, 1) & arr1(i, 2)))) Then
            arr2(d.Item(UCase(CStr(arr1(i, 1) & arr1(i, 2)))), 3) = arr2(d.Item(UCase(CStr(arr1(i, 1) & arr1(i, 2)))), 3) + 1
        Else
            ind = ind + 1
            d.Add UCase(CStr(arr1(i, 1) & arr1(i, 2))), ind
            arr2(ind, 1) = arr1(i, 1)
            arr2(ind, 2) = arr1(i, 2)
            arr2(ind, 3) = arr2(ind, 3) + 1

        End If
    Next i

    rng.Offset(, 4) = arr2

End Sub
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 08.09.2010 в 00:58.
Hugo121 вне форума Ответить с цитированием
Старый 08.09.2010, 07:43   #5
SAS888
Старожил
 
Аватар для SAS888
 
Регистрация: 05.12.2007
Сообщений: 4,180
По умолчанию

Ну, если речь пошла о времени выполнения, то предложу и свой вариант. Он мало отличается от варианта nilem, но, чуть быстрее. Посмотрите вложение в котором более 60 000 строк и в котором объединены все 3 варианта с измерением времени выполнения. Для корректной оценки, попробуйте каждый вариант запустить по несколько раз.

P.S. Необходимо заметить, что в варианте Hugo121 отсутствует сортировка. В принципе, для решения задачи таким способом она и не нужна, но если это нужно автору вопроса, то время выполнения процедуры увеличится.
Вложения
Тип файла: rar Test.rar (446.9 Кб, 57 просмотров)
Чем шире угол зрения, тем он тупее.

Последний раз редактировалось SAS888; 08.09.2010 в 07:54.
SAS888 вне форума Ответить с цитированием
Старый 08.09.2010, 09:34   #6
nilem
Форумчанин
 
Регистрация: 25.04.2010
Сообщений: 616
По умолчанию

SAS888, да, Ваш код быстрее (и выглядит проще). Т.е. заполнять новый массив быстрее, чем перезаписывать существующий? - по сравнению со своим вариантом основное отличие увидел только в этом (доп. функции вроде бы не должны тормозить).
Чтобы уж не экспериментировать, расскажите в чем преимущества Вашего подхода.
nilem вне форума Ответить с цитированием
Старый 08.09.2010, 09:36   #7
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Хорошо, погоняемся. Я свой код чуть подкрутил, добавил пару переменных:
Код:
Sub UniqCount()
    iTimer! = Timer
    Dim i As Long, ind As Long
    Dim d As Scripting.Dictionary
    Dim arr1, arr2, rng As Range, x As Long, temp As String
    Set d = New Dictionary
    Set rng = Range("A2:C" & Cells(Rows.Count, 1).End(xlUp).Row)
    arr1 = rng.Value
    ReDim arr2(1 To UBound(arr1), 1 To 3)
    x = UBound(arr1, 1)
    For i = 1 To x 'UBound(arr1, 1)
    temp = UCase(CStr(arr1(i, 1) & arr1(i, 2)))
        If d.Exists(temp) Then
            arr2(d.Item(temp), 3) = arr2(d.Item(temp), 3) + 1
        Else
            ind = ind + 1
            d.Add temp, ind
            arr2(ind, 1) = arr1(i, 1)
            arr2(ind, 2) = arr1(i, 2)
            arr2(ind, 3) = 1 'arr2(ind, 3) + 1
        End If
    Next i
    rng.Offset(, 7) = arr2
    MsgBox "Время выполнения макроса составило " & Timer - iTimer! & " сек.", vbExclamation, ""
End Sub
Результат = мой 0,40, ваши оба по 0,65 в среднем...
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 08.09.2010 в 10:00.
Hugo121 вне форума Ответить с цитированием
Старый 08.09.2010, 10:22   #8
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Цитата:
Сообщение от Hugo121 Посмотреть сообщение
Хорошо, погоняемся.
Моя лошадка пробегает дистанцию за 1 секунду,но привозит совершенно другой результат
Анализ,обработка данных Недорого

Последний раз редактировалось doober; 08.09.2010 в 10:27.
doober вне форума Ответить с цитированием
Старый 08.09.2010, 10:25   #9
Hugo121
Старожил
 
Регистрация: 11.05.2010
Сообщений: 5,166
По умолчанию

Ну так - яж ещё дополнительно UCase подключил
А в коллекциях похоже по регистру данные не отличить?
В моём варианте можно легко переключение организовать, по чекбоксу например.
И кстати без UCase() моя лошадка за 0,37 пробегает
webmoney: E265281470651 Z422237915069 R418926282008

Последний раз редактировалось Hugo121; 08.09.2010 в 10:33.
Hugo121 вне форума Ответить с цитированием
Старый 08.09.2010, 10:30   #10
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Hugo121 На время выполнения вашего варианта не влияет предварительная сортировка
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Объединение 2-х одинаковых баз данных AlexeiDelejov БД в Delphi 6 24.06.2010 17:55
Поиск данных в нескольких таблицах a_n_n_a БД в Delphi 10 23.04.2010 11:33
Подсчет числа одинаковых слов в нескольких категориях. Hagen83 Microsoft Office Excel 2 13.03.2010 09:45
Найти совпадения данных в 2ух таблицах.?? fifty50 Microsoft Office Excel 14 24.02.2010 17:46
Величина изменения данных текущей даты от предыдущей в сводных таблицах. Strelec79 Microsoft Office Excel 0 05.08.2009 19:20