Я настоящий новичок в VBA, и я пытаюсь создать цикл копирования / вставки, чтобы автоматизировать задачу на работе. Я пробовал это в течение нескольких дней и пока безуспешно, так что мне нужна небольшая помощь!

Итак, основы таковы. У меня есть два статических списка, один из которых содержит 6 строк (static1), а другой - 37 строк (static2). Мне нужно, чтобы они отображались в определенном формате, чтобы разрешить импорт в другую программу с фиксированной спецификацией импорта. Мне нужно, чтобы static1 повторялся в блоках по 6 штук, что я делаю с помощью следующего кода:

Sheet3.Range("I1:I6").Copy
    For i = 0 To totalChannels
    Cells(1 + 6 * i, 2).Select
ActiveSheet.Paste

Я полностью понимаю, как это работает, static1 хранится в ячейках I1: I6, и он просто копируется и вставляется снова и снова, пока не достигнет максимального количества, указанного в totalChannels.

Static2 немного сложнее. static2 содержится в ячейках G1: G37 Мне нужно создать цикл внутри цикла, чтобы скопировать ячейку G1 и вставить ее в 312 последовательных строк, затем скопировать ячейку G2 и вставить ее в 312 последовательных строк и так далее, пока не дойдет до G37.

Я постепенно осваиваю vba, но я опередил то, на чем я сейчас нахожусь, и я не могу найти в Интернете источник, который бы объяснил мне это простым способом - надеюсь, что кто-то здесь может помочь !!

Надеюсь, я достаточно подробно все объяснил,

Спасибо.

0
roastbeeef 26 Мар 2014 в 20:02
1
Вы должны взглянуть на этот пост на Как избежать использования .Select
 – 
simpLE MAn
26 Мар 2014 в 20:21
Спасибо - интересная статья.
 – 
roastbeeef
26 Мар 2014 в 21:28

2 ответа

Лучший ответ

Последовательные действия - это больше упражнение для воображения, чем что-либо еще. Есть много способов делать то, что вы хотите.

Например, если вы хотите последовательно скопировать A1:A5 в B1:B25, следующее работает достаточно просто без цикла for.

Sub RapidFireOne()

    Dim SrcRng As Range
    Set SrcRng = Sheet1.Range("A1:A5")

    'Copy in one go to Column B.
    SrcRng.Copy Sheet1.Range("B1:B25")

End Sub

Результат:

enter image description here


Если вы действительно хотите сделать это через цикл и хотите сделать это в последовательности диапазонов, используйте свойство Step, например:

Sub RapidFireTwo()

    Dim SrcRng As Range
    Set SrcRng = Sheet1.Range("A1:A5")

    'Copy repeatedly to Column B with one space between.
    For Iter = 1 To 25 Step 5
        SrcRng.Copy Sheet1.Range("B" & Iter)
    Next

End Sub

Результат такой же, как и у первого.


Если вы хотите скопировать каждую ячейку в пакетные диапазоны, как то, что вы делаете с static2, следующий метод работает, просто измените его (в основном изменив 5 на {{X2 }} или что-то в этом роде):

Sub RapidFireThree()

    'This one copies each cell sequentially.
    Dim SrcRng As Range
    Set SrcRng = Sheet1.Range("A1:A5")

    'Copy each cell in order to Column B.
    Set TargetRng = Sheet1.Range("B1:B5")
    For Each Cell In SrcRng
        Cell.Copy TargetRng
        Set TargetRng = TargetRng.Offset(5, 0).Resize(5, 1)
    Next

End Sub

Результат:

enter image description here


Сообщите нам, если это поможет.

4
WitchGod 26 Мар 2014 в 20:47
Чтобы добавить больше гибкости, во втором примере вы можете изменить For Iter = 1 To 25 Step 5 на For Iter = 1 To 25 Step SrcRng.Rows.Count. И кстати, отличный ответ (+1).
 – 
simpLE MAn
26 Мар 2014 в 21:25
Это выглядит абсолютно идеально - спасибо. у меня нет возможности внедрить это в мой код сейчас, так как я просто выхожу из двери, но я попробую утром - спасибо!!
 – 
roastbeeef
26 Мар 2014 в 21:30
+1 за команду «Шаг» — я не был знаком с ней — это здорово!
 – 
DanK
26 Мар 2014 в 23:44
1
+1 (на самом деле я уже проголосовал за этот ответ), есть небольшая проблема, которую я недавно обнаружил: этот код вставляет значения только в используемую часть листа: SrcRng.Copy Sheet1.Range("B1:B25" ) фактически дает тот же результат, что и SrcRng.Copy Intersect(Sheet1.Range("B1:B25"),Sheet1.UsedRange). Вы можете увидеть, как я решил эту проблему здесь: -the-same-row-in-exc/22510920#22510920" title="копирование нескольких значений подряд и вставка их несколько раз в одну и ту же строку в exc"> stackoverflow.com/questions/22510230/…
 – 
Dmitry Pavliv
27 Мар 2014 в 02:33
@simoco: Кажется, я это помню. Это идет рука об руку с другой проблемой UsedRange, которая также ограничена определенным количеством строк. Думаю, вы тоже поднимали этот вопрос. В любом случае, приятно отметить, что у OP, похоже, есть большой диапазон для выполнения действий.
 – 
WitchGod
27 Мар 2014 в 02:37

Этот код должен помочь вам выполнить эту задачу. Выполнить цикл внутри другого цикла довольно просто, но вы должны стараться избегать его там, где это возможно. Этот код, например, принимает время O (n ^ 2) (http://en.wikipedia.org/wiki/ Big_O_notation), что означает, что при увеличении размера статического 1 или статического 2 производительность будет снижаться в два раза быстрее. В программировании вы всегда хотите использовать O (1) или статическое время (это означает, что процесс будет выполняться одинаково, независимо от количества данных, которые вы передаете через него.

Также обратите внимание на перечисленные мною комментарии. Вы можете выполнить эту задачу с гораздо меньшим количеством кода, потому что VBA - это язык сценариев, который позволяет вам сильно обмануть синтаксис. Но разработка хороших методов кодирования в конечном итоге избавит вас от огромной боли.

Удачи! VBA - отличный язык для начала изучения программирования!

Sub Test()
'Always explicitly define your variables
Dim oStatic2 As Range
Dim oWksht As Excel.Worksheet
Dim srow As Integer
Dim ct As Integer
Dim pstrow As Integer
Dim column As String

'Use 'SET' when setting object instances; primitive variables don't require it
Set oWksht = ThisWorkbook.Sheets("Sheet1")
Set static2 = oWksht.Range("G1:G37")

'set placemark
pstrow = 1

'set column to paste into
column = "A"

'Loop through each cell in static2
For srow = 1 To 37
    'Set individual cell to be copied
    Set static2 = oWksht.Range("G" & srow)
    static2.Copy
    'Loop through 312 sequential rows for each single row in the outer loop
    For ct = pstrow To (pstrow + 312)
        oWksht.Range(column & ct).PasteSpecial
        pstrow = pstrow + 1
    Next
Next

'Always release memory for objects after finished using
Set oWksht = Nothing
Set static2 = Nothing

End Sub
1
DanK 26 Мар 2014 в 20:44