excel 在for循环中向后执行?

ryoqjall  于 11个月前  发布在  其他
关注(0)|答案(3)|浏览(79)

我正在尝试为电子表格编写一些代码,以计算物料清单(BoM)中的项目是否是采购组件的子项。我将尝试更详细地解释。
基本上,我的电子表格有很多列,但只需要2列来计算。为了简单起见,我只说这些是列A和B,VBA的输出放在列C。
A列包含物料清单级别--它总是从0级开始,该级别的子级是1级,1级的子级是2级,依此类推。目前,在我创建的所有物料清单中,10级是"最深的",但这不是不可能增加。
列B包含装配状态-我对该列唯一感兴趣的值是"P",表示已采购。
由于我的电子表格中有多个标题,数据从第12行开始,由于这是最高级别,我可以在C列中将其标记为"TL"。
现在我正在纠结的是,对于从13开始的每一行(这可以很容易地扩展到100,000行或更高!),我需要查看A列(物料清单级别),然后向上查找以找到低于**的级别,直到找到购买的级别(B列中的"P")或达到物料清单级别0。
希望这张table能帮上忙
| 列a|列b|列c|
| - -|- -|- -|
| 0| ih| TL|
| 1| ih|虚假|
| 2||虚假|
| 2||虚假|
| 1| p|虚假|
| 2| p|真正|
| 3||真正|
| 3||真正|
在考虑如何自动处理这个问题的同时,我想我可以使用一个For循环,它带有一个嵌套的Select Case,后跟一个嵌套的For循环(步骤-1)。
第一个For循环从顶部开始,向下查看最后一行,在每一行,它查看物料清单级别,并根据该值使用Select Case运行For循环(步骤-1),以开始向上查看行。
我可以看到的问题是,我需要为每个可能的物料清单级别(可能的最大总级别为99)提供一个案例
到目前为止的代码摘录(仅转到案例3):

Sub Purch_Child_Formula()   'ADD CHILD OF PURCHASED ASSY FORMULA
Dim AssyStatus As Double
Dim ChildPurchStatus As Double
Dim CurrentBomLevel As Integer
Dim X As Long

Last_Row = ActiveSheet.Range("A" & rows.Count).End(xlUp).Row

For ChildPurchStatus = 13 To Last_Row
    CurrentBomLevel = Cells(ChildPurchStatus, 1).Value
    
        Select Case CurrentBomLevel
        
        Case 1
            For X = ChildPurchStatus To 13 Step -1
            If Cells(X - 1, 1).Value = CurrentBomLevel Then
            Exit For
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            Else
                Cells(X, 3).Value = "FALSE"
            End If
            Next X
        Case 2
            For X = ChildPurchStatus To 13 Step -1
            If Cells(X - 1, 1).Value = CurrentBomLevel Then
            Exit For
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 2) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            Else
                Cells(X, 3).Value = "FALSE"
            End If
            Next X
        Case 3
            For X = ChildPurchStatus To 13 Step -1
            If Cells(X - 1, 1).Value = CurrentBomLevel Then
            Exit For
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 1) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 2) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            ElseIf Cells(X - 1, 1).Value = (CurrentBomLevel - 3) And Cells(X - 1, 2).Value = "P" Then
                Cells(X, 3).Value = "TRUE"
            Else
                Cells(X, 3).Value = "FALSE"
            End If
            Next X
        Case 4
            
        Case 5
            
        Case 6
            
        Case 7
            
        Case 8
            
        Case 9
            
        Case 10
        
        End Select
            
Next ChildPurchStatus
    
End Sub

字符串
这开始起作用,但在达到物料清单级别4之前确实出错。
所以现在我在想,也许我应该使用一个初始的for循环来向下查找行,然后再使用另一个for循环来向上查找数据,但是这个for循环应该继续下去,直到它在第2列中找到条件"P"--我们已经到达了一个Until循环。这可能吗?(很明显,编码不是我正常工作的一部分!)
很抱歉,非常罗嗦的职位,但我的情况似乎是独特的,因为一些网上搜索还没有帮助到目前为止。
希望有足够的信息在这篇文章。我会添加任何其他细节要求。

d5vmydt9

d5vmydt91#

你可以用一个公式来做。

=COUNTIFS(RC3:OFFSET(RC1,MAX(FILTER(ROW(R1C1:RC1),R1C1:RC1=0))-ROW(RC),2),"=P")>0

字符串


的数据
在A1模式下,我的单元格D1有:

=COUNTIFS($C1:OFFSET($A1,MAX(FILTER(ROW($A$1:$A1),$A$1:$A1=0))-ROW(D1),2),"=P")>0

rlcwz9us

rlcwz9us2#

  • 布尔解 *

如前所述,我使用一个布尔值来跟踪哪个BoM lvl是最低的,我还有一个额外的变量:

Sub Purch_Child_Formula()   'ADD CHILD OF PURCHASED ASSY FORMULA
    Dim lRow As Long, i As Long, bomLvl As Long
    Dim ws As Worksheet
    Dim pCheck As Boolean
    
    Set ws = ActiveSheet
    lRow = ws.Range("A" & ws.Rows.Count).End(xlUp).Row
    
    If lRow < 13 Then
        MsgBox "Not enough rows to check"
        Exit Sub
    End If
    
    Dim arr, arrPr
    arr = ws.Range("A13:B" & lRow).Value 'from your example
    ReDim arrPr(1 To UBound(arr, 1), 1 To 1)
    
    For i = 1 To UBound(arr, 1)
        If arr(i, 1) = 0 Then 'resetting
            pCheck = False
            bomLvl = 0
        End If
        If arr(i, 2) = "P" Then
            If Not pCheck Then
                pCheck = True
                bomLvl = arr(i, 1)
            End If
            If bomLvl > arr(i, 1) Then bomLvl = arr(i, 1)
        End If
        arrPr(i, 1) = pCheck And bomLvl < arr(i, 1)
        'there is a P and its BoM is lower than current one ... or not
    Next i
    
    ws.Range("C13:C" & lRow).Value = arrPr 'print everything at once
End Sub

字符串
如果下面的结果是错误的,请告诉我:

  • 0重置一切
  • lvl 3有P -> lvl 4及以上为真
  • lvl 2有P,所以现在lvl 3和更高的是真的

x1c 0d1x的数据

ycggw6v2

ycggw6v23#

  • 使用Dictionary对象存储上层BOM的状态。
Option Explicit
Sub Demo()
    Dim i As Long, j As Long
    Dim Sht1 As Worksheet
    Dim arrRes, rngRes As Range
    Dim objDic As Object, sKey As Long
    Set Sht1 = Sheets("Sheet1") ' Modify as needed
    Set rngRes = Sht1.Range("A1").CurrentRegion ' Modify as needed
    arrRes = rngRes.Value
    Set objDic = CreateObject("scripting.dictionary")
    ' Loop through data
    For i = LBound(arrRes) To UBound(arrRes)
        sKey = CLng(arrRes(i, 1))
        If Not objDic.exists(sKey) Or UCase(arrRes(i, 2)) = "P" Then
            objDic(sKey) = UCase(arrRes(i, 2))
        End If
        If sKey > 0 Then
            arrRes(i, 3) = False
            ' Loop through up BoM
            For j = sKey - 1 To 0 Step -1
                If objDic(j) = "P" Then
                    arrRes(i, 3) = True
                    Exit For
                End If
            Next
        End If
    Next i
    ' Update data on sheet
    rngRes.Value = arrRes
End Sub

字符串

相关问题