在VBA中,选择语句的"Fall through"是什么意思?

3
我正在使用select case语句与函数结合创建VBA中的“穿透”,但我似乎无法弄清楚它应该如何构造。以下是我希望它能够完成的内容:
1. 检查行值1和10是否具有相同的唯一ID(如果没有:1和9;1和8,1和7,...,1和2) 1a. 如果行值1和10具有相同的唯一ID,则中间的所有行也是如此 2a. 即使所有行都具有相同的唯一ID,并不意味着我想要检查的单元格都是相同的——例如:行1、3、4、7、8、10可能有空单元格,而行2、5、9则不为空。为了确定这一点,必须从10到1逐个检查每一行。一行不会影响另一行;1-10行中的任何/全部/无一行都可以有空单元格,尽管它们都具有相同的唯一ID。
3. 检查第一个和最后一个之间的所有行中的空单元格。 4. 连接所有具有空单元格的行的唯一ID。
问题在于:仅对于第一个检查,我将需要10+9+8+7+6+5+4+3+2嵌套的select语句。
以下是伪代码示例:
开始第一个循环(第一个范围:Excel工作表行2-12;10行):
行1和10具有相同的唯一ID
检查第10行是否有空单元格
第10行没有空单元格
检查第9行是否有空单元格
发现空单元格->添加信息到字符串
检查第8行是否有空单元格
发现空单元格->添加信息到字符串
检查第7行是否有空单元格
未发现空单元格
检查第6行是否有空单元格
发现空单元格->添加信息到字符串
检查第5行是否有空单元格
...
不再发现空单元格
开始第二个循环(第二个范围:Excel工作表行12-14;3行):
单元格12和14匹配
检查第14行是否有空单元格
发现空单元格->将信息添加到另一个字符串中
检查第13行是否有空单元格
未发现空单元格
检查第12行是否有空单元格
未发现空单元格
我的当前代码如下:
Sub selectcasetryagain()
Dim c As Range
Dim r As Range
Dim lastRow As Long
Dim lastCol As Long

lastRow = Range("A:A").End(xlDown).Row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

Set r = ActiveSheet.Range(Cells(1, 1), Cells(lastRow, lastCol))

For i = 2 To lastRow
    Set c = r.Cells(i, 6)
    Select Case c.Value
        Case SelectCaseFallThru(c)

    End Select
Next i

End Sub

Option Explicit
Public c, r As Range
Public i As Integer
Public lastRow, lastCol As Long
Public RMissing As Variant

Function SelectCaseFallThru(Optional c As Variant, Optional d As Variant)
    If c.Value = c.Offset(10, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(10, 0).Value
        If IsEmpty(c.Offset(0, 46)).Value And IsEmpty(c.Offset(0, 47)).Value Then
            RMissing = c.Offset(0, 42).Value
        i = i + 10
    ElseIf c.Value = c.Offset(9, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(9, 0).Value
        i = i + 9
    ElseIf c.Value = c.Offset(8, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(8, 0).Value
        i = i + 8
    ElseIf c.Value = c.Offset(7, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(7, 0).Value
        i = i + 7
    ElseIf c.Value = c.Offset(6, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(6, 0).Value
        i = i + 6
    ElseIf c.Value = c.Offset(5, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(5, 0).Value
        i = i + 5
    ElseIf c.Value = c.Offset(4, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(4, 0).Value
        i = i + 4
    ElseIf c.Value = c.Offset(3, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(3, 0).Value
        i = i + 3
    ElseIf c.Value = c.Offset(2, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(2, 0).Value
        i = i + 2
    ElseIf c.Value = c.Offset(1, 0).Value Then
        Debug.Print c.Value & " - " & c.Offset(1, 0).Value
        i = i + 1
    Else
        Exit Function
    End If


End Function

我不理解这个语句:“仅对于第一个检查,我将需要1098765432个嵌套选择语句”。难道你不只需要10个吗? - SJR
2
看起来你想得太多了 - 我认为你可以用两个嵌套循环实现所有这些。 - dwirony
两个值之间的所有行都相同(例如,1和10相同,则2-9与1和10相同)。我想逐个检查每一行并将其唯一ID添加到字符串中。如果循环命中其中一个,则不会检查其他条件,就我所理解的而言?这意味着它必须在每次命中时深入一层,以成功收集具有空单元格的行的所有唯一ID? - Gregory
1
你能发一张截图吗?我有点跟不上。 - SJR
@slai 不一定所有的都相等。可能是10、8、6、2相等,但其他的不相等。 - Gregory
显示剩余4条评论
1个回答

0

我重写了你的selectcasefallthrough,使其更加灵活,并增加了一些注释。由于我不确定你伪代码的哪一部分目前让你感到困扰,所以我没有添加任何额外的功能。但是,一旦我知道你当前卡住的伪代码步骤,我可以进行编辑。

Sub selectcasetryagain()
Dim c As Range 'Will no longer access Global c
Dim r As Range
Dim lastRow As Long
Dim lastCol As Long

lastRow = Range("A:A").End(xlDown).Row
lastCol = Cells(1, Columns.Count).End(xlToLeft).Column

Set r = ActiveSheet.Range(Cells(1, 1), Cells(lastRow, lastCol))

For i = 2 To lastRow
    Set c = r.Cells(i, 6)
    Select Case c.Value
        Case SelectCaseFallThru(10, c) ' Added in row number to make it variable

    End Select
Next i

End Sub

Option Explicit
Public c, r As Range 'Note: currently Global c is defined as a Variant
Public i As Integer
Public lastRow, lastCol As Long
Public RMissing As Variant

'This function does not currently return anything.
Function SelectCaseFallThru(maxRowNum as Integer, Optional c As Variant, Optional d As Variant) 'This Function will use the Optional c, not the Global c
    Dim counter as Integer
    Dim found as Boolean

    For counter = maxRowNum to 1 step -1
        If c.Value = c.Offset(counter, 0).Value Then
            Debug.Print c.Value & " - " & c.Offset(counter, 0).Value
            If IsEmpty(c.Offset(0, 46)).Value And IsEmpty(c.Offset(0, 47)).Value and counter = maxRowNum Then 'added check for counter
                RMissing = c.Offset(0, 42).Value
            End if
            i = i + counter
            found = True
            Exit For
        End If
    Next counter

    If not found Then Exit Function

End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接