Comments 20
Для мелкой задачи, реально too match. Если думать о серьезном расширении наперёд, то такой подход может и имеет право на существование. Но с точки зрения ежедневного бытия офисного программиста, это в большинстве своём реально потеря времени и сил. Так сказать, искусство ради искусства. Особенно когда речь идёт уже про интерфейсы, наследование и всё такое прочее. Это в итоге может оказаться ещё более неудобным для следующего программиста, который попытается разобраться в структуре такого legacy доставшегося уже ему по наследству. То что решается просто - должно решаться просто. В исходном коде конечно есть ад и ужас в плане тех же наименований в стиле 1С только латиницей (хотя VBA вполне себе сразу поддерживает кирилицй в названиях и переменных и функций, но это бээээ), но в целом, если задача решается, её просто можно причесать, убрать очевидные просчёты от неграмотности предыдущего программиста, а не строить проект, с десятком модулей, изящными алгоритмическими ходами "на будущее" и потратить на это всё пару дней, вместо пары часов. А через год ещё пару дней, чтобы вспомнить зачем такая структура модулей была нагорожена и прыгать по открытым вкладкам VBE вспоминая что и для чего.
Но в плане именно большого проекта, с серьезными задачами - материал безусловно достоит плюса. Для большого проекта, люто поддерживаю!
Прям идеальный пример программиста, которому нужно обосновать своё существование.
Это очень плохая практика – объявление всех переменных блоком в начале процедуры. Всегда лучше объявлять их непосредственно перед первым использованием.
Не всегда. Это не всегда удобно, особенно когда кода много и писали его не вы. Но позлить того, кто будет работать после вашего увольнения, позволит - пусть неудачник перечитает все внимательно, попроматывает туда-сюда, поиском хоть поучится пользоваться. Времени у него будет много.
Для тех, кто пишет в VBA функци из одной-двух строк и выносит их в отдельный модуль, надо по-хорошему предусмотреть отдельный котел в аду. Хотя для выбешивания следующего Василия Пупкина пойдет. Можно ещё листы по диапазонам разбить и ввод в каждый в отдельную функцию вынести, чтобы люди после вас не пользовались на халяву вашим трудом, а переписали весь код заново. Жизнь не должна быть легкой
В защиту автора: он же вроде как написал в дисклеймере, что пример отчасти надуманный. Для серьезных задач, так писать будет грамотным подходом. Как и описание в заголовке переменных. Это очень реально хорошо дисциплинирует программиста, и приучает его писать "чистый" код. За что напротив, следующий грамотный программист, ему скажет только спасибо.
Как я понимаю, о том, что плагины на VBA можно писать и в грамотном современном виде, а не только в виде спагетти кода из бешеного переплетения функций в одном модуле, собственно и вся статья.
У меня есть проекты на VBA (правда не для офиса а для CorelDraw), в которых несколько десятков модулей, классов и форм. И именно примерно такое разделение и позволяет сопровождать макросы уже много лет.
плагины на VBA можно писать и в грамотном современном виде
Только отчасти. VBA все равно останется устаревшим языком, с кучкой странных по сегодняшним временам решений. Чуть лучше сделать можно - но страдать все равно придется.
Если автор переписал 100 строк в 380, то мне приходилось переписывать 120 тысяч строк кода, которые были намного сложнее, чем работа с данными внутри листов таблицы. Там были и файловая система, и шина данных, и сложный UI.
Если у вас реально стоит задача переписать в современном виде - возьмите и перепишите на C#, будет намного, намного лучше.
Ну ок. Спорить глупо, VBA это и правда с точки зрения современного программиста - очень устаревший язык. На смену ему, мелкомягкие предлагают как вариант работать на современном и прогрессивном JS. Ну так в гробу я видал такую замену! Там такой ад и слёзы, чтобы начать хоть что то серьезной писать, что я лучше буду автоматизировать на старом добром VBA, как делает автор! Или лучше что-ли когда вообще нет альтернатив, например как в наших "отечественных" редакторах? Попробуйте там чего-нибудь автоматизировать так же просто как на VBA, где парой строк можно подтянуть в интерфейс любой установленный в системе COM+ ActiveX компонент, или системную библиотеку dll, с использованием почти любых внутренних функций, используя при этом голый Lua (в МойОфис) или на js с его сопутствующими ограничениями для вэб программирования, когда нужны возможности для десктоп приложений (в Р7).
То-то крупные фирмы ищут-ищут компании кто бы перевел их наработки автоматизации с MSO в импортозамещаемые офисные пакеты, да никак найти не могут.
Заметьте, я не говорил что VBA это плохо. Это зависит от многого. Даже тот монстр на 120 тыщ строк, что я переписывал - он работал, и он при этом был написан непрофессиональным программистом. И большАя часть моих трудностей по переписыванию была вызвана отсутствием автора и документации - т.е. я не понимал бизнес-смысла написанного.
И насчет JS я тоже скорее согласен - опять же, заметьте, я не предлагал на него переходить, я предлагал на c#.
Не вижу ничего плохого в "плохом" примере. А вот архитектурное космонавство, в которое он по ходу статьи превращается, удручает.
Когда строк всего 100 как в примере, "плохого" действительно не много. А вот когда их 500 и более становится очень сложно:
Понять, что вообще делает код. Посмотрите полный код в процедуре Main после рефакторинга. Беглый взгляд в течении 5-10 секунд сразу даст понять что там происходит. Чего не скажешь о всей процедуре в начале статьи. Нужно потратить минуту, а то и две, чтобы примерно вникнуть в смысл. Еще раз, когда 100 строк, это может и не страшно. Страшно когда их тысячи.
Найти кусок кода который выдает ошибку, или кусок кода с логикой, которую нужно изменить. Придется потратить те же 1-2 минуты, чтобы вникнуть в почти весь код. Зачем столько тратить, когда можно пройтись по 5-10 строчкам в точке входа, найти шаг, который вызывает нужную нам логику и провалиться в нее.
Наверное, есть еще пункты, но эти более значимые, как по мне.
Все же, читаем мы код гораздо больше, чем пишем. Так почему бы не потратить чуть больше времени на написание удобного для чтения и понимания кода?
Ну если только в задачу не входит «подосрать» потомкам, как упомянул другой комментатор. Тогда вопросов нет.
Ну и повторюсь, я не навязываю подобный подход, вы вольны делать так, как вам вздумается. Просто есть люди, как я, которые ищут подобный материал на vba, а его нет. Для них и писал статью ?
Я снимаю шляпу перед Вами и тем, как Вы владеете VBA. Я не программист, я аналитик.
"Даю вам 2 минуты на разбор кода в самостоятельном режиме, а после можете возвращаться и сравнить результаты. Время пошло... ". Я всё же экономист, а не программист, поэтому у меня ушло 10 мин:
1. ставим точку останова
F8 до ошибки
Правим
Стрелку выполнения на исправленную строку
Вернуться к п.2 в случае новой ошибки.
По необходимости используем Immediate Window
...
Готово!
Подвигал столбцы исходных данных и всё заработало.
Дорогой коллега, за рефакторинг VBA кода никто не платит. Да, VBA позволяет писать красиво, но в Excel и других продуктах MS Office - это в первую очередь инструмент для скриптования.
Отдельно отмечу, что такие старые скрипты надо регулярно пересматривать на актуальность бизнес логики. Поэтому, если много говнокода, то неплохо переписать всё заново, учтя дополнительные пожелания заказчика, для чего могут быть задействованы более подходящие инструменты (сводные таблицы, Access, Power Query, SQL и пр.)
П.С. Васю Пупкина ругать не надо, т.к. говнокод получается из говнобизнеспроцессов.
…
Подвигал столбцы исходных данных и всё заработало.
Вы все сделали правильно. Именно так я и делаю в работе. Конечно рефакторинг дело неблагодарное и дорогое.
Тут, скорее, задача была в том, чтобы показать, как непонятную мешанину превратить в структурированный код. И больше руководство для новых проектов, а не для переписывания (хотя кто знает, возможно есть среди коллег те, кому и за рефакторинг платят).
это в первую очередь инструмент для скриптования
Да, но это не значит, что нужно делать тяп ляп. Все таки работа должна приносить не только деньги, но и кайф от процесса. Неужели Вы не радуетесь, когда получается хорошо оформленная и структурированная кодовая база? Такое ведь и поддерживать крайне быстро, удобно, приятно, и ошибок в процессе эксплуатации минимум у клиента.
Со столбцами-то, в примере, почему так случилось? Потому что Вася не удосужился подумать о том, что отчет может поменяться. И, как я уже несколько раз упоминал, если это такой маленький проект - это не критично, доработать/исправить можно минут за 10-30.
Но в больших проектах речь уже о часа разработчика. И раз уж речь зашла за деньги, то часы разработчика - это деньги компании.
говнокод получается из говнобизнеспроцессов
и согласен и нет. БП могут быть идеально настроены на позитивную разработку, но Вася просто развиваться не хочет. И говоря про Васю я держу в голове уже не выдуманных людей, к сожалению ?
Спасибо за отзыв!
По моему, одним из главных достоинств VBA является возможность быстро перенести код из одной книги в другую. Я всегда старался организовывать скрипты так, чтобы можно было не вникая поделиться с другом или перетащить некую возможность в новый проект. Не тратя кучу времени на анализ того, что требуется для той или иной процедуры. Например, модуль с функциями для работы с файловой системой, модуль интерфейса (прогрес бары, окна), модуль со специфической математикой и т.д.
Меня вмегда раздражало наличие классов, особенно если была "матрешка" из них. Из-за этого перенос на новое место чреват ошибкой из-за того, что чего-то не хватает.
Кстати, используемый подход в обработке ошибок не совсем подходящий для применения в VBA. Он останавливает выполнение кода в любом случае. Было бы лучше использовать resume next и проверять, что случилось по ходу дела. Часто ошибка может быть не критической и ее можно проигнорировать. Или повторить операцию, пока ошибка не пропадет. Ошибка - не приговор.
В общем, такое "высокое искусство" интересно. С академической точки зрения. Но практически...
Быстро перенести код из проекта в проект, безусловно, достоинство, но это не к vba явно и Вы сами упомянули проблему?
Так вот лично я эту проблему(перенос сразу нескольких связных модулей) решил пакетным менеджером и пользуюсь им уже на протяжении полутора лет. Когда-нибудь дойдут руки привести весь код в порядок и выложить его, но пока просто поверьте на слово ?
Что касаемо подхода с ошибками - это частный случай. Тут можно Catch'ить и отдельные процедуры и обрабатывать их по своему усмотрению (это даже есть в примерах). Но Вы абсолютно правы, Resume Next крайне полезная вещь, и ее нужно использовать. Просто конкретно в этом проекте я не нашел для нее место, да и это не была сама цель.
Ну и как я уже упомянул:
Я не претендую на истину в последней инстанции, вы вольны поступать так, как вам заблагорассудится
спасибо за отзыв!
Я не понимаю, зачем под каждой картинкой из интернета писать, что она "с просторов интернета".
Круто ты реально молодец.
НО от VBA надо уходить как и от решения задач в excel "Нужно из таблицы (пример ниже) вытащить уникальные строки с товарами количество которых или больше или меньше 20 " - такое в БД решается SQL запросом в 3 строки.
Я раньше тоже работал в гос.конторе где были только word и excel - потихоньку перешли в начале на access + postgres потом уже и на web + postgres , но это конечно было не быстро...
Я очень надеюсь, что это просто абстрактный пример, т.к. в данном конкретном случае подобный рефакторинг сделал скрипт просто нечитаемым. По факту-то: добавлен только поиск нужной колонки по имени, и всё. Это можно было бы в виде трех строк впихнуть в тот же скрипт. Ни его читабельность ни его работоспособность бы не пострадала.
Да, скрипт выглядит неряшливо. Да, нейминг переменных крайне некорректен. Но это всего 100 строк при взгляде на которые сразу понятна вся реализация всех действий. При взгляде же на отрефакторенный вариант становится понятно, что за конкретными реализациями придется полазить да так, что скроллинг от объявления переменных к их инициализациям в исходном скрипте раем покажется.
Спасибо, кстати, за информацию о возможности присвоения значения переменным в окне свойств проекта.
VBA макросы. От бессмыслицы к осмысленному. Ядро