Возможно ли, чтобы одна строка сценария VBA повторялась N раз?

Я впервые экспериментирую с рекурсией. В этой задаче у меня есть огромный набор данных со многими строками, и в каждой строке есть N число из 4 диапазонов ячеек для копирования (от столбца O до столбца GB). У меня написана следующая функция:

Function Recursive(Rng As Range)

If N = 1 Then

Rng.Offset(, -3).Resize(, 670).Copy
Rng.Offset(1, -3).Insert Shift:=xlDown
Rng.Offset(, 6).Resize(, 4).Copy
Rng.PasteSpecial Paste:=xlPasteValues

Else
Rng.Offset(, -2).Resize(, 670).Copy
Rng.Offset(1, -2).Insert Shift:=xlDown 'Repeat these two lines N times'

Rng.Offset(, 7 + 4 * N).Resize(, 3).Copy
Rng.Offset(N, 0).PasteSpecial Paste:=xlPasteValues
Recursive (N - 1)
End If
N = 0
End Function

Я знаю, что это довольно грубо, и я уже вижу некоторые проблемы. По сути, если N равно 4, то я хочу, чтобы первые две строки инструкции Else повторялись 4 раза, а затем переходили к выполнению следующих трех строк снова и снова, пока N не станет равным 1. В основном, где есть много диапазонов, проходящих через набор данных, я хочу создать новую строку, чтобы поместить их, включая ячейки слева от Rng. Можно ли вставить строку, в которой я сделал свой комментарий, в которой говорится: «Вернитесь и повторите эти две строки N раз?»


person user1996971    schedule 11.08.2015    source источник
comment
if (...) then { loop ...}, в общем.   -  person Marc B    schedule 11.08.2015
comment
Мой ответ был не по адресу. Я удалил.   -  person Stephen Lloyd    schedule 11.08.2015


Ответы (1)


Чтобы уточнить комментарий @MarcB, существует много типов циклов. Я выбрал один основной цикл, который уменьшает N на 1, пока N = 0. В этом цикле, если N = 1, выполняется ваш специальный код N = 1; в противном случае, если N = 4, он выполняет 4 цикла по этому разделу кода, в противном случае он запускает ваш «еще» блок кода.

Function Recursive(Rng As Range)

Dim OriginalN as Integer

OriginalN = N

While N <> 0

If N = 1 Then

    Rng.Offset(, -3).Resize(, 670).Copy
    Rng.Offset(1, -3).Insert Shift:=xlDown
    Rng.Offset(, 6).Resize(, 4).Copy
    Rng.PasteSpecial Paste:=xlPasteValues

ElseIf N = OriginalN Then
    For x = 1 To OriginalN
        Rng.Offset(, -2).Resize(, 670).Copy
        Rng.Offset(1, -2).Insert Shift:=xlDown 'Repeat these two lines N times'
    Next x
Else
    Rng.Offset(, 7 + 4 * N).Resize(, 3).Copy
    Rng.Offset(N, 0).PasteSpecial Paste:=xlPasteValues
    Recursive (N - 1)
End If

N = N - 1

Wend

End Function

Вы имеете в виду «возврат» и переделывание кода, но использование оператора GoTo часто считается неаккуратным, если есть другие доступные методы, поскольку без надлежащего ухода операторы GoTo могут выполняться неправильно/неопределенно и их несколько сложнее читать.

person Grade 'Eh' Bacon    schedule 11.08.2015
comment
Обратите внимание, что я не совсем понял ваши инструкции, когда N = 4; Я сделал так, что после запуска 2 строк кода 4 раза он останавливает этот оператор IF и снова зацикливается, не запуская 3 строки кода до тех пор, пока N не вернется в цикл как 3. Если вы хотите, чтобы эти 3 строки кода также выполнялись после того, как 2 строки будут повторены, вам нужно будет скопировать эти 3 строки и поместить их после цикла FOR. - person Grade 'Eh' Bacon; 11.08.2015
comment
Спасибо, это определенно в правильном направлении. По сути, N может быть где-то между 1 и 50. Я просто использовал 4 в качестве примера того, что я хотел бы, чтобы он делал в этом случае. Думаю, у меня могла бы быть строка, которая говорит ElseIf N <> 1 Then и заменяет 4 на N, где бы вы ни были? - person user1996971; 11.08.2015
comment
@user1996971 user1996971 Я не понимаю, что вы ищете, математически. Цикл должен иметь согласованный шаблон, чтобы его можно было установить таким образом. Вы имеете в виду, что когда N = исходное значение N, вы хотите, чтобы эти 2 строки кода запускались N раз. Затем для каждого другого значения N, уменьшающегося на 1, вы хотите, чтобы 3 строки кода выполнялись один раз, пока N = 1, когда вы хотите, чтобы эти строки кода выполнялись? Если да, то вам нужно сначала определить новую переменную, которая = исходному значению N; в противном случае N всегда будет = N и всегда будет выполняться цикл N = 4. - person Grade 'Eh' Bacon; 11.08.2015
comment
Ах да, теперь я понимаю. Я бы хотел, чтобы эти две строки запускались N раз, а остальные три строки выполнялись до тех пор, пока N = 0, без повторного запуска первых двух строк. Полагаю, тогда мне придется их разделить. Любые предложения, как? - person user1996971; 11.08.2015
comment
@user1996971 user1996971 Смотрите мои правки выше. Теперь он делает (я думаю) то, что вы хотите математически, но обратите внимание, что из-за рекурсии, если N = 20 в начале, то N будет равно OriginalN 20 раз (по одному разу при уменьшении до 1). - person Grade 'Eh' Bacon; 11.08.2015
comment
Спасибо, чувак, теперь я на правильном пути. Похоже, завтра мне придется опубликовать остальную часть макроса и контекст данных, чтобы все заработало гладко. Большое спасибо! - person user1996971; 11.08.2015