powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Как узнать имя sub
25 сообщений из 42, страница 1 из 2
Как узнать имя sub
    #39847881
quickstar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Нужен лог ошибок, в котором записано какой sub был вызван в момент появления ошибки.
Как узнать имя вызванного sub?
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847908
Фотография sdku
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стесняюсь спросить:а зачем?
Если ошибка в коде то это не код
Если ошибка возникает в результате действий пользователя то код и пишется для того чтоб этого избежать (часто "защита от дурака" занимает намного больший объем чем "полезный" код)
обработчик ошибок обязан присутствовать в сколь-нибудь "серьезном" коде.
Единственное-отключение питания. В зависимости от важности информации применяют ИБП
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847917
ROI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarДобрый день!
Нужен лог ошибок, в котором записано какой sub был вызван в момент появления ошибки.
Как узнать имя вызванного sub?
В обработчике ошибок и напишите имя процедуры.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847918
ROI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstar,

Да и ошибка-ошибке рознь.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847953
quickstar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ROI, вот и нужно понять как имя процедуры через VBA узнать?
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847956
quickstar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sdku, чтобы знать где именно ошибка возникла.
чтобы опираться на факты, а не на мнение пользователя о том, что произошло.
открыл лог и посмотрел в какой процедуре ошибка была.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39847958
quickstar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может есть метод как узнать строку, на которой произошла ошибка?
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848009
Фотография sdku
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarsdku, чтобы знать где именно ошибка возникла.
чтобы опираться на факты, а не на мнение пользователя о том, что произошло.
открыл лог и посмотрел в какой процедуре ошибка была.Вы говорите об этапе отладки.А при использовании приложения не должно быть никаких ошибок. Для этого и создан обработчик ошибок.Если она случится, а обработчика нет,что произойдет? Поэтому-то он и нужен.Какие при этом выполнятся действия зависит только от Вас (В том числе и запись кода ошибки и имя объекта в таблицу ). Лично мне не известно свойство которое бы возвращало имя процедуры. Да и вся Ваша затея весьма сомнительна-после передачи в работу проекта возникновение ошибок-плохая(никудышняя) программа. тынц
(Много ошибок,которые останавливают работу программы Вы встречали в Ворде или Ёкселе)
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848031
Фотография vmag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarНужен лог ошибок, в котором записано какой sub был вызван в момент появления ошибки.
Как узнать имя вызванного sub?
- в момент появления ошибки уже никакой sub не вызывается, программа вылетела и всё...
- по идее в каждой стремной процедуре должен быть тот самый обработчик ошибок, который и может при желании писать лог вместо вылета программы, вот один из простых примеров:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Public Sub1
On Error Goto er1
' тело процедуры
' ....
' тело процедуры
Exit Sub
er1:
' Вот тут и сообщение что эта плюха именно тут в Sub1
' Вот тут и запись лога если нужно...
End Sub1



sdku(часто "защита от дурака" занимает намного больший объем чем "полезный" код)
Ну почти всё так как уже говорили, главное чтобы программа говорила что не так, а не тупо вылетала...
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848064
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarМожет есть метод как узнать строку, на которой произошла ошибка?Err.Source
Если у строки есть метка - именно она и будет в этом свойстве.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848065
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стоп, вру. Это Access - т.е. err.source содержит имя процедуры/функции, в которой возникла ошибка.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848070
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaСтоп, вру. Это Access - т.е. err.source содержит имя процедуры/функции, в которой возникла ошибка.нее, это будет имя vba-проекта базы (оно не обязательно совпадает с именем БД)
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848071
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarМожет есть метод как узнать строку, на которой произошла ошибка?метод есть - erl
Но для того что бы она возвратила что-то полезное, нужно что бы строка на которой произошла ошибка имела числовую метку
Типа этого
Код: vbnet
1.
2.
3.
4.
5.
6.
Sub test()
On Error Resume Next
    Dim i As Long
4:  i = 1 / 0
    Debug.Print Erl
End Sub
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848077
ROI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court,

Зачем такие извращения
делаем стандартный обработчик ошибок
в 99 случаех хватает

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Private Sub roi_PermissView()
On Error GoTo HandleErro
........
........    
 
ExitProc:
    Exit Sub
HandleError:
    MsgBox vbCrLf & Err.Description & _
            vbCrLf & vbCrLf & "  Имя объекта = " & Me.Name & _
            vbCrLf & vbCrLf & "  Имя процедуры = roi_PermissView", _
            vbCritical, "Ошибка " & Err.Number
    Resume ExitProc
End Sub


это для форм.
для модулей убираем Me.Name
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848086
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ROI,

И в чём "извращение" ?

ТС хочет "запилить" глобальный обработчик ошибок, разве ещё кто-то не понял ?
Вполне похвальное желание, имхо, все через это проходили :)

Плюсы вполне очевидные:
- везде, во всех подпрограммах, будет стандартный обработчик ошибок, который можно даже в шаблон Sub/Function вставить и забыть о нём навсегда.
- обработчик ошибок один для всего, а там уже делай в нём что хочешь, - хочешь в лог пиши, хочешь смс-ку разработчику отправляй.
- в режиме отладки - реагировать так, а в нормальном, рабочем режиме - иначе. И весь перевод из одного режима в другое, - это изменение значения одной константы
- можно предусмотреть возврат из обработчика какого-то кода, по которому "упавшая" процедура будет действовать дальше
В общем, что-то типа такого
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
ExitProc:
    Exit Sub
HandleError:
    ErrHandleResult = GlobalErrHandle (ErrProc := "MySub", ErrLine := Erl, ErrMsg := MyErrMsg)
    Select Case ErrHandleResult 
        Case 0: Resume
        Case 1: Resume Next
        Case 2: Resume ExitProc
        ...
        Else: MsgBox MyErrMsg: Resume ExitProc
    End
    Resume ExitProc
End Sub



Но, реально, в ВБА, сделать такое "по-простому" не получится.
Разве что, писать какой-то парсер модулей, который будет "бегать" по процедурам, нумеровать строки, определять наименование подпрограммы и прописывать блок обработки ошибок
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848137
Слышал про MZTools. Может автору поможет. Сам не пользовался.
Вот:
Автоматическая вставка обработчиков ошибок в модули
Вставка комментариев в заголовок процедуры, с автоматической вставкой времени, имени модуля и процедуры, возможностью указать автора процедуры
Автоматическая нумерация строк кода
Снятие нумерации со строк кода
Создание шаблонов часто используемых кодов
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848167
alecko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все уже написано
кстати пользую, модифицированный под себя конечно, но суть та же
в обычных процедурах по err.raise улетаем в головную, где происходит обработка события ошибки - выход из каких-то программ(закрытия Excel скажем, запись в лог и т.д. и т.п.)
все это используется для модулей класса и аналогичных вещей где одна функция вызывает кучу подфункций.
создатель назвал его "Всплывающий обработчик ошибок".
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848226
ROI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtНо, реально, в ВБА, сделать такое "по-простому" не получится.
Разве что, писать какой-то парсер модулей, который будет "бегать" по процедурам, нумеровать строки, определять наименование подпрограммы и прописывать блок обработки ошибок
Опять повторюсь
--Зачем такие извращения!?
Alecko вам даже ссылку дал (изучайте)
Что доктор прописал.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848275
Фотография vmag
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще не понимаю зачем весь этот огород с наворотами по обработке ошибок, да еще с указанием строки...
Если в этом есть у кого очень острая необходимость, советую срочно просто поменять профессию, это не ваша стезя...
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848332
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vmagВообще не понимаю зачем весь этот огород с наворотами по обработке ошибок, да еще с указанием строки...
Честно говоря, не ожидал от Вас такого ответа :)
Эти навороты обязательно нужны в любой более-менее сложной программе, передаваемой заказчику, который не разбирается в Акцессе и не полезет в отладчик. Это просто необходимо для качественной поддержки приложения. Обработчик должен выдать подробную информацию, которую можно послать скриншотом разработчику для быстрого определения источнока ошибки.
Ни одна более-менее сложная программа не обходится без ошибок, это сделать практически не реально. К тому же бывают не зависящие от качества написания кода ошибки: диска, сети, повреждения файлов, корявые данные и т.д. и т.п. - всех ситуаций не предусмотришь и все баги выловить тоже практически не реально.

Я всегда передаю заказчику программы, которые выводят подробную информацию об ошибке, включая стек вызова процедур с номерами строк в каждой процедуре. Без использования MZ-Tools сделать корректный обработчик быстро нельзя, ибо нужно нумеровать строки и вписывать имя модуля и имя процедуры текстом, т.к. получить эти данные без запущеного редактора VBA не возможно, это абсолютно точно, изучал вопрос подробно. Тулза позволяет это сделать одним нажатием клавиши.

Могу привести здесь мои шаблоны обработчиков и саму процедуру обработки, обкатанные на многих программах и клиентах. Типов обработчиков как минимум нужно 2 - "всплывающий" и "клиентский" - выводящий собственно сообщение об ошибке.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848348
quickstar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MrShin, да, покажите, пожалуйста.
Я хочу пользователя всего-лишь уведомить, что "ошибка записана в лог", а весь необходимый набор данных отправляется мне в MySQL.
От данных о компе и сборке Access до строки, в которой произошла ошибка.
Цель проста - без общения с пользователем понимать источник и причину бага.

Пользователь рассказывает свое мнение. а нам нужно опираться на факты.
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848375
ROI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
quickstarMrShin, да, покажите, пожалуйста.
слепой вы чёли.
https://www.sql.ru/forum/1283697/obrabotka-oshibok-pri-vyzove-procedury-iz-procedury
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848405
Фотография sdku
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vmagВообще не понимаю зачем весь этот огород с наворотами по обработке ошибок, да еще с указанием строки...+100500
MrShinНи одна более-менее сложная программа не обходится без ошибок, это сделать практически не реально. К тому же бывают не зависящие от качества написания кода ошибки: диска, сети, повреждения файлов, корявые данные и т.д. и т.п..Еще как обходится.
Разве что непредвиденные ошибки,которые и возникают по вышеперечисленным причинам (достаточно знать что она возникла,без разницы где-потому как возникнуть может в любом месте, и надо разбираться с "железом" или сетью).А все остальное-выполненный небрежно(или вообще не выполненный) этап разработки называемый ОТЛАДКА(который зачастую очень трудоемок,сложен и занимает много времени-а все о чем говорится в этом топике есть попытка переложить часть этого этапа на пользователя и РС)-передавать такую программу заказчику ой как рано
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848409
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я использую MZ-Tools 8, он платный, но есть бесплатный V3, там шаблоны аналогичные.

Вот наиболее используемый шаблон MZ-Tools для вывода сообщения об ошибке, используется в процедурах, которые вызываются системой и могут взамидействовать с пользователем - события обычно
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    On Error GoTo ErrorHandler

$P[METHOD_BODY_EXCLUDING_DECLARATIONS]$P[I]
ExitHere:
    On Error Resume Next
    Exit $P[CODE_ELEMENT_KIND_KEYWORD]
ErrorHandler:
    LogError Err.Number, Err.Description, Erl, "$P[CODE_ELEMENT_NAME]", "$P[PARENT_CODE_ELEMENT_NAME]"
    Resume ExitHere
    Resume '>> remove in release


Здесь $P
Код: _ELEMENT_NAME
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 заменяется на имя процедуры, а $P[PARENT_CODE_ELEMENT_NAME] - на имя модуля. $P[METHOD_BODY_EXCLUDING_DECLARATIONS]$P[I] - здесь будет код процедуры, $P[CODE_ELEMENT_KIND_KEYWORD] заменяется на Sub, Function или Property в зависимости от типа процедуры.
Второй Resume, который никогда не выполняется в обычном режиме, нужен для удобства отладки - получив сообщение об ошибке, прерываем выполнение, возвращаемся из LogError по Ctrl-Shift-F8, руками с помощью Ctrl-F9 переводим выполнение на второй Resume и нажав F8 попадаем на строку, вызвавшую ошибку, где можем проанализировать переменные, исправить и заново запустить код с проблемной строки без перезапуска всего приложения.

Это шаблон для "всплывающего обработчика, используется в процедурах, которые вызываются только другими процедурами:
 [code=vbnet]
    On Error GoTo ErrorHandler
$P[METHOD_BODY_EXCLUDING_DECLARATIONS]$P[I]
ExitHere:
    Exit $P[CODE_ELEMENT_KIND_KEYWORD]
ErrorHandler:
    Debug.Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
    Err.Raise Err.Number, "$P[CODE_ELEMENT_NAME] of $P[PARENT_CODE_ELEMENT_NAME]", Err.Description & vbCrLf & "in $P[CODE_ELEMENT_NAME] of $P[PARENT_CODE_ELEMENT_NAME] at " & Erl
    Resume '>> remove in release


Задача этого обработчика - только добавить в сообщение об ошибке дополнительную информацию о месте ошибки и отправить ошибку выше. Конструкция
Код: vbnet
1.
Debug.Assert Not (STOP_AT_ERROR And IS_DEV)


останавливает выполнение для отладки до передачи ошибки выше. Соотвественно, константы STOP_AT_ERROR и IS_DEV - просто булевские, в режиме отладки обе должны быть True, в продакшне просто меняю значение IS_DEV на False и остановок с перебрасыванием в редактор не будет.

Третий тип - всплвающий обработчик с финальным кодом, который должен быть выполнен в любом случае, обычно это закрытие курсоров:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    On Error GoTo ErrorHandler
$P[METHOD_BODY_EXCLUDING_DECLARATIONS]$P[I]
ExitHere:
    On Error Resume Next
    Dim err_num As Long, err_descr As String, err_ln As String
    If Len(err_descr) > 0 Then GoTo ErrorRaise
    Exit $P[CODE_ELEMENT_KIND_KEYWORD]
ErrorHandler:
    err_num = Err.Number: err_descr = Err.Description: err_ln = Erl
    Debug.Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
    Resume ExitHere
ErrorRaise: On Error GoTo 0
    Err.Raise err_num, "$P[CODE_ELEMENT_NAME] of $P[PARENT_CODE_ELEMENT_NAME]", err_descr & vbCrLf & "in $P[CODE_ELEMENT_NAME] of $P[PARENT_CODE_ELEMENT_NAME] at " & err_ln
    Resume '>> remove in release


Финальный код вставляется как и в случае первого обработчика сразу после On Error Resume Next

Ну и, собственно процедура записи в базу и вывода ошибки на экран:
Код: vbnet
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.
'// module with error handling functions
    ' Purpose: Generic error handler.
    ' Logs errors to table "ErrorLog".
    ' Arguments: lngErrNumber - value of Err.Number
    ' strErrDescription - value of err.description
    ' strLine - code line number (Erl) Erl=0 if no row number in the line
    ' strCallingProc - name of sub|function that generated the error.
    ' strCallingModule - name of code module that generated the error.
    ' vParameters - optional string: List of parameters to record.
    ' bShowUser - optional boolean: If False, suppresses display.
Function LogError(ByVal lngErrNumber As Long, ByVal strErrDescription As String, strLine As String, _
                  strCallingProc As String, Optional strCallingModule As String, Optional vParameters = "{Missing}", Optional bShowUser As Boolean = True) As Boolean
    On Error GoTo Err_LogError
    Dim strMsg As String                              ' String for display in MsgBox
    Dim rst    As DAO.Recordset                       ' The Aph_tblErrorLog table
    Select Case lngErrNumber
        Case 0
            Debug.Print strCallingProc & " called error 0."
        Case 2501                                     ' Cancelled
            'Do nothing.
'        Case 3314, 2101, 2115                         ' Can't save.
'            If bShowUser Then
'                strMsg = "Record cannot be saved at this time." & vbCrLf & "Complete the entry, or press <Esc> to undo."
'                MsgBox strMsg, vbExclamation, "Error"
'            End If
        Case Else
            If bShowUser Then
                strMsg = "Error " & lngErrNumber & ": " & strErrDescription & vbCrLf & "in " & _
                strCallingProc & " of " & strCallingModule & " at " & strLine
                Interaction.MsgBox strMsg, vbExclamation, "Error " & Now()
            End If
            'log the error to database
            Set rst = CurrentDb.OpenRecordset("tbl_BMS_ErrorLog", , dbAppendOnly)
            rst.AddNew
            rst![ErrorNum] = lngErrNumber
            rst![ErrorDescription] = Left$(strErrDescription, 255)
            rst![ErrLine] = strLine
            rst![CallingProc] = strCallingProc
            rst![Module] = strCallingModule
            rst![CreatedTimeStamp] = Now()
            rst![UserName] = GetCurrentUserID()
            If Not IsMissing(vParameters) Then
                rst![Parameters] = Left(vParameters, 255)
            End If
            rst.Update
            rst.Close
            LogError = True
    End Select

Exit_LogError:
    Set rst = Nothing
    Exit Function
Err_LogError:
    strMsg = "An unexpected situation arose in your program." & vbCrLf & _
             "Please write down the following details:" & vbCrLf & vbCrLf & _
             "Calling Proc: " & strCallingProc & vbCrLf & _
             "Error Number " & lngErrNumber & " in line " & strLine & vbCrLf & strErrDescription & vbCrLf & vbCrLf & _
             "Unable to record because Error " & Err.Number & " in line " & Erl & vbCrLf & Err.Description
    Interaction.MsgBox strMsg, vbCritical, "LogError()"
    Resume Exit_LogError
End Function


Процедура не зациклится, если возникнет ошибка при ее выполнении (например, если таблица с логами ошибок будет недоступна)

На картинке один из примеров выдачи, когда ошибка возникла на 3-м уровне вызовов процедур, при этом в самой верхней процедуре, взаимодействующей с пользователем (cmdAccept_Click) были не пронумерованы строки, поэтому самый последний символ - 0, а не номер строки. Т.к. в этой процедуре было несколько сот строк, то определить причину было сложно, поэтому стараюсь не забывать нумеровать строки
...
Рейтинг: 0 / 0
Как узнать имя sub
    #39848413
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sdkuэтап разработки называемый ОТЛАДКА
Кроме отладки вобщем случае есть этап тестирования, котрый обычно выполняется не разработчиком, а тестером, котрый может не занть VBA совсем, и подробная выдача жизненно необходима.
...
Рейтинг: 0 / 0
25 сообщений из 42, страница 1 из 2
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Как узнать имя sub
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]