VBA中的循环?我想使用循环来选择并复制到最后一个单元格

时间:2014-08-03 18:36:03

标签: vba loops

我正在尝试选择行K中的每个连续单元格(从范围K1开始),并且对于每个单元格下移,复制该值并将其粘贴到单元格M10中。但是,当前写入宏的方式,宏正在选择范围K中最后一个单元格正下方的单元格,因此将空白复制到M10中。相反,我希望循环一次只能处理一个单元格。我想一次选择一个单元并复制它,即循环将选择K1并将其复制到M10,然后选择K2并将其复制到M10等,然后使循环在范围K的最后一个单元格之后停止。

任何人都可以帮我解决这个问题吗?

Sub test() 

lastcell = Range("K" & Cells.Rows.Count).End(xlUp) 

Range("K2").Select 
Do 
ActiveCell.Offset(1, 0).Select 
Selection.Copy 
Range("M10").Select 
Selection.PasteSpecial
Application.Run ("Second Macro") 
Loop Until IsEmpty(ActiveCell.Value) 

End Sub

1 个答案:

答案 0 :(得分:2)

您可以使用下面的小脚本循环显示K列:

Option Explicit
Sub LoopThroughColumnK()

Dim LastRowInColK As Long, Counter As Long
Dim SourceCell As Range, DestCell As Range
Dim MySheet As Worksheet

'set references up-front
Set MySheet = ThisWorkbook.Worksheets("Sheet1")
With MySheet
    LastRowInColK = .Range("K" & .Rows.Count).End(xlUp).Row
    Set DestCell = .Range("M10")
End With

'loop through column K, copying from cells(counter, 11) to M10
With MySheet
    For Counter = 1 To LastRowInColK
        Set SourceCell = .Range("K" & Counter)
        SourceCell.Copy Destination:=DestCell
        'call MyMacro below
        '... doing cool MyMacro stuff
    Next Counter
End With

End Sub

总结一下发生了什么,我们:

  1. 分配工作表变量以确保我们正在处理正确的工作表
  2. 为最后一行和单元格M10
  3. 分配易于阅读和引用的变量
  4. 循环浏览相关范围,从Kn复制并粘贴到M10
  5. 此技术还避免使用.Select,这是运行时错误的常见来源。这是一篇令人惊叹的帖子,其中列出了许多不使用.Select.Activate的方法:How to avoid using Select in Excel VBA macros


    编辑:我在上面的评论中描述的重构可以毫不费力地实施。让我们把整个问题分成两个一小块的块:

    1. 获取列K中的所有已占用单元格并将其另存为Range
    2. 为我们在上面步骤1中保存的Cell中的每个Range运行已锁定在单元格M10上的辅助宏。我们现在将调用辅助宏MyOtherMacro
    3. 让我们开始吧。星期天Funday你们都!下面的代码经过大量评论,以解释每个函数和步骤中发生的事情:

      Option Explicit
      Sub DoWork()
      
      Dim MySheet As Worksheet
      Dim ColKRange As Range
      
      'set the worksheet we want to work on, in this case "Sheet1"
      Set MySheet = ThisWorkbook.Worksheets("Sheet1")
      
      'get the range of occupied cells in col K
      Set ColKRange = OccupiedRangeInColK(MySheet)
      
      'kick off the other macro using the range we got in the step above
      Call MyOtherMacro(ColKRange)
      
      End Sub
      

      DoWork(上面)是一个“控制器”类型的脚本。它所做的只是开始我们在下面写的其他两个函数,OccupiedRangeInColK然后,一步之后,MyOtherMacro

      'this function returns a range object representing all
      'the occupied cells in column K, starting at row 1 and ending
      'at the last occupied row (in column K)
      Public Function OccupiedRangeInColK(TargetSheet As Worksheet) As Range
          Dim LastRow As Long
      
          'check for unassigned worksheet object, return nothing if that's the case
          If TargetSheet Is Nothing Then
              Set OccupiedRangeInColK = Nothing
          End If
      
          With TargetSheet
              LastRow = .Range("K" & .Rows.Count).End(xlUp).Row
              Set OccupiedRangeInColK = .Range(.Cells(1, 11), .Cells(LastRow, 11))
          End With
      End Function
      

      酷 - 描述性名称在脚本编写方面是一件好事。 OccupiedRangeInColK(上方)需要Worksheet,然后从K列返回占用的Range

      'this function is a shell to be populated by @polymorphicicebeam
      Public Function MyOtherMacro(TargetRange As Range)
          Dim Cell As Range
      
          'check for an empty range, exit the function if empty
          If TargetRange Is Nothing Then Exit Function
      
          'loop through all the cells in the passed-in range
          For Each Cell In TargetRange
              'Do cool stuff in here. For demo purposes, we'll just
              'print the address of the cell to the screen
              MsgBox (Cell.Address)
          Next Cell
      End Function
      

      最后,MyOtherMacro(上图)是您添加自己的魔法的地方。我为您构建了一个“shell”函数,它只使用MsgBox打印相关单元格的地址。您可以在For Each Cell In TargetRange循环内指示添加自己的逻辑。宇!