Страницы: 1
RSS
Скрытие строк по условию
 
Здравствуйте.  
 
Есть вопрос по макросу. Во вложении файл с двумя страницами - на странице "Data" находятся некие данные, на странице "Check" в столбце А - искомые данные. Макрос скрывает строки на странице "Data", данные в которых не равны искомым данным с страницы "Check".    
 
Но есть одна проблема - он работает только когда в искомых данных больше одного значения. В случае, когда там лишь одно значение он не работает. Помогите понять где ошибка и как ее исправить. Заранее большое спасибо!  
 
Макрос:  
 
Option Explicit  
 
Sub Checking()  
 
Dim i As Integer, n As Integer  
Dim v1 As Variant, v2 As Variant  
Dim s As Long, t As Long  
 
s = ActiveWorkbook.Sheets("Data").Cells(1, 3).End(xlDown).Row  
t = ActiveWorkbook.Sheets("Check").Cells(1, 1).End(xlDown).Row  
 
ActiveWorkbook.Sheets("Data").Rows(2 & ":" & s).Hidden = True  
 
v1 = Range(ActiveWorkbook.Sheets("Data").Cells(2, 3), ActiveWorkbook.Sheets("Data").Cells(s, 3)).Value  
v2 = Range(ActiveWorkbook.Sheets("Check").Cells(1, 1), ActiveWorkbook.Sheets("Check").Cells(t, 1)).Value  
 
For n = LBound(v1) To UBound(v1)  
For i = LBound(v2) To UBound(v2)  
If v1(n, 1) = v2(i, 1) Then  
 
ActiveWorkbook.Sheets("Data").Rows(n).Hidden = False  
 
End If  
 
Next i  
Next n  
 
ActiveWorkbook.Sheets("Data").Select  
 
End Sub
 
В чем ошибка, не понял,  
но макрос ваш можно заметно упростить:  
 
Sub Checking()  
   Dim cell As Range, ra As Range: Application.ScreenUpdating = False  
   Set ra = data.Range(data.[c2], data.Range("c" & data.Rows.Count).End(xlUp))
   For Each cell In ra.Cells  
       cell.EntireRow.Hidden = check.Range("a:a").Find(cell) Is Nothing  
   Next cell  
   data.Activate  
End Sub  
 
Пример в файле: http://excelvba.ru/XL_Files/Sample__28-07-2011__12-50-13.zip
 
Естественно макрос далеко не самый лучший, так как писал его я. Большое спасибо за улучшенную версию! Только один вопрос: а ваш макрос работает когда искомое значение только одно?
 
Две ошибки - типы переменных не те, и по месту надо n + 1 использовать:  
 
 
Option Explicit  
 
Sub Checking()  
 
Dim i As Long, n As Long  
Dim v1 As Variant, v2 As Variant  
Dim s As Long, t As Long  
 
s = ActiveWorkbook.Sheets("Data").Cells(1, 3).End(xlDown).Row  
t = ActiveWorkbook.Sheets("Check").Cells(1, 1).End(xlDown).Row  
 
ActiveWorkbook.Sheets("Data").Rows(2 & ":" & s).Hidden = True  
 
v1 = Range(ActiveWorkbook.Sheets("Data").Cells(2, 3), ActiveWorkbook.Sheets("Data").Cells(s, 3)).Value  
v2 = Range(ActiveWorkbook.Sheets("Check").Cells(1, 1), ActiveWorkbook.Sheets("Check").Cells(t, 1)).Value  
 
For n = LBound(v1) To UBound(v1)  
For i = LBound(v2) To UBound(v2)  
If v1(n, 1) = v2(i, 1) Then  
 
ActiveWorkbook.Sheets("Data").Rows(n + 1).Hidden = False  
 
End If  
 
Next i  
Next n  
 
ActiveWorkbook.Sheets("Data").Select  
 
End Sub  
 
Хотя в случае с одной строкой есть вариант через If определять - если последняя определилась как конец листа, то берём xlUp (нет примера кода под рукой...)
 
А вместо вопроса взять и проверить - не пробовали?
 
Мой макрос работает так:  
берется очередная ячейка в 3-м столбце листа DATA, и производится поиск этого значения в первом столбце листа CHECK.  
Если такое значение найдено на листе CHECK - строка делается видимой, если не найдено - строка скрывается.
 
To EducatedFool & To Юрий М:  
 
Пробовал...  
Попробовал запустить макрос - не хочет работать, ругается на третью строку.  
Возможно там нужно вместо data написать Sheets"Data" или что-то в этом роде?
 
To Hugo:  
 
Спасибо большое. Ошибки разобрал и понял их.
 
To Hugo:  
 
Опять-таки, при проверке, если значение одно - файл виснет, и не возвращает никаких данных...
 
To Hugo:  
 
Есть, вернул! Только работает очень долго...но это все равно лучше, чем ничего. Еще раз спасибо большое!  
 
To EducatedFool:  
 
Мне так и не удалось подправить ваш макрос так, чтоб он работал...(
 
{quote}{login=}{date=28.07.2011 11:28}{thema=}{post}  
To EducatedFool:  
 
Мне так и не удалось подправить ваш макрос так, чтоб он работал...({/post}{/quote}  
 
По-вашему, зачем я дал вам ссылку на скачивание файла с примером?  
В нем всё работает...  
 
Я изменил кодовые имена листов - чтобы упростить код.
 
Я, прежде чем код выкладывать, его проверил - работает.  
Сейчас проверил ещё раз - открыл файл из архива, оставил одно значение, заменил код, нажал кнопку - всё сработало.  
Но если нажать повторно - тогда виснет. Но это уже другой косяк, лень вникать. Вероятно, нужно строки отобразить, прежде чем в массив брать...  
Но если брать в массив при t=1  
v2 = Range(ActiveWorkbook.Sheets("Check").Cells(1, 1), ActiveWorkbook.Sheets("Check").Cells(t, 1)).Value  
то это будет не массив, а одно значение, и будет ошибка. Это нужно проработать.
 
To EducatedFool:  
 
Прошу прощения, действительно виноват. Не скачал Ваш файл, код вставил в свой файл и запустил его - естественно, он не захотел работать.
 
Если брать Вашу реализацию - я бы посоветовал добавить в Check шапку - тогда проблемы с одной строкой не будет. Массив будет минимум из двух строк и максимум из всех строк, а не как сейчас - при одной строке он на весь лист (поэтому долго).  
Ну и тогда перебирать его не с начала, а со вторго элемента.
 
Последний вопрос:  
 
Временами возникает ситуация, когда ему задаются одни значения, а он возвращает совсем другие. Я думаю, это из-за того, что данные на листах заданы в разных форматах. Можно ли каким-либо образом в коде перед сравниванием присваивать данным один формат?  
 
Если необходим пример - я выложу...  
 
З.Ы. пробовал это делать на листе Excel - присваивал и текстовый формат, и числовой - все равно возвращает некорректные значения...
 
To Hugo:  
Решение проблемы добавлением шапки - просто гениально! Вот уж действительно все гениальное просто...как я сам не додумался?! :)
 
{quote}{login=}{date=28.07.2011 11:40}{thema=}{post}Последний вопрос:  
 
Временами возникает ситуация, когда ему задаются одни значения, а он возвращает совсем другие. Я думаю, это из-за того, что данные на листах заданы в разных форматах. Можно ли каким-либо образом в коде перед сравниванием присваивать данным один формат?  
 
Если необходим пример - я выложу...  
 
З.Ы. пробовал это делать на листе Excel - присваивал и текстовый формат, и числовой - все равно возвращает некорректные значения...{/post}{/quote}  
 
Помогите, пожалуйста, еще с проблемой, описанной выше, а от получается, что с макросом ковырялся впустую...времени жаль, а самому исправить эту проблему не удается...
 
Попробуйте  
 
If Cstr(v1(n, 1)0 = Cstr(v2(i, 1)) Then  
 
Но нужно конечно в Locals глянуть, что там в массивах в этих случаях.  
Да и может просто банально Trim() или Application.Trim() нужен...
 
Cstr(v1(n, 1)) конечно же...
 
Таким образом мы проверим, одинаковый ли формат имеют данные...а можно ли присвоить данным одинаковый формат? Не проверять их, а просто, в каком бы формате пользователь не вставил данные на лист Check, привести их в тот же формат, что и данные на листе Data?
 
Нет, так мы перед проверкой приведём их в один формат, т.е. при сравнении 1 и "1" мы будем сравнивать "1" и "1".
 
Все понял. Всем спасибо большое. Отдельное громаднейшее спасибо Hugo.
Страницы: 1
Читают тему
Наверх
Loading...