Подскажите - как отфильтровать и скопировать регион?

Программирование на Visual Basic for Applications
Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Подскажите - как отфильтровать и скопировать регион?

Сообщение Andrey Fedorov » 20.03.2008 (Чт) 9:34

Нужно - определенный регион на листе отфильтровать по колонке (пустое поле или значение не дата) и результат скопировать на другой лист. Подскажите, как это лучше сделать кодом на VBA...

Попытки разобраться к ничему такому что самому понравится пока не привели... :cry:
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 20.03.2008 (Чт) 12:56

Речь про Эксель, правильно?

У меня код, полученный по записи макроса, сработал после минимальной доработки напильником. Т. е. если копировать все строки области, на которую наложен фильтр, а потом их вставлять, то вставятся только те, которые удовлетворяли условию фильтра - хоть ручками делай, хоть макросом.

Т. е. код буквально вот такой:

Код: Выделить всё
    Selection.AutoFilter
    ActiveSheet.Range("$A$1:$B$18").AutoFilter Field:=1, Criteria1:="1"
    Rows("2:18").Copy
    Sheets("zzz").Cells(1, 1).PasteSpecial
Быть... или не быть. Вот. В чём вопрос?

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 20.03.2008 (Чт) 13:13

uhm писал(а):У меня код, полученный по записи макроса, сработал после минимальной доработки напильником.


Мне нужно чтобы соблюдались одновременно два условия:

1. Не пустая ячейка колонки A
2. Ячейка колонки B пустая или содержит значение не даты.

Как это прописать в автофильтр???
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 20.03.2008 (Чт) 13:32

Ясно, я по формулировке вопроса подумал, что проблемы вызывает именно копирование :)

Кроме дат что-то еще в числовом формате в колонке В может быть? Если да, то я не уверен, что это вообще возможно - загнать в автофильтр проверку того, что что-то является датой.
Быть... или не быть. Вот. В чём вопрос?

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 20.03.2008 (Чт) 13:50

uhm писал(а):Кроме дат что-то еще в числовом формате в колонке В может быть? Если да, то я не уверен, что это вообще возможно - загнать в автофильтр проверку того, что что-то является датой.


Обычно есть текст. Не числа.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 20.03.2008 (Чт) 14:41

Мдя... отобрать даты, оказывается, куда проще, чем не даты :)

Я уже готов, если Excel 2007, предложить выделить даты другим цветом и сделать фильтр по цвету шрифта... Хотя решение зверски некрасивое, да и Эксель наверняка окажется 2003 и ранее :)

Пошел думать дальше...
Быть... или не быть. Вот. В чём вопрос?

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 20.03.2008 (Чт) 14:45

А, ну и еще стандартно - если нет запрета на использование дополнительных колонок, то проще добавить колонку, в которой формулами вычислить, то ли, что нужно, стоит в колонке B, и дальше фильтровать по новой колонке.
Быть... или не быть. Вот. В чём вопрос?

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 20.03.2008 (Чт) 14:51

uhm писал(а):Мдя... отобрать даты, оказывается, куда проще, чем не даты :)


Дык в том то и сложность... Да еще дополнительный фильтр по другой колонке...

uhm писал(а):Пошел думать дальше...


Сие есть гуд! А то с Excel-ем работаю дюже периодически...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 20.03.2008 (Чт) 15:02

А использование автофильтра принципиально? Потому что все проблемы именно в его ограниченности, я все сильнее подозреваю, что без дополнительной колонки или манипуляций с цветами задача не решается. Может быть, проще пройтись циклом по всем строкам области и просто формулами VBA проверить условия и скопировать нужные строки?
Быть... или не быть. Вот. В чём вопрос?

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 20.03.2008 (Чт) 16:05

uhm писал(а):А использование автофильтра принципиально? Потому что все проблемы именно в его ограниченности, я все сильнее подозреваю, что без дополнительной колонки или манипуляций с цветами задача не решается. Может быть, проще пройтись циклом по всем строкам области и просто формулами VBA проверить условия и скопировать нужные строки?


Там штук 20 закладок и в каждой может быть тысячи записей. Так что работать будет дюже долго...

Сейчас у меня работает копирование через Recordset, но там свои прелести - в колонках юзер может ввести данные разного типа...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Gloom
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 200
Зарегистрирован: 23.11.2004 (Вт) 15:57
Откуда: СПб

Сообщение Gloom » 21.03.2008 (Пт) 4:03

Примерчик:
Код: Выделить всё
Dim firstSheet As Worksheet
Dim dataRange1 As Range, dataRange2 As Range, criteriaRange As Range, targetRange As Range
   
Set firstSheet = Worksheets(1)
   
Set dataRange1 = firstSheet.Range("A1:A7")
Set dataRange2 = dataRange1.Offset(ColumnOffset:=1)
Set criteriaRange = firstSheet.Range("C1:C2")
Set targetRange = Worksheets(2).Range("A1")
   
' создаём исходный диапазон
dataRange1.Value = WorksheetFunction.Transpose(Array("Date", "1/1/08", "1/2/08", Empty, "1/3/08", "test", "1/4/08"))
dataRange2.Value = WorksheetFunction.Transpose(Array("Text", "Row_1", "Row_2", "Row_3", "Row_4", "Row_5", "Row_6"))
   
' фильтруем диапазон и помещаем результат на второй лист
criteriaRange.Cells(2).Formula = "=IF(N(A2)>0,0,1)"
Application.Union(dataRange1, dataRange2).AdvancedFilter xlFilterCopy, criteriaRange, targetRange

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 21.03.2008 (Пт) 11:35

Не совсем честно, поскольку все равно используются дополнительные ячейки :)
Быть... или не быть. Вот. В чём вопрос?

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 21.03.2008 (Пт) 15:10

Код: Выделить всё
Sub Test()
    Sheets(1).Range("B:B").SpecialCells(xlCellTypeConstants, xlTextValues).EntireRow.Copy Sheets(2).Range("A2")
End Sub
Привет,
KL

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 21.03.2008 (Пт) 21:05

Gloom писал(а):Примерчик:


Интересно... Попробую...
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 25.04.2008 (Пт) 15:12

Если вместо:

Gloom писал(а):Примерчик:
Код: Выделить всё
...
Application.Union(dataRange1, dataRange2).AdvancedFilter xlFilterCopy, criteriaRange, targetRange


поставить

Код: Выделить всё
firstSheet.Range("A1:B7").AdvancedFilter xlFilterCopy, criteriaRange, targetRange


все работает, но мне не нужно чтобы копировался заголовок таблицы, пытаюсь выполнить

Код: Выделить всё
firstSheet.Range("A2:B7").AdvancedFilter xlFilterCopy, criteriaRange, targetRange


И нарываюсь на ошибку. Как быть?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 25.04.2008 (Пт) 15:47

Andrey Fedorov писал(а):
Код: Выделить всё
firstSheet.Range("A1:B7").AdvancedFilter xlFilterCopy, criteriaRange, targetRange


все работает, но мне не нужно чтобы копировался заголовок таблицы, пытаюсь выполнить


Ну во-первых, самое простое это цинично удалить заголовок после копирования.

Но если очень надо, то можно и так:

Код: Выделить всё
Sub test()
    Dim targetRange As Range
    Dim criteriaRange As Range
   
    Set targetRange = SecondSheet.Range("A3")
    Set criteriaRange = SecondSheet.Range("A1:B2")
   
    Application.ScreenUpdating = False
    With firstSheet.Range("A1:B7")
        .AdvancedFilter xlFilterInPlace, criteriaRange
        .Offset(1).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Copy targetRange
        .Parent.ShowAllData
    End With
    Application.ScreenUpdating = True
End Sub
Привет,
KL


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 118

    TopList