我对Loops很臭

时间:2013-10-15 18:31:24

标签: excel vba excel-vba

我有3张表:工作,比尔和客户。 Cust列A包含我的唯一客户,然后我将其粘贴到工作表上的单元格A3上,然后运行其计算,然后将其粘贴到Bill表单上。然后我在Cust表上取下一个值,然后将其粘贴回Work,运行计算并将其粘贴到Bill表上的上一个集合下面。我有两个问题。

为什么我的循环不起作用?我试图继续前进,直到我在客户表上用完客户? 为什么我可以在我的代码的第一部分使用自定义范围BillPlace,但实际上我必须参考后面部分中的单元格? 提前致谢

Sub test1()
    Dim WorkPlace As Range, BillPlace As Range, WorkProd As Range

    Set WorkPlace = Sheets("Work").Cells(3, 1)
    Set BillPlace = Sheets("Bill").Cells(3, 1)
    Set WorkProd = WorkPlace.CurrentRegion

    WorkPlace.CurrentRegion.Copy
    BillPlace.PasteSpecial xlPasteAll

    Sheets("Cust").Select
    Cells(1, 1).Copy
    WorkPlace.PasteSpecial xlPasteAll

    WorkProd.Copy
    Sheets("Bill").Select
    Range("A3").Select
    Selection.End(xlDown).Select
    Selection.Offset(1, 0).PasteSpecial xlPasteAll
    Sheets("Cust").Select
    Cells(2, 1).Select
    Selection.Offset(1, 0).Select

    Do
        ActiveCell.Offset(1, 0).Copy
        WorkPlace.PasteSpecial xlPasteAll
        WorkProd.Copy
        Sheets("Bill").Select
        Range("A3").Select
        Selection.End(xlDown).Select
        Selection.Offset(1, 0).PasteSpecial xlPasteAll
    Loop Until IsEmpty(ActiveCell.Offset(1, 0))
End Sub

3 个答案:

答案 0 :(得分:2)

@Portland Runner有一个关于使用For Each / Next循环的观点。通过这样做,你可以消除计数器和从上面的工作代码中选择一堆,从你的过程中消除一堆复杂性。

For / Next循环的原理很简单:定义包含要循环的单元格的TheLargerRange。定义SingleCell范围以包含您正在使用的当前单元格。然后你可以开始循环说:

For Each SingleCell in TheLargerRange 
    '~~> your loop actions go here 
Next SingleCell

此外,您可以在不选择工作簿中的特定位置的情况下做很多事情。而是仅通过引用位置来复制,粘贴或分配值。如果需要,您可以设置变量,以便在更长的代码中更轻松。

以下示例仅将一列客户数据从一个工作表移动到另一个工作表,作为如何使用For Each / Next循环结构以及如何避免选择您使用的所有内容的示例。此代码中只有一个选项,这只是因为如果使用End(xldown)尝试在未选中的选项卡上设置范围,编译器会发生阻塞。否则可能没有选择。

Sub UsingForNextAndAvoidingSelections()

    '~~> Set variables for referencing the "Cust" tab
        Dim CustomerList As Range
        Dim Customer As Range
        Dim CustomerTab As Worksheet

        Set CustomerTab = Sheets("Cust")
        CustomerTab.Select
        Set CustomerList = CustomerTab.Range("A1", Range("A1").End(xlDown))

    '~~> Set variables for referencing the "Bill" tab
        Dim BillTab As Worksheet
        Dim BillRow As Range

        Set BillTab = Sheets("Bill")
        Set BillRow = BillTab.Range("A1")

    '~~> Loop through the customer list, copying each value to the new BillRow location
        For Each Customer In CustomerList
            Customer.Copy
            BillRow.PasteSpecial xlPasteAll
            Set BillRow = BillRow.Offset(1, 0)
        Next Customer

End Sub

2013年12月27日:我刚刚意识到为什么代码Set CustomerList = CustomerTab.Range("A1", Range("A1").End(xlDown))在未选择CustomerTab时抛出错误:我忘了完全限定该行中的第二个范围语句:Range("A1").End(xlDown)

我相信,如果您符合此Set CustomerList = CustomerTab.Range("A1", CustomerTab.Range("A1").End(xlDown))这样的代码行,则可以消除其前面的CustomerTab.Select,并在没有Select的情况下执行整个过程。

答案 1 :(得分:1)

     WorkProd.Copy
    Sheets("Bill").Select
    Range("A3").Select
    Selection.End(xlDown).Select
    Selection.Offset(1, 0).PasteSpecial xlPasteAll
Loop Until IsEmpty(ActiveCell.Offset(1, 0))

您将到达列的末尾并进一步向下粘贴一行。然后检查下一行的单元格是否为空,但不会是因为您刚刚粘贴到它中。这就是它无休止地重复的原因。

我假设您应该在当前光标位置下方的一行以外的地方寻找一个空单元格。

答案 2 :(得分:0)

HA!我修好了它。这不是最正统的方法,但它起作用。哦,原谅我,但我在生产中做到了,所以床单名称和单元格位置略有变化。 CountC是一个辅助单元,用于计算客户数量。谢谢大家的帮助。

Sub Pull_Billing()
    Dim WorkPlace As Range, BillPlace As Range, WorkProd As Range, PlaceHolder As Range, CountC As Integer, n As Integer


    Set WorkPlace = Sheets("Work").Cells(3, 1)
    Set BillPlace = Sheets("ABS_Billing_Sheet").Cells(3, 1)
    Set WorkProd = WorkPlace.CurrentRegion
    CountC = Sheets("CTA_Info").Cells(1, 5).Value


    Sheets("CTA_info").Cells(2, 2).Copy
    WorkPlace.PasteSpecial xlPasteAll
    WorkPlace.CurrentRegion.Copy
    BillPlace.PasteSpecial xlPasteAll
    Sheets("CTA_Info").Select
    Cells(3, 2).Copy
    WorkPlace.PasteSpecial xlPasteAll


    WorkProd.Copy
    Sheets("ABS_Billing_Sheet").Select
    Range("A3").Select
    Selection.End(xlDown).Select
    Selection.Offset(1, 0).PasteSpecial xlPasteAll


    Sheets("CTA_Info").Select
    Cells(4, 2).Select
    n = ActiveCell.Row
    Do
    Cells(n, 2).Select
    Selection.Copy
    WorkPlace.PasteSpecial xlPasteAll
    WorkProd.Copy
    Sheets("ABS_Billing_Sheet").Select
    Range("A3").Select
    Selection.End(xlDown).Select
    Selection.Offset(1, 0).PasteSpecial xlPasteAll
    Sheets("CTA_Info").Select
    Cells(n + 1, 2).Select
    n = ActiveCell.Row
    Loop Until n > CountC + 2


    Sheets("CTA_info").Cells(2, 2).Copy
    WorkPlace.PasteSpecial xlPasteAll


    Sheets("ABS_Billing_Sheet").Select



    End Sub