Страницы: 1
RSS
Цикл по фильтру
 
Как сделать цикл по фильтру? Т.е. чтобы курсор бежал только по тем записям, которые отображаются на экране...
 
А рядом тема "Как исключить из области видимости цикла скрытые строки" не об этом?
 
Спасибо, Юрий. Действительно о том же.) Но я все-равно кое-что не понимаю...  
 
ikki написал "обрабатывайте в цикле диапазон, полученный с помощью SpecialCells". Думаю, в моем случае нужен SpecialCells(xlCellTypeVisible), но как сделать, чтобы он построчно двигался в фильтре, а не обрабатывал каждую ячейку отдельно?  
 
Я пока сделал так (вроде работает, но может быть есть другие методы?)    
 
Dim cRange As Range  
   Set cRange = ActiveCell.CurrentRegion.SpecialCells(xlCellTypeVisible)  
     
   For Each c In cRange  
       If Left(c.Address, 2) = "$D" Then  
       c.Activate  
       Application.Speech.Speak c.Value  
       End If  
   Next    
 
получается, что на экране видно движение курсора вниз (что мне и нужно) после проговаривания ячейки.
 
ну так и перебирайте строки :)  
 
for each r in cRange.rows  
 r.cells(1).activate  
 application.speech.speak r.cells(1).value  
next  
 
примечание: cells(1) здесь  - ячейки первого столбца выделенного диапазона. если нужны, к примеру, ячейки из 4-го столбца, поменяйте 1 на 4.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
ikki, спасибо, действительно работает! )  
 
Дело в том, что я сначала ради эксперимента пробовал простенький цикл, типа  
 
for i=1 to cRange.Rows.Count  
next  
 
но cRange.Rows.Count при этом возвращало значение 1, это меня и смутило! Почему это происходит?
 
честно говоря... только никому, да?... для меня самого такой вариант - открытие :)  
вообще говоря, диапазон видимых ячеек после применения фильтра в общем случае представляет собой несмежный диапазон (конечно, могут быть и исключения - это уж как фишка ляжет)  
и, "по-хорошему", надо в цикле перебирать все области такого диапазона, а внутри каждой области - все строки этой области  
 
for each a in cRange.Areas  
 for each r in a.rows  
   ...  
 next  
next  
 
но, оказывается конструкции типа  
for each c in cRange.cells  
или  
for each r in cRange.rows  
 
обеспечивают "сквозной" доступ ко всем ячейкам (строкам) даже несвязного диапазона.  
   
а вот ваше cRange.Rows.Count даёт кол-во строк только для первой из областей.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Ничего удивительного. То же произойдет при попытке считать все в массив. Туда попадет только первая область. Поэтому в другой теме я и писал, что проще скопировать видимые на лист, а оттуда уже взять в массив.
Я сам - дурнее всякого примера! ...
 
Еще один вопрос (совсем, наверное, несложный).  
 
Если сделать, как выше, то цикл обязательно начнется только с первой записи фильтра. Но мне нужно, чтобы он мог начаться с любой записи, например с той, на которой в данный момент стоит курсор, и затем продолжился до конца фильтра.    
 
Наверное, здесь нужно как-то использовать Offset(), только не пойму как...
 
Так не получится. По какому-то же признаку Вы выделяете нужную строку? Вот и проверяйте наличие этого признака в цикле.
Я сам - дурнее всякого примера! ...
 
пара вариантов  
 
1) перед определением диапазона запомнить номер строки текущей ячейки, а затем в цикле пропускать строки с меньшими номерами  
n&=activecell.row  
set cRange=ActiveCell.CurrentRegion.SpecialCells(xlCellTypeVisible)  
for each r in cRange.rows  
 if r.row>=n then  
   r.cells(1).activate  
   application.speech.speak r.cells(1).value  
 end if  
next  
 
2) таки задать правильный диапазон  
n&=activecell.row  
set cRange=intersect(ActiveCell.CurrentRegion, activesheet.rows(n & ":" & rows.count)).SpecialCells(xlCellTypeVisible)  
дальше - старый цикл
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
{quote}{login=ikki}{date=21.10.2012 10:27}{thema=}{post}  
   application.speech.speak    
{/post}{/quote}  
Аааа, класс! Спасибо, не знал, не знал.. :)
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
я тоже не знал.  
так что передаю это спасибо Алмейде.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Да ладно вам... это мелочи! Но все-равно мерси, особенно за ответную помощь! ) Главное поставьте хороший голосовой движок, например Loquando Olga TTS и выберите его в панели управления - будет вообще супер ;)    
 
А вообще я делаю обновление к раздаче (может, кому-то тоже будет интересно))):  
http://rutracker.org/forum/viewtopic.php?t=3930493  
Осталось уже совсем чуть-чуть. Надеюсь с вашей помощью доделать все по-человечески! ))))  
 
ikki, спасибо большое. Но теперь придется уже завтра потестировать, а то сейчас уже поздно...)
 
{quote}{login=ikki}{date=21.10.2012 10:27}{thema=}{post}пара вариантов  
2) таки задать правильный диапазон  
n&=activecell.row  
set cRange=intersect(ActiveCell.CurrentRegion, activesheet.rows(n & ":" & rows.count)).SpecialCells(xlCellTypeVisible)  
дальше - старый цикл{/post}{/quote}  
просто суперовское решение... высший класс ^^
 
а кстати, что знак "&" делает в выражении "n&=activecell.row"?
 
две недели тестировали? :)  
 
тип переменной он конкретизирует (long)  
конечно, в случае, если она не объявлена ранее.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
я извиняюсь, что опять так поздно, но, блин, у меня по-другому не получается :)  
> две недели тестировали? :)  
XDDD.... да загребся тут немного с другим , но эта строчка меня поразила.) что самое интересное, я ее так и не реализовал пока в конечной процедуре, но протестировать таки успел ;)    
 
а насколько, кстати, оправдано такое объявление переменных? я как-то видел кто-то писал, что, например, знак доллара для строковых переменных скорее просто для совместимости, нет?
Страницы: 1
Читают тему
Loading...