Microsoft Excel: макрос повторить определенное действие несколько раз

Кажется, что это очень аккуратный трюк. вы можете использовать git diff > file.diff (и зафиксировать файл), а затем восстановить изменения с помощью git apply file.diff (из любого места) для достижения того же результата.

Это объяснялось здесь здесь как хорошо.

4
задан Pᴇʜ 13 July 2018 в 09:29
поделиться

2 ответа

Этот код должен сделать трюк. Код дает вам InputBox, в котором вы можете ввести количество раз, чтобы запустить код.

Sub test()
Application.ScreenUpdating = False
Dim Grab As Range
Dim RunTimes As Long

On Error GoTo Get_Out
RunTimes = InputBox("How many times shall the code run?", "Run times")
On Error GoTo 0

For x = 1 To RunTimes * 1.5 + 3 Step 2
    Set Grab = ActiveSheet.Range("A" & x + 4)
    Grab.EntireRow.Insert
    Grab.Offset(-1, 0).Value = Grab.Offset(-2, 0).Value + 0.1
    Grab.Offset(-1, 1).Value = Grab.Offset(1, 1).Value
    Grab.Offset(-1, 2).Value = Grab.Offset(1, 2).Value
Next x

MsgBox "Succes"

Get_Out:
Application.ScreenUpdating = True
End Sub

Сообщите мне, если у вас есть какие-либо вопросы о коде или если вы хотите, чтобы я объясните это далее:)

1
ответ дан DirtyDeffy 17 August 2018 в 13:17
поделиться
  • 1
    Код работает по назначению, InputBox - приятный штрих. Очень признателен! Хотя я виноват не в том, что не заявлял об этом, я действительно надеялся, что он будет выбирать только 3 ячейки в строке, а не всю строку. Но я исправил это сам :) Еще раз спасибо. – Alcomoney 13 July 2018 в 15:04
  • 2
    Удивительный - рад помочь :) – DirtyDeffy 13 July 2018 в 15:26

[Prologue:]

Привет, я дам вам ответ, и я попытался прокомментировать его, чтобы сделать его максимально дружелюбным к новичкам, но правда в том, :

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


[Разрывы в логике:]

Вероятно, самая большая проблема заключается в том, что вы не указали, что происходит, когда ваши данные попадают в пустые ячейки (что Я имею в виду под этим) - если в вашем цикле вы были в строке 10 (7, M, N), у вас больше не было бы букв для добавления, так как следующие 2 строки (12) больше не содержат eny-данных.

Учитывая это, я изменил цикл, чтобы начать с n-2-й строки вместо этого, чтобы это не произошло (это означает, что в вашем примере это закончится (или начнет быть более точным) в 6.1, поскольку это последний строка, которая может извлекать данные)

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


[Теоретическая часть вашего вопроса:]

Я немного скрою вас (g7)

  1. Если вы хотите повторить определенное действие, вы всегда должны использовать один из 2 (или 3 в зависимости от того, как вы их классифицируете) петли for и do (while/until)
  2. . Еще лучше, если вы хотите циклически повторять количество действий за повторное количество раз, вы должны использовать либо процедуру Sub, либо функцию Function, поэтому вы можете использовать аргументы, которые действуют как переменная для цикла.
  3. Как правило, при добавлении или удалении строк важно перебирать из нижнего в верхний (от последнего к первому). Зачем? Потому что если вы добавите дополнительную строку, это испортит ваш порядок строк.

Учитывая все это, сама процедура может выглядеть примерно так:


[Само решение:]

Вы можете использовать следующую процедуру каждый раз для указанного диапазона.

Option Explicit 'prevents typo. errors, undeclared variables and so on

Private Sub extra_row(ByVal rng As Range) 'declaration of procedure

 Dim i As Long
 ' we loop for the n-th - 2 row (last row - 2) to the pre-first (added) row.
 For i = (rng.Rows.Count + rng.Row - 2) To rng.Row + 1 Step -1
 'why the -2? ^ Because if you add the letters from next 2 rows,_
  the last 2 would have no to grab _
  eg. Row 10 and 11 in your original data would have no data under them to grab

 ' a bit harder section to comprehend, if it's the first data entry _
   we need to account for the fact that we have not added any extra rows yet_
   hence we also need to decrement the row from which we receive the data by 1 _
   it 's bit of difficult to word, i'd highly recommend debugging yourself _
   and seeing what happens with or without it
  Dim fp As Integer
    If (i - 2 = rng.Rows.Count) Then
      fp = 1
    Else
      fp = 0
    End If

    ' now we just add the extra rows where we can
    Rows(i).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
    Cells(i, 1) = Cells(i, 1).Offset(-1, 0) + 0.1 'we add 0.1 to cell one above
    Cells(i, 2) = Cells(i + 3 - fp, 2) ' similar case, with letters, but two below
    Cells(i, 3) = Cells(i + 3 - fp, 3) ' similar case, with letters, but two below
  Next i 'and we loop for every cell in our specified range

End Sub

Например. в вашем случае вы можете запустить эту процедуру с помощью следующей команды:

Call extra_row(Range("A4:A11"))

[Практическое использование]

Хотя само решение должно работать, в реальном мире возможно, более разумно не использовать определенный диапазон для вызова каждой процедуры. Особенно, если это означает, что использование должно смотреть на рабочий лист, проверить диапазон и подсчитать строки вручную.

Это одна из причин, по которым мы начали процедуру для начала. Таким образом, я создал еще одну процедуру, сродни main() на большинстве языков программирования, которая обнаруживает последнюю активную строку и применяет эту процедуру к вашему диапазону данных, автоматически определяя ее.

Итак, в конце концов, ваш взгляд должен выглядеть что-то вроде этого:

Option Explicit
Private Sub extra_row(ByVal rng as Range)
  '... code from the answer here
End Sub

Private Sub rundata()
    Dim lr As Long
    lr = Sheets("Your Sheet Name").Cells(Rows.Count, 1).End(xlUp).Row 
    'detects the last active (nonempty) row _
     rememeber to change the  Sheets("") to wherever your data is stored

    Dim mydata As Range
    Set mydata = Range("A4:A" & lr) 'under presumption your data always begins with A4

    Call extra_row(mydata)     
End Sub

Теперь, когда вы будете запускать (манально) или Call процедуру run_data(), она автоматически определит диапазон и применит процедуру, которую мы ему определили.


[Ожидаемые результаты визуализации и закрытия слов:]

Мы начали с этого:

После выполните процедуру:

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

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


Удачи вам в путешествии по кодированию! :) Rawrplus

3
ответ дан Rawrplus 17 August 2018 в 13:17
поделиться
  • 1
    Хорошо структурированный ответ. Что касается логики, то скриншоты, которые вы видите, точно соответствуют моим данным, за исключением букв, которые являются целыми числами, и существует более 20000 строк данных. Я надеялся получить простой цикл «for loop» и настроить его на i = 1 до 20000 вручную, ничего необычного. Тем не менее, я ценю комментарии к соответствующим строкам кода. Мне нужно больше времени на анализ вашей работы. Спасибо за отличный ответ. – Alcomoney 13 July 2018 в 17:17
Другие вопросы по тегам:

Похожие вопросы: