en
Feedback
Дневник VBAшника

Дневник VBAшника

Open in Telegram

Разное о Visual Basic for Application (VBA)

Show more
204
Subscribers
No data24 hours
No data7 days
No data30 days
Posts Archive
Вот так выглядит граф одного макроса на текущий момент☕️ Очень помогает ppm sync с такими ситуациями. Если кто не в курсе: На
Вот так выглядит граф одного макроса на текущий момент☕️ Очень помогает ppm sync с такими ситуациями. Если кто не в курсе: На скрине ветки гита. Каждая отдельная ветка - отдельная доработка той или иной части макроса. Почему их столько? Потому что пользователей макроса очень много (а конкретно этот макрос это надстройка с кучей различных сервисов) и вот сейчас разом пришли трое с просьбой доработать (одна из веток (розовая) - основная, прод/мастер/актуальная версия, как хотите называйте). Сейчас протестят и будем сливать. Причем сливать можно отдельно каждую ветку и заливать макрос на прод. И ничего не сломается🥳 Вот зачем git и ppm нужны🖖 Stay tuned❤️

А вот и новый перевод статьи с Rubberduckvba.blog Приятного чтения ☕️

Дорогой дневник ❤️, Сегодня хочу поделиться с тобой небольшой новостью. Ведя этот канал, я стараюсь вкладываться в него всей душой, сердцем и знаниями, чтобы делиться с тобой полезными и интересными материалами. Твои отклики и поддержка всегда мотивируют идти вперед и придумывать что-то новое, как, например, мой долгострой ppm, который уже довольно скоро (я думаю) перейдет в стадию первого релиза🥹 Если тебе, дорогой дневник, нравится то, что я делаю, и у тебя есть желание и возможность поддержать меня, то теперь есть такая возможность, достаточно тыкнуть в сердце в заголовке этого поста. Это совершенно необязательно действие, и мой контент всегда останется доступным для всех без исключения. Спасибо, что всегда выслушиваешь мои мысли, твоя поддержка значит очень много! Stay tuned❤️

👍
+1
👍

ppm: Большое обновление Ох, столько всего добавил, что даже не знаю с чего начать… 🔄Обновления 📌export Реализовал давнюю «мечту»: Теперь при экспорте убираются лишние строки в конце модуля. Ну знаете, вот эти вот, которые никто не добавлял, а они добавились? Вот они убираются. Остается только одна пустая, но это, вроде как, правило хорошего тона🙂 И экспорт красивый и проект в поряде. 📌init, publish Сделал небольшой редизайн команд. Теперь, если вызвать init при уже существующем модуле package, информация из него будет в качестве значений по умолчанию. Соответственно, их можно будет удобно скорректировать при необходимости. Так же, init переименовывает проект в виде "ИмяПакетаProject". То есть, если в init мы укажем название MyPackage, то проект переименуется в MyPackageProject. В publish добавил немного выводимой информации: - выводится список всех модулей, которые будут публиковаться - выводится информация о названии, версии, размере пакета
=== File to publish ===
/src/MyModules/Module1.bas
/src/Module2.bas
/src/Classes/Class1.cls
=== Pack details ===
name           MyPack
version        1.0.0
pack size      5.0 kb
unpacked size  10.0 kb
total files    3
🆕 Новые команды 📌sync Отладил, проверил на рабочем, очень большом и не моем макросе, вроде все корректно отрабатывает. Теперь будет удобно его поддерживать (пока не перепишем).😍 Подробнее описывал здесь. 📌uninstall Команда для удаления пакетов из проекта. Удаляет пакеты вместе с зависимостями, но при условии, что ни пакет, ни зависимости не ипользуются другими пакетами, установленными в проекте (для исключения ошибок). То есть, если мы хотим удалить пакет PStrings, который, к примеру, использует пакет PJSON, то менеджер не удалит пакет и выведет соответствующее сообщение. Если пакет не используется, но какие-то из зависимостей задействованы в других пакетах, то сам пакет будет удален, а используемые зависимости будут сохранены. Если же пакет и его зависимости не используются, то пакет будет полностью удален. 📌version Команда для упрощения изменения версии пакета в модуле package. Если вызвать без параметров, отобразится текущая версия:
ppm "version"

' Вывод v1.0.0
Для изменения версии, можно передать номер новой версии в формате семантического версионирования. Менеджер проверяет номер на соответствие формату и выдаст ошибку, если передано некорректное значение:
ppm "version 1.1.0"

' Вывод v1.1.0
'''package.bas

'@Folder("PearPMProject")
'{
'  "name": "PearPM",
'  "version": "1.1.0",
'  "description": "",
'  "author": "",
'  "git": ""
'}
Так же, для быстрого изменения версии patch, minor или major есть соответствующие команды:
' Текущая версия: 1.1.0
ppm "version patch"

' Вывод v1.1.1
' Текущая версия: 1.1.1
ppm "version minor"

' Вывод v1.2.0
' Текущая версия: 1.2.0
ppm "version major"

' Вывод v2.0.0
📌Прочие изменения Куча исправлений и отладок. А еще, обновление README ☕️ Все уже давно на github Stay tuned❤️ Дневник VBAшника

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

Не удаляются модули, что делать? 📔Вот вам интересный кейс: Код ниже не всегда может удалить все модули. Отчего это зависит, совершенно не понятно. Ну, вернее, не совсем так.. Сейчас расскажу.
Dim Component As Object
Dim Components As Object: Set Components = Application.VBE.ActiveVBProject.VBComponents
For Each Component In Components
  Components.Remove Component
Next
ℹ️Предыстория Работаю я, значит, над командой ppm "sync", которая будет синхронизировать проект с его экспортом. Для чего? Ну решили вы, например, работая с git, создать новую ветку, чтобы попробовать отрефакторить несколько модулей. Внесли довольно много изменений, а тут бац и заявка на доработку этого макроса прилетела. Что делать? Откатывать получается. Переключились вы обратно в master ветку, файлы свое состояние вернули, а модули нет... беда. И тут на помощь ppm "sync" приходит. Все файлы из папки проекта подбирает и засовывает их в проект, попутно удаляя те, которых нет в папке. Синхронизирует, короче говоря. И вот вы можете вносить изменения, делать git push, git rebase, ppm "sync" и продолжать работу над рефакторингом. Здорово же! Здорово. Только, для того чтобы синхронизировать проект, нужно, как бы, модули старые удалить, а новые импортировать. Так я и сделал, но из-за неизвестного бага, во время выполнения макроса по удалению модулей, не все модули удаляются сразу. То есть после того, как макрос отработает они, конечно, удалятся. Но во время выполнения кода (runtime) VBA их продолжает видеть, а значит при импорте произойдет конфликт имен.. Как быть то? Я перепробовал кучу вещей, но в итоге все оказалось прозаично. Нужно: - Переименовать удаляемый модуль, например "del_ModuleName" - Импортировать новый - Удалить переименованный Решение взял здесь, спасибо автору CmputrAce. После этого, желательно бы, еще разок в цикле пробежаться по всем модулям и проверить у них наличие префикса "del_", ну и удалить, если он есть. У меня один раз, почему-то, остались эти модули. Возможно была ошибка какая-то. Нужно будет перепроверить. UPD: проверил, этот пункт не нужен 👌 Такие вот дела. 🌃З.Ы. Команду почти доделал, буду проверять в работе, в боевых условиях 😬 Stay tuned❤️ Дневник VBAшника

Мультиязычность Добавил поддержку сразу нескольких языков – Русского и Английского. Переключаться можно с помощью команды: pp
Мультиязычность Добавил поддержку сразу нескольких языков – Русского и Английского. Переключаться можно с помощью команды:
ppm "config set language=<код языка в формате ISO>"
Переводы лежат в xml файлах. Как по мне – удобно. Корректируются быстро и без заморочек. P.S. Мало пишу, в последнее время, т.к. немного запарно на работе стало. Постараюсь реабилитироваться, так что Stay tuned ❤️ Дневник VBAшника

ppm install Вчера доделал основную логику команды установки пакетов💃 ℹ️Из нюансов: Как вы знаете, в VBA нет возможности доба
ppm install Вчера доделал основную логику команды установки пакетов💃 ℹ️Из нюансов: Как вы знаете, в VBA нет возможности добавлять два модуля с одинаковым именем. Это, в свою очередь, накладывает ограничения, как минимум на то, что нельзя загрузить две версии одного пакета (будет конфликт имен). В связи с этим я принял решение использовать подход уплощение зависимостей (flat dependencies). Возможно я не совсем верно понял суть подхода, но реализацию сделал примерно следующую: ➡️проверяем зависимости устанавливаемых пакетов ➡️выбираем из них самые новые по версии и используем их Пример: Если Пакет 🚩 использует Пакет 🚩 версии 1.0.0, а Пакет 🚩 использует тот же Пакет 🚩 версии 2.0.0, то менеджер установит более новую версию 2.0.0 Пакета 🚩.Не без вопросов Конечно, это несет за собой кучу возможных проблем (например изменение имен функций в новых версиях или их удаление, то есть отсутствие обратной совместимости и тд), но на данном этапе других вариантов я, к сожалению, не вижу. Если есть предложения, обязательно делитесь в комменты. Сразу уточню, что вариант с переименовыванием модулей и/или функций не подходит (ооочень много проблем сразу возникнет и в итоге это почти нереально реализовать). Да и в целом, пакетный менеджер для VBA (в плане глобального использования) достаточно спорная и сложная в реализации штука, как я сейчас понял. Не зря же до сих пор никто толком не реализовал его😬. К примеру, будет огромной проблемой, если два разных пакета используют модуль с одним названием (например Constants), да даже функцию или публичную переменную/константу/тип/enum.. И это только то, что лежит на поверхности. В общем, проблем и ошибок может быть куча. ⚙️И все же, этим можно пользоваться.. ведь так? Да, если соблюдать определенные правила (я же пользуюсь🥳). К примеру использовать префиксы к названиям модулей (не Strings, а PStrings) и вызывать функцию начиная с обращения к модулю (Strings.Replace). Это немного усложняет процесс разработки переиспользуемых модулей, но минимизирует конфликты и ошибки. Из плюсов: уже сейчас есть возможность создания локального репозитория, а значит как минимум можно составить список своих пакетов разработанных по своим правилам 🙂 Обновление уже на github Stay tuned❤️ Дневник VBAшника

ppm publish Наконец-то удалось🥳 Пришлось потратить кучу времени на отладку, но результат корректный. Теперь можно publish'ит
+1
ppm publish Наконец-то удалось🥳 Пришлось потратить кучу времени на отладку, но результат корректный. Теперь можно publish'ить проект. Причем в двух направлениях: ➡️локально, в указанную в конфиге папку ➡️на сервер🥳 (разработка сервера идет параллельно, но пока его никуда не выкладывал) Да, в планах есть сервер и его поддержка🙈 Конечно, есть еще задачи на доработку, но это уже результат, ящитаю Обновление уже на github Stay tuned❤️ Дневник VBAшника

Было! 💯+💯 Ребята, это настолько круто, что даже не передать) Вы мне даете стимул делать больше материала, спасибо!
Было! 💯+💯 Ребята, это настолько круто, что даже не передать) Вы мне даете стимул делать больше материала, спасибо!

Удивительно, но статья про рефакторинг стала второй по количеству 👁️ в моем ассортименте после статьи, где мы вместе с ChatG
Удивительно, но статья про рефакторинг стала второй по количеству 👁️ в моем ассортименте после статьи, где мы вместе с ChatGPT пишем библиотеку для vba (которая, к слову, еще и заминусованная) Приятное удивление 🥹

Lexer (все серьезно) Подумал я, что неудобно мне работать с аргументами командной строкиimmediate window и решил "А че бы Lexer не замутить". Взял и замутил🥳 Lexer — это такой инструмент, который используется в компиляторах/интерпретаторах языков программирования (да и, наверное, не только в них), для преобразования обычных слов в токены. С токенами несколько проще работать дальше, так как это уже не просто строка с пробелами и различными символами, а конкретные сущности. Решение пришло после реализации команды init. Тяжеловато было наличие аргументов проверять. Но более интересный, в плане взаимодействия, класс – Tokens. По большей части, вся логика в нем. Тут все под рукой, с удобными абстракциями. В общем, на текущий момент уже: 🟢реализованы три команды: init, export, help 🟢разработаны классы Lexer и Tokens для удобства разбора переданных аргументов 🟢в процессе работа над командой config Обновление уже на github Stay tuned❤️ Дневник VBAшника

ppm export Экспорт реализован🥳 ➡️Краткая справка о команде из ppm: Exports the selected project. Usage: ppm "export []" Opti
+2
ppm export Экспорт реализован🥳 ➡️Краткая справка о команде из ppm:
Exports the selected project.

Usage:
ppm "export [<options>]"

Options:
--save-struct   Save the RubberDuck structure when exporting a project.
--encoding      Export files with set encoding. Default UTF-8.
Пока все справки на английском, но в планах добавить мультиязычность (уже пробовал, рабочая тема, нужно только продумать как удобнее построить). Еще продумываю как добавить вывод коротких опций в справку (-s для --save-struct, -y для --yes и т.д.). Но главное, проект экспортируется в двух вариантах: 🟠как есть в Project Explorer 🟠как есть в Rubberduck Code Explorer Собсна, на втором и третьем скрине как раз пример. Переключение происходит установлением флага. Можно задать кодировку выгрузки, по умолчанию UTF-8 (в github будет грузится без кракозябр). ➡️Как работает За root папку проекта берется папка с именем проекта (по умолчанию VBAProject, которая). root экспорта (куда выгружаем модули) – папка, в которой сохранен текущий файл. К примеру, если в проекте есть папки VBAProject.src, VBAProject.src.Utils, Excel (вне папки VBAProject), modules (тоже вне), то они выгрузятся в .\src, .\src\Utils, .\Excel, .\modules и т.д. При первой выгрузке, ppm "запоминает" файлы, которые он выгрузил и при последующих экспортах сначала удаляет предыдущую выгрузку (по списку из "памяти"), а уже после выгружает текущее состояние проекта, "запоминая" уже его. Это доработанный вариант экспорта из ipm. Там необходимо было прописывать в модуле deleteignore комментарии с именами файлов или папок, которые не нужно удалять при выгрузке (по аналогии с .gitignore). Новый вариант, как по мне, лучше👍 ➡️Ссылочка Ну и раз уж есть функция выгрузки, то можно грузить проект на github🙈 У нас же тут опен сурс, как никак. Если будете пробовать работоспособность, отпишитесь по результату, буду благодарен🤝 Ну и желательно тестить в изоляции, чтобы случайно не потерять нужные данные (кто его знает где я мог ошибиться). Stay tuned, как говорится❤️ Дневник VBAшника

Короче говоря, package manager Я таки решил вернуться к проекту, как обычно с грандиознейшими планами. Идея интеграции в VBE
Короче говоря, package manager Я таки решил вернуться к проекту, как обычно с грандиознейшими планами. Идея интеграции в VBE канула в лету, т.к. сейчас мне это кажется маловыполнимой задачей.. возможно когда-нибудь.. ➡️По порядку Название ipm решил изменить на ppm, но что значит p я пока не расскажу 😌 Изменение названия связано, как минимум, с ускорением ввода этой команды, как максимум с тем, что я хочу полностью переработать проект, так как поддерживать ipm крайне тяжело (многие фичи пришли в процессе использования и тогда же пришло понимание, что нужна новая архитектура). На текущем этапе реализован паттерн команда, для быстрого внедрения новых команд в менеджер. Также, успел реализовать функционал для вывода справки о командах. На скрине как раз результат. Как видите, блок Options аккуратно выровнен. Это я доработал свою функцию FString для такого случая 🍷 ➡️О планах Хочу начать с реализации команды export, которая будет экспортировать весь проект в папку с файлом макроса. В команде будет флаг -s|--save-struct, при установке которого будет производиться выгрузка проекта с созданием папок таких же как в RubberDuck. Такой функционал уже реализован в ipm, поэтому я его просто перенесу сюда, возможно слегка видоизменю. Скорее всего, нужно будет еще добавить флаг --encoding, для выгрузки в определенной кодировке (стандартная выгрузка модуля идет в кодировке win1251, я ее переделывал в utf-8 по умолчанию, чтобы можно было легко грузить код на github). Далее init, install etc. Stay tuned, как говорится❤️ Дневник VBAшника

System.Text.StringBuilder Кстати, StringBuilder есть в стандартных библиотеках Windows и его можно подключить поздней (да и р
System.Text.StringBuilder Кстати, StringBuilder есть в стандартных библиотеках Windows и его можно подключить поздней (да и ранней, вроде, тоже) привязкой. Вот только интерфейса у него нет, некоторые методы немного странно называются, например Append_3 (видимо связано с тем, что в оригинальной реализации метод перегружен), но по скорости он прям на уровне (на скрине результат тестирования на 10 000 итераций, несколько запусков дали примерно один результат). А еще иногда его нужно сначала подключить на ПК (вернее не его, а библиотеку mscorlib). Рассказывал как это сделать в конце этой статьи.
Public Sub StringBuilderCOM_Test()
  Dim SB As Object: Set SB = CreateObject("System.Text.StringBuilder")

  Dim i As Long
  For i = 1 To ITERATIONS
    SB.Append_3("Hello,").Append_3 " World!"
  Next

  Debug.Print SB.Length
End Sub
Дневник VBAшника

StringBuilder Решил я тут потестить простой самописный StringBuilder и сравнить по скорости с обычной строкой. Не стал сильно заморачиваться с реализацией (и оптимизацией), добавил только два метода: Append и ToString, и одно свойство Length.
Private Type TStringBuilder
  Capacity As Long
  Length As Long
  Value() As Variant
End Type

Private this As TStringBuilder

Private Sub Class_Initialize()
  this.Capacity = 10 ' Устанавливаем стартовое значение размера массива
  ReDim this.Value(this.Capacity)
End Sub

Public Property Get Length() As Long
  Length = this.Length ' Возвращаем длину значения
End Property

Public Function Append(ByVal Text As String) As StringBuilder
  Dim TextLength As Long: TextLength = Strings.Len(Text) ' Получаем длину текста
  If this.Capacity - this.Length < TextLength Then ' Проверяем, влезет ли он в текущий массив
     ' Можно пооптимизировать, но для наглядности, если текст больше текущей вместимости, просто умножим объем массива на 2 и добавим длину текста
    this.Capacity = this.Capacity * 2 + TextLength
    ReDim Preserve this.Value(this.Capacity)
  End If

  Dim Index As Long
  For Index = this.Length To TextLength + this.Length
    Dim i As Long: i = i + 1
    this.Value(Index) = Strings.Mid(Text, i, 1) ' Посимвольно добавляем текст в массив
  Next

  this.Length = Index - 1 ' Получаем текущую длину итогового значения
  Set Append = Me ' Возвращаем текущий инстанс для возможности добавлять сразу несколько значений конструкцией StringBuilder.Append(Val1).Append(Val2)... и т.д.
End Function

Public Function ToString() As String
  ToString = Strings.Join(this.Value, "") ' Преобразуем массив обратно в строку
End Function
Процедуры для теста:
Public Sub StringBuilder_Test()
  Dim SB as StringBuilder: Set SB = New StringBuilder

  Dim i As Long
  For i = 1 To ITERATIONS
    SB.Append("Hello,").Append " World!"
  Next

  Debug.Print SB.Length
End Sub

Public Sub RegularString_Test()
  Dim Str as String

  Dim i As Long
  For i = 1 To ITERATIONS
    Str = Str & "Hello,"
    Str = Str & " World!"
  Next

  Debug.Print Strings.Len(Str)
End Sub
Результаты интересные Запускал 5 раз по: ➡️5 * 1 000 итераций Regular string: ~13ms🟢 StringBuilder: ~ 26ms🟣 ➡️5 * 10 000 итераций Regular string: ~687ms🟣 StringBuilder: ~ 213ms🟢 ➡️5 * 100 000 итераций Regular string: 🟣не дождался окончания, vbe завис трижды не выдав ни одного результата Debug.Print 😞 StringBuilder: ~ 2.43ms🟢
5 * N – то есть пять раз вызывалась функция, в которой в течении N итераций формировались строки
Получается, что если вам нужно собрать довольно длинную строку используя большое количество итераций, то скорее всего StringBuilder отыграет лучше (ну или хотя бы вообще отыграет👍). Да и в целом, с интерфейсом класса поудобнее работать чем просто со строкой, имхо. Дневник VBAшника

Сделал перевод статьи Матьё, нашего, Гиндона, о типизированных массивах и почему их не надо использовать ➡️Уже на хабре p.s. Впервые такое делаю, но судите строго) Дневник VBAшника

Встретил недавно в легаси такой комментарий Чтоб вы понимали, был упрощен код (процедура) в котором 2000 строк 😌 У - упрощен
Встретил недавно в легаси такой комментарий Чтоб вы понимали, был упрощен код (процедура) в котором 2000 строк 😌 У - упрощение! P.s. И да, на скрине количество строк в одном модуле🙂

Проект на разбор Всем привет 🖖 думаю подразобраться в объектных моделях не только на excel, а для этого было бы интересно взять какой-то проект, чтоли. Накидайте в комменты какое-нибудь, что-то вроде, тз с указанием платформы (word, outlook, excel etc.) Желательно что-то не очень крупное, так чтобы за день можно было управиться. Заодно, возможно, на основе опыта статью накидаю 🙂