Excel vba только отфильтрованные строки

The SpecialCells Does not actually work as it needs to be continuous. I have solved this by adding a sort funtion in order to sort the data based on the coloumns i need.

Sorry for no comments on the code as i was not planning to share it:

Sub testtt()
    arr = FilterAndGetData(Worksheets("Data").range("A:K"), Array(1, 9), Array("george", "WeeklyCash"), Array(1, 2, 3, 10, 11), 1)
    Debug.Print sms(arr)
End Sub
Function FilterAndGetData(ByVal rng As Variant, ByVal fields As Variant, ByVal criterias As Variant, ByVal colstoreturn As Variant, ByVal headers As Boolean) As Variant
Dim SUset, EAset, CMset
If Application.ScreenUpdating Then Application.ScreenUpdating = False: SUset = False Else SUset = True
If Application.EnableEvents Then Application.EnableEvents = False: EAset = False Else EAset = True
If Application.Calculation = xlCalculationAutomatic Then Application.Calculation = xlCalculationManual: CMset = False Else CMset = True
For Each col In rng.Columns: col.Hidden = False: Next col

Dim oldsheet, scol, ecol, srow, hyesno As String
Dim i, counter As Integer

oldsheet = ActiveSheet.Name


Worksheets(rng.Worksheet.Name).Activate

Worksheets(rng.Worksheet.Name).AutoFilterMode = False

scol = Chr(rng.Column + 64)
ecol = Chr(rng.Columns.Count + rng.Column + 64 - 1)
srow = rng.row

If UBound(fields) - LBound(fields) <> UBound(criterias) - LBound(criterias) Then FilterAndGetData = "Fields&Crit. counts dont match": GoTo done

dd = sortrange(rng, colstoreturn, headers)

For i = LBound(fields) To UBound(fields)
    rng.AutoFilter Field:=CStr(fields(i)), Criteria1:=CStr(criterias(i))
Next i

Dim rngg As Variant

rngg = rng.SpecialCells(xlCellTypeVisible)
Debug.Print ActiveSheet.AutoFilter.range.address
FilterAndGetData = ActiveSheet.AutoFilter.range.SpecialCells(xlCellTypeVisible).Value

For Each row In rng.Rows
    If row.EntireRow.Hidden Then Debug.Print yes
Next row


done:
    'Worksheets("Data").AutoFilterMode = False
    Worksheets(oldsheet).Activate
    If SUset Then Application.ScreenUpdating = True
    If EAset Then Application.EnableEvents = True
    If CMset Then Application.Calculation = xlCalculationAutomatic
End Function
Function sortrange(ByVal rng As Variant, ByVal colnumbers As Variant, ByVal headers As Boolean)

    Dim SUset, EAset, CMset
    If Application.ScreenUpdating Then Application.ScreenUpdating = False: SUset = False Else SUset = True
    If Application.EnableEvents Then Application.EnableEvents = False: EAset = False Else EAset = True
    If Application.Calculation = xlCalculationAutomatic Then Application.Calculation = xlCalculationManual: CMset = False Else CMset = True
    For Each col In rng.Columns: col.Hidden = False: Next col

    Dim oldsheet, scol, srow, sortcol, hyesno As String
    Dim i, counter As Integer
    oldsheet = ActiveSheet.Name
    Worksheets(rng.Worksheet.Name).Activate
    Worksheets(rng.Worksheet.Name).AutoFilterMode = False
    scol = rng.Column
    srow = rng.row

    If headers Then hyesno = xlYes Else hyesno = xlNo

    For i = LBound(colnumbers) To UBound(colnumbers)
        rng.Sort key1:=range(Chr(scol + colnumbers(i) + 63) + CStr(srow)), order1:=xlAscending, Header:=hyesno
    Next i
    sortrange = "123"
done:
    Worksheets(oldsheet).Activate
    If SUset Then Application.ScreenUpdating = True
    If EAset Then Application.EnableEvents = True
    If CMset Then Application.Calculation = xlCalculationAutomatic
End Function

Я не знаю, какой именно код с сайта Pashulka Вы используте. Но если речь идет именно об Автофильтре, то в коде должна быть инструкция, похожая на это:

Код: Выделить всё

    Workbooks(i).Worksheets(k).AutoFilter Field:=1, Criteria1:="4"

— где вместо Workbooks(i).Worksheets(k) может быть любая конструкция, возвращающая объект листа с автофильтром, а значения параметров Field и Criteria различны.

Видимо после этой инструкции должна быть часть кода, которая считает количество строк, отфильтрованных автофильтром. Так?

Если после подсчета количества строк нужно выделить все видимые строки (после фильтрации) и удалить их, то я бы сделал это так:

Допустим ws — это объектная переменная, возвращающая лист с нашим автофильтром, (например, Set ws = ActiveSheet)

Код: Выделить всё

    Set mr = ws.AutoFilter.Range.Offset(1, 0). _
        Resize(ws.AutoFilter.Range.Rows.Count - 1, ws.AutoFilter.Range.Columns.Count)
    mr.SpecialCells(xlCellTypeVisible).EntireRow.Delete

Здесь mr — будет областью Range Автофильтра на листе ws без строки заголовков.
А вторая инструкция удалит все строки выбранные автофильтром (т.е. видимые после выборки автофильтра). Если вместо слова Delete написать Select, то вместо удаления будет происходить выделение строк.

Всякое решение плодит новые проблемы.

Записать в массив только отфильтрованные ячейки

Xpert

Дата: Пятница, 16.07.2021, 19:13 |
Сообщение № 1

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Всех приветствую!
Помогите, пожалуйста, с написанием макроса, который загонял бы в массив только отфильтрованные(видимые) значения.
Макрос:
[vba]

Код

Sub FltR()
Dim qarr, lrw&, i&, b#, s
With Лист1
    s = 0
        lrw = .Range(«D» & Rows.Count).End(xlUp).Row
            qarr = .Range(«C2:D» & lrw).SpecialCells(xlVisible)
    On Error Resume Next
        For i = LBound(qarr) To UBound(qarr)
         If qarr(i, 2) = «EUR» Then
            b = 1
            Else
            b = .Range(«F1»).Value
        End If
            qarr(i, 1) = Application.Round(qarr(i, 1) / b, 2)
            s = s + qarr(i, 1)
        Next i
    On Error GoTo 0
.Range(«K1») = «ВСЕГО КП на сумму: » & Format(s, «Standard») & » » & » евро.»
    With .Range(«K1»)
        .Font.Color = -3407872
        .Font.Bold = True
    End With
End With
End Sub

[/vba]
работает не совсем корректно. При фильтрации по нескольким диапазонам, он сохраняет данные только первого отфильтрованного блока, игнорируя остальные.
Подскажите, где подправить нужно?
И ещё вопрос: можно ли как-то сделать, чтобы макрос запускался автоматически при фильтрации?
Пример прилагаю.

К сообщению приложен файл:

7978952.xlsm
(22.8 Kb)

Сообщение отредактировал XpertПятница, 16.07.2021, 19:16

 

Ответить

doober

Дата: Пятница, 16.07.2021, 20:30 |
Сообщение № 2

Группа: Друзья

Ранг: Ветеран

Сообщений: 912


Репутация:

317

±

Замечаний:
0% ±


Excel 2010

Подскажите, где подправить нужно?

Здравствуйте.
Так не работают с видимыми ячейками, их только перебирают
[vba]

Код

Sub FltR()
    Dim qarr, lrw&, i&, b#, b1#, s#, Rng As Range, cel As Range, vl#
    With Лист1
        s = 0
        b1 = .Range(«F1»).Value
        lrw = .Range(«D» & Rows.Count).End(xlUp).Row
        Set Rng = .Range(«C2:D» & lrw).SpecialCells(xlVisible)
        For Each cel In Rng.Cells
            Select Case cel.Column
            Case 3
                vl = cel
            Case 4
                b = IIf(cel = «EUR», 1, b1)
                s = s + vl / b
            End Select
        Next
        s = Math.Round(s, 2)
        .Range(«K1») = «ВСЕГО КП на сумму: » & Format(s, «Standard») & » » & » евро.»
        With .Range(«K1»)
            .Font.Color = -3407872
            .Font.Bold = True
        End With
    End With
End Sub

[/vba]


 

Ответить

Xpert

Дата: Понедельник, 19.07.2021, 09:27 |
Сообщение № 3

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

doober, спасибо!
Подскажите, пожалуйста, что означает IIf в строке
[vba]

Код

Case 4
  b = IIf(cel = «EUR», 1, b1)

[/vba]

И ещё: как сделать, чтобы макрос запускался не с кнопки, а непосредственно при фильтрации?

 

Ответить

doober

Дата: Понедельник, 19.07.2021, 12:54 |
Сообщение № 4

Группа: Друзья

Ранг: Ветеран

Сообщений: 912


Репутация:

317

±

Замечаний:
0% ±


Excel 2010

И ещё: как сделать, чтобы макрос запускался не с кнопки, а непосредственно при фильтрации?

Никак, нет события на которое можно повесть макрос
[vba]

Код

    b = IIf(cel = «EUR», 1, b1) Это краткая записи условия, которое ниже
    If cel = «EUR» Then
        b = 1
    Else
        b = b1
    End If

[/vba]


 

Ответить

RAN

Дата: Понедельник, 19.07.2021, 13:25 |
Сообщение № 5

Группа: Друзья

Ранг: Экселист

Сообщений: 5645

А так? :p

К сообщению приложен файл:

5498486.jpg
(17.4 Kb)


Быть или не быть, вот в чем загвоздка!

 

Ответить

doober

Дата: Понедельник, 19.07.2021, 14:06 |
Сообщение № 6

Группа: Друзья

Ранг: Ветеран

Сообщений: 912


Репутация:

317

±

Замечаний:
0% ±


Excel 2010

Я не сторонник дергать этот макрос не по кнопке.
Например, будет 100к строк.


 

Ответить

Xpert

Дата: Понедельник, 19.07.2021, 14:19 |
Сообщение № 7

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013


При попытке использовать метод, предложенный RAN, возникает ошибка.

А при попытке закрыть документ — программа зависает.

К сообщению приложен файл:

1034629.png
(48.9 Kb)

 

Ответить

Serge_007

Дата: Понедельник, 19.07.2021, 14:34 |
Сообщение № 8

Группа: Админы

Ранг: Местный житель

Сообщений: 15888


Репутация:

2623

±

Замечаний:
±


Excel 2016

При попытке использовать метод, предложенный RAN

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


ЮMoney:41001419691823 | WMR:126292472390

 

Ответить

Xpert

Дата: Понедельник, 19.07.2021, 14:59 |
Сообщение № 9

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Суть поста Андрея сводится к тому, что применяя на листе любую волатильную функцию, использовать возникающее при использовании фильтра событие пересчета листа

Serge_007, именно это я и назвал «методом». Завёл на лист функцию СЕГОДНЯ, и прикрутил макрос doober’а к событию Calculate.
При использовании фильтра возникает ошибка

К сообщению приложен файл:

1169109.png
(48.9 Kb)

 

Ответить

Serge_007

Дата: Понедельник, 19.07.2021, 15:41 |
Сообщение № 10

Группа: Админы

Ранг: Местный житель

Сообщений: 15888


Репутация:

2623

±

Замечаний:
±


Excel 2016

Определение «метод» существует в VBA, но это совсем не то, что Вы назвали «методом», поэтому Вы сбили меня с толку)

При использовании фильтра возникает ошибка

Эта ошибка не связана, выражаясь по-Вашему, с «методом» Андрея, ошибка в исходном макросе, вернее в форме его применения


ЮMoney:41001419691823 | WMR:126292472390

 

Ответить

doober

Дата: Вторник, 20.07.2021, 12:47 |
Сообщение № 11

Группа: Друзья

Ранг: Ветеран

Сообщений: 912


Репутация:

317

±

Замечаний:
0% ±


Excel 2010

вернее в форме его применения

Котяра мяукнул картинкой и ввел в заблуждение ТС.
Так применять надо[vba]

Код

Private Sub Worksheet_Calculate()
    Application.Calculation = xlCalculationManual
    FltR
    Application.Calculation = xlCalculationAutomatic
End Sub

[/vba]


 

Ответить

Xpert

Дата: Вторник, 20.07.2021, 14:47 |
Сообщение № 12

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

doober, к сожалению, при таком способе также выскакивает ошибка(ссылается ошибку метода Special Cells объекта Range), далее файл зависает, и выйти из него можно только через диспетчер задач…

К сообщению приложен файл:

8057806.png
(127.0 Kb)

Сообщение отредактировал XpertВторник, 20.07.2021, 14:47

 

Ответить

doober

Дата: Вторник, 20.07.2021, 17:23 |
Сообщение № 13

Группа: Друзья

Ранг: Ветеран

Сообщений: 912


Репутация:

317

±

Замечаний:
0% ±


Excel 2010

так надо[vba]

Код

Private Sub Worksheet_Calculate()
    With Application
        .Calculation = xlCalculationManual
        .EnableEvents = False
        FltR
        .Calculation = xlCalculationAutomatic
        .EnableEvents = True
    End With

End Sub

[/vba]


 

Ответить

Xpert

Дата: Среда, 21.07.2021, 08:26 |
Сообщение № 14

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 103


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Спасибо большое всем, особенно doober.

Вопрос решён.

 

Ответить

Romario

Дата: Четверг, 09.09.2021, 14:14 |
Сообщение № 15

Группа: Пользователи

Ранг: Прохожий

Сообщений: 3


Репутация:

0

±

Замечаний:
0% ±


2013

Всем доброго времени суток! Давно уже бьюсь над задачей копирования данных из одной книги в другую, НО с учетом фильтра в одном столбце (фильтр должен быть в файле откуда копируются данные).
У нас с работы просто уволился коллега, который отлично шарил в макросах, но писал довольно непростые коды мягко говоря, для понимания новичка и вот собственно некоторые коды удалось мне переварить и использовать в работе, но вот в одном из кодов наступил конкретный ступор…. :(

Добрые и умные люди, можете, пожалуйста, подсказать где и какие правки нужно внести в код?
Заранее благодарю!

Макрос:

[vba]

Код

Sub Подгрузка_Кред_проц_ЮЛ_ПОС()

Dim wbImportFile As Workbook
Dim t_

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False

ChDrive Left(ThisWorkbook.Path, 1)
ChDir ThisWorkbook.Path & «»

Имяфайла = Application.GetOpenFilename(«Excel files(*.xls*),*.xls*», 1, «Выберите файл 115_099_DD.MM.YY», , False)
If VarType(Имяфайла) = vbBoolean Then Exit Sub

Set wbImportFile = Workbooks.Open(Имяфайла)
t_ = Timer

‘лист в рабочем файле-макросе
Set ws = ThisWorkbook.Worksheets(«Кред. проц. ЮЛ ПОС»)

‘лист в файле-доноре, из которого копируется информация
Set ws1 = wbImportFile.Worksheets(«Кред. проц. ЮЛ ПОС»)

kol_str = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row
start_row1 = ws1.Columns(«A:A»).Find(What:=»Портфель», After:=ws1.Cells(1, 1), LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Row + 1

For i = start_row1 To kol_str

‘не получается у меня правильно поставить фильтр / условие в 12-ой графе (графа L в файле-доноре), чтобы в этой графе фильтровалось значение «Основной долг» и копировалась бы информация в рабочий файл с учетом этого фильтра.
‘В разные места это условие пытался ставить – бестолку, на фильтр реакции либо не было, либо копировался всё равно весь массив данных или вообще ничего не копировалось, пробовал вносить всякие правки и корректировки в разные строки кода – в итоге макрос писал Debug постоянно….уже не знаю что делать…

‘If Cells(i, 12).Value = «Основной долг» Then

start_row = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
ws.Cells(start_row, 1) = ws1.Cells(i, 1)
ws.Cells(start_row, 2) = ws1.Cells(i, 2)
ws.Cells(start_row, 3) = ws1.Cells(i, 3)
ws.Cells(start_row, 4) = ws1.Cells(i, 4)
ws.Cells(start_row, 5) = ws1.Cells(i, 5)
ws.Cells(start_row, 6) = ws1.Cells(i, 6)
ws.Cells(start_row, 7) = ws1.Cells(i, 7)
ws.Cells(start_row, 8) = ws1.Cells(i, 8)
ws.Cells(start_row, 9) = ws1.Cells(i, 9)
ws.Cells(start_row, 10) = ws1.Cells(i, 10)
ws.Cells(start_row, 11) = ws1.Cells(i, 11)
ws.Cells(start_row, 12) = ws1.Cells(i, 12)
ws.Cells(start_row, 13) = ws1.Cells(i, 13)
ws.Cells(start_row, 14) = ws1.Cells(i, 14)
ws.Cells(start_row, 15) = ws1.Cells(i, 15)
ws.Cells(start_row, 16) = ws1.Cells(i, 16)
ws.Cells(start_row, 17) = ws1.Cells(i, 17)
ws.Cells(start_row, 18) = ws1.Cells(i, 18)
ws.Cells(start_row, 19) = ws1.Cells(i, 19)
ws.Cells(start_row, 20) = ws1.Cells(i, 20)
ws.Cells(start_row, 21) = ws1.Cells(i, 21)
ws.Cells(start_row, 22) = ws1.Cells(i, 22)
ws.Cells(start_row, 23) = ws1.Cells(i, 23)
ws.Cells(start_row, 24) = ws1.Cells(i, 24)
ws.Cells(start_row, 25) = ws1.Cells(i, 25)
ws.Cells(start_row, 26) = ws1.Cells(i, 26)
ws.Cells(start_row, 27) = ws1.Cells(i, 27)
ws.Cells(start_row, 28) = ws1.Cells(i, 28)
ws.Cells(start_row, 29) = ws1.Cells(i, 29)
ws.Cells(start_row, 30) = ws1.Cells(i, 30)
ws.Cells(start_row, 31) = ws1.Cells(i, 31)
ws.Cells(start_row, 32) = ws1.Cells(i, 32)
ws.Cells(start_row, 33) = ws1.Cells(i, 33)
ws.Cells(start_row, 34) = ws1.Cells(i, 34)
ws.Cells(start_row, 35) = ws1.Cells(i, 35)

End If
Next i
wbImportFile.Close (False)

Application.ScreenUpdating = True
Application.EnableEvents = True

MsgBox «Данные подгружены! Время: » & Format((Timer — t_), «0») & » сек.», vbOKOnly

End Sub

[/vba]

Сообщение отредактировал RomarioЧетверг, 09.09.2021, 14:47

 

Ответить

 

Как сделать цикл по фильтру? Т.е. чтобы курсор бежал только по тем записям, которые отображаются на экране…

 

Юрий М

Модератор

Сообщений: 60570
Регистрация: 14.09.2012

Контакты см. в профиле

А рядом тема «Как исключить из области видимости цикла скрытые строки» не об этом?

 

Спасибо, Юрий. Действительно о том же.) Но я все-равно кое-что не понимаю…  

  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    

  получается, что на экране видно движение курсора вниз (что мне и нужно) после проговаривания ячейки.

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

ну так и перебирайте строки :)  

  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, это меня и смутило! Почему это происходит?

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

честно говоря… только никому, да?… для меня самого такой вариант — открытие :)  
вообще говоря, диапазон видимых ячеек после применения фильтра в общем случае представляет собой несмежный диапазон (конечно, могут быть и исключения — это уж как фишка ляжет)  
и, «по-хорошему», надо в цикле перебирать все области такого диапазона, а внутри каждой области — все строки этой области  

  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 — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Ничего удивительного. То же произойдет при попытке считать все в массив. Туда попадет только первая область. Поэтому в другой теме я и писал, что проще скопировать видимые на лист, а оттуда уже взять в массив.

Я сам — дурнее всякого примера! …

 

Еще один вопрос (совсем, наверное, несложный).  

  Если сделать, как выше, то цикл обязательно начнется только с первой записи фильтра. Но мне нужно, чтобы он мог начаться с любой записи, например с той, на которой в данный момент стоит курсор, и затем продолжился до конца фильтра.    

  Наверное, здесь нужно как-то использовать Offset(), только не пойму как…

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Так не получится. По какому-то же признаку Вы выделяете нужную строку? Вот и проверяйте наличие этого признака в цикле.

Я сам — дурнее всякого примера! …

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

пара вариантов  

  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 — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

LightZ

Пользователь

Сообщений: 1748
Регистрация: 22.12.2012

{quote}{login=ikki}{date=21.10.2012 10:27}{thema=}{post}  
   application.speech.speak    
{/post}{/quote}  
Аааа, класс! Спасибо, не знал, не знал.. :)

Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

я тоже не знал.  
так что передаю это спасибо Алмейде.

фрилансер 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»?

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

две недели тестировали? :)  

  тип переменной он конкретизирует (long)  
конечно, в случае, если она не объявлена ранее.

фрилансер Excel, VBA — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

Алмейда

Гость

#17

06.11.2012 16:56:01

я извиняюсь, что опять так поздно, но, блин, у меня по-другому не получается :)  
> две недели тестировали? :)  
XDDD…. да загребся тут немного с другим , но эта строчка меня поразила.) что самое интересное, я ее так и не реализовал пока в конечной процедуре, но протестировать таки успел ;)    

  а насколько, кстати, оправдано такое объявление переменных? я как-то видел кто-то писал, что, например, знак доллара для строковых переменных скорее просто для совместимости, нет?

Reminds me of some code I wrote a while ago. It’s not tailored to do exactly what you’re asking (directly copying or acting on colors), but it’s a very handy tool for the general case of handling filter row gaps.

What it does: Populates a field named «F» in the first ListObject (Table) in a sheet with a value 0 if the row is hidden, or 1 if the row is visible. If no column/field «F» exists, one gets created and added at the right end of the table. Then It clears all sheet filters, sorts column F so all visible rows come to the top, then re-filters. The result is that you get all your filtered values together without gaps in between. A secondary effect is that you can save a complex combination of filters by renaming the «F» column/field.

Disclaimer: I wrote this code a while ago and I’m sure there’s room for improvement. It’s served my purpose though, so I just haven’t taken the time. let me know if you come up with anything better.

Sub Filter_By_Sorting()
Application.ScreenUpdating = False
Dim r As Double
Dim C As Double
Dim A As Worksheet
Set A = ActiveSheet
r = A.ListObjects(1).ListRows(1).Range.Row
On Error Resume Next
C = A.Range(ActiveSheet.ListObjects(1).Name & "[F]").Column
    If Err <> 0 Then
         C = A.ListObjects(1).ListColumns(A.ListObjects(1).ListColumns.Count).Range.Column + 1
         Columns(C).Select
         Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
         Cells(A.ListObjects(1).ListRows(1).Range.Row - 1, C) = "F"
    End If
On Error GoTo 0
Dim end_r As Double
end_r = A.ListObjects(1).ListRows.Count + A.ListObjects(1).ListRows(1).Range.Row - 1
Dim e() As Double
ReDim e(r To end_r, 0)
    Do Until r > end_r
        If A.Rows(r).EntireRow.Hidden = False Then
            e(r, 0) = 1
        Else
            e(r, 0) = 0
        End If
        r = r + 1
    Loop
    A.Cells(A.ListObjects(1).ListRows(1).Range.Row, _
    A.ListObjects(1).ListColumns(1).Range.Column).Select
    'Application.ScreenUpdating = True
    On Error Resume Next
    ActiveSheet.ShowAllData
        If Err <> 0 Then
            MsgBox "No Filter Detected, Macro Aborted"
            Exit Sub
        End If
    On Error GoTo 0
    'Application.ScreenUpdating = False
    Range(Cells(A.ListObjects(1).ListRows(1).Range.Row, C), Cells(end_r, C)) = e
    A.ListObjects.Item(1).Sort.SortFields.Clear
    A.ListObjects.Item(1).Sort.SortFields. _
        Add Key:=Range(A.ListObjects.Item(1).Name & "[F]"), SortOn:=xlSortOnValues, Order:=xlDescending _
        , DataOption:=xlSortNormal
    With A.ListObjects.Item(1).Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
   'A.Range(ActiveSheet.ListObjects(1).Name & "[F]").AutoFilter Criteria1:="1"
   A.ListObjects(1).Range.AutoFilter Field:=C, Criteria1:="1"
End Sub

Понравилась статья? Поделить с друзьями:
  • Excel vba только видимые ячейки в excel
  • Excel vba тип объекта
  • Excel vba тип значения в ячейке
  • Excel vba тип данных массив
  • Excel vba тип данных дата