powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
8 сообщений из 8, страница 1 из 1
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920478
ъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ъ
Гость
Приветствую Уважаемый All!

Пишу в VBA пользовательский класс, и вот такой вопрос возник.
У класса есть такие методы:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
Sub D()
    ...
End Sub
   
Sub C()
    Call D
End Sub

Sub B()
    Call C
End Sub

Sub A()
    Call B
End Sub


т.е. вызов метода A объекта, приводит к вызову метода D "хрен-знает-какой" вложенности - A->B->C->D.
Дальше, в методе D, я определяю, что данные некорректны, и дальнейшее выполнение не имеет смысла .
И теперь вопрос: можно ли как-то, в методе D, "погасить" весь процесс (всю "цепочку" вызова A->B->C->D), БЕЗ ВОЗВРАТА в те процедуры-методы, из которых он вызван?
Или, например, по какому-то условию в D, процесс перешёл в метод KillMe (где я обнулю всё что нужно и "скажу" пользователю, всё что о нём думаю), и уже "назад не вернулся"?
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
Sub D()
    ...
    If IsDataError Then GoTo AllFuckedUp
    ...
    Exit Sub
AllFuckedUp:
    Call KillMe
End Sub
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920482
Казанский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Создайте в А обработчик ошибки (On Error Goto ...), а во вложенных не создавайте. При обнаружении в любой вложенной ошибки делайте Err.Raise ..., управление будет передано в ближайший обработчик ошибки, т.е. в обработчик ошибки в А.
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920515
Фотография VSVLAD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
+ Всё же можно создать обработчики во "вложенных" методах, но создавайте свою ошибку, и пробрасывайте её дальше. Какие сможете ошибки - обработаете, остальные - пробрасывайте через Err.Raise наружу, пока не дойдёте до того метода, который её обработает
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920520
ъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ъ
Гость
VSVLAD+ Всё же можно создать обработчики во "вложенных" методах, но создавайте свою ошибку, и пробрасывайте её дальше. Какие сможете ошибки - обработаете, остальные - пробрасывайте через Err.Raise наружу, пока не дойдёте до того метода, который её обработаетДа, спасибо!
В итоге, после совета от Казанский тоже к этому пришёл - генерировать "свою" ошибку и "транслировать" её "на верх" :)
Код: 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.
62.
63.
64.
65.
66.
67.
68.
69.
Option Compare Database
Option Explicit

Const vbMyDataError = vbObjectError + 1

Sub D()
On Error GoTo Err_
    Err.Raise vbMyDataError
    
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "D", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub
   
Sub C()
On Error GoTo Err_
    Call D
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "C", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub

Sub B()
On Error GoTo Err_
    Call C
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "B", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub

Sub A()
On Error GoTo Err_
    Call B
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "A", Err.Number
            MsgBox "!"
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub


Не так, конечно, "лаконично" как хотелось, но полюбому лучше, чем вводить статус завершения процедуры и проверять его в вызвавшей процедуре.
Всем спасибо!
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920837
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ълучше, чем вводить статус завершения процедуры и проверять его в вызвавшей процедуре.
Вот интересно, чем же это лучше? тем, что появляется потенция к double fault error? что нарушается нормальная трасса выполнения? что нет возможности определить точку возникновения проблемы? что процедуры фактически становятся не-повторноиспользуемыми?
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38920962
ъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ъ
Гость
AkinaВот интересно, чем же это лучше? тем, что появляется потенция к double fault error?

Это я не знаю что такое, но педивикия говорит, что в "современном защищенном режиме операционной системы" такое получить - постараться нужно,
типа использовать функции ядра ... у меня такого нет
Akinaчто нарушается нормальная трасса выполнения?

В том то и дело, что ХОТЕЛ, что бы "нарушалась", а в итоге - "не получил" :)
Выполнение всё равно "возвращается", по всему "дереву" процесса к вызванному методу.
Просто инициирует этот возврат, не десяток проверок возвр.статуса+Exit во всех вложенных методах,
типа
Код: vbnet
1.
2.
3.
4.
if D() = constMyDataError then
    C = constMyDataError
    Exit Function
end if 


и так же для Function B, и во всех точках вызова D, C и B

а одна "типовая" конструкция, которая описывается один раз и навсегда!
Сколько бы после этого я не менял (добавлял или убирал вызовы из A->B, B->C, C->D), данная конкретная ошибка в данных - будет обрабатываться, без доп.проверок.
Akinaчто нет возможности определить точку возникновения проблемы?

С этим, как раз, всё в порядке
во-первых так
Код: vbnet
1.
Err.Raise vbMyDataError, Sourse:="и здесь всё что угодно рисуем, последующие вызовы Err.Raise, в секции обработчика ошибок, это значение не меняют"

а, во-вторых, можно и дальше создавать/генерировать другие пользовательские ошибки, со своим номером, под каждый "случай"
Akinaчто процедуры фактически становятся не-повторноиспользуемыми?С этим, в общем согласен.
Только у меня всё кроме A - приватные методы, и к ним доступа не будет. Так что тут всё "на совести разработчика" :)
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38921078
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто альтернатива - конвертация процедуры в функцию,- более проста и прозрачна. Возвращаемое значение = статус, который прямо на месте можно и анализировать:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
function c(...) as integer ' скажем, вызывает d(), сама вызвана из b()
...
status = d(...)
if status < 0 then ' например, отрицательный код есть код ошибки
   с = status ' код ошибки, который нужно вернуть в вызвавшую функцию - тот же или другой
              ' а ведь ещё может существовать глобальная коллекция расширенных статусов
   exit function
end if
...
end function


Половина WinAPI так живёт...
...
Рейтинг: 0 / 0
Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
    #38921146
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъVSVLAD+ Всё же можно создать обработчики во "вложенных" методах, но создавайте свою ошибку, и пробрасывайте её дальше. Какие сможете ошибки - обработаете, остальные - пробрасывайте через Err.Raise наружу, пока не дойдёте до того метода, который её обработаетДа, спасибо!
В итоге, после совета от Казанский тоже к этому пришёл - генерировать "свою" ошибку и "транслировать" её "на верх" :)
Код: 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.
62.
63.
64.
65.
66.
67.
68.
69.
Option Compare Database
Option Explicit

Const vbMyDataError = vbObjectError + 1

Sub D()
On Error GoTo Err_
    Err.Raise vbMyDataError
    
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "D", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub
   
Sub C()
On Error GoTo Err_
    Call D
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "C", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub

Sub B()
On Error GoTo Err_
    Call C
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "B", Err.Number
            Err.Raise vbMyDataError
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub

Sub A()
On Error GoTo Err_
    Call B
Exit_:
    Exit Sub
Err_:
    Select Case Err.Number
        Case vbMyDataError:
            Debug.Print "A", Err.Number
            MsgBox "!"
        Case Else
            MsgBox Err.Description, vbCritical
            Resume Exit_
    End Select
End Sub


Не так, конечно, "лаконично" как хотелось, но полюбому лучше, чем вводить статус завершения процедуры и проверять его в вызвавшей процедуре.
Всем спасибо!Генерация ошибок очень накладная операция. Если прерывание происходит достаточно часто, то этот способ заметно затормозит программу.

Я бы сделал общий флажок и проверял его в начале каждого метода в цепочке. Это и выглядит короче:

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Dim bTerminate as Boolean
 
Sub C()
    If bTerminate then Exit Sub
    Call D
End Sub

Sub B()
    If bTerminate then Exit Sub
    Call C
End Sub

Sub A()
    If bTerminate then Exit Sub
    Call B
End Sub
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как завершить выполнение процедуры (метода объекта) из вложенной в неё процедуры (метода)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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