Я знаю, какое у вас сейчас лицо: Но на самом деле идея не нова и изначально я даже думал не изобретать велосипед, ведь есть по описанию неплохой vba-blocks, с открытым исходным кодом. Бери не хочу.Увы, так вышло, что я не умею писать скрипты в powershell, а у меня при установке какой-то из этих скриптов не отрабатывает и падает. Если, кстати, кому-то интересно, попробуйте поправить, расскажите хоть как оно? Ну а я беру палки и колеса, и начинаю лепить творить  все же лепить. Прежде чем мы начнем 1. Я не программист, я музыкант. Но сейчас моя профессия – разработчик VBA. Я не знаю как правильно писать код. Но учусь, кажется. И когда я делюсь своими мыслями – я тоже учусь. Если вы хотите помочь мне научиться, я буду только рад  😀 2. Далее пойдет многобуквенный текст о том, как автор делает для себя инструмент для упрощения работы с VBA. Кода нет. Вернее у меня то он есть, но его много и какие куски сюда добавлять я не знаю (да и надо ли оно). 3. Здесь вы не увидите очень крутую штуку, которую точно-приточно надо быстрее запихивать в мой проект, оспаде, как же я раньше жил без этого.Это, по сути, личный инструмент автора, про который он (кто он? я, получается) решил поведать всему миру хабру.Так что если вы сюда за святым граалем — Thank you Mario! But our princess is in another castle! А всем остальным приятного время провождения. Не буду нудить скучными вырезками из википедии и постараюсь своими словами объяснить.Package Manager – это npm, и pip, и nuget, и composer etc. Ну вы поняли. Нет? Тогда вот вам википедия под катом: Система управления пакетами (также иногда «менеджер пакетов» или «пакетный менеджер») — набор программного обеспечения, позволяющего управлять процессом установки, удаления, настройки и обновления различных компонентов программного обеспечения. Системы управления пакетами активно используются в различных дистрибутивах операционной системы Linux и других UNIX-подобных операционных системах. Программное обеспечение представляется в виде особых пакетов, содержащих, помимо дистрибутива программного обеспечения, набор определённых метаданных, которые могут включать в себя полное имя пакета, номер версии, описание пакета, имя разработчика, контрольную сумму, отношения с другими пакетами. Метаданные сохраняются в системной базе данных пакетов. Исходя из того, что делает менеджер пакетов, можно вывести список того, что же нам предстоит разработать.Ну, вроде все просто: Нужно создать консольное приложение, которое будет парсить.......Так, стоп Всё, да? Приплыли. Консольное. А как же в excel/word/access открывать консоль-то? Отдельно чтоли? Это же неудобно!А Immediate Window только и умеет, что выводить информацию через Debug.Print. Да, но не совсем. Immediate (я буду называть ее вбансоль, чтоб понятней было) умеет выполнять процедуры и функции: Ну, то есть, есть у нас какая-то функция, мы ее в вбансоли вызываем, она нам выдает какой-то результат. Уже можно парсить аргументы, получается.Попробуем еще раз пройти по списку? Нужно создать консольное вбансольное приложение, которое будет парсить аргументы и исходя из переданной команды выполнять некие действия:1. Инициализировать проект (init)2. Находить и устанавливать пакеты (install)3. Публиковать пакеты в некое хранилище (publish)4. Обновлять уже установленные пакеты (update)5. Удалять установленные пакеты из проекта (uninstall) Ну это база. Нет, а действительно, зачем? Разве макросы настолько большие, что туда постоянно нужно что-то импортировать? Да. Причем на моей практике таких макросов много. И так как VBAшники работают в современных IDE, а сам VBA – современный язык программирования, для которого как крупные компании, вроде google, так и энтузиасты пишут кучу разных пакетов/библиотек/фреймворков, ими нужно как-то управлять. ... Ладно, на самом деле всё чуточку плачевней. Откровенно говоря, я действительно в каждый проект импортирую кучу кода, который специально пишу для переиспользования. И да, все это пишется только для себя, как и любые VBA инструменты (надстройки не берем в расчет, наверное, как удобно; вы можете взять в расчет, а я не хочу). Самый частый гость в моих проектах – класс модуль CRegExp, который помогает взаимодействовать с регулярками (напишите в комменты, если интересно глянуть как он выглядит, закину на GitHub |=| там по сути обертка для VBScript.RegExp, так что наверное ничего интересного |=| я передумал, короче, не пишите в комменты).И подобных гостей много. И импортировать все это каждый раз руками... я что, не программист чтоли? До недавнего времени, для импорта пакетов я пользовался... Ни за что не догадаетесь... изобретенным для себя велосипедом в виде надстройки, которую подключал к проекту. В ней есть несколько функций, вызывая которые в вбансоли, можно было импортировать код, заранее сохраненный в какую-нибудь папочку, в подключенный проект и спокойно им пользоваться. Очень удобно, поверьте. И вот сейчас кодовая база моих пакетов начала разрастаться и ими стало неудобно управлять. Отсутствует нормальное версионирование, например. Неудобно прописывать зависимости для того или иного пакета (а так как код переиспользуемый, некоторые пакеты ссылаются на другие пакеты). И вот тут я понял, что настало время нового велосипеда... 🟢 – реализовано🟡 – в процессе реализации, но уже что-то работает🔴 – пока даже класс не создал Итак, с чего начать новый проект? Правильно – с названия. Я потратил на то, чтобы придумать название менеджера пакета для VBA почти полчаса, но теперь оцените: ipm – Immediate Package Manage А? Каково?Думали vpm (vba package manager) увидеть, а вот и нет. Искушенный читатель сразу заметил отсылку к другому менеджеру – npm. И да, для меня он стал идейным вдохновителем и лекалом всего проекта, поэтому велосипед будет изобретаться по его образу и подобию (со своей реализацией, конечно). Вспоминаем, что там у нас идет первым делом: Инициализировать проект (init) Вот с init и начнем. При вызове этой команды, вбансоль должна запросить: Имя пакета Версию Автора Описание и записать все эти данные. В npm они хранятся в файле package.json. И что, опять стоп? Как вбансоль диалог то делать будет? Отставить панику, я все придумал. ...Так вот, думал, как бы сделать аналог консольного диалога (в npm, например, после вызова команды init происходит диалог с пользователем, после чего из полученных данных формируется package.json). Immediate Window не совсем для таких вещей сделали. Но выдумать, таки, получилось. Суть простая:Пишем основную процедуру, в которой будет вызван диалог.Заканчиваем выводом сообщения с названием следующей функции и нижним подчеркиванием, в которую ожидаем аргумент от пользователя. Примерно так все выглядит: В итоге в Immediate Window получаем такой диалог: Причем ответ можно писать не в полных кавычках («y»), а только с первой («y). Работает одинаково. Вот такая имитация cli диалога. Не думаю, что кому-то пригодится, но кажется что штука забавная🙂 Далее, файл package.json.Мы, как прогрессивные программисты, в VBIDE создавать файлы не можем, поэтому для этих целей будем использовать стандартный модуль и комментарии. Выглядеть все должно примерно так: Заметили последнюю строку? Ее на вкусное оставлю, затрону позже. Тут, в принципе, все просто. Спарсили команду, создали (или нашли) модуль Package, записали полученную информацию. Но. В npm каждый импортируемый пакет идет со своим package.json. То есть таких файлов в проект импортируется ровно столько, сколько пакетов и их зависимостей будет импортировано. А у нас что? На этом все. Подписывайтесь на канал, ставьте лайки. Первое решение, которое пришло мне в голову – лепить к названию модуля имя пакета. И думаете я придумал еще парочку и выбрал лучшее? Глупости какие.В случае с примером будет CRegExpPackage.Это имя для экспорта. А для init, чтобы отделить основной пакет от импортных (шутка про импортозамещение), будем называть модуль ThisProjectPackage.Даже нативно получается. Идем дальше по списку: Находить и устанавливать пакеты (install) Ох, как тут все неоднозначно. Во-первых, где хранить пакеты?Ну в текущей итерации, ForMyselfMode, вполне достаточно и локального хранилища.Для того, чтобы первично задать путь к этому хранилищу, я решил сделать доп команду config в которой нужно будет прописать значение опции --rootpath – путь к папке со всеми пакетами. Команда парсит путь и записывает его в переменную окружения PACK для текущего пользователя . Во-вторых, а как быть с версиями?И вот над этим я сейчас скрипящими и кипящими мозгами думаю. Вот вам синтетический пример: Есть пакет Четверочка, на который логотип наносит компания РисуемНаПакетах версии 1.0.0.А еще есть пакет Магнезия, на который логотип наносит та же компания РисуемНаПакетах, но более поздней версии – 2.0.0.Мне нужны в проекте оба этих пакета, но они за собой потянут компанию РисуемНаПакетах, и вот тут произойдет конфликт версий (придется брать версию 1.0.0 и 2.0.0). В npm это решается очень просто – создается новая папка node_modules внутри папки загружаемого пакета и уже в нее импортируется нужная версия. Внимание вопрос.  Если у вас есть мысли, как сделать совмещение версий в одном проекте, напишите коммент.Вот тут правда, честно. Вообще не представляю. И напоследок, в-третьих, при импорте пакета, информация о нем должна записаться в файлмодуль ThisProjectPackage, а именно в раздел '@dependencies, ну чтобы понятно было, какие пакеты используются в проекте. Более того, туда же нужно записать версию пакета, ну чтобы понятно было, какая версия пакета используется в проекте. Выглядеть это должно примерно так: На текущей итерации у меня небольшой баг в этой команде – в зависимости основного проекта попадают пакеты и их зависимости (а должны только сами пакеты, т.к. их зависимости прописаны в их модуле Package), но это поправимо. Не знаю зачем вам эта информация, просто решил рассказать. Вы же зачем-то аж сюда дочитали😁 Публиковать пакеты в некое хранилище (publish) Какие тут могут быть проблемы? Берем модуль, сохраняем в папку. Готово. Ну в целом то да, но как зависимости то не сохранять в папку с основным пакетом?У нас же задача в чем? Настроить удобное управление пакетами, то есть их импорт, экспорт, изменение и т.д. Вот чтобы изменение было легко производить, нужно отделить мух от котлетзависимости от основного кода. А что, а как?А Rubberduck! нам на что? Раз уж я очень крепко прикипел к этому аддону, решил задействовать его в своей надстройке.Для тех кто не в курсе: Ну уж про Rubberduck вы должны были слышать! Так ведь? В общем для своего Code Eplorer'а этот аддон добавляет в каждый модуль комментарии.Один из таких комментариев – '@Folder.Как следует из названия, он отображает информацию о том в какой папке лежит модуль (ну как папке... ну вы поняли). Вот эту инфу мы и будем парсить.Всего лишь нужно экспортируемый/публикуемый код поместить в папку src в корневом каталоге. ThisProjectPackage выносим в корень: Всё, мухи отдельно, котлеты отдельно. Еще одно обязательное условие, перед экспортом переименовать ThisProjectPackage в [NameOfProject]Package, а потом, и это не менее важно, вернуть название обратно. Ну и, естественно, в нашем хранилище должна создаваться папка с названием пакета, в которой должна создаваться папка с номером версии, в которой должна создаваться папка src, в которую мы экспортируем весь проект + package модуль. Зачем src? На самом деле не зачем, просто раньше я выносил package отдельно от основного кода.Возможно надо фиксить, но мне пока лень и вдруг в этом есть смысл? Устали? Ща побыстрому пробежимся по последним пунктам. И вот вы уже почти уснули, а я начинаю предпоследнюю главу своего умопомрачительного повествования. Обновлять уже установленные пакеты (update) Тут, как обычно, все очень просто. Парсим package модуль, ищем там нужный нам пакет, проверяем до какой версии можно обновить, обновляем.Самая короткая задача, наверное. Поправьте меня, может я ошибаюсь? Удалять установленные пакеты из проекта (uninstall) А вот тут есть что сказать по сложностям. Одно слово – зависимости.Нужно пройтись по всем установленным пакетам и их зависимостям. Еще раз, по всем пакетам и по всем их зависимостям, гуглим Dependency hell. Как вы поняли, ipm пока в разработке. Буквально вчерашняя ночь прошла в отладке трех команд из-за переименования модуля package. Но результат того стоит.Сам проект я выложу в open source по завершению и отредактирую статью. Если вам не понравилась статья, ни за что не подписывайтесь на мой телеграм. Не надо, правда. Ссылка еще в профиле есть. А вы изобретаете велосипеды в VBA?  Музыкант