【问题标题】:looping in vba excel在vba excel中循环
【发布时间】:2020-06-25 13:06:29
【问题描述】:

我正在创建的 vba 代码有问题。我有一个 excel 文件,在前 3 列中我有一些信息,例如零件/编号等,请求的数量。然后在其他列的同一张表中,我有更多数据,其中我可能具有或可能不具有与第一列中相同的部件/编号,以及更多信息。这个想法是在第一列中逐个零件/编号,并检查它是否存在于最后一列(或数据集)中,并检查第二个数据集是否满足第一个数据集的数量要求,如果不要像在第二个数据集中那样向下移动到下一行,因为它们具有不同的价格、项目等,可能存在相同零件/编号的重复项。所以想法是,如果我在第二个数据集中有所需的数量首先,将这些值复制到不同的单元格中并创建一个总和,这样我就会知道最后的总数。我做了一些编码,但我遇到了错误,因为我对 vba 很陌生。任何帮助将不胜感激。谢谢。

A 列是第一个数据集的部分/编号,C 列是需要/请求的数量 AP 列是第二个数据集的零件/编号,AQ 是可用数量

Sub ExitFor_Loop()

    Dim i, j, qty   As Integer
    Dim mySum       As Double
    mySum = 0

    For i = 2 To 374
        qty = Range("C" & i).Value
        For j = 2 To 13672
            If Range("A" & i).Value = Range("AP" & j).Value Then
                Do
                    If qty > Range("AQ" & j).Value Then
                        Range("BC" & j).Value = Range("A" & i).Value
                        Range("BD" & j).Value = Range("AT" & j).Value
                        Range("BE" & j).Value = Range("AQ" & j).Value
                        Range("BF" & j).Value = Range("AV" & j).Value
                        Range("BG" & j).Value = Range("AW" & j).Value
                        Range("BH" & j).Value = Range("AX" & j).Value
                        Range("BI" & j).Value = Range("AY" & j).Value
                        Range("BJ" & j).Value = Range("AZ" & j).Value
                        mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
                        qty = qty - Range("AQ" & j).Value
                    Else
                        Range("BC" & j).Value = Range("A" & i).Value
                        Range("BD" & j).Value = Range("AT" & j).Value
                        Range("BE" & j).Value = Range("AQ" & j).Value
                        Range("BF" & j).Value = Range("AV" & j).Value
                        Range("BG" & j).Value = Range("AW" & j).Value
                        Range("BH" & j).Value = Range("AX" & j).Value
                        Range("BI" & j).Value = Range("AY" & j).Value
                        Range("BJ" & j).Value = Range("AZ" & j).Value
                        mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
                    End If

               Loop While (qty > Range("AQ" & j).Value  And ("A" & i).Value = Range("AP" & j).Value)
            Next j
        Next i

    End Sub

【问题讨论】:

  • 你也应该知道Dim i, j, qty As Integer这个语句只是将qty声明为Integer类型变量。 ij 被声明为 Variant 类型。在 vba 中,您需要独立且明确地声明每个变量。 Dim i as Integer, j as Integer, qty as Integer
  • mySum 要写入哪一列?

标签: excel vba


【解决方案1】:

下面的代码修复了您遇到的错误。有一个示例数据片段和请求的操作来优化代码会很有帮助。

Option Explicit

Sub ExitFor_Loop()

Dim i, j, qty   As Integer
Dim mySum       As Double
mySum = 0

For i = 2 To 374
  qty = Range("C" & i).Value
    For j = 2 To 13672
      If Range("A" & i).Value = Range("AP" & j).Value Then
        Do While (qty > Range("AQ" & j).Value And Range("A" & i).Value = Range("AP" & j).Value)
            If qty > Range("AQ" & j).Value Then
                Range("BC" & j).Value = Range("A" & i).Value
                Range("BD" & j).Value = Range("AT" & j).Value
                Range("BE" & j).Value = Range("AQ" & j).Value
                Range("BF" & j).Value = Range("AV" & j).Value
                Range("BG" & j).Value = Range("AW" & j).Value
                Range("BH" & j).Value = Range("AX" & j).Value
                Range("BI" & j).Value = Range("AY" & j).Value
                Range("BJ" & j).Value = Range("AZ" & j).Value
                mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
                qty = qty - Range("AQ" & j).Value
            Else
                Range("BC" & j).Value = Range("A" & i).Value
                Range("BD" & j).Value = Range("AT" & j).Value
                Range("BE" & j).Value = Range("AQ" & j).Value
                Range("BF" & j).Value = Range("AV" & j).Value
                Range("BG" & j).Value = Range("AW" & j).Value
                Range("BH" & j).Value = Range("AX" & j).Value
                Range("BI" & j).Value = Range("AY" & j).Value
                Range("BJ" & j).Value = Range("AZ" & j).Value
                mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
            End If
         Loop
      End If
  Next j
Next i

End Sub

【讨论】:

  • 在 qty = Range("C" & i).Value 处出现运行时错误 6 溢出
  • @Jonathan C 列中最大的数字是多少,是 > 32,767 吗?
【解决方案2】:

以及缺少Range的编码错误

'Loop While (qty > Range("AQ" & j).Value  And ("A" & i).Value = Range("AP" & j).Value)
Loop While (qty > Range("AQ" & j).Value  And Range("A" & i).Value = Range("AP" & j).Value)

LoopNext j之间缺少End If,逻辑有缺陷。

在循环内部,j 的值没有改变,所以计算总和 无论可用数量如何,都使用找到的第一个项目的价格。不需要循环,应将其删除。

同样在数量少于可用数量的情况下,价格是使用可用数量(不是所需数量)计算的,所需数量不变。

If qty > Range("AQ" & j).Value Then
    ' range copy
    mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
    qty = qty - Range("AQ" & j).Value
Else
    ' range copy
    mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
End If

应该是

If qty > Range("AQ" & j).Value Then
    ' range copy
    mySum = mySum + Range("AQ" & j).Value * Range("AV" & j).Value
    qty = qty - Range("AQ" & j).Value
Else
    ' range copy
    mySum = mySum + qty * Range("AV" & j).Value
    qty = 0
End If

请注意,如果可用总数量少于所需数量,则总和将不正确。

这些声明最好是Long

' Dim i, j, qty   As Integer  
Dim i as Long, j as Long, qty as Long  

因为如果 qty > 32767 会失败

此代码将每个部分的总和写入 D 列

Sub ExitFor_Loop2()

    Const SHEET_NAME = "Sheet1" ' change as required

    Const COL_PART = "A"
    Const COL_QU = "C"
    Const COL_SUM = "D" ' sum for each part change as required

    Const COL_STOCKPART = "AP"
    Const COL_STOCKQU = "AQ"
    Const COL_STOCKPRICE = "AV"

    Dim wb As Workbook, ws As Worksheet
    Dim iRow As Long, iLastRow As Long
    Dim t0 As Single, count As Long
    t0 = Timer

    Set wb = ThisWorkbook
    Set ws = wb.Sheets(SHEET_NAME)

    Dim iQu As Long, dSum As Double, sPart As String
    Dim iStockRow As Long, iStockQu As Long, dStockPrice As Double
    Dim iLastStock As Long

    iLastStock = ws.Range(COL_STOCKPART & Rows.count).End(xlUp).Row
    iLastRow = ws.Range(COL_PART & Rows.count).End(xlUp).Row
    'Debug.Print iLastRow, iLastStock

    ' double loop
    Application.ScreenUpdating = False
    For iRow = 2 To iLastRow

        sPart = ws.Cells(iRow, COL_PART)
        iQu = ws.Cells(iRow, COL_QU)
        dSum = 0

        For iStockRow = 2 To iLastStock

            ' matching part no
            If sPart = ws.Cells(iStockRow, COL_STOCKPART) Then

                iStockQu = ws.Cells(iStockRow, COL_STOCKQU) 'qu
                dStockPrice = ws.Cells(iStockRow, COL_STOCKPRICE) 'price

                With ws.Rows(iStockRow)
                   .Columns("BC") = sPart
                   .Columns("BD").Value = .Columns("AT").Value
                   .Columns("BE").Value = .Columns("AQ").Value
                   .Columns("BF:BJ").Value = .Columns("AV:AZ").Value
                End With

                If iQu > iStockQu Then

                    dSum = dSum + iStockQu * dStockPrice
                    iQu = iQu - iStockQu

                Else

                    dSum = dSum + iQu * dStockPrice
                    iQu = 0
                    iStockRow = iLastStock ' end search

                End If

            End If
            count = count + 1
        Next

        ' not enough stock
        If iQu > 0 Then
            MsgBox iQu & " items short for " & sPart, vbExclamation, "Part row " & iRow
            dSum = 0
        End If

        ws.Cells(iRow, COL_SUM) = dSum ' sum in coll E
   Next
   Application.ScreenUpdating = True

   MsgBox "Scanned col " & COL_PART & " to row " & iRow - 1, vbInformation, _
          count & " iterations completed in " & Format(Timer - t0, "0.00") & " secs"
End Sub
~~~

【讨论】:

    猜你喜欢
    • 2017-05-26
    • 2023-03-29
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-12-06
    相关资源
    最近更新 更多