Использование инструкции Exit Sub в VBA

#excel #vba

#excel #vba

Вопрос:

У меня есть код, в котором я в основном перебираю и копирую данные с одного листа Excel и вставляю их в свою активную рабочую книгу. Однако в текущем способе написания моего кода я использую Exit Sub инструкцию, и все, что ниже этой инструкции, не будет выполняться. Есть ли альтернатива, которую я могу использовать Exit Sub , которая все еще будет работать с моей текущей структурой кода?

 Dim ws As Worksheet

Dim Prefix As String, Suffix As String
Dim ROfs As Integer, COfs As Integer
Dim Source As Range, Dest As Range, This As Range


Set ws = ThisWorkbook.Worksheets("Sheet1")



  With ws
    'The formula becomes Prefix amp; Source.Address amp; Suffix
    Prefix = "='C:xxx[Workbook1.xls]Worksheet1'!"
    Suffix = "/1000"
    'Direction for the next Source cell
    COfs = -1

    'Destination cells
    Set Dest = .Range("G8:G12")
    Set Source = Range("G8")
    GoSub Fill

    Set Dest = .Range("G13:G17")
    Set Source = Range("G9")
    GoSub Fill
    
    Suffix = ""
    Set Dest = .Range("G3:G7")
    Set Source = Range("G10")
    GoSub Fill

    Suffix = "/1000"
    Set Dest = .Range("G26:G30")
    Set Source = Range("G35")
    GoSub Fill
   
    Suffix = ""
    Set Dest = .Range("G21:G25")
    Set Source = Range("G37")
    GoSub Fill
   
    Suffix = "/1000"
    Set Dest = .Range("G31:G35")
    Set Source = Range("G36")
    GoSub Fill
    
  End With
  
Exit Sub
 
Fill:
  For Each This In Dest
    This.Formula = Prefix amp; Source.Address(0, 0) amp; Suffix
    Set Source = Source.Offset(ROfs, COfs)
  Next
  Dest.Value = Dest.Value
  Return

'''Everything Below Does Not Execute'''

ws.Columns("C").EntireColumn.Delete

Dim strFormulas As Variant

    With ws
         strFormulas = "=(F3-C3)"
        .Range("G3:G17").Formula = strFormulas
        .Range("G3:G17").FillDown
   End With

End Sub
  

Комментарии:

1. Что делает эта строка: Dest.Value = Dest.Value ?

2. Я использую это, чтобы избавиться от ссылки на ячейку. По сути, это то же самое, что вставить как значения

3. Я бы сделал Fill: block отдельным подразделом, который принимает аргументы. Это сделает ваш код намного проще для чтения. Вероятно, затем вы могли бы удалить свой Exit Sub.

4. GoSub это пережиток гораздо более ранней эры Basic. Не используйте его. Когда-либо.

5. Спасибо за информацию, Крис, я понятия не имел.

Ответ №1:

Без Gosub/Return — как отмечено в комментариях, это не «идиоматический» способ записи в VBA

 Sub Test()
    
    Dim prefix As String, suffix As String
    
    With ThisWorkbook.Worksheets("Sheet1")
        'The formula becomes Prefix amp; Source.Address amp; Suffix
        prefix = "='C:xxx[Workbook1.xls]Worksheet1'!"
        suffix = "/1000"
        
        'Destination cells
        DoFill Range("G8"), .Range("G8:G12"), prefix, suffix
        DoFill Range("G9"), .Range("G13:G17"), prefix, suffix
        DoFill Range("G10"), .Range("G3:G7"), prefix, ""
        DoFill Range("G35"), .Range("G26:G30"), prefix, suffix
        DoFill Range("G37"), .Range("G21:G25"), prefix, ""
        DoFill Range("G36"), .Range("G31:G35"), prefix, suffix
    
        .Columns("C").EntireColumn.Delete
        .Range("G3:G17").Formula = "=(F3-C3)"
    End With
      
End Sub

Sub DoFill(src As Range, dest As Range, prefix As String, suffix As String)
      Dim c As Range
      For Each c In dest
        c.Formula = prefix amp; src.Address(0, 0) amp; suffix
        Set src = src.Offset(0, -1)
      Next
      dest.Value = dest.Value
End Sub
  

Комментарии:

1. Большое спасибо за вашу помощь. Это имеет гораздо больше смысла, чем то, что я делал.

Ответ №2:

Перетасуйте последние блоки кода:

 ' <snip>

  End With
  
ws.Columns("C").EntireColumn.Delete

Dim strFormulas As Variant

    With ws
         strFormulas = "=(F3-C3)"
        .Range("G3:G17").Formula = strFormulas
        .Range("G3:G17").FillDown
   End With

Exit Sub
 

Fill:
  For Each This In Dest
    This.Formula = Prefix amp; Source.Address(0, 0) amp; Suffix
    Set Source = Source.Offset(ROfs, COfs)
  Next
  Dest.Value = Dest.Value
  Return

End Sub
  

Ответ №3:

Не используйте для этого «goto», лучше вызвать функцию или sub.

«Goto» идеально подходят в vba для ошибок catch