Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
3 / 3 / 0
Регистрация: 09.07.2022
Сообщений: 132
Excel

Обработчик ошибок

28.04.2023, 11:34. Показов 2026. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые форумчане, подскажите пожалуйста, существует ли возможность разместить всего лишь в одном волшебном месте такой код, который бы при возникновении ошибки в работе любого из сотен макросов, останавливал работу того макроса, который вызвал ошибку и сразу запускал другой макрос, в котором уже прописан алгоритм, позволяющий исправить ситуацию?

Этот макрос уже есть. Вопрос лишь в том, как его запустить при любой ошибке, и чтобы не пришлось прописывать обработчик ошибок в каждом макросе. Уж больно их много.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
28.04.2023, 11:34
Ответы с готовыми решениями:

Глобальный обработчик ошибок. Если отключить обработчик ошибок в одной из процедур, будет ли он работать в других?
Есть какой то код Sub main On error goto ErrorLine 'тут какой-то код call fng_1 'тут вызывается новая процедура 'тут какой-то...

Обработчик ошибок
Обрабатывает ли оператор on error ошибки типа compile error (к примеру syntax error) или только глобальные, которые с debug и end?

Обработчик ошибок
Наконец таки в изучении VBA добрался до момента когда понадобилось использование обработчика ошибок и приехал. Чтение форумов не очень...

33
14 / 10 / 4
Регистрация: 19.07.2016
Сообщений: 101
28.04.2023, 15:13
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от MikeVol Посмотреть сообщение
Fck_This, а вы внимательно прочли весь текст что под кодом идёт или просто решили поумничать? Там же написано в первом же обзаце сразу после кода:
В этом примере обработчик ошибок определяется для событий Workbook_SheetSelectionChange и Workbook_SheetActivate, но вы можете добавить обработчики для других событий, которые могут возникнуть в вашем проекте.
И я так понял что вы умеете правильно задать вопрос для ChatGPT? В моем вопросе к ИИ был стартовый вопрос от ТС.
Читайте внимательно что пишут в постах прежде чем выставить себя глупцом!
К чему вы вообще? Про иные события и так ясно, хотя бы исходя из этих. Во вторых ваш запрос, по всей видимости был корректен, раз он выдал вразумительный ответ, который действительно может с большой вероятностью решение на поставленную задачу. Про правильность это касательно пользователя Jack Famous, который так скептически относится к GPT, который по сути является усовершенствованной поисковой системой с результатом высокой релевантности. Чем же я выставил себя глупцом?
0
3 / 3 / 0
Регистрация: 09.07.2022
Сообщений: 132
28.04.2023, 15:27  [ТС]
И всё же господа, лучше обмениваться знаниями или попытками познания, чем репликами, тешащими или защищающими своё эго))) Это не продуктивно, и не ведёт ни к чему позитивному. Глупости всегда лучше игнорировать, так как они питаются вашим вниманием, и множатся от него как Гидра.
0
14 / 10 / 4
Регистрация: 19.07.2016
Сообщений: 101
28.04.2023, 15:52
Цитата Сообщение от Jack Famous Посмотреть сообщение
Fck_This, дабы не быть голословным, предоставьте, пожалуйста рабочее решение. Думаю, многим, в том числе и мне, это будет полезно.
Уже выложили решение, которое, возможно, и принесёт результат, причём дал его GPT, который у вас обычно "как всегда — текста много, толку мало" А дело было не в бобине...
По факту описываемый обработчик ошибок скорее относится к категории философского камня, т.к. обработчик событий подхватывает действия на листе (например ввод данных, а не работу кода, а события Error для Application не существует). А если лень добавлять везде обработчики, то можно программно добавить везде:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Dim oModules As Object
    Dim oCode As Object
    Dim iLine%, iEach%
    Set oModules = ActiveWorkbook.VBProject.VBComponents
    For iEach = 1 To oModules.Count
        'MsgBox oVB.Item(iEach).Name
        Set oCode = oModules.Item(iEach).CodeModule
        MsgBox oCode.CountOfLines
        If oCode.CountOfLines > 0 Then
            For iLine = oCode.CountOfLines To 1 Step -1
                If oCode.Lines(iLine, 1) = "End Sub" Then
                    'MsbBox "Код обработчика"
                End If
            Next iLine
        End If
    Next iEach
1
3 / 3 / 0
Регистрация: 09.07.2022
Сообщений: 132
28.04.2023, 15:57  [ТС]
Fck_This,
0
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
28.04.2023, 16:23
Цитата Сообщение от Fck_This Посмотреть сообщение
Уже выложили решение, которое, возможно, и принесёт результат, причём дал его GPT
это не так
0
1401 / 859 / 92
Регистрация: 08.02.2017
Сообщений: 3,646
Записей в блоге: 2
28.04.2023, 16:30
Код не оптимизирован под x64, недавно была тема, про SetWindowHookEx, можете там посмотреть.
В стандартном модуле. Событие ошибки готово, окно поймано, но надо его еще закрыть и дальше выполнять какой-то код. Закрыть это окно можно просто, сэмулировав нажатие ESC, если оно на переднем плане, в ином случае эта задачка, по моему, не очень простая, учитывая ,что это окно дочернее и нужно закрыть именно его а не весь Excel.
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
72
73
74
75
76
77
78
79
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
    ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
    (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
 
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5           'Система собирается активизировать окно
Private Const HCBT_CREATEWND As Long = 3  'Окно собирается создаваться. Система вызывает процедуру фильтра (hook) перед отправкой в окно сообщения WM_CREATE или WM_NCCREATE. Если процедура фильтра (hook) возвращает ненулевое значение, система уничтожает окно; функция CreateWindow возвращает значение  ПУСТО (NULL), но сообщение WM_DESTROY не отправляется в окно. Если процедура фильтра (hook) возвращает значение нуль, окно создается как обычно.
Private Const HCBT_DESTROYWND As Long = 4 'Окно собирается разрушаться.
Private Const HCBT_MINMAX As Long = 1     'Окно собирается быть свернутым или развернутым.
Private Const HCBT_MOVESIZE As Long = 0   'Окно собирается перемещаться или изменить размер.
Private Const HC_ACTION = 0
 
Private hHook As Long
 
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim RetVal
    Dim strClassName As String, lngBuffer As Long
    On Error Resume Next
    
    If lngCode < HC_ACTION Then
        NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
        Exit Function
    End If
 
    className$ = String$(256, " ")
    lngBuffer = 255
    windTitle$ = String$(256, " ")
    
    If lngCode = HCBT_ACTIVATE Then
        RetVal = GetWindowText(wParam, windTitle, lngBuffer)
        windTitle = Left$(windTitle, RetVal)
        RetVal = GetClassName(wParam, className, lngBuffer)
        className = Left$(className, RetVal)
'        Debug.Print "HCBT_ACTIVATE"; wParam; ; className; " "; windTitle
        If className = "#32770" And windTitle = "Microsoft Visual Basic" Then
            Debug.Print "Ошибка!!!"
        End If
    End If
 
    CallNextHookEx hHook, lngCode, wParam, lParam
 
End Function
 
Sub TestHook()
    Dim lngModHwnd As Long, lngThreadID As Long
 
    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)
 
    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
    ThisWorkbook.Sheets(1).Cells(1) = hHook
End Sub
 
Sub UnHook()
    If hHook = 0 Then
        hHook = ThisWorkbook.Sheets(1).Cells(1)
    End If
    UnhookWindowsHookEx hHook
    ThisWorkbook.Sheets(1).Cells(1).Clear
End Sub
 
Sub Ошибка()
    Dim a
    a = 1 / 0
End Sub
 
Sub НеОшибка()
    MsgBox "sffafasf"
End Sub
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
28.04.2023, 16:34
jampayeshe, попробуйте пересмотреть подход. За годы постоянной практики в VBA, ни у меня, ни у моих знакомых (профессиональных программистов) не возникло даже мысли о подобном. Всякое, конечно, может быть, но, мне кажется, что вы не с той стороны зашли, и вопрос является классическим "мне нужно X, для этого, наверное, нужно сделать Y и Z. Спрошу-ка я про для начала про Y".
Спросите сразу про X
0
1401 / 859 / 92
Регистрация: 08.02.2017
Сообщений: 3,646
Записей в блоге: 2
28.04.2023, 16:37
Цитата Сообщение от testuser2 Посмотреть сообщение
недавно была тема, про SetWindowHookEx
Глобальный хук на мышь Excel
0
28.04.2023, 16:43

Не по теме:

Fck_This, это ж матом. Куда модераторы смотрят?...

0
1401 / 859 / 92
Регистрация: 08.02.2017
Сообщений: 3,646
Записей в блоге: 2
28.04.2023, 18:40
Окно закрывается, осталось только подогнать под x64. А вот здесь, возможно, более правильный вариант хука Как из программы управлять другой, уже запущенной программой
Кликните здесь для просмотра всего текста
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, _
    ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" _
    (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" _
(ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetCurrentThreadId Lib "kernel32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hwnd As Long, _
                                                                        ByVal wMsg As Long, _
                                                                        ByVal wParam As Long, _
                                                                        lParam As Any) As Long
Private Const EM_SETPASSWORDCHAR = &HCC
Private Const WH_CBT = 5
Private Const HCBT_ACTIVATE = 5           'Система собирается активизировать окно
Private Const HCBT_CREATEWND As Long = 3  'Окно собирается создаваться. Система вызывает процедуру фильтра (hook) перед отправкой в окно сообщения WM_CREATE или WM_NCCREATE. Если процедура фильтра (hook) возвращает ненулевое значение, система уничтожает окно; функция CreateWindow возвращает значение  ПУСТО (NULL), но сообщение WM_DESTROY не отправляется в окно. Если процедура фильтра (hook) возвращает значение нуль, окно создается как обычно.
Private Const HCBT_DESTROYWND As Long = 4 'Окно собирается разрушаться.
Private Const HCBT_MINMAX As Long = 1     'Окно собирается быть свернутым или развернутым.
Private Const HCBT_MOVESIZE As Long = 0   'Окно собирается перемещаться или изменить размер.
Private Const HC_ACTION = 0
 
Private Const WM_LBUTTONDOWN As Long = &H201
Private Const WM_LBUTTONUP As Long = &H202
 
Private hHook As Long
 
Public Function NewProc(ByVal lngCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Static i&, j&, endBtn&
    Dim RetVal
    Dim strClassName As String, lngBuffer As Long
    On Error Resume Next
    
    If lngCode < HC_ACTION Then
        NewProc = CallNextHookEx(hHook, lngCode, wParam, lParam)
        Exit Function
    End If
 
    className$ = String$(256, " ")
    lngBuffer& = 255
    windTitle$ = String$(256, " ")
    
    Select Case lngCode
      Case HCBT_CREATEWND
        RetVal = GetClassName(wParam, className, lngBuffer)
        className = Left$(className, RetVal)
'        Debug.Print "HCBT_CREATEWND"; wParam; ; className
        i = i + 1
        If i = 4 Then
            If className = "Button" Then
                endBtn = wParam
            End If
        End If
      Case HCBT_ACTIVATE
        i = 0: j = j + 1
        If j = 1 And endBtn Then
            RetVal = GetWindowText(wParam, windTitle, lngBuffer)
            windTitle = Left$(windTitle, RetVal)
            RetVal = GetClassName(wParam, className, lngBuffer)
            className = Left$(className, RetVal)
'            Debug.Print "HCBT_ACTIVATE"; wParam; ; className; " "; windTitle
            If className = "#32770" And windTitle = "Microsoft Visual Basic" Then
                SendMessage endBtn, WM_LBUTTONDOWN, 1, ByVal 0
                SendMessage endBtn, WM_LBUTTONUP, 0, ByVal 0
                endBtn = 0
                Debug.Print "Ошибка!!"
                '!!!!Здесь должен быть исполняемый код
                '#####################################
                                
                '#####################################
            End If
        Else: j = 0
        End If
    End Select
 
    CallNextHookEx hHook, lngCode, wParam, lParam
End Function
 
Sub TestHook()
    Dim lngModHwnd As Long, lngThreadID As Long
    
    lngThreadID = GetCurrentThreadId
    lngModHwnd = GetModuleHandle(vbNullString)
 
    hHook = SetWindowsHookEx(WH_CBT, AddressOf NewProc, lngModHwnd, lngThreadID)
    ThisWorkbook.Sheets(1).Cells(1) = hHook
End Sub
 
Sub UnHook()
    If hHook = 0 Then
        hHook = ThisWorkbook.Sheets(1).Cells(1)
    End If
    UnhookWindowsHookEx hHook
    ThisWorkbook.Sheets(1).Cells(1).Clear
End Sub
 
Sub Ошибка()
    Dim a
    a = 1 / 0
End Sub
 
Sub НеОшибка()
    MsgBox "sffafasf"
End Sub
0
14 / 10 / 4
Регистрация: 19.07.2016
Сообщений: 101
29.04.2023, 15:06
Цитата Сообщение от Jack Famous Посмотреть сообщение
...не возникло даже мысли о подобном.
Вот это верно сказано, по сути код должен стремится к тому, чтобы ошибок не возникало, а не чтобы их отлавливать. Немного тупиковая позиция, особенно, если нужно подтягивать ради этой задачи api. Хотя всякое может понадобится.
0
3 / 3 / 0
Регистрация: 09.07.2022
Сообщений: 132
29.04.2023, 20:57  [ТС]
По поводу смысла в таком обработчике - сам код без ошибок. Но обрабатываются огромные массивы данных. Иногда памяти не хватает и происходит ошибка. Вот на такие случаи и нужен обработчик.
0
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
02.05.2023, 09:31
Цитата Сообщение от jampayeshe Посмотреть сообщение
обрабатываются огромные массивы данных. Иногда памяти не хватает
на каком моменте перестаёт хватать памяти — тот и обрабатывайте отдельно. У меня, в подавляющем большинстве случаев, нехватка памяти происходит из-за взятия массива из огромного диапазона (или несколько более меньших). Эти моменты прекрасно можно отследить и обработать.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18035 / 7738 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
11.05.2023, 15:58
Цитата Сообщение от jampayeshe Посмотреть сообщение
Уважаемые форумчане, подскажите пожалуйста, существует ли возможность разместить всего лишь в одном волшебном месте такой код, который бы при возникновении ошибки в работе любого из сотен макросов
Смотря, что вы называете "сотней макросов". Если у них разные точки входа, то такого единого обработчика нет, только вставлять в каждую функцию отдельно ручками, макросом, или расширением.
Если вы так называете функции, вызываемые одна из другой с одной точкой входа, то оборачиваете точку входа в единый On Error Goto xx, затем в настройках IDE ставите опцию "Break On Unhandled Errors":
Миниатюры
Обработчик ошибок  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.05.2023, 15:58
Помогаю со студенческими работами здесь

Обработчик ошибок On Error GoTo
'Составить программу подсчёта количества прожитых дней по введёной дате рождения до сегодняшнего дня. Sub ObrabotchikData() On...

Универсальный обработчик ошибок для VBA
Спасибо что обратили внимание на тему. В общем, нужно сделать 10 лаб, за 2 дня, к каждому приклеить обработчик ошибок. Решил начать с...

Обработчик ошибок
Доброго времени. Преподавать дал задание сделать обработчик ошибок при подключении база данных. Здесь идет подключение: Public Sub...

Обработчик ошибок
Для программы, нужно сделать обработчик ошибок(проверку). У меня есть уже есть в программе, что при случае когда программа просит задать...

Обработчик ошибок
Всем привет! Наверняка же кто-то уже писал универсальный обработчик ошибок? Типа: ... invoke function cmp eax, NO_ERROR jne...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru