Как использовать On Error, чтобы сломать al oop в VBA? - PullRequest
1 голос
/ 03 августа 2020

В настоящее время я создаю форму, которая содержит одну многостраничную форму с 11 страницами. На каждой странице есть несколько флажков, от 3 до 12 флажков. Флажки представляют элементы списка, которые выглядят следующим образом:

Я планирую использовать двумерное для l oop (для l oop внутри для l oop), чтобы установить каждый флажок, используя следующий синтаксис.

Я привык к Python, поэтому я думал l oop до тех пор, пока не произойдет ошибка (с указанием, что флажков больше нет), а затем прервите текущий l oop и продолжите.


For Each pg In Me.MultiPage1.Pages
    x = 1
    For i = 0 To 12 
        If ActiveSheet.Shapes("CheckBox" & x & i).Value = xlOn Then
            'Code to be executed
             x = x = 1
    On Error ExitHandler

ExitHandler:
    Exit

Итак, я пытаюсь сделать что-то похожее на функциональность continue внутри Python. Или, возможно, я делаю это совершенно неправильно.

Более того, я также не уверен, что мой метод присвоения имен флажкам правильный, поскольку они связаны с элементами списка, который выглядит следующим образом:

1.1
1.2
1.3
...

11.1
11.2
11.3

Я также понимаю, что названия флажков могут быть немного запутанными. Я использовал следующий метод. Это выглядит так:

Page 1
CheckBox11
CheckBox12
CheckBox13 
CheckBox14

Page 2
CheckBox21,
CheckBox22, 
CheckBox23, 
CheckBox24,

...
Page 11
CheckBoxEleven1,
CheckBoxEleven2, 
CheckBoxEleven3, 
CheckBoxEleven4, 
CheckBoxEleven5, 

Я использовал «Одиннадцать», потому что имена флажков для 1.11 и 1.12 противоречили друг другу и вызывали ошибку неоднозначного имени.

Ответы [ 5 ]

1 голос
/ 03 августа 2020

Попробуйте следующий подход:

Sub testSelectSheet()
   Sheets("Operational").Activate
    For Each pg In Me.MultiPage1.Pages
        x = 1
        For i = 0 To 12
            On Error Resume Next
            'Use True here, to return the check box value:
            If ActiveSheet.Shapes("CheckBox" & x & i).Value = True Then
                'Code to be executed
                 x = x = 1
                 If Err.Number <> 0 Then
                    Err.Clear: On Error GoTo 0 'clear the error and stopping On Error Resume next effect.
                    'record the error:
                    Debug.Print "Error: " & Err.Number & ", Error description: " & Err.Description & " on CheckBox" & x & i
                    'if you want exiting throudh error handler you can use:
                    GoTo ExitHandler
                    ' or if you want exiting, exit directly"
                    Exit Sub
                    'not using any of the above ways to exit, the code will only skip this control and jump to the next one. Only a record in Immediate Window will be made...
                 End If
                 On Error GoTo 0 'make the code stop on error for the next lines
            End If
        Next i
    Next
ExitHandler:
   'no need for Exit Sub, because this is the last procedure row and code exits anyhow...
End Sub
1 голос
/ 03 августа 2020

Basi c logi c для обработчика ошибок в VBA выглядит примерно так:

Sub Something()

On Error GoTo ErrorHandler

    'Your loop here

    Exit Sub 'Exit sub if no error appears
    
ErrorHandler:
        ' If error do something else
End Sub
1 голос
/ 03 августа 2020

Если вы хотите выйти из l oop при возникновении ошибки, это можно сделать с помощью On Error GoTo ExitHandler. Как указано выше в steph ie, обработчик необходимо разместить перед l oop. Вам также не хватает инструкции GoTo. Вам также понадобится оператор Exit Sub перед ExitHandler (если вы не хотите запускать ExitHandler, даже если ошибки не было - тогда вы его оставите).

Я установил упрощенную структуру:

Sub Test()
    Dim i As Long
    
    'Error handler before the loop!
    On Error GoTo ExitHandler
    
    For i = 0 To 12
        'Code to be executed
         Debug.Print 1 / 0

    Next i
    
    MsgBox "No error"
    'Exit sub to avoid that the ExitHandler runs if no error occurs
    'Leve the Exit sub if you want to run the EXitHandler even if no error occurs
    Exit Sub
ExitHandler:
    'Code to perform when an error occurs
    MsgBox "Error occured"
End Sub

Имейте в виду, что вы также можете оставить l oop контролируемым образом, используя Exit for.

1 голос
/ 03 августа 2020

К вашей первой проблеме: переместите 'On Error GoTo ExitHandler' над строкой, которая может вызвать ошибку. Excel должен знать, что делать в случае ошибки, прежде чем она произойдет.

0 голосов
/ 04 августа 2020

Спасибо за все ответы, они дали мне лучшее понимание системы обработки ошибок VBA.

Я создал решение своей проблемы, используя подход, аналогичный тому, что было указано @Damian в этом сообщении .

Dim cont As Control

For Each pg In Me.MultiPage1.Pages
        
    For Each cont In pg.Controls
            
        If cont.Value = True Then
            checkBoxes.Add cont.Caption
        End If

            
    Next cont

Next pg

Просто нужно было поместить элементы управления страницы в переменную Control variable, которую я мог бы использовать с For Each до l oop точное количество раз мне нужно иметь возможность установить флажок. Это решение работает для меня, так как на странице у меня есть только флажки. Поэтому все, что мне нужно было сделать, это проверить значение элемента управления, а не также проверить тип элемента управления.

Если бы у меня были другие элементы управления, мне нужно было бы сначала проверить тип элемента управления. Это также означает, что мне не нужно формулировать имя флажка, как я пытался раньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...