Страницы: Пред. 1 2 3 След.
RSS
Скрыть строку при равенстве значений в двух столбцах
 
почему макрос нормально отрабативает если его записать в рабочую книгу, а если запускать макрос с PERSONAL.xlsb, то ошибка Subscript out of range (Error 9)
 
sergey2303,на сколько я понимаю, при способе:
Код
Set oSht1 = .Sheets(1): Set oSht2 = .Sheets(2)
Эксель нумерует листы по порядку, а не по имени. То есть первым выступает Ваш на 380.
Может лучше ...Sheets("Лист1") ?

Кстати, Выше об этом уже было написано.  :sceptic:
Изменено: AlexTM - 08.09.2015 10:09:17
 
Цитата
sergey2303 написал:
А если сравнить и закрасить по времени будет одинаково по сравнении с сравнить и скрить
Быстрее будет создать новый лист с отобранными строками (если там не очень много столбцов занято, что так и есть судя по примеру, но много строк нужно скрывать или красить).
Зачем вообще это всё? И скажете наконец сколько всего строк?
 
Так все же с какого листа (Название) отбираются данные для дальнейшего скрытия строк ?
Set oSht2 = .Sheets(2) - такое обращение к листу имеет один минус. .Sheets(2) - VBA понимает как лист второй по порядку. Если лист переместить, то и порядок листов изменится, в итоге процедура (функция) может выполнить действия с данными другого листа и/или выдать ошибку.
 
Цитата
sergey2303 написал: с PERSONAL.xlsb, то ошибка Subscript out of range (Error 9)
В процедуре есть обращение к книге   With ThisWorkbook - что означает работаем с этой книгой.
В PERSONAL.xlsb нет листов к которым обращается процедура при обработке данных.
Если хотите в PERSONAL.xlsb разместить процедуру нужно изменить обращение на With ActiveWorkbook - что означает работаем с активной книгой.
А также побеспокоиться о том как указать процедуре активную книгу с которой нужно работать.
 
TSN, отбираются данные для дальнейшего скрытия строк с листа с именем Лист1, Дание скриваются на листе 380*
 
Значит в моей процедуре нужно изменить строку
Код
Set oSht1 = .Sheets("Лист1"): Set oSht2 = .Sheets("Лист2")
Я не комментировал код. Согласно логики процедуры сначала собираем данные для дальнейшего скрытия с "листа2", потом работаем и скрываем на "Листе1".
В вашем случае, если правильно понял замените часть кода на
Код
Set oSht2 = .Sheets("Лист1")                                ''' c этого листа отбираем данные для дальнейшего скрытия
For Each vl In .Worksheets
   If vl.Name Like "380*" Then Set oSht1 = .Sheets(vl.Name) ''' листом  на котором нужно скрывать строки
Next
'''Также можно проверку выполнить c с последующим выходом....
If oSht1 Is Nothing Then MsgBox "Листа 380* нет в файле", vbCritical: Exit Sub
Изменено: TSN - 08.09.2015 11:11:41
 
TSN, а можно полний код, а то я запутался и идут ошибки
 
sergey2303, не нужны пустые строки между обращением (копированным из сообщения именем) и текстом.
 
Откоректированный последний вариант
Код
Sub HiddenRow1()
Dim oSD As Object, arr(), x As Long
Dim oSht1 As Worksheet, oRng As Range, vl As Object
'Dim iTimer
'iTimer = Timer
Set oSD = CreateObject("Scripting.Dictionary")
    oSD.comparemode = 1

  With ThisWorkbook '''если хотите перенести в PERSONAL.xlsb нужно изменить на With ActiveWorkbook
    For Each vl In .Worksheets
      If vl.Name Like "380*" Then Set oSht1 = .Sheets(vl.Name)
    Next
    If oSht1 Is Nothing Then MsgBox "Листа 380* нет в файле, досрочное завершение работы", vbCritical: Exit Sub
    
    With .Sheets("Лист1") ''' c этого листа отбираем данные для дальнейшего анализа
      arr = .Range(.Cells(1, 1), .Cells(Rows.Count, 1).End(xlUp)).Value
    End With
    For x = LBound(arr) To UBound(arr):  If Not oSD.exists(arr(x, 1)) Then oSD.Add arr(x, 1), 0
    Next x
    Erase arr

Application.ScreenUpdating = False
    ''' работаем с листом 380* анализ данных и дальнейшее скрытие строк
    Set oRng = oSht1.Range(oSht1.Cells(1, 6), oSht1.Cells(Rows.Count, 6).End(xlUp))
      For Each vl In oRng 'цикл по колонке F листа 380*
        If Not IsEmpty(vl.Value) Then: If oSD.exists(vl.Value) Then vl.EntireRow.Hidden = True
      Next
  End With
Application.ScreenUpdating = True

'MsgBox Timer - iTimer & " с.", vbInformation
Set oRng = Nothing: Set oSht1 = Nothing: Set vl = Nothing
Set oSD = Nothing
End Sub
 
TSN
запустил на рабочем файле. процес идет минут 5
а можете переделать скрипт на основе надстройки Plex.
Там есть функция сравнить и закрасить совпавшие.
у меня отрабативает ета функция до минути
 
Цитата
sergey2303 написал:
а можете переделать скрипт на основе надстройки Plex.
Надстройка Plex не моя переделать не могу.
Какой объем данных у вас в файле мне неизвестно.
На тестах моя процедура обработала 10000 строк за 2 секунды (на моем слабом рабочем компе).
У вас спрашивали сколько строк нужно обработать ?. Возможно нужно изменить алгоритм на  работу с массивами.
А в целом подход к решению Вашей общей задачи нужно изменить.
Я писал алгоритм на основе того, что видел в файле примере. И из переписки понял, что данная задача только часть более крупного проекта.
 
Как видно вся работа проделана впустую... Я не о себе - я пока нет ясности по задаче к решению не приступаю. А ясности так и нет, все вопросы без ответа... И уже и времени решать нет.
 
Цитата
Hugo написал:
Как видно вся работа проделана впустую...
Согласен.
Но с другой стороны, для себя лично я попрактиковался в VBA, и возможно кому то пригодится мое решение.
Вот примет (тест) с таймером.
Изменено: TSN - 08.09.2015 13:46:43
 
Цитата
Юрий М написал:
Радикально увеличить скорость работы макроса можно, работая не с ячейками листа (строками) поочерёдно, а собрав в массив (диапазон) номера нужных строк, и затем скрыв их одним махом.
На досуге написал процедуру в таком формате, реально скорость увеличилась в разы.
Но согласно слов Hugo пока нет ясности в задаче выкладывать не буду.
Изменено: TSN - 08.09.2015 13:52:21
 
TSN
робочий файл состоит: Лист  380* --  103 000 строк, Лист1-- 2 500 строк
в колонке F Листа 380* --- города, в колонке А Листа1 города которие нужно скрить на листе 380*
 
Цитата
sergey2303 написал: Лист  380* --  103 000 строк, Лист1-- 2 500 строк
Небольшой размер данных.
Для oSD - словаря 2500 строк загруженных через массив, вообще ерунда, задержки не может быть.
Анализ совпадений ведется циклом по ренж и словарю, скорость выполнения достаточно быстрая, уступает лишь массиву со словарем и/или SQL.
Только что потестил 65530 строк из которых скрылось около 65000, процедура выполнилась за 12 секунд, ваши 103000 строк должно отработать примерно 20 с (если конечно комп не Pentium 3  :)).
Возможно в вашем коде участвуют дополнительные процедуры ?
 
TSN
Возможно в вашем коде участвуют дополнительные процедуры ?

нет
 
И большого количества формул нет в файле ?
Тогда непонятно выполнение процедуры на вашем файле за 5 минут.
 
нету формул
 
TSN
а можно Ваш емейл, я сброшу файл
 
Скинул e-mail в личку. Смогу посмотреть вечером дома после работы.
Изменено: TSN - 08.09.2015 16:10:08
 
sergey2303 Потестил Ваш файл дома.
Странная ситуация происходит.
Если активна ячейка листа 380* скажем А1 или F1 (первая строка листа)  то выполнение процедуры Sub HiddenRow1 () происходит на моем компе 304 секунды. Но если активная ячейка скажем А1048576 (последняя строка листа) или F103476 (в конце таблицы с данными) то выполнение процедуры происходит за 12 секунд.
Задача выполняется одинаково, скрываются практически все строки.
Не могу понять в чём зависимость.
Конечно в код можно добавить такую конструкцию, что автоматом будет переводить лист к последней строке и выполняется тогда всё быстро, но это слишком топорно.
Код
oSht1.Activate
    oSht1.Cells(Rows.Count, 1).Activate
Посижу еще подумаю, с такой проблемой не сталкивался

Может ГУРУ форума подскажут почему так происходит ?

P.S Если активный "Лист1" выполняется еще быстрей (за 8 секунд)
Изменено: TSN - 08.09.2015 19:01:54
 
Так и не понял в чем причина вышеизложенного глюка.
Но с учётом увиденного предлагаю откоректированный код (с учетом особенностей Вашего sergey2303 рабочего файла)
Скрытый текст

Альтернативный вариант решения задачи. Предлагаю новую процедуру.
Процедура основана на массивах, работает в разы быстрее, но имеет одну особенность описанную в комментариях.
Скрытый текст

P.S. На работе проверил файл из поста №44 (primer (test)) - глюков описанных постом выше не наблюдается.  
Изменено: TSN - 09.09.2015 08:55:37
 
Первий вориант(
Sub HiddenRow1()) работает отлично

Альтернативный вариант(HiddenRowArr)
ошибка Run-time error 1004
на робочем файле. макрос помещен PERSONAL.xlsb
 
Цитата
sergey2303 написал:
Альтернативный вариант(HiddenRowArr)  ошибка Run-time error 1004 на робочем файле. макрос помещен PERSONAL.xlsb
Да я знаю про нее.  Описано в комментариях кода постом выше. Возможно Ваш рабочий вариант данных увеличился по количеству строк на листе 380*.
Измените строку кода в Sub HiddenRowArr()  
Код
If x / 8 = x \ 8 Then   '''скрываем строки частями
на
Код
If x / 6 = x \ 6 Then   '''скрываем строки частями
Другого варианта я не придумал, как ее обойти. Просто никогда ранее не заморачивался над скрытием строк и/или раскраской ячеек на листах. Всегда работаю с данными в массивах или диапазонах, а при необходимости выгружаю на новый лист или в созданную новую книгу или в файл .doc, .txt, .dbf
Если честно так и не понял зачем Вам это нужно.
Изменено: TSN - 09.09.2015 17:07:34
 
TSN
Если честно так и не понял зачем Вам это нужно.

отработав макрос показивает строки в которих не допустима пустая ячейка в колонке E, которие потом нужно заполнить в базе
(скриваются те строки в которих допустимо пустое значение колонки E)
 
Не мне дает покоя Run-time error 1004. При изучении ошибки на вашем рабочем файле выяснил, что ошибка возникает, когда переменная sRows содержит более 256 символов. Возможно это связано с ограничением самой книги Ексель. Поэтому и обход решил выполнить ограничивая запись до 246 символов, т.к. в переменной sRows содержатся индексы строк. В Ексель 2010 максимальная строка 1048576 - 7 символов и 3 запасные оставил.
Изменил часть кода в Sub HiddenRowArr(), а именно эту часть
Скрытый текст
Изменил на более простую
Скрытый текст

Протестировал Ваш рабочий файл на 1044829 записей, выполнилось без Run-time error 1004, за 15 секунд. Измените код у себя на рабочем файле, думаю будет веселей работать. Есть еще одна мысль, как будет время проверю ее и при успешном выполнении кода выложу.
 
TSN, про длину строки я уже говорил тут: http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=69336&TITLE_SEO=69336-skryt-s...
Правда не сказал сколько можно... Но мы уже это на форуме когда-то обсуждали в теме про удаление строк.
ZVI удаление делал так - собирал массив меток, выгружал его рядом, сотировал по меткам, удалял сразу весь блок (сперва считал сколько нужно удалять).
Для скрытия это не вполне подходит, но если порядок строк не важен - то можно и так делать.
А если например важно просто узнать номера строк, чтоб потом править в базе - то зачем вообще всё это скрытие и всё остальное? Собрали номера в коллекцию, выгрузили куда-нибудь.
А если этот файл и есть база - тогда можно и сортировать, а скрывать и не обязательно.
 
Hugo Я видел Ваш ответ, но не придал значения, пока на практике не столкнулся с ошибкой.1004, в следующий раз буду вдумчивей читать комментарии мастеров форума. sergey2303 хотел скрывать строки, ему так удобней наверное. Если знать полноценно весь объем данных, как они поступают, что нужно получить на выходе то и алгоритмы можно использовать другие. В данном случае, я сделал только то, что попросили и параллельно получил доп.навыки и практику в VBA Excel.
Ну и напоследок дабы закрепить практику по скрытию большого количества строк в файле, выложу последний вариант процедуры Sub HiddenRowArr() с доработанным алгоритмом. Файл на 1 044 829 записей, выполнилось без Run-time error 1004, за 4,2 секунды.
Скрытый текст

sergey2303 тестируй.
Изменено: TSN - 10.09.2015 21:58:44
Страницы: Пред. 1 2 3 След.
Наверх