Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/2: Рейтинг темы: голосов - 2, средняя оценка - 5.00
здесь больше нет...
3376 / 1674 / 184
Регистрация: 03.02.2010
Сообщений: 1,219

Авторские программы, библиотеки, надстройки и шаблоны

12.02.2010, 17:42. Показов 291252. Ответов 268
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
 Комментарий модератора 
Коллектив модераторов раздела оставляет за собой право использовать данный пост аналитики для размещения и обновления оглавления темы.

Оглавление
- по тематике:

Утилиты


Инструменты программиста

Графические редакторы



Защита программного кода

Офисные операции

Веб-сервис


Игры




- по автору:
A-Z





Конец оглавления

Оригинальное сообщение от аналитики:

Надстройка для VBE "IndenterVBA" - позволяет редактировать стиль оформления программного кода.
Вложения
Тип файла: rar IndenterVBA.rar (253.1 Кб, 1962 просмотров)
27
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
12.02.2010, 17:42
Ответы с готовыми решениями:

Создать дистрибутив для надстройки Word
У меня Visual Studio 2010. 1. Я создал свой первый проект: WordAddIn. 2. Добавил в решение...

Excel 2000. Самокопирование надстройки при первом запуске
написал я соотв. надстройку на Excel записал на дискету. но не учел тот факт что каждому...

Редактирование надстройки EXCEL
Ситуация: есть файл start.xla (при запуске сам не показывается, а формирует и запускает временный...

268
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
16.08.2026, 16:15
Студворк — интернет-сервис помощи студентам
Решение проблеммы State Loss или Global Variable Reset иначе говоря потери состояния переменных в исполняемой среде VBA (надеюсь правильно написал, но скорее всего нет). Проблемма проявляется, когда, в коде используются инициализируемые данные, хранящиеся в глобавльных или статик-переменных и эти данные внезапно обнуляются в следствие каких-то не предвиденных или предвиденных но не очень желательных сбоев.
Предисловие: заметил интересный момент у Кристиана Буса в его VBA-SafeTimer, где он запускает таймер следующим образом:
Visual Basic
1
2
    SetTimer m_form.Controls.Add("Forms.Frame.1").[_GethWnd], ObjPtr(Me) _
           , uElapse, GetTimerProc(Me)
Т.е. таймер привязывается к хэндлу контрола на форме и т.о. при любом сбое форма автоматически уничтожится вместе с добавленным на нее контролом и таймер будет будет остановлен также предотвращая не нужные срабатывания. Форма в данном сулчае абсолютно пустая, и существует именно только для созания автозавершаемого таймера. Тут интересно в частности и то, что он использует скрытое свойство [_GethWnd], которое, по всей видимости, есть далеко не у каждого из доступных vba-контролов. У самой формы нет такого свойства.
Мне пришла мысль, что такую же форму вполне можно использовать для решения выше-описанной пролеммы. При любом сбросе состояния, инициализированный объект формы уничтожается также как и его окно, а по скольку этот момент можно отследить посреством хука окнонной процедуры, то можно в этом моменте решить сразу 2 задачи - 1) освободить любые хэндлы и указатели, если это нужно, 2) запланиовать повторную инициализацию необхоимых данных после сброса (с помощью OneTime или апи-таймера).
Пример:
Для работы кода нужно создать пустую форму с названием "frmStateKeeper" и на ней добавить фрейм "Frame1".
В коде формы можно добавить
Visual Basic
1
2
3
Private Sub UserForm_Activate()
    Me.Hide ' препядствуем отображению формы, чтобы предотвратить поток не нужных сообщений в процедуру субкласса
End Sub
Стандартный модуль mdStateKeeper
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
' 16.08.2026 Testuse2
'Модуль mdStateKeeper: решение проблеммы "потри состояния" (State Loss или Global Variable Reset)
' В стандартном модуле
'LONG_PTR SetWindowLongPtrW(
'  [in] HWND     hWnd,
'  [in] int      nIndex,
'  [in] LONG_PTR dwNewLong
');
Option Explicit
 
#If Win64 Then
    Private Declare PtrSafe Function SetWindowLongPtrW Lib "User32.dll" ( _
        ByVal hWnd As LongPtr, _
        ByVal nIndex As Long, _
        ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function SetWindowLongPtrW Lib "User32.dll" Alias "SetWindowLongW" ( _
        ByVal hWnd As LongPtr, _
        ByVal nIndex As Long, _
        ByVal dwNewLong As LongPtr) As LongPtr
#End If
'LRESULT CallWindowProcW(
'  [in] WNDPROC lpPrevWndFunc,
'  [in] HWND    hWnd,
'  [in] UINT    Msg,
'  [in] WPARAM  wParam,
'  [in] LPARAM  lParam
');
Private Declare PtrSafe Function CallWindowProcW Lib "User32.dll" ( _
    ByVal lpPrevWndFunc As LongPtr, _
    ByVal hWnd As LongPtr, _
    ByVal Msg As Long, _
    ByVal wParam As LongPtr, _
    ByVal lParam As LongPtr) As LongPtr
 
Private Const GWL_WNDPROC = -4
Private Const WM_CLOSE = &H10
Private Const WM_DESTROY = &H2
 
Private PrevWndProc As LongPtr
Private FormHandle As LongPtr
Public oForm As frmStateKeeper
 
Private Function NewWndProc(ByVal hWnd As LongPtr, ByVal Msg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    If Msg = WM_DESTROY Then
        RemoveHook
        Debug.Print "Восстановление состояния"
        Application.OnTime Now, "StartStateKeeper"
        ' Если нужно отменить закрытие, можно не передавать сообщение дальше
        ' NewWndProc = 0
         Exit Function
    End If
    ' Все остальные сообщения передаём стандартной процедуре
    NewWndProc = CallWindowProcW(PrevWndProc, hWnd, Msg, wParam, lParam)
End Function
 
Sub StartStateKeeper()
    If PrevWndProc = 0 Then Else Exit Sub
    Set oForm = New frmStateKeeper
    ' Thanks to Christian Buse for this trick https://github.com/cristianbuse/VBA-SafeTimer/blob/master/src/SafeTimer.cls
    FormHandle = oForm.Frame1.[_GethWnd] 'FindWindowW(StrPtr("ThunderDFrame"), StrPtr("frmStateKeeper"))
    ' Установка перехвата
    PrevWndProc = SetWindowLongPtrW(FormHandle, GWL_WNDPROC, AddressOf NewWndProc)
End Sub
 
' Снятие хука для корректного уничтожения окна формы (возможно это не нужно)
Sub RemoveHook()
    If FormHandle <> 0 And PrevWndProc <> 0 Then
        Call SetWindowLongPtrW(FormHandle, GWL_WNDPROC, PrevWndProc)
    End If
End Sub

В модуле в качестве примера инициализированных данных выступает непосредственно объект формы oForm, который я специально сделал Public, чтоб можно было проверять его состояние в Immediate. Этот объект будет автоматичеки инициализирован при любом сбросе состояния если однократно выполнить StartStateKeeper. Чтобы остановить автовосстановление нужно выполнить RemoveHook.

Добавлено через 15 минут
Так, стоп, недоработка там, не работает решение, если будет ошибка и нажать "End" то крушение всей прилаги. На всякий случай говорю, как г-тся )
1
ᴁ ©
Эксперт MS Access
 Аватар для АЕ
4088 / 2469 / 514
Регистрация: 13.12.2016
Сообщений: 8,397
Записей в блоге: 5
17.08.2026, 08:08
Цитата Сообщение от testuser2 Посмотреть сообщение
когда, в коде используются инициализируемые данные, хранящиеся в глобавльных или статик-переменных и эти данные внезапно обнуляются в следствие каких-то
К сожалению такая проблема действительно есть. Я решаю ее следующим - максимально простым (как мне кажется) способом.
1. Все глобальные переменные дублирую при присвоении также в спец. таблицу.
2. Каждый раз перед их использованием выполняю процедуру переприсвоения из этой таблицы (например при открытии формы)
1
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
17.08.2026, 10:23
Цитата Сообщение от АЕ Посмотреть сообщение
Я решаю ее следующим - максимально простым (как мне кажется) способом.
Да, в сущности, это конечно не является какой-то краеугольной проблеммой, а больше вопрос удобства, такого, как нармер, возможность созать единый обработчик ошибок для всех процедур. Хотя, в принципе штатно это решается созданием обработчика по типу On Error Goto в каждой процедуре.. И вопрос инициализации глобальных переменных, также решаем, о чем говорит ваш вариант решения.
0
ᴁ ©
Эксперт MS Access
 Аватар для АЕ
4088 / 2469 / 514
Регистрация: 13.12.2016
Сообщений: 8,397
Записей в блоге: 5
17.08.2026, 10:31
Цитата Сообщение от testuser2 Посмотреть сообщение
штатно это решается созданием обработчика по типу On Error Goto в каждой процедуре..
Да, если не сделать ни одного бага в коде. А иногда код приходится "вылизывать" больше года, т.к. вылазят новые жучки во всевозможных нетривиальных ситуациях, которые изначально и предположить не мог...
0
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
19.08.2026, 05:22
Цитата Сообщение от testuser2 Посмотреть сообщение
Решение проблеммы State Loss или Global Variable Reset
Новая версия рабочая, поскольку "критический" код выполняется в отдельно процессе Excel. Выполненная в виде надстройки, но не должно подключаться как надстройка, а как библиотека в референсах. Данная "надстройка" имеет 2 модуля mdLocal и mdRemote, и для реализации отслеживания сбоев VBA дополнительно запускает свою копию в отдельно процессе Excel и там устанавливается хук (с помщоью SetWinEventHook) на закрытие окон и т.о. образом, как уже писалось выше, отслеживается момент StateLoss. Возможно было бы даже удобнее разделить на два файла - удаленного и локального назначения, но, чтобы не надстраивать лишних пристроек над балаганами, сделал все в одном файле.
Пример использования.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Option Explicit
 
Private hWndForm As LongPtr
Private Productions As New Collection
Private Init As Boolean
 
Private Sub ExapmleUsing()
    If Init Then Else Initialize      ' инициализируем все нужные переменные
    Start_StateLossDetector           ' запускаем детектор
    
    Dim filePath$: filePath = "C:\Test\5555.txt"
    Dim fileNum&
    fileNum = StoreHandle(FreeFile)   ' открываем условный хэндл и сохраняем его в надежном месте
    Open filePath For Binary Access Read As #fileNum
    
    End ' не предвиденная плохая ситуация, сопровождаемая "State Loss", и прерывание кода
    
    '***
    Close fileNum
End Sub
 
Private Sub Initialize()
    If PersistData.Exists("Продукты") Then
        Set Productions = PersistData("Продукты")
    Else
        Productions.Add "редиска"
        Productions.Add "картошка"
        Productions.Add "укроп"
        Productions.Add "повидло"
        
        PersistData.Add "Продукты", Productions
    End If
    Init = True
End Sub
 
Private Sub Start_StateLossDetector()
    ' В VBA-проекте обязательно должна быть форма!
    hWndForm = GetFormHWnd(DummyForm)
    StartStateLossDetector _
        hWndForm, _
        "'" & ThisWorkbook.FullName & "'!Module1.AfterStateLoss_Event"
End Sub
 
Private Function StoreHandle(ByVal lHandle As Long) As Long
    ' Handles - объект Collection, находящийся в модуле надстройки, т.о. он защищен от сбоя в данной книге
    Handles.Add lHandle
    StoreHandle = lHandle
End Function
 
' При возникновении сбоя, если быть точнее сразу после него будет запщено это "событие"
Private Sub AfterStateLoss_Event()
    Debug.Print "AfterStateLoss_Event"
    ReleaseAllHandles ' освобождение всех хэндлов, оставшихся после аварийного завершения
    Initialize        ' восстанавливаем инициализацию переменных
'    Start_StateLossDetector ' запускаем по новой
End Sub
 
Private Sub ReleaseAllHandles()
    Dim Handle
    For Each Handle In Handles
        Close Handle
    Next
    Set Handles = New Collection
End Sub
Вложения
Тип файла: zip StateLossDetector.zip (41.7 Кб, 11 просмотров)
0
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
19.08.2026, 09:25
Цитата Сообщение от АЕ Посмотреть сообщение
вылазят новые жучки во всевозможных нетривиальных ситуациях, которые изначально и предположить не мог...
Буквально вот вылез такой случай, при написании вышепредставленного кода. Ни как не мог понять, событие EVENT_OBJECT_DESTROY приходит, но сравнение If LEvent = EVENT_OBJECT_DESTROY Then не проходит.
Как оказалось, константу надо обхявлять не так &H8001, а вот так &H8001&. Наглядно представить прблему может такой код:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Private Sub ExampleProblem()
    Const a1 As Long = &H8001
    Const a2 As Long = &H8001&
    Const a3 = &H8001
    Debug.Print Hex(&H8001)   ' 8001
    Debug.Print Hex(&H8001&)  ' 8001
    Debug.Print Hex(a1)       ' FFFF8001 (внезапно!)
    Debug.Print Hex(a2)       ' 8001
    Debug.Print Hex(a3)       ' 8001
    Debug.Print a1 = a2       ' False
End Sub
0
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
19.08.2026, 16:10
Добавлю послденее дополнение, дальше все изменения будут (если конечно будут) в репозитории
Если использовать ООП возможности VBA и, что важно, настройку PublicNoCreatable, то вполне можно в одном VBA-проекте использовать экземпляры класса из другого проекта, что позволяет в исходном проекте даже не созавать форму для реализации, того, о чем писалось выше, а инициализировать экземпляр класса из проекта-надстройки и инициализировать форму внутри этого экземпляра класса и т.о. использование детектора State Loss может выглядеть так.
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Private SLDetector As SLDetector
 
Private Sub ExampeUsing()
    Set SLDetector = New_SLDetector
    SLDetector.StartDetector "'" & ThisWorkbook.FullName & "'!Example2.AfterStateLoss_Event"
'    End
End Sub
 
Private Sub AfterStateLoss_Event()
    Debug.Print "AfterStateLoss_Event"
    ' Производим необходимые действия
    
    ' Перезапускаем детектор (если необходимо)
    Set SLDetector = New_SLDetector
'    SLDetector.StartDetector "'" & ThisWorkbook.FullName & "'!Example2.AfterStateLoss_Event"
End Sub
0
1412 / 874 / 93
Регистрация: 08.02.2017
Сообщений: 3,726
Записей в блоге: 2
21.08.2026, 17:31
Еще одна "надстройка года" от меня! Цель надстроки - автоматизировать экспорт vba-модулей в текстовые файлы и импорт их от туда, в целях упрощения гит-версионирования, упорядочивания модулей по папкам, упрощение миграции, или как его там.. в общем это, кога один модуль можно легко распространить на несколько проектов, раскопировав его по нескольким папкам или раскидав на него символьные ссылки. Другой неоспоримый плюс текстовых файлов, что с ними можно работать в текстовых редакторах. Конечно, подобных надстроек в сети, я уверен не мало, но я не хотел проверять, от части, из соображения, что, вроде бы не редко проще написать что-то самому, чем разбираться в чужом (или кажется проще, скорее всего даже так), при том другая причина, в том, что я даже уверен, что наверняка, там не реализована эта идея-фикс с символьными ссылками, которую мне почему-то хочется реализовать.
Принцип работы простой. При сохранении (при срабатывании события сохранения) файла с макросами, надстройка проверяет, существует ли папка в дирректории файла вида "Имя файла.vbaproject" и если существует, то происходит синхронизация состояния всех модулей проекта с папкой проекта. Если что-то изменилось в папке, следует нажать в vba-проекте Ctrl+S, чтоб произошел мерджинг всех изменеий. Много чего конечно и наверняка не доработано. Например спорные ситуации я не прорабатывал, когда файл изменился и там и сям.. Нужно строго соблюдать очередность - где-то что-то изменилось нажимать Ctrl+S. Также строго соблюдать уникальность имен модулей. Дальнейшие изменения будут в репозитории. Там много мусора. В начале я хотел сделать файловый мониторинг изменений в реальном времени, и, в общем, то он уже был готовый, если не учитывать идею с симлинками и джунками, а они уже вносят существенное усложнение, поэтому пока остановился на простой схеме - Ctrl+S.
Вложения
Тип файла: zip VBAGitHelper.xlam.zip (96.7 Кб, 16 просмотров)
0
ᴁ ©
Эксперт MS Access
 Аватар для АЕ
4088 / 2469 / 514
Регистрация: 13.12.2016
Сообщений: 8,397
Записей в блоге: 5
09.09.2026, 10:01
Поделюсь с коллегами и я своей надстройкой, которую собирал по крохе с просторов и кое-что сам писал. Собрал в нее то, что считал нужным для работы. Некоторые возможности, такие как информация по вагонам и судам или температура воды в Новороссийске скорее всего народу не нужны. Ну так и не пользуйтесь.. Остальное может пригодится. Ставить просто. Снабжена справкой. В меню появляется как "Дополнения". Для начала можете загрузить Help и посмотреть насколько она вам нужна.
Вложения
Тип файла: rar Help.rar (394.9 Кб, 30 просмотров)
Тип файла: rar InstallAE.rar (925.8 Кб, 14 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.09.2026, 10:01

Надстройки AddIns. Кто-нибудь работал с этим?
Надстройки AddIns. Кто-нибудь работал с этим? Где можно почитать рускоязычную доку?

Функция из надстройки приводит к ошибке: ошибка: "Sub or Function not defined"
добрый день. я сделал надстройку для Excel с публичной функцией: Public Function...

Вызов надстройки через VBA
Здравствуйте. Очень нужна Ваша помощь. Задача следующая: В VBA для Excel 2003 необходимо...

Всё про надстройки .XLA
Предлагаю в этой теме обсудить все аспекты надстроек .XLA . Частично эти вопросы затрагивались в...

Назначение комбинации клавиш макроса у надстройки
Есть надстройка в ней полезные макросы.....для вызова которых есть комбинации клавиш.... и так...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
269
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru