Страницы: 1 2 След.
RSS
И снова уникальные значения в массиве (vba)
 
Доброе утро!  
 
Подскажите пожалуйста, есть массив данных, одномерный a(2 to lastrow) (lastrow ~9000записей)  
Помогите кодом VBA для обработки его путем поиска уникальных значний и записи их в E:E листа. Написать в ячейки не значение в массиве, а порядковый номер записи массива.  
 
Надеюсь понятно объяснил. Не нашел готового кода на форуме, но интересно, уверен, у кого-нибудь есть он.  
 
P.S. ЕСли не затруднит, то с использованием коллекций/дикшенари/и т.д(и есть ли смысл в этом, при такой объеме данных). Комментариям в коде буду только рад.
 
Это все или еще что-нибудь нужно?
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
А что Вам даст ТОЛЬКО порядковый номер? Продуктивнее номер + значение.  
P.S. Почему не хотите создать НЕБОЛЬШОЙ пример? Повторюсь - Н Е Б О Л Ь Ш О Й.
 
Смысл есть - т.к. чтоб отобрать уникальные, без словаря придётся делать не один проход по 9000, а 9000.  
Или иначе говоря, не 9000 сравнений, а грубо 9000*9000 (ну можно конечно втрой цикл всё время сокращать... но не суть).  
Насчёт одномерного массива сомневаюсь...  
 
Давайте пример в файле (можно не 9000 строк, а 90, чтоб размер соблюсти).  
Ну и подробно пример того, что нужно получить - а то пока неоднозначно всё...
 
Хм... Если только номера, то, зная Uniq.Count...
 
Юрий М, понимаете, это же только частичка большого макроса будет. Поэтому мне нужно понять как работает, номера мне будет достаточно. Дальше я уже сам.  
 
nerv, это всё.  
 
Прикладываю пример.
 
Расширенным фильтром выделить уникальные в промежуточный столбец, с помощью ПОИСКПОЗ найти их порядковые номера. Не?
 
{quote}{login=Hugo}{date=26.06.2012 11:05}{thema=}{post} без словаря придётся делать не один проход по 9000, а 9000.{/post}{/quote}Игорь, почему?  
Sub qqq()  
Dim Uniq As New Collection, LastRow As Long, i As Long, a()  
LastRow = Cells(Rows.Count, 1).End(xlUp).Row  
a = Range(Cells(2, 1), Cells(LastRow, 1)).Value  
   For i = 1 To UBound(a, 1)  
       On Error Resume Next  
       Uniq.Add a(i, 1), CStr(a(i, 1))  
   Next  
MsgBox Uniq.Count  
End Sub
 
Казанский, не. все столбцы будут заняты. поэтому некуда формулы вводить, то что в A:A находится, этого в рабочем листе не будет - содержание массива.  
 
P.S. да и вообще решил отходить от формул. если что минимум надо делать, да не вопрос, а сложные вещи удобнее на vba писать, чтобы столбцы не занимать.
 
{quote}{login=petrov77}{date=26.06.2012 11:32}{thema=}{post}1)..все столбцы будут заняты....  
2)  ..то что в A:A находится, этого в рабочем листе не будет - содержание массива.{/post}{/quote}1). Если все столбцы заняты, то куда выводить №?  
2). А массив откуда берется?  
 
Почему № начинаются с "2"?
 
Михаил С.,  
1) Если все столбцы заняты, то куда выводить №? на данном примере можно в E:E. а так этот номер будет исопльзоваться для последующих вычислений.  
2) путем обработки данных из двух других таблиц  
 
3) мне так удобнее, чтобы, порядковый номер соответствовал строке в табличке.
 
Т.Е. массива, как такового, в реале нет, есть только виртуальный? Что тогда дадут номера на листе?
 
вот, завалялсь
Живи и дай жить..
 
Вот так попробуйте:  
 
Sub ert()  
Dim x, i&, s$  
x = Range("A1", Cells(Rows.Count, 1).End(xlUp)).Value  
On Error Resume Next  
With New Collection  
   For i = 2 To UBound(x)  
       s = x(i, 1)  
       If IsEmpty(.Item(s)) Then  
           x(i, 1) = i: .Add 1, s  
       Else  
           x(i, 1) = vbNullString  
       End If  
   Next i  
End With  
Range("E1").Resize(i - 1).Value = x  
End Sub  
 
PS С куками на форуме еще не скоро решится?
 
petrov77, моё сообщение видели?
 
Юрий М, да, как раз ковыряю.  
Просто не успеваю отвечать. работать и ковырять :) стараюсь, приоритетнее отвечать на вопросы. Извините.  
 
Михаил С., для визуального изучения работы. потом это все будет в своем массиве, что тоже будет обрабатываться.  
 
 
P.S. пошел смотреть все примеры. скоро отпишусь.
 
Вариант  
Sub qqq()  
   arr = [a1].CurrentRegion.Value
   With CreateObject("Scripting.Dictionary")  
       For i = 2 To UBound(arr)  
           If Not .exists(arr(i, 1)) Then  
               j = j + 1  
              .Item(arr(i, 1)) = j  
                    Cells(i, 1).Next.Next = j  
           End If  
       Next  
   End With  
End Sub
 
{quote}{login=Юрий М}{date=26.06.2012 11:28}{thema=Re: }{post}{quote}{login=Hugo}{date=26.06.2012 11:05}{thema=}{post} без словаря придётся делать не один проход по 9000, а 9000.{/post}{/quote}Игорь, почему?  
Sub qqq()  
Dim Uniq As New Collection, LastRow As Long, i As Long, a()  
...  
End Sub{/post}{/quote}  
зануда... :)
 
:-) Будешь тут занудой: RAN стащил патентованное имя макроса - qqq, Серж стащил www...
 
У меня tt тоже стащили...  
Или это я сперва у кого-то спёр? :)  
 
P.S. Если кто не понял про зануду - в данном случае что словарь, что коллекция - те же яйца... :)
 
зато осталось RRR  :) и звучит!
Живи и дай жить..
 
{quote}{login=слэн}{date=26.06.2012 02:43}{thema=}{post}зато осталось RRR  :) и звучит!{/post}{/quote}Ещё как звучит - устрашающе! :-)
 
{quote}{login=слэн}{date=26.06.2012 02:43}{thema=}{post}зато осталось RRR  :) и звучит!{/post}{/quote}  
Если до клавиши дотянусь - стащу обязательно! :)
 
Юрий М, подскажите по своему макросу.  
как я понимаю - a - диапазон ячеек с которыми будем работать.  
 
Не могу допетреть как написать, чтобы a ссылался на массив допустим b (2 to lastrow) либо на значение двух ячеек типа Range("A"&i).value & Range("B"&i).value. Данные для отбора уникальных в оригинале же в массиве лежат.  
 
Похоже коллекции для меня пока сложно. :-D
 
petrov77, есть два разных варианта - либо данные есть на листе, либо данные в виртуальном массиве.    
И, опять же вывод - на лист или достаточно в массив..
 
Михаил С., я как ученик учусь еще у вас всех. Пример который я пока разбираю - первый, от Юрия М. Так вот. Я почти разобрался в нем, и начал его модифицировать, чтобы до конца вникнуть в синтаксис и столкнулся с проблемой.  
Юрий берет диапазон с листа(переменная 'а') и с ним работает. Т.к. у меня будет виртуальный массив, я попытался подставить его вместо диапазона ячеек. у меня не получилось.  
Потом попробовал(чего я так же раньше не делал) подставить диапазон склеенных ячеек. т.е. типа такого, - Range("A2:A"&lastrow).Value & Range("E2:E"&lastrow).Value, что тоже не получилось.  
Как выбирать уникальные с диапазона на листе я понял, а из вирт.массива пока не могу понять.  
 
> И, опять же вывод - на лист или достаточно в массив..  
пока на лист, если выводить на лист, то в массив потом легко будет запихнуть.  
На лист потому, что пока разбираюсь, его дебажить проще, видно, что не так сразу.
 
Информация к размышлению  
Range("E2:E"&lastrow).Value - массив думерный.  
Range("A2:A"&lastrow).Value & Range("E2:E"&lastrow).Value - так массив создать нельзя.  
Можно так  
Range("A2:E"&lastrow).Value или два так  
arr1 = Range("A2:A"&lastrow).Value    
arr2 = Range("E2:E"&lastrow).Value
 
И кстати у Юрия "a" - это как раз уже виртуальный массив, а не диапазон листа.
 
Hugo,    
тогда я не понимаю  
ведь  
a = Range(Cells(2, 1), Cells(LastRow, 1)).Value  
будет по сути то же самое что и  
a = Range("A2:A"&lastrow).Value (извините, просто с литерацией, мне более наглядно понятно)  
ведь массив получается одномерный, как я понимаю.  
тогда почему тут "Uniq.Add a(i, 1), CStr(a(i, 1))" указывается a(i, 1), как будто он двумерный, почему нельзая просто a(i)?
 
1. После того, как взяли данные в массив (например a = Range(Cells(2, 1), Cells(LastRow, 1)).Value), они уже там, а не на листе. Лист/файл можно вообще закрыть и удалить - на данных это не отразится.  
2. Рекомендую в окне Locals посмотреть, как выглядят внутри массивы - думаю всё сразу будет понятнее.
Страницы: 1 2 След.
Читают тему
Наверх