Excel "Do While" 循环在第一次迭代后无法正常运行

Excel "Do While" Loop Not functioning correctly after first iteration

我有一个 Sub 可以进行一些简单的格式化,然后我需要它来评估和计算列是否包含“1”或什么都不包含,以及该列是否具有 header 是否为数字.

Do...Until 循环的第一次迭代完全正常运行。但是,如果我第二次尝试 运行 它,它会将活动单元格一直扔到工作表 (XFD) 中最右边的列。我总共有大约 114,000 行需要循环。

请看下面的代码,只有第一个循环;这将需要嵌套在另一个循环中以循环遍历所有行:

Sub TotalBookCountsProcess()

    Dim ws As Excel.Worksheet
    Dim numberedBooks As Integer 'Total Number of physical books
    Dim virtualBooks As Integer 'Total Number of virtual books
    Dim firstBookCol As Integer 'First Column with a book number
    Dim ispeecCol As Integer 'ISPEC Column
    Dim lastWorksheetCol As Integer 'Last Column in the worksheet after adding total book count columns
    Dim loopColOffset As Integer  'Offset column amounts for new row reset after loop
    Dim lastItem As String 'Last item number in last row of the worksheet

    ActiveCell.End(xlDown).Select
    lastItem = ActiveCell.Value
    ActiveCell.End(xlUp).End(xlToRight).Select
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = "Total Numbered Books"
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = "Total CS Books"
    lastWorksheetCol = ActiveCell.Column

    Columns.AutoFit

    numberedBooks = 0
    virtualBooks = 0

    Cells.Range("1:1").Find("ISPEC").Select

    ispecCol = ActiveCell.Column
    firstBookCol = ispecCol + 1
    ActiveCell.Offset(1, 1).Select

    loopColOffset = ((lastWorksheetCol - firstBookCol) * -1)

Do Until ActiveCell.End(xlUp).Value = "Total Numbered Books"
    If ActiveCell.Value = 1 And IsNumeric(ActiveCell.End(xlUp).Value) = True Then
        numberedBooks = numberedBooks + 1
        ActiveCell.Offset(0, 1).Select
    ElseIf ActiveCell.Value = 1 And IsNumeric(ActiveCell.End(xlUp).Value) = False Then
        virtualBooks = virtualBooks + 1
        ActiveCell.Offset(0, 1).Select
    Else
        ActiveCell.Offset(0, 1).Select
    End If
Loop

    ActiveCell.Value = numberedBooks
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = virtualBooks
    ActiveCell.Offset(1, loopColOffset).Select



End Sub

非常感谢任何见解。

首先不要使用 select ...你不需要,而且你的代码会变得很慢,并且会依赖于 selected 的单元格。

我没有详细看到你的代码,但是如果你第一次告诉它 运行 是正确的,但第二次不是......通常会发生这种情况,因为在第二次 运行 selected 单元格不同。

如何避免问题:

  • 第一个解决方案:在函数中强加起始单元格

    Range("a1").Select '这是一个例子

  • 第二种解决方案:将您的代码独立于 activeCell 或 selectedCell。只是也许只是在开始时才开始算法。

    sheet1.range("A1") .....(代码中没有使用select和activeCell)

第一个解决方案使您的系统始终处于相同的起始条件。第二种解决方案与开始条件无关(更好)。

原因在于

ActiveCell.End(xlUp).Value = "Total Numbered Books"

作为循环的结束条件

您的真正目标是在 ActiveCell 列是第一行中具有 "Total Numbered Books" 值的列时立即结束行循环

但是

  • ActiveCell.End(xlUp).Value 将引用 ActiveCell

  • 上方的第一个非空单元格
  • 从第二次迭代开始,列第一行值实际上是 "Total Numbered Books" 的单元格也有其正上方的单元格填充了 numberedBooks

  • 所以它一直跳到下一列直到列结束...

您的代码可能如下所示:

Option Explicit

Sub TotalBookCountsProcess()

    Dim ws As Excel.Worksheet
    Dim numberedBooks As Integer 'Total Number of physical books
    Dim virtualBooks As Integer 'Total Number of virtual books
    Dim firstBookCol As Integer 'First Column with a book number
    Dim ispeecCol As Integer 'ISPEC Column
    Dim lastWorksheetCol As Integer 'Last Column in the worksheet after adding total book count columns
    Dim loopColOffset As Integer  'Offset column amounts for new row reset after loop
    Dim lastItem As String 'Last item number in last row of the worksheet
    Dim ispecCol As Long

    ActiveCell.End(xlDown).Select
    lastItem = ActiveCell.Value
    ActiveCell.End(xlUp).End(xlToRight).Select
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = "Total Numbered Books"
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = "Total CS Books"
    lastWorksheetCol = ActiveCell.Column

    Columns.AutoFit

    numberedBooks = 0
    virtualBooks = 0

    Cells.Range("1:1").Find("ISPEC").Select

    ispecCol = ActiveCell.Column
    firstBookCol = ispecCol + 1
    ActiveCell.Offset(1, 1).Select

    loopColOffset = ((lastWorksheetCol - firstBookCol) * -1)

Do
    numberedBooks = 0
    virtualBooks = 0
    Do Until Cells(1, ActiveCell.Column) = "Total Numbered Books"
        If ActiveCell.Value = 1 Then
            If IsNumeric(Cells(1, ActiveCell.Column)) Then
                numberedBooks = numberedBooks + 1
            Else
                virtualBooks = virtualBooks + 1
            End If
        End If
        ActiveCell.Offset(0, 1).Select
    Loop

    ActiveCell.Value = numberedBooks
    ActiveCell.Offset(0, 1).Select
    ActiveCell.Value = virtualBooks
    ActiveCell.Offset(1, loopColOffset).Select
Loop Until Cells(ActiveCell.Row - 1, 1) = lastItem


End Sub

我还添加了行循环

但要确保真正的解决方案是避免所有这些 selecting/activating