скопировать и вставить результирующий столбец в другую электронную таблицу - PullRequest
0 голосов
/ 12 февраля 2012

Мне было интересно, может ли кто-нибудь помочь мне сократить код, так как боюсь, что может потребоваться много времени для запуска после добавления других кодов.То, что я хочу сделать, будет объяснено в следующем:

Я хочу скопировать скажем test2 (обратите внимание, что интервал означает, что переменные находятся в своих собственных строках и столбцах)

test1 1 2 1
test2 2 1 4
test3 1 1 1

После копирования я вставлю его на другой лист.

Допустим, у меня есть другой набор результатов. Скажите

test2 2 1 4
test3 3 9 8
test5 1 1 1

Я хотел скопировать test2, но мой код VBA не смогпоскольку он по-прежнему предполагает, что test2 находится во 2-й строке.

И последний случай будет, если test2 недоступен, он продолжит копирование оставшейся части результата и вставит его на другие листы.

Я немного программировал, пробежался и помог мне решить эту проблему.СПАСИБО!

Sub Macro1()

 iMaxRow = 6 ' or whatever the max is.
    'Don't make too large because this will slow down your code.

    ' Loop through columns and rows
    For iCol = 1 To 1 ' or however many columns you have
        For iRow = 1 To 1

        With Worksheets("Sheet3").Cells(iRow, iCol)
            ' Check that cell is not empty.
            If .Value = "Bin1" Then
                Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin2" Then
                Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin3" Then
               Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin4" Then
                Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin5" Then
                Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin6" Then
                Range("A1:G1").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A1").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If



        End With

    Next iRow
    Next iCol

For iCol1 = 1 To 1 ' or however many columns you have
        For iRow1 = 1 To 2

        With Worksheets("Sheet3").Cells(iRow1, iCol1)
            ' Check that cell is not empty.

                If .Value = "Bin2" Then
                Range("A2:G2").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A2").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin3" Then
                Range("A2:G2").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A2").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin4" Then
               Range("A2:G2").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A2").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin5" Then
               Range("A2:G2").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A2").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin6" Then
                Range("A2:G2").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A2").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If

        End With

    Next iRow1
    Next iCol1

For iCol2 = 1 To 1 ' or however many columns you have
        For iRow2 = 1 To 3

        With Worksheets("Sheet3").Cells(iRow2, iCol2)
            ' Check that cell is not empty.

                If .Value = "Bin3" Then
                Range("A3:G3").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A3").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin4" Then
               Range("A3:G3").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A3").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin5" Then
                Range("A3:G3").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A3").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin6" Then
                Range("A3:G3").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A3").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If

        End With

    Next iRow2
    Next iCol2

For iCol3 = 1 To 1 ' or however many columns you have
        For iRow3 = 1 To 4

        With Worksheets("Sheet3").Cells(iRow3, iCol3)
            ' Check that cell is not empty.

                If .Value = "Bin4" Then
                Range("A4:G4").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A4").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin5" Then
                Range("A4:G4").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A4").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin6" Then
                Range("A4:G4").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A4").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If

        End With

    Next iRow3
    Next iCol3

For iCol4 = 1 To 1 ' or however many columns you have
        For iRow4 = 1 To 5

        With Worksheets("Sheet3").Cells(iRow4, iCol4)
            ' Check that cell is not empty.

                If .Value = "Bin5" Then
                Range("A5:G5").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A5").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            ElseIf .Value = "Bin6" Then
                Range("A5:G5").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A5").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If

        End With

    Next iRow4
    Next iCol4

For iCol5 = 1 To 1 ' or however many columns you have
        For iRow5 = 1 To 6

        With Worksheets("Sheet3").Cells(iRow5, iCol5)
            ' Check that cell is not empty.

                If .Value = "Bin6" Then
                 Range("A6:G6").Select
                Selection.Copy
                Sheets("sheet4").Select
                Range("A6").Select
                ActiveSheet.Paste
                Sheets("sheet3").Select
            End If

        End With

    Next iRow5
    Next iCol5
Sheets("Sheet4").Select
Range("A1").Select

End Sub

1 Ответ

3 голосов
/ 12 февраля 2012

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

Изменить 1

Пожалуйста, используйте Option Explicit и, пожалуйста, объявите свои переменные. Это позволяет избежать принятия переменной опечатки в качестве нового неявного объявления.

Изменить 2

Пожалуйста, используйте Application.ScreenUpdating = False. Это позволяет избежать перекрашивания экрана, поскольку макрос выполняет свои задачи. Это было бы важно для вашего кода из-за всех переключений между листами. Это менее важно для моего кода, потому что я не переключаю листы.

Изменить 3

Заменить:

With Sheets("Sheet3")
  :
  Range("A1:G1").Select
  Selection.Copy
  Sheets("sheet4").Select
  Range("A1").Select
  ActiveSheet.Paste
  Sheets("sheet3").Select
  :
End With

по:

With Sheets("Sheet3")
  :
  .Range("A1:G1").Copy Destination:=Worksheets("Sheet4").Range("A1")
  :
End With

Это позволяет избежать переключения листов, что является самой большой тратой времени.

Изменить 4

Для каждого If-ElseIf-ElseIf-EndIf вы делаете одну и ту же копию. Итак:

If .Value = "Bin1" Or .Value = "Bin2" Or .Value = "Bin3" _
   .Value = "Bin4" Or .Value = "Bin5"                   Then

будет иметь тот же эффект.

Сводка на данный момент

Я полагаю, что следующее делает точно так же, как ваш первый цикл:

Option Explicit
Sub Macro1()
  Dim iCol As Long
  Dim iRow As Long
  Dim ValueCell as String

  With Sheets("Sheet3")
    For iCol = 1 To 1
      For iRow = 1 To 1
        ValueCell = .Cells(iRow, iCol).Value
        If ValueCell = "Bin1" Or ValueCell = "Bin2" Or ValueCell = "Bin3" Or _
           ValueCell = "Bin4" Or ValueCell = "Bin5"                   Then
         .Range("A1:G1").Copy Destination:=Worksheets("Sheet4").Range("A1")
        End If
      Next
    Next
  End With

End Sub

Возможны дальнейшие изменения

Действительно ли циклы независимы? Для меня это выглядит так, как будто вы можете объединить их в один цикл.

Добавлен новый раздел в ответ на обмен комментариями

Считайте код в вашем вопросе:

  • У вас есть шесть двойных петель.
  • В каждом случае внешний цикл равен For iCol = 1 to 1. То есть вы проверяете только столбец «А», хотя подразумеваете, что проверяли бы больше столбцов, если код был быстрее.
  • Внутренний цикл - For iRow = 1 to №. № 1 в первом цикле, 2 во втором и 6 в шестом цикле. Опять же, вы подразумеваете, что проверяли бы больше строк, если бы код был быстрее.
  • Действие для каждого цикла зависит от значения №.

Таблица, показывающая эффект № действия:

Value
 of №   Cells examined   Values checked for   Range moved
   1    A1               "Bin1" ... "Bin6"    A1:G1
   2    A1, A2           "Bin2" ... "Bin6"    A2:G2
   3    A1, A2, A3       "Bin3" ... "Bin6"    A3:G3
   4    A1, A2, ... A4   "Bin4" ... "Bin6"    A4:G4
   5    A1, A2, ... A5   "Bin5", "Bin6"       A5:G5
   6    A1, A2, ... A6   "Bin6"               A6:G6
  • То есть в двойном цикле № вы проверяете ячейки с A1 по A№, проверяете значения от "Bin№" до "Bin6" и, если найдено, копируете Sheets("Sheet3").Range("A№:G№") в Sheets("Sheet4").Range("A№).

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

Новый синтаксис 1

Рассмотрим:

For iRow = 1 to 6
    :
  .Range("A6:G6").Copy Destination:=Worksheets("Sheet4").Range("A6")
    :
Next

"A6:G6" и "A6" - строки, которые вы можете построить во время выполнения.

Теперь рассмотрим:

For iRow = 1 to iRowMax
    :
  .Range("A" & iRowMax & ":G" & iRowMax)).Copy _
                         Destination:=Worksheets("Sheet4").Range("A" & iRowMax)
    :
Next

В соответствии со значением iRowMax это дает:

iRow    Statement    
  1     .Range("A1:G1")).Copy Destination:=Worksheets("Sheet4").Range("A1")
  2     .Range("A2:G2")).Copy Destination:=Worksheets("Sheet4").Range("A2")
  3     .Range("A3:G3")).Copy Destination:=Worksheets("Sheet4").Range("A3")

Новый синтаксис 2

Другой способ изменить диапазон во время выполнения - заменить:

.Range(string)

с

.Range(.Cells(RowTop,ColLeft),.Cells(RowBottom,ColRight))

С помощью этого синтаксиса вы можете легко указать прямоугольник требуемого размера.

Новый синтаксис 3

Рассмотрим:

For i = 1 to 5
  If this(i) = that Then
    Do something fixed
    Exit For
  End If
Next
' Exit For statement jumps to here

В этом цикле я тестирую пять значений. Если есть совпадение, я что-то делаю. Если я получаю совпадение по первому значению, мне не нужно проверять другие значения. Exit For позволяет мне выпрыгнуть из цикла For-Loop. Если есть вложенные циклы For-Loops, Exit For выходит только из внутреннего цикла

Новый синтаксис 4

"Bin1", "Bin2" и т. Д. Также могут быть созданы во время выполнения.

iRowMax = 4
For iRow = 1 to iRowMax
  For iBin = iRowMax to 6
    If ValueCell = "Bin" & iBin Then
      ' Move Range
      Exit For
    End If 
  Next
  ' Exit For statement jumps to here
Next

При iRow = 4 внутренний цикл For-loop устанавливает iBin на 4, 5 и 6. Это устанавливает "Bin" & iBin на "Bin4", "Bin5" и "Bin6".

Итак:

  For BinNum = iRowMax to 6
    If ValueCell = "Bin" & BinNum Then
      ' Move Range
      Exit For
    End If 
  Next

совпадает с:

  If ValueCell = "Bin4" Or ValueCell = "Bin5" Or ValueCell = "Bin6" Then
    ' Move Range
  End If 

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

Резюме

Я показал вам разные способы изменения того, что происходит в зависимости от значения iRow. Я надеюсь, что один из них позволит вам построить рутину, которую вы хотите.

Я не проверял это, но я думаю, что это делает то же самое, что и все шесть циклов в вашем исходном коде:

Option Explicit
Sub Macro1()
  Dim iBin as Long
  Dim iCol As Long
  Dim iRow As Long
  Dim iRowMax as Long
  Dim ValueCell as String

  Application.ScreenUpdating = False

  With Sheets("Sheet3")
    For iRowMax = 1 to 6
      For iCol = 1 To 1     ' This could be replaced by iCol = 1 at the top
        For iRow = 1 To iRowMax
          ValueCell = .Cells(iRow, iCol).Value
          For iBin = iRowMax to 6
            If ValueCell = "Bin" & iBin Then
              .Range("A" & iRowMax & ":G" & iRowMax)).Copy _
                      Destination:=Worksheets("Sheet4").Range("A" & iRowMax)
            End If
          Next iBin
        Next iRow
     Next iCol
  End With
End Sub 

Примечание:только удаление всех операторов Select делает этот код быстрее, чем ваш. Другие изменения делают его меньше и немного медленнее, потому что у меня есть два дополнительных цикла For-Loops, и я строю строки во время выполнения.

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