Форум программистов, компьютерный форум, киберфорум
Наши страницы
VBA
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.77/31: Рейтинг темы: голосов - 31, средняя оценка - 4.77
Mishel915
206 / 13 / 2
Регистрация: 10.10.2009
Сообщений: 154
1

Два оператора On Error GoTo в одном макросе не срабатывают

13.01.2010, 21:38. Просмотров 5672. Ответов 11
Метки нет (Все метки)

Всем доброе время суток !

Макрос

Visual Basic
1
2
3
4
5
6
On Error GoTo metkaopen
     Workbooks("Книга2.xls").Activate
     GoTo metkadalee
metkaopen:
    Set wb1 = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Книга2")
metkadalee:
в общем модуле Книги1 с одним On Error GoTo срабатывает.

В макросе

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
On Error GoTo metkaopen
     Workbooks("Книга2.xls").Activate
     GoTo metkadalee
metkaopen:
    Set wb1 = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Книга2")
metkadalee:
 
.......
 
Обработка
 
........
 
On Error GoTo metkaop
     Workbooks("Книга3.xls").Activate
     GoTo metkadal
metkaop:
    Set wb2 = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Книга3")
metkadal:
в общем модуле Книги1 с двумя On Error GoTo срабатывает конструкция с метками только для первого On Error GoTo . Метки второго On Error GoTo управление программы не видет. Если Книга3 не открыта то возникает ошибка №9 - отсутствует книга.

Такой вопрос : допускается ли в одном макросе записывать два оператора On Error GoTo с представленными метками ? Или, - из-за чего не срабатывают метки второго On Error GoTo ?

Добавлено через 18 часов 28 минут
Во втором макросе поменял местами Книгу2 с Книгой3
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
On Error GoTo metkaopen
     Workbooks("Книга3.xls").Activate
     GoTo metkadalee
metkaopen:
    Set wb1 = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Книга3")
metkadalee:
 
.......
 
Обработка
 
........
 
On Error GoTo metkaop
     Workbooks("Книга2.xls").Activate
     GoTo metkadal
metkaop:
    Set wb2 = Workbooks.Open(Filename:=ThisWorkbook.Path & "\Книга2")
metkadal:
В этом случае ошибка №9 относится к Книге2. Выходит что два оператора On Error GoTo в одном макросе не срабатывают, а только один (первый).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.01.2010, 21:38
Ответы с готовыми решениями:

Как в одном макросе закрыть все книги Excel?
Всем доброе время суток ! Две книги Excel (Книга1 и Книга2)...

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

Не работает конструкция On Error GoTo
On Error GoTo Обработчик код..... Обработчик: код..... У меня...

Ошибка в макросе run-time error '13' type mismatch
Выдаётся ошибка при запуске макроса Sub fonts() Dim obj As Font, i As...

два оператора between в одном запросе не работают
Добрый день, может кто подскажет. Нужно сделать выборку с проверкой диапазона...

11
EducatedFool
0 / 0 / 0
Регистрация: 28.09.2009
Сообщений: 88
14.01.2010, 06:45 2
Такой вопрос : допускается ли в одном макросе записывать два оператора On Error GoTo с представленными метками ? Или, - из-за чего не срабатывают метки второго On Error GoTo ?
А Вы не используйте все эти метки - и проблем не будет.
К тому же, в Вашем случае использование оператора Goto (а, тем более, нескольких таких операторов) необоснованно.


Есть несколько вариантов.

Вариант 1: Открывает файл, если он не был открыт ранее.
Visual Basic
1
2
3
4
5
6
7
8
Sub test1()
    Filename = ThisWorkbook.Path & "\Книга3"
 
    Set wb = [B]GetObject(Filename)[/B]
    Application.Windows(Dir(Filename)).Activate
 
    Debug.Print wb.Worksheets(1).[a1]
End Sub
Вариант 2: (используется наиболее часто)
Visual Basic
1
2
3
4
5
6
7
8
9
Sub test2()
    On Error Resume Next
    
    Set wb1 = Workbooks("Книга1.xls")
    If wb1 Is Nothing Then Set wb1 = Workbooks.Open(ThisWorkbook.Path & "\Книга1")
 
    Set wb2 = Workbooks("Книга2.xls")
    If wb2 Is Nothing Then Set wb2 = Workbooks.Open(ThisWorkbook.Path & "\Книга2")
End Sub
Есть ещё с десяток вариантов.
0
Mishel915
206 / 13 / 2
Регистрация: 10.10.2009
Сообщений: 154
14.01.2010, 19:31  [ТС] 3
EducatedFool большое спасибо !

Ваши варианты это изменение (переворот) в моей программе !
0
Busine2009
Заблокирован
16.01.2010, 07:10 4
Mishel915,
Я тоже помню, что-то пытался сделать подобное. Я например не знаю, можно ли использовать несколько обработчиков ошибок в одной процедуре или нет. Но можно рассудить логически.
Обработчик ошибки должен находиться в начале процедуры. Т.е. после запуска процедуры в память закладывается обработчик ошибки. Если в процедуре будут 2 обработчика ошибок, то как ей выбрать из них нужный? Получается, что процедура берёт самый первый обработчик ошибок.
0
Abu
1154 / 279 / 22
Регистрация: 28.09.2008
Сообщений: 553
16.01.2010, 16:33 5
Если в процедуре будут 2 обработчика ошибок, то как ей выбрать из них нужный? Получается, что процедура берёт самый первый обработчик ошибок.
Вовсе нет, лично у меня выбирает последний (т.е. тот, что стоял перед ошибкой), вот пример:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Dim myByte As Byte
Dim bookName As String
On Error GoTo ErrLab1
Application.Workbooks.Open bookName
MsgBox "Книга открыта"
On Error GoTo ErrLab2
myByte = 256
Exit Sub
ErrLab1:
MsgBox "Нету такого файла " & bookName
bookName = "c:\for test\Файл1.xls" 'тут имя реально существующей книги
Resume 'возвращает на ту строку, где произошла ошибка
Exit Sub
ErrLab2:
MsgBox "Overflow"
Ещё можно отключать обработчик On Error GoTo 0 в месте, где ошибки уже быть не должно, это для того чтоб, ошибки, о которых мы пока не подозреваем не ловились обработчиком, и не казалось, что программа ведёт себя как ей вздумается. С On Error много всяких интересных прибамбасов, но если есть возможность ошибки избежать (например проверить файл на существование, перед открытием), то лучше воспользоваться этой возможностью, чем включать в код On Error.
0
Busine2009
Заблокирован
16.01.2010, 17:16 6
Abu,
то есть получается, что идёт чтение процедуры сверху вниз и когда доходит до обработчика ошибки, то обработчик ошибки помещается в память и заменяет там другой обработчик ошибки? Вы напишите, а не проще ли всё проверить на примере каком-нибудь, а я отвечу - неохота.
Я например использую обработчики ошибки специально, потому что есть ситуации, когда ошибка должна произойти обязательно, например, в Word если написать макрос по созданию Стиля и если этот Стиль уже существует в документе, то будет ошибка.
0
Abu
1154 / 279 / 22
Регистрация: 28.09.2008
Сообщений: 553
16.01.2010, 18:05 7
Цитата Сообщение от Busine2009 Посмотреть сообщение
то есть получается, что идёт чтение процедуры сверху вниз и когда доходит до обработчика ошибки, то обработчик ошибки помещается в память и заменяет там другой обработчик ошибки?
Понятия не имею, как там всё это при компиляции происходит, если кому-то интересно то он может просто прочесть статьи или книги про работу компиляторов (конкретно про работу компилятора vb).

Цитата Сообщение от Busine2009 Посмотреть сообщение
Вы напишите, а не проще ли всё проверить на примере каком-нибудь, а я отвечу - неохота.
Врятли я это напишу, но Вы уже ответили на свой вопрос - "не охота" - значит не интересно, чё тада спрашивать?


Цитата Сообщение от Busine2009 Посмотреть сообщение
Я например использую обработчики ошибки специально, потому что есть ситуации, когда ошибка должна произойти обязательно, например, в Word если написать макрос по созданию Стиля и если этот Стиль уже существует в документе, то будет ошибка.
Любой разработчик делает программу так, как ему удобно, и очень редко кто делает так, как надо (потому что считают, что так как удобно, так и надо). Дело Ваше, Вам за Вашу программу отвечать и выдумывать объяснения её некорректной работы . А что касается Стиля в Worde, то я вообще с VBA Word мало знакома, но мне кажется, что должен быть какой-то способ проверки существования этого самого загадочного "Стиля" (я пока не знаю о чём конкретно Вы говорите), и если его нету, то лучше написать этот способ самостоятельно, чем пихать в код On Error. Но не буду спорить, On Error займёт гораздо меньше времени, чем изобретение функции проверки. Так что тут дело вкуса и интереса.
0
Mishel915
206 / 13 / 2
Регистрация: 10.10.2009
Сообщений: 154
24.01.2010, 12:17  [ТС] 8
Busine2009,
Следующие два оператора On Error срабатывают в одном макросе.
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
On Error Resume Next
    Workbooks("Книга1.xls").Activate
    If Workbooks("Книга1.xls") Is Nothing Then Set wb1 = Workbooks.Open(ThisWorkbook.Path & "\Книга1.xls")
    On Error GoTo 0
    
...   ...
    
    On Error Resume Next
    Workbooks("Книга2.xls").Activate
    If Workbooks("Книга2.xls") Is Nothing Then Set wb1 = Workbooks.Open(ThisWorkbook.Path & "\Книга2.xls")
    On Error GoTo 0
Возможно заменив Книги на Стили программа будет предоставлять необходимый стиль.
0
Busine2009
Заблокирован
24.01.2010, 14:48 9
Mishel915,
эти операторы одинаковые, поэтому нельзя использовать этот пример для подтверждения того, что в одной процедуре можно размещать 2 обработчика ошибки.
0
НикоН
22 / 21 / 3
Регистрация: 21.01.2010
Сообщений: 95
25.01.2010, 07:26 10
Всем доброго дня!

Ребят обработчик ошибок в процедуре может быть только один.
Оператор On Error реагирует на сам факт ошибки, т.е. дает понять процедуре, что в случае возникновения ошибки необходимо перейти к метке обозначенной оператором GoTo и уже там продолжить работу, независимо от того какая ошибка возникла.

Читать это следует примерно так: - появилась ошибка иди туда.

Помимо этого On Error еще возвращает код ошибки, вот его уже можно обрабатывать.
1
Abu
1154 / 279 / 22
Регистрация: 28.09.2008
Сообщений: 553
26.01.2010, 00:43 11
Цитата Сообщение от НикоН Посмотреть сообщение
Ребят обработчик ошибок в процедуре может быть только один.
Нифига! Его может быть хоть десять! Вопрос в том, насколько он необходим (его количество). Да и процедура может быть настолько огромна, что замучаешься искать, где именно вылетает ошибка (поможет только трассировка), а отключение обработчика видимо и выдумано для отладки.
Цитата Сообщение от НикоН Посмотреть сообщение
Помимо этого On Error еще возвращает код ошибки, вот его уже можно обрабатывать.
Конечно можно, только если кто-то готов описывать в коде Select Case на все существующие ошибки, то да, конечно он тада может забить на On Error GoTo 0.

P.S. Возможно я просто не врубаюсь в вышесказанное, в этом случае прошу простить мне мою некомпетентность.
1
НикоН
22 / 21 / 3
Регистрация: 21.01.2010
Сообщений: 95
26.01.2010, 08:33 12
Цитата Сообщение от Abu Посмотреть сообщение
Любой разработчик делает программу так, как ему удобно, и очень редко кто делает так, как надо (потому что считают, что так как удобно, так и надо). Дело Ваше, Вам за Вашу программу отвечать и выдумывать объяснения её некорректной работы .
Вот тут я с тобой совершенно согласен!
Обработчик позволит хотя бы корректно завершить работу программы и предложит обратиться к разработчику. Поэтому, я всегда встраиваю обработчик даже там, где он казалось бы не нужен Т.к. пользователь зверь особый и смогет сделать то, чего сделать теоретически не возможно Да и глупых вопросов меньше возникнет.
Цитата Сообщение от Abu Посмотреть сообщение
Нифига! Его может быть хоть десять! Вопрос в том, насколько он необходим (его количество).
Это тоже верно, но только от части. Работает всегда только один обработчик, поэтому не вижу смысла его переопределять. Это только раздует процедуру. Реально проще через пол года дорабатывать Case, чем разбираться какая метка за что отвечает и куда она тебя потом пошлет))) Я давно пытаюсь строить логику так, что бы как можно меньше меток было.
Цитата Сообщение от Abu Посмотреть сообщение
Да и процедура может быть настолько огромна, что замучаешься искать, где именно вылетает ошибка (поможет только трассировка), а отключение обработчика видимо и выдумано для отладки.
Эт точно!!!
Как то написал процедурку для бухгалтерии. 6 листов мелко напечатанного текста (специально этого монстра в ворд копировал). Так когда они попросили ее "чуть чуть подправить" я вспомнил всех богов и боженят
Цитата Сообщение от Abu Посмотреть сообщение
Конечно можно, только если кто-то готов описывать в коде Select Case на все существующие ошибки, то да, конечно он тада может забить на On Error GoTo 0.
А все возможные ошибки и не надо обрабатывать. Только наиболее вероятные, это как правило не более 3-4 ошибок. А в Case Else вставляем корректное выход из процедуры и сообщение об ошибке для пользователя.
0
26.01.2010, 08:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2010, 08:33

Верно ли утверждение: « действие оператора continue; в приведенных ниже примерах эквивалентно действию оператора goto next; ».
Помогите пожалуйста ответить на вопрос,если можно с примером;Верно ли...

Замена оператора goto
Здравствуйте. Подскажите, пожалуйста, как в представленном коде правильно...

Необходимо избавиться от оператора goto
#include <CONIO.H> #include <STDIO.H> #include <CTYPE.H> #define STARTX ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru