Страницы: 1 2 След.
RSS
VBA: Обработчик ошибок, пропуск куска кода
 
Коллеги, приветствую,

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

Необходимо, чтобы в случае ошибки, которая возникает в определенный момент в коде, часть кода пропускалась, появлялся MsgBox с определенным текстом, после чего макрос продолжал бы работать в нормальном режиме (если будет какая-нибудь другая ошибка далее - выскочит диалоговое окно).

Знаю, что задача простая, ну вот туплю что-то...
         
Код
            On Error GoTo ErrorHandler            
            Set iWb = GetObject("C:\Users\A670669\Desktop\SCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
            On Error Resume Next

На данный момент все как надо, только вот когда даже ошибки нет вылезает MsgBox.

Заранее спасибо.

P.S. Как-то криво написал название темы, должна была быть VBA: Обработчик ошибок, пропуск кода и продолжение выполнения макроса.
Изменено: Framed - 05.03.2019 00:54:10
 
Код
On Error Resume Next
If Err then Goto ...
 
Anchoret, вот так?
Код
 On Error Resume Next
            MsgBox "Произошла ошибка"
            If Err Then GoTo ErrorHandler
            Set iWb = GetObject("C:\Users\A670669\Desktop\SCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:






 
Цитата
Framed написал: только вот когда даже ошибки нет вылезает MsgBox
Обработчик ошибок поместите в самый конец кода, а перед ним должна быть строка Exit Sub
Код
On Error GoTo ErrorHandler
    Set iWb = GetObject("C:\Users\A670669\Desktop\SCR_Managers.xlsx")
    iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row
    Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
    iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
    With .ListColumns("Rate").DataBodyRange
        .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
        .Cells.Value = .Cells.Value
    End With
    iWb.Close False
    Exit Sub
'обработчик ошибок
ErrorHandler:
    MsgBox "Произошла ошибка"
End Sub
Согласие есть продукт при полном непротивлении сторон
 
Sanja, спасибо, но разве Exit Sub не остановит выполнение всего макроса, если ошибки не будет?

Я уточню, а то мне кажется, я плохо объяснил в шапке.
Код
'Код
'Код
'Код
 On Error GoTo ErrorHandler
            Set iWb = GetObject("C:\Users\A670669\Desktop\SCR_Managers.xlsx")
            iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
            Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
            iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
            With .ListColumns("Rate").DataBodyRange
                .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                .Cells.Value = .Cells.Value
            End With
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
'Код
'Код
'Код
Выполняется макрос, и вот на 5 строке может выскочить ошибка, например, если файла нет, или его имя неверное. Мне нужно, чтобы в этом случае, часть кода 5-13 строка игнорировалась, не выполнялась и выскочил бы MsgBox c текстом, например, "Нет файла или имя некорректно". Далее код, который идет после ErrorHandler должен выполняться в обычном режиме (обычный режим для меня - это когда дальнейшие ошибки не вернут меня к ErrorHandler, простите за убогое объяснение).

В случае же, если ошибки на 5 строке моего примера не возникнет - код работает в штатном режиме.
Изменено: Framed - 04.03.2019 20:03:53
 
Framed,
Код
On Error Resume Next
перед строкой, в которой вероятна ошибка
Код
If Err then Goto ...
после такой строки. Ну и замечание от Sanja,
 
Как-то не выходит. Дальнейшие ошибки в коде игнорируются, MsgBox вылезает, даже если ошибки не произошло.
 
только наверно так


Код
'Код
'Код
'Код
 On Error resume next
            Set iWb = GetObject("C:\Users\A670669\Desktop\SCR_Managers.xlsx")
            if err =0 then
                 iLastRowSCR = iWb.Sheets(1).Cells(Rows.Count, 1).End(xlUp).row
                 Set iBodySCR = iWb.Sheets(1).Range("B2:M" & iLastRowSCR)
                iWb.Names.Add Name:="BodySCR", RefersTo:=iBodySCR
                With .ListColumns("Rate").DataBodyRange
                    .Formula = "=IFERROR(VLOOKUP(A3,SCR_Managers.xlsx!BodySCR,12,0),0)"
                    .Cells.Value = .Cells.Value
                End With
                iWb.Close False
           else
                MsgBox "Произошла ошибка"
                err.clear  '  или on error goto 0
          end if
'Код
'Код
'Код
 
По вопросам из тем форума, личку не читаю.
 
БМВ, спасибо, все отлично, только теперь в случае ошибки ниже End If, VBA продолжит выполнение кода, даже если, к примеру, название листа out of range и так далее.  
 
Framed,  я не зря там написал '  или on error goto 0
В зависимости от потребностей или сбросить ошибку или и сбросить и прекратить обработку ошибок.
Конечно и через переход на метки можно сделать, но я отвык.
Изменено: БМВ - 04.03.2019 20:49:50
По вопросам из тем форума, личку не читаю.
 
БМВ, простите, я проглядел. Спасибо большое за помощь, теперь я понял больше, без вас не разобрался бы.

Цитата
БМВ написал: Конечно и через переход на метки можно сделать, но я отвык.
Я где-то читал, что метки не приветствуются в VBA. Да и мне привычнее с операторами условия  :)  
 
в документации вроде все есть
https://docs.microsoft.com/ru-ru/office/vba/language/reference/user-interface-help/on-error-statement
По вопросам из тем форума, личку не читаю.
 
Цитата
Framed написал: метки не приветствуются в VBA.
Метки не беда, если не злоупотреблять и если они не нарушаюют (не сильно нарушают) структуру кода
 
Причина ошибки в данном куске кода в чем заключается?
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, потенциально ошибка в том, что файл с таким названием может отсутствовать на рабочем столе у юзера. Этот файл (если он есть) в моем коде открывается, оттуда ВПР-ом подтягивается информация, после чего он закрывается. Если такого файла нет - мне нужно было, чтобы:

1. Выводилось сообщение со специальным текстом, т.е. MsgBox;
2. Пропускался кусок кода (который открывает файл, создает именной диапазон для ВПР, подтягивает куда надо данные с этого листа с помощью ВПР, превращает формулы в значения и закрывает книгу);
3. Макрос снова бы работал в обычном режиме (то есть в режиме "on error go to 0").

Вообще, мне помогли и тему можно было закрывать, но раз уж вы спросили :)

БМВ, да, и я даже прочитал это несколько раз перед тем, как создать тему. Просто, откровенно говоря, не доходило до меня, как это правильно использовать; примеры из гугла не добавили ясности. Одним словом, еще учиться и учиться.
Изменено: Framed - 05.03.2019 14:33:07
 
Цитата
Framed написал:
Nordheim , потенциально ошибка в том, что файл с таким названием может отсутствовать на рабочем столе у юзера.
А если так:

Код
Sub test()
    Dim fname$, iPath$
    iPath = "C:\Users\A670669\Desktop\SCR_Managers.xlsx"
    fname = Dir(iPath)
    If fname <> "" Then
        'обработка если файл существует
    Else: MsgBox "Произошла ошибка"
    End If
End Sub


Никакого On Error

PS:
Обработчик ошибок это конечно хорошо, вставил в начало и никаких проблем с кодом, зато потом вылезет какая ни-будь "бяка" в отчетах.
Изменено: Nordheim - 05.03.2019 14:48:24
"Все гениальное просто, а все простое гениально!!!"
 
Framed, очень много чего вам посоветовали - лень читать всё))
1. В большинстве случаев от меток можно абсолютно безболезненно избавится, но иногда они помогают. Например, можно избежать "ветвления" кода далеко "вправо" — вот ссылка на тему с холиваром)))

Итак, в чём проблема… Всё просто — код доходит до строки ErrorHandler: MsgBox "Произошла ошибка" и выводит сообщение об ошибке (как и должен). Чтобы этого избежать, я обычно делаю, как в #4 (Sanja), но можно и "в лоб" обойти:
Код
GoTo nx
            iWb.Close False
ErrorHandler:
            MsgBox "Произошла ошибка"
nx:
— в таком случае, если мы дошли до GoTo nx, то просто "перепрыгиваем" ErrorHandler на метку nx. Если же произойдёт ошибка, то макрос "перепрыгнет" уже к метке ErrorHandler, минуя GoTo nx.

P.S.: скорее всего, в вашем случае никакого On Error GoTo ErrorHandler не нужно — это подтверждает и наличие примеров, где легко без него можно обойтись. Я использую метки в основном, если нужно вернуться "выше по коду" (повтор ввода информации пользователем в случае ошибки) или, как уже сказал, чтобы избежать "ветвления" (многоуровневых вложенных "If—Else—End If").
Но дело (как кодить) исключительно ВАШЕ  ;)
Изменено: Jack Famous - 05.03.2019 15:34:40
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Nordheim,
тут есть подвох, я с таким встречаюсь регулярно (правда не со скриптамии, но не суть)
Код
    iPath = "C:\Users\A670669\Desktop\Год 2019\Документы раздолбая\" _
          & "Результаты совещания по вопросам бездумного использования длинных имен файлов и каталогов\" _
          & "Выступление главного систематизатора\……\SCR_Managers.xlsx"

Короче, при полном пути более 260 символов, файл есть, он виден, но открыть его не возможно, впрочем как и скопировать или удалить, понятно что лучше в этом случае обработать длину пути, но порой проще просто обратится и обработать ошибку.
Вариант 2, это уже последствия сетевого доступа к общим файлам. При переносе файлов или каталогов права не наследуются от каталога в который поместили файлы , а сохраняются прежними. Это может привести к тому что также видеть видно, а вот прочесть никак. И в этом случае без обработки ошибки не обойтись.

Но в целом я полностью согласен, что обрабатывать ошибку надо там, где избежать её не возможно другими методами.

Jack Famous, так как я родом из VBS, а там нет Resume, то перешел на метку по ошибке, обратно не вернешься, что означает не продолжить с того же места. а это означает или куча меток и отдельные обработчики для каждой ошибки или …..
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ: я родом из VBS
а я, стало быть, из VBA и могу использовать крутые штуки типа возврата наверх))
Вот такая, например
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
БМВ, На сколько я понимаю в данном случае путь прописывается руками, и визуально видно сколько символов.
Цитата
БМВ написал:
при полном пути более 260 символов, файл есть, он виден, но открыть его не возможно
Не сталкивался, потому наверное, что c Excel работаю постольку поскольку, это больше для саморазвития (интересные задания иногда встречаются).
Но теперь буду знать, а обработчиками в основном пользуюсь либо для заполнения коллекции либо в цикле где неправильный тип данных указывают и цикл не завершается пока ошибка не будет устранена.  ;)
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
Nordheim написал:
На сколько я понимаю в данном случае путь прописывается руками, и визуально видно сколько символов
да все верно, ремарка относилась скорее к тому, что бывает, когда невозможно отсечь возможность возникновения ошибки заранее.
По вопросам из тем форума, личку не читаю.
 
Цитата
БМВ написал:
так как я родом из VBS, а там нет Resume, то перешел на метку по ошибке, обратно не вернешься
Забыл, забыл ты свою родину ;) Нет там меток, и GoTo только в конструкции On Error GoTo 0.
 
Jack Famous, спасибо за разъяснения;
Nordheim, вам тоже большое спасибо, на самом деле, мне очень понравилось это решение, как и решение участника БМВ.
БМВ, спасибо за полезную информацию про ограничение.

Все-таки поясню: планируется, что файл, наличие которого проверяется, я буду высылать юзерам ежемесячно. У него относительно постоянная форма, меняются лишь данные. Соответственно, название файлу задаю тоже я. Файл носит вспомогательный характер. Вряд ли юзеры будут его переименовывать (я обязательно скажу, чтобы этого не делали) - их задача состоит лишь в том, чтобы один раз скопировать этот файл из Аутлука и куда-нибудь его закинуть, а после прописать корректный путь в VBA (а вот это им придется делать в любом случае самим, увы).
 
Цитата
Казанский написал:
Забыл, забыл ты свою родину
:-) вооот , там даже шанса не было :-) По сему и не применяю :-)
По вопросам из тем форума, личку не читаю.
 
Цитата
Framed написал:
(а вот это им придется делать в любом случае самим, увы)
А если написать юзерам что бы сохранили файл с макросом и файл из которого берутся данные, в одну папку, то и прописывать ничего не нужно. Как вариант, можно сделать выбор файла.
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
БМВ написал:
Короче, при полном пути более 260 символов
Еще короче. Для Exsel, кажется, 218 символов. Попадал.  :D
 
Off
Цитата
RAN написал:
Для Exsel, кажется, 218 символов
Это не совсем про файл, а скорее про обращение к нему из самого Excel
https://support.microsoft.com/en-us/help/213983/error-message-when-you-open-or-save-a-file-in-microsoft-excel-filename

This behavior is based on a 256-character limitation in Excel for creating links to another file. This limit of 218 characters for the path name is based on the following:•Up to 31 characters in a sheet name.

•Apostrophes and brackets used to denote the workbook name.

•An exclamation point.

•A cell reference.

For example, the path for a file might resemple the following:

  'c:\excel\personal\...\[my workbook.xls]up_to_31_char_sheetname'!$A$1

Если перевести кратко, то, для работы с другой книгой, ссылка не может быть больше 256 символов, включая дополнительные символы (скобки,апострофы, восклицательный знак), имя листа  и диапазон.   если учесть что  Адрес может быть $AAA$1000000 (12 сим) +31 на имя листа + 5 на спец символы, то на путь останется менее 218ти
256-12-31-5=208
По вопросам из тем форума, личку не читаю.
 
В дополнении  
Цитата
Nordheim написал:
А если написать юзерам что бы сохранили файл с макросом и файл из которого берутся данные, в одну папку
Вариант файла с макросом при открытии запрашивает папку  для сохранения, затем сохраняет текущую книгу в указанную папку, и удаляет модуль с процедурой сохранения.
создал доп. модуль в котором дублировал код из удаляемого модуля, потому что после первого открытия его больше не будет. Может понадобится.
"Все гениальное просто, а все простое гениально!!!"
 
Коллеги, прошу прощения заранее, что поднимаю старую тему и задаю в ней вопрос, но он связан с тем же макросом и с тем, что мне ответил пользователь Nordheim.
Цитата
Nordheim написал:
А если написать юзерам что бы сохранили файл с макросом
Файлы не с макросом, потому что модуль с ним находится в личной книге макросов.
Цитата
Nordheim написал:
Как вариант, можно сделать выбор файла.
Вот тут я хотел бы уточнить, если вы не против. Можно ли сделать такой алгоритм (но я точно не знаю, в самом макросе, или сделать отдельный), который поможет юзеру выбрать вспомогательный файл (как с сохранением, с помощью окна), а основной макрос бы ссылался на выбранный файл.

Зачем это нужно: планируются, что такие вспомогательные файлы будут отправляться юзерам раз в месяц, соответственно, можно их просто назвать одним именем и заменять один другим (как и реализованно в данный момент), но было бы лучше, если бы они сохранялись в специально созданной для этого папке, а юзеры могли бы просто "переключаться" между файлами, из которых нужно брать инфу.  
 
Framed, если вопрос не связан с темой (Обработчик ошибок, пропуск куска кода), то создавайте новую
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1 2 След.
Наверх