[Excel] Как выбрать из массива Excel уникальные элементы?
Есть ли вообще решение этой задачи без использования VBA?
Кстати, используя VBA также можно мучить расширенный фильтр, причём, это не занимает много времени :
Action:=xlFilterCopy, CopyToRange:=Worksheets.Add.Range("A1"), Unique:=True
xlFilterCopy, , Worksheets.Add.Range("A1"), True
xlFilterCopy, , Worksheets("name2").Range("A1"), True
однако код, где dest_book - другая книга выдает ошибку
xlFilterCopy, , dest_book.Worksheets("name2").Range("A1"), True
правда и это можно обойти, вставив ссылки на сами листы
xlFilterCopy, , dest_sheet.Range("A1"), True
Отсюда и возникают вопросы, правильно ли будет работать фильтр в последнем примере? Почему изначально Excel не разрешает копировать не то, что в другую книгу, а даже на другой лист, а в VBA эти ограничения можно обойти? Зачему нужны такие ограничения?
xlFilterCopy, , Workbooks("Книга2.xls").Worksheets("Лист2").Range("A1"), True
Set iSourceWB = Workbooks("Книга1.xls")
Set iDestinationWB = Workbooks("Книга2.xls")
iSourceWB.Worksheets("Лист1").[A:B].AdvancedFilter _
2, , iDestinationWB.Worksheets("Лист2").[A1], True
А что касается вопроса, связанного с непрограммным использованием расширенного фильтра, то его, конечно же, нужно адресовать непосредственно разработчикам.
Спасибо.
если фильтруемые ячейки - значения (например числа, то все работает), если же фильтруемые ячейки - формулы, то фильтруются сами формулы, а не значения.
Как отфильтровать значения с помощью расширенного фильтра, если я фильтрую столбец, который получен с помощью формул?
Что же касается копирования формул, то это абсолютно нормально, к слову сказать, тоже самое произойдёт и при обычном копировании, типа, CTRL+C и CTRL+V, а бороться с этим безобразием можно использовав, к примеру, фильтрацию на месте + копирование и специальную вставку значений :
.AdvancedFilter xlFilterInPlace, , , True
.Copy
Application.Range("[Книга2.xls]Лист2!A1").PasteSpecial xlValues
.Worksheet.ShowAllData
End With
'Если имя книги/листа может содержать, например, пробел, то _
Application.Range("'[Книга1.xls]Лист 1'!A:B")
или
With Workbooks("Книга1.xls").Worksheets("Лист1").Range("A:B")
.AdvancedFilter xlFilterInPlace, , , True
.Copy
Workbooks("Книга2.xls").Worksheets("Лист2").Range("A1").PasteSpecial xlValues
.Parent.ShowAllData
End With
Application.ScreenUpdating = True
Все таки есть различия между vba и excel в плане пользования этого расширенного фильтра: попробовал в excel на рабочем листе, так там по значениям, а не по формулам отфильтровал.
P.S.: Не учел
Application.Range("'[Книга1.xls]Лист 1'!A:B")
Вот и писал, что ошибка выдается когда ссылаешься по workbook.sheet("").
В одном месте используется код
Set srcSht = srcFile.Worksheets(1)
srcSht.Range("A:AC").AdvancedFilter _
xlFilterCopy, dstSht.Range("критерий"), dstSht.Range("результат"), False
Работает отлично.
Ниже в макросе используется следующий код
Не работает. Вместо результата в ячейке A1 присваивается имя "Извлечь" и все.
Как ни крутил, не могу найти ошибку. Уже и dstSht и srcSht занулил, думал как-нить может ссылки как-то пересекаются, не помогает. Даже не знаю, где искать ошибку. В этой одной строчке?
В чем может быть проблема?
Проблема в том, что я в упор не вижу ошибку во втором фагменте кода, когда хочу отобрать уже уникальные записи. Может устал.
Рыща по интернету, заметил несколько замечаний по-поводу расширенного фильтра, что могут ошибки возникать из-за минимальных изменений. Например, если к книге сделать общий доступ, то правильно работающий код до этого, перестает работать.
Вот и вопрос, как узнать, при каких условиях и каких параметрах работает расширенный фильтр? В мсдн я, по крайне мере, ничего не нашел полезного.
Кстати, вместо База_данных, Критерии, Извлечь можно использовать DataBase, Criteria, Extract
Я тоже устал, но синтаксис правильный, более того, в моём примере он таки позволяет получить уникальные записи, возможно собака порылась в чём-то другом ... но в любом случае Вы можете попробовать использовать в качестве критерия отбора формулу, или посмотреть чем Вам может помочь Microsoft Query (если он, конечно, установлен), который также позволяет извлечь уникальные записи (Данные - Внешние данные)
С MSDN и справкой соревноваться не возьмусь, однако, замечу, что общая книга это вообще отдельный разговор и в оной есть много ограничений, в т.ч. и запрет на использование расширенного фильтра.
1. Почти во всех Ваших примерах источник информации и назначение - две разные книги. Только в первом примере используется одна и таже книга, правда результат помещается во вновь добавляемый лист.
2. Первая часть моего кода работает с разными книгами, поэтому все и получается и фильтруется нормально. Вторая же часть кода должна фильтровать данные с одного листа и вставлять результат на другой лист той же книги. Вот здесь ничего и не происходит. Но если создать новую книгу и скопировать туда данные, которые хочу фильтровать, то код начинает работать.
Отсюда вопрос, в чем суть проблемы и можно ли это обойти, не создавая временную книгу?
Проверил код первого примера, где добавляется страница - такой же результат. Вот код:
ThisWorkbook.Worksheets("техн_инфо").Range("A:I").AdvancedFilter _
xlFilterCopy, , ThisWorkbook.Sheets.Add.Range("A1"), True
То же самое. Фильтрации не происходит. В последнем случае просто добавляются подписи данных (первая строчка данных) на новый лист, сами данные не фильтруются и не вставляются.
У Вас действительно работает расширенный фильтр при копировании внутри одной книги?
У меня это не заработало!
Отсюда решение:
Если Вы используете более одного расширенного фильтра, то нужно либо, чтобы источник данных и "приемник" скопированных данных находились в разных книгах, либо во время выполнения макроса удалять, появляющиеся после каждой "расширенной" фильтрации, имена Извлечь и Критерии.
Для второго варианта либо
ThisWorkBook.Names("Extract").Delete
либо
ThisWorkBook.Sheets("sheet_name").Names("Extract").Delete
Тоже самое и для Критерии ("Criteria")
P.S.: Я бы вообще рекомендовал после каждого использования расширенного фильтра затирать указанные имена, чтобы в дальнейшем не возникало лишних хлопот и проблем
Отнюдь, не только в первом, но и последнем примере используется одна и таже рабочая книга, и если в первом примере результат действительно копируется в ячейки нового рабочего листа, то в последнем уже в ячейки рабочего листа с именем "Свод"
[quote=JJJJoke]У Вас действительно работает расширенный фильтр при копировании внутри одной книги? У меня это не заработало![/quote]
Естественно, иначе зачем бы я стал это предлагать и даже закачивать пример, более того, в XL97, XL2000 нет никаких конфликтов имён, расширенный фильтр можно применять в нескольких рабочих листах, удалять имена перед этим не нужно.
Кстати, если уж опять вспомнили имена, рекомендую более детально разобраться с об'ектом Name, ибо два вышеопубликованных варианта будут идентичны только в том случае, если речь идёт о имени уровня рабочей книги(глобальном), а в этом случае можно использовать ещё и следующий синтаксис :
Если же наличие дополнительного рабочего листа нежелательно, то можно скопировать в ячейки новой рабочей книги, заполнить ComboBox, используя свойство List, и закрыть новую книгу без изменений. Естественно, все эти операции желательно скрыть, а посему Application.ScreenUpdating = False / True