Pull to refresh

Comments 25

Можно такой же фильтр, т.е. проверку на уникальность, сделать формулами массива самого MS Excel в таблице

Я думаю, что тут скорее вопрос об замене в широком смысле использования. В том же Word нет фильтрации таблицы (по крайней мере в старых версиях офиса). Да и не всегда фильтрация это функция скажем так - известная пользователям, как ни странно это звучит. Иногда такие запросы от пользователей бывают, что даже удивительно почему они не пользуются штатными методами программы, и такое решение именно в макросе - может быть очень даже полезным, в плане экономии сил при разработке. Хотя конечно, все эти подключаемые модули, могут и дурную роль сыграть, когда у кого то без проблем работает, а у кого то надо додумать по началу, почему ошибки валятся, по причине отсутствия таких библиотек

Вот буквально пару месяцев назад при программировании правда на VBScript в SCADA использовал ArrayList. Вообще, если поковыряться в MS COM интерфейсах, можно найти ещё несколько коллекций или структур данных, типа очереди (Queue), которые можно в VBScript задействовать через COM. Главное, чтобы имелся тривиальный конструктор, в нетривиальные COM не умеет передавать параметры.

Когда сравнивают похожие по назначению структуры данных, ожидаешь хотя бы пару слов о сложности операций (в идеале в O-нотации) и предпочтительности выбора в разных ситуациях, опирающихся не только на удобство стандартной библиотеки: методы можно найти в сторонних библиотеках или написать самому, а вот плюсы и минусы разных подходов весьма постоянны и структуру надо подбирать исходя из назначения.
С VBA совсем не знаком, но быстрый гуглеж говорит, что ArrayList - это динамический массив, а Collection вовсе построен на (дву-?) связном списке и хеш-таблице одновременно, так что сразу можно предположить, например, что в Collection будет самый быстрый поиск - O(log n), по скорости вставки статический массив всех уделает с O(1) (без учета расширения), ну и так далее. С ростом n разница быстро становится гигантской.

Где-то я читал, что на низком уровне (да простят меня знатоки, я не знаю правильно ли я применяю это словосочетание здесь) есть свои нюансы в плане производительности, но, откровенно говоря, за все время использования этого объекта каких-либо проблем я не замечал и время работы макроса из-за него если и растет вообще, то совсем не критично.

Думаю, вам будет интересно таки поглубже изучить классические структуры данных: они не зависят от языка, так что это знание очень универсально. Да и объем материала не особенно велик.
А вот предсказывать производительность на глаз очень не рекомендую: даже программистам сложно осознать, насколько быстры современные компьютеры, вот хорошая статья была https://habr.com/ru/post/578232/. На глаз не увидеть разницу ни между наносекундой и микросекундой, ни даже между микросекундой и миллисекундой, а это, между прочим, уже 1000x1000. Так бывает, что в деве разработчик запустит метод с условными 100 единицами данных и решит, что он работает практически мгновенно, а на проде туда придет 10 тысяч и все внезапно встанет намертво. О-нотация тем и хороша, что предсказывает, как быстро будет "плохеть" программе при увеличении объема обрабатываемых данных.

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

Если речь о hash-таблицах и т.п., то поверхностно ознакомлен. Сильно глубоко не вдавался, т.к. пока не вижу как таковой нужды в плане применения (аналог тех же hash-таблиц в VBA — Dictionary, если я правильно понимаю).

ожидаешь хотя бы пару слов о сложности операций (в идеале в O-нотации)

По оценке сложности операций я не силен. В VBA подобная оценка как будто отсутствует (ну по крайней мере у большинства пользователей точно), возможно в этом причина. Поэтому как-то даже в голову не пришло добавить ее в статье. Но свою ошибку я понял, постараюсь на будущее учесть, спасибо!

UFO just landed and posted this here

Боюсь даже представить что там было😁

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

Думаю подавляющее большинство VBA-программистов — люди, которые пару раз юзали макрорекордер и в лучшем случае научились объявлять переменные. Но статистики у меня нет, поэтому это лишь домыслы.

UFO just landed and posted this here

Было бы интересно узнать мысли автора(ов) этого монстра) ну в смысле: зачем/почему/что мешало и тд

Бывают просто забавные ситуевины, когда ты чувствуешь потенциал, хочешь его раскрыть, а тебе говорят «нет, батенька, excel и не более, не надо нам ваших C#/Java/C++ etc.»

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

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

Но черт возьми, мне теперь интересно глянуть на этого монстра😈

UFO just landed and posted this here

Прям мини блокбастер😁 спасибо

нуу... когда начинали, просто подумали, что офис есть у всех, а чё заморачиваться...

Интересная концепция🫠

объем кодовой базы, она стала настолько большой, что VBA ну просто может переварить такой объем кода

Вот с одной стороны я надеюсь когда нибудь увидеть такой «макрос», с другой, не хотелось бы чтобы этот зверек попал тебе на попечение🥲

UFO just landed and posted this here
UFO just landed and posted this here

Еще не забываем, что ArrayList оперирует типом object, отсюда объект сразу создается не на стеке, а в куче, потому что используется упаковка (для объекто ладно, но для типов значений - камон Карл), отсюда еще куча всего вытекает... Ну блин, там что нет своих массивов? Ну это точно не правильный способ для VBA

Позвольте с Вами поспорить.

Конечно есть свои массивы. А еще есть коллекция. Но можно же и без нее, просто на массивах все делать, верно?

Ладно, возможно не совсем уместный сарказм, но я вот какую мысль хочу донести.. mscorlib это динамически подключаемая библиотека, верно? Верно. Ровно такая же, как и scrrun (Scripting runtime, в составе которой FileSystemObject и Dicrionary, так горячо любимые всеми VBAшинками). Возможно Вы скажете ими тоже не стоит пользоваться по причинам производительности? Тогда точно останутся одними массивы да коллекция, с которой не особо удобно (ну лично мне, возможно кто-то со мной и не согласится) работать, т.к. ключ/значение в нее добавлять можно, а проверить наличие ключа (встроенными средствами) нет, приходится изворачиваться. Метод извлечения списка ключей/значений? Не, не слышал. Про FSO вообще молчу, стандартные функции для работы с файлами крайне скудны. Я пробовал принципиально ими пользоваться, тяжко.

Если не использовать тип Object, а пользоваться ранней привязкой, то конечный клиент может словить интересные ошибки (ну не поддерживают VBA, куча багов в нем, которые никто уже не исправит). Поэтому только поздняя привязка, поэтому только через тип Object, хоть мне поначалу это дико не нравилось и я пытался продвигать раннюю привязку, но после нескольких обращений от клиентов о том, что у них что-то не работает из-за этого (даже, казалось бы, такие родные либы Word и Outlook), пришлось смириться.

Это я все к чему? Все эти библиотеки и прочее - они ведь сделаны для удобства программиста, чтобы ему не нужно было сотни раз переписывать один и тот же код и можно было пользоваться уже готовыми и проверенными решениями. Да, порой они дают маленькую просадку в плане производительности, но, наверное, иногда можно пожертвовать этими нано-миллисекундами в угоду удобства, читаемости кода (возможно я и не прав, но это сугубо личное мнение). В VBA и без ArrayList кучу всего приходится писать самостоятельно, что в других языках решается подключением какой-либо библиотеки.

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

Вы про заголовок? Надо было добавить дисклеймер, что это, конечно, для красного словца) кликбейт, так сказать

Прошу прощения, если ввел в заблуждение

Добавлю в ближайшее время🙂

Люблю Excel и как результат порой использую VBA.

Можно декларировать в VBA внешние библиотеки, передавать параметры, получать результат. (Как мне помнится можно самому наклепать dll и использовать функции написанные на чистом С, достаточно описать интерфейсы методов). А можно описать свой собственный объект который будет работать с выделением памяти и копированием даннных.

Проблемы возникают следующего характера:

  1. стабильность работы. ( excel вдруг ни с того ни с сего падает или зависает при использовании внешних объектов) Может конечно в последние годы что-то поправили, но исторически, любой внешний модуль это неожиданные падения с откатом к уже успевшей устареть версии файлика.

  2. Во встроенном редакторе нет возможности использовать автодополнение (autocompletion) в редактировании кода использующего Variant object. ( не сказать чтобы критично, но неудобно )

  3. Сильно сокращаются возможности отладки.

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

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

Получиться что то вроде:

Sub Sort_RemDuplicates()
    ActiveSheet.UsedRange.Columns(1).RemoveDuplicates Columns:=1, Header:=xlYes
    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add2 Key:=Columns(1) _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        .SetRange Columns(1)
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

Будет на порядок быстрее и надежнее чем работать с массивами самостоятельно.

При условии отключения автоподстча, обновления связей и перерисовки.

Спасибо за развернутый комментарий)

Задача, приведенная в статье, просто пример который пришел в голову. Возможно решение не самое действенное, но наглядно показывающее как можно упростить задачу. А ведь бывают задачи, когда нужно работать именно с массивом (да что там бывают, вечно есть).

Согласен, встроенные возможности Excel чаще гораздо удобнее, чем сочиненные самостоятельно, но их все таки часто не хватает.

Ну, тут хозяин барин.

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

Увы в моей работе принцип:

Интрументы как и родителей не выбирают😁

Ну то есть, необходимо именно с Excel работать. Возможно в будущем, когда-нибудь. Но пока так.

Эта фича к версии MS Excel привязана или к .NET?

В MS Excel 2007 будет работать?

Насколько я понял, к .NET.

Не уверен, но думаю от версии Excel она не зависит.

Посмотрите описание задачи. А также первый листинг в статье(Dim Buffer As Object: Set Buffer = CreateObject(«Scripting.Dictionary»)). Одного только Dictionary для решения задачи недостаточно, ничего для сортировки данный объект не предоставляет.
Sign up to leave a comment.

Articles