【问题标题】:For-loop with multiple if-conditions does not complete correctly具有多个 if 条件的 for 循环无法正确完成
【发布时间】:2013-01-02 22:33:48
【问题描述】:

我编写了一个相对简单的程序,旨在执行以下操作:

  • 我的电子表格中有两列,B 和 C。两个数据集都从第 26 行开始
  • B 包含项目的编号(例如项目 1),C 包含每个行项目的标识符,以便可以将多个服务分配给一个项目。然后,这两个变量的组合将形成每个订单项的唯一 ID(例如,项目 1 中第三项的 1/3)
  • 每次在 B 列中输入新的项目 ID 时,C 列应重新从 1 开始
  • 一旦项目列表完成,循环应该停止(第一个 if 条件)
  • 我使用另一个过程按项目编号和另一个标准对数据集进行排序,这意味着我每次还必须重写 C 列
  • 为了使代码更易于阅读,我创建了ThisRowLastRow

我的代码不会产生错误消息,但也不会返回所需的结果:单元格 C27 的值应该为 2,但它返回 1,并且同一列中下面的所有单元格都是空白的。这看起来很奇怪,因为在即时窗口中它们都得到了 1 的值(这仍然不正确,但与它打印到电子表格的不同)。

我已经尝试了一段时间来修复它,但我不知道错误可能出在哪里。非常感谢您的帮助!代码如下:

Sub DataSort()

Dim i As Object, ThisRow As Integer , LastRow As Integer

Range("C26").Value = 1
Range("C27").Activate    
ThisRow = ActiveCell.Offset(0, -1).Value

LastRow = ActiveCell.Offset(-1, -1).Value


    For Each i In Range("ProcessID")
        If ThisRow = 0 Then
            Exit Sub
        ElseIf ThisRow > LastRow Then
            ActiveCell.Value = ActiveCell.Offset(0, -1).Value + 1
        Else
            ActiveCell.Value = 1
        End If
        Debug.Print ActiveCell.Value
    Next i
End Sub

>更新: 这是电子表格的屏幕截图;希望这会有所帮助:

【问题讨论】:

  • ThisRowLastRow 取自您手动设置值的单元格?由于您有足够的代表来发布图片,您能否向我们展示您在问题中描述的输入数据列的小示例屏幕截图(B、C ......等等)
  • i 应该是 Range,ThisRow 和 LastRow 应该是 Long,并且 cmets 存在并且应该添加以使此代码易于理解。
  • 感谢编辑;我现在已经上传了电子表格中的屏幕截图。
  • 您没有在循环中的任何地方使用i 吗?
  • 不,他没有使用它,所以他只是一遍又一遍地激活同一个单元格。需要激活当前单元格(i)。 i.激活

标签: excel for-loop offset vba


【解决方案1】:

您在同一组单元格上循环,因为您从不更改循环中的活动单元格。您还需要为每一行重新计算 ThisRow 和 LastRow 的值,因此需要将其包含在循环中。

Sub DataSort()

Dim i As Range, ThisRow As Integer , LastRow As Integer

' Set the initial active cell and first process number
Range("C26").Value = 1
Range("C27").Activate    

   ' Loop through each cell in the Process column  
    For Each i In Range("ProcessID")
        ' Load the value of this row and the last row
        ThisRow = ActiveCell.Offset(0, -1).Value
        LastRow = ActiveCell.Offset(-1, -1).Value

        ' Check if we are at the change of a project - update process number
        If ThisRow = 0 Then
            Exit Sub              
        ElseIf ThisRow > LastRow Then
            ActiveCell.Value = 1
        Else
            ActiveCell.Value = ActiveCell.Offset(0, -1).Value + 1
        End If
        ' Move the active cell down one row
        ActiveCell.Offset(1,0).Activate
    Next i
End Sub

注意:我没有测试过这段代码。

但是,您的代码没有靠近 i 变量。使用它,我们不需要使用ActiveCell

Sub DataSort()

Dim i As Range, ThisRow As Integer , LastRow As Variant



   ' Loop through each cell in the Process column  
    For Each i In Range("ProcessID")
        ' Load the value of this row and the last row
        ThisRow = i.Offset(0, -1).Value
        LastRow = i.Offset(-1, -1).Value

        ' Check if we are at the change of a project - update process number
        If ThisRow = 0 Then
            Exit Sub
        ' First Row of Data
        ElseIf LastRow = "Project ID" Then
            i.Value = 1
        'Change of Project - reset Process ID
        ElseIf ThisRow > LastRow Then
            i.Value = 1
        'Same Project so increase the Process ID
        Else
            i.Value = i.Offset(-1, 0).Value + 1
        End If
        ' Move the active cell down one row
    Next i
End Sub

我认为您在检查 ThisRow 是否大于 Last row 时也可能已经交换了逻辑 - 这应该意味着项目发生了变化,因此请重置进程 ID 号。

【讨论】:

  • Le Magritte 非常适合你 ;)
  • @boncodigo 我自己对它印象深刻;)
  • 非常感谢尼克(和其他所有人)的帮助。我已经测试了你的代码,它工作正常;只是两个小的更正:如果我们将codeLastRowcode 设置为整数,则会在检查“项目 ID”时创建类型不匹配。我已将其更改为 Variant 并且可以正常工作。另一件事是 codeElsecode 条件中的偏移量:它需要读取 codei.Offset(-1,0)code 以便它引用上面的行,而不是左侧的列.我已经进行了编辑并测试了代码;现在很好。
  • 谢谢@Matthias 我已经在答案中解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
  • 2023-01-29
  • 2020-08-21
  • 2011-10-06
  • 2020-04-10
  • 1970-01-01
  • 2014-05-21
相关资源
最近更新 更多