在一个循环中查找下一个空行的索引(VB Excel)。

huangapple go评论62阅读模式
英文:

Find the index of the next empty row inside of a loop ( VB Excel )

问题

我有一个充满数据部分的Excel表格,每个数据部分之间由空行分隔。

当我循环遍历工作表的每一行时,我需要找到下一个空行的索引,以便知道当前数据部分的结束位置,并在传递给下一个数据部分之前进行修改。

这是我的第一个循环的示例(在此循环内,我需要找到下一个空行的索引):

Dim x As Integer
Dim lastrow As Long
lastrow = Cells(Rows.Count, "A").End(xlUp).Row    

Range("A1").Select
For x = 1 To lastrow
    If Left(Cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(Cells(x, "H"))) Then
        '在这里,我需要添加另一个循环来查找下一个空行的索引
        idxblankrow = Range(Cells(x, "A")).CurrentRegion.Row
        MsgBox "Idx blank row is " & idxblankrow
        Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "H")).Cut Range(Cells(x + 2, "B"), Cells(idxblankrow - 1, "I"))
        Range(Cells(x, "H")).Select
        Selection.Copy
        Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "A")).Select
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
        Application.CutCopyMode = False
    End If
Next

这是另一个失败的尝试(第二个嵌套的For循环尝试搜索空行的地方):

Dim x As Integer
Dim lastrow As Long

lastrow = Cells(Rows.Count, "A").End(xlUp).Row

For x = 1 To lastrow
    If Left(Cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(Cells(x, "H"))) Then
        For j = x To lastrow
            If IsEmpty(Cells(j, "A")) Then idxblankrow = Cells(j, "A").Row
            MsgBox "blank row " & idxblankrow
            Exit For
        End If
    Next

    Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "H")).Cut Range(Cells(x + 2, "B"), Cells(idxblankrow - 1, "I"))
    Range(Cells(x, "H")).Select
    Selection.Copy
    Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "A")).Select
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Application.CutCopyMode = False
Next

希望这些示例能帮助你解决问题。如果还有其他问题,请随时提出。

英文:

I have an excel sheet full of data sections, each data section is separated by an empty row.

While I'm looping over each row of the worksheet, I need to find the index of the next blank row so I can know where the current data section ends & apply modifications to it before passing to the next data section.

Here is an example of my first loop (inside this loop I need to find the index of the next blank row):

Dim x As Integer
Dim lastrow As Long
lastrow = Cells(Rows.Count, "A").End(xlUp).Row    

Range("A1").Select
For x = 1 To lastrow
    If Left(Cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(Cells(x, "H"))) Then
          
'''Here I need to add another loop to find the index of my next blank row please'''
            idxblankrow = Range(Cells(x, "A")).CurrentRegion.Row
            MsgBox "Idx blank row is " & idxblkrow
            Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "H")).Cut Range(Cells(x + 2, "B"), Cells(idxblankrow - 1, "I"))
            Range(Cells(x, "H")).Select
            Selection.Copy
            Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "A")).Select
            Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
                :=False, Transpose:=False
            Application.CutCopyMode = False
        End If
    Next

Here is another failed attempt(the second nest For loop is what tries to search for the blank row):

Dim x As Integer
Dim lastrow As Long

lastrow = Cells(Rows.Count, "A").End(xlUp).Row
 
   
For x = 1 To lastrow
    If Left(Cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(Cells(x, "H"))) Then
        For j = x To lastrow
            If IsEmpty(Cells(j, "A")) Then idxblankrow = Cells(j, "A").Row
            MsgBox "blank row " & idxblankrow
                Exit For
            End If
                        
        
        Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "H")).Cut Range(Cells(x + 2, "B"), Cells(idxblankrow - 1, "I"))
        Range(Cells(x, "H")).Select
        Selection.Copy
        Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "A")).Select
        Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False
        Application.CutCopyMode = False
    End If
Next

Any kind of help would be appreciated!

答案1

得分: 1

如果我想知道整行是否为空,只需连接整行并检查其长度。如果长度为零,则该行为空。否则,不为空。

请参见以下示例截图(仅第四行为空,这在第四个公式中可见,结果为零):

在一个循环中查找下一个空行的索引(VB Excel)。

英文:

If I want to know if an entire row is empty, I just concatenate the whole row and check the length. If this is zero, then the row is blank. Else, it's not.

See following exemplary screenshot (only the fourth row is empty, which is seen in the fourth formula, giving zero as a result):

在一个循环中查找下一个空行的索引(VB Excel)。

答案2

得分: 1

请使用以下适配的方式。它不会选择,也不会使用剪贴板:

For x = 1 To LastRow
    If Left(Cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(Cells(x, "H"))) Then

        idxblankrow = Cells(x, "A").End(xlDown).Row
        MsgBox "Idx blank row is " & idxblankrow
        Range(Cells(x + 2, "A"), Cells(idxblankrow - 1, "H")).Cut Cells(x + 2, "B")
        '从整个A:A列的部分复制“H”上的值:
        Range("A" & x & ":A" & idxblankrow - 1).Value = Cells(x, "H").Value '不使用剪贴板...

        Stop '在这里停下来检查是否已经完成了需要的操作
             '如果是的话,请按F5继续检查。

        '现在,您可能需要递增x以继续迭代已处理的部分
        '可以这样实现:
        x = x + (idxblankrow - x) + 2 '???
    End If
Next x

现在,您可能需要递增x,以匹配已处理的行数,但必须用文字解释您尝试完成的任务。在这里,猜测并不是一个适当的工作方式...

英文:

Please, use the next adapted way. It does not select, it does not use clipboard:

For x = 1 To LastRow
    If left(cells(x, "A").Value, 8) = "!JOURNAL" And Not (IsEmpty(cells(x, "H"))) Then
          
            idxblankrow = cells(x, "A").End(xlDown).Row
            MsgBox "Idx blank row is " & idxblankrow 
            Range(cells(x + 2, "A"), cells(idxblankrow - 1, "H")).Cut cells(x + 2, "B")
            'copy the value from "H" on the whole A:A column portion:
            Range("A" & x & ":A" & idxblankrow - 1).Value = cells(x, "H").Value 'not using clipboard...
            
            Stop 'check when stopped here if it did what you need
                 'if so, please press F5 to continue and check again.
            
            'you probably need to increment x to continue iteration after the processed portion
            'something as:
            x = x + (idxblankrow - x) + 2 '???
        End If
Next x

You probably need now to increment x with the number of rows which have been processed, but you must explain in words what you try accomplishing. Guessing is not an appropriate way of working here...

答案3

得分: 1

使用标志来识别组的开始和结束。这处理了组之间的多个空行。

Option Explicit

Sub macro()

   Dim ws As Worksheet
   Dim lastrow As Long, i As Long, n As Long
   Dim x As Long, z As Long
   Dim bStart As Boolean, bEnd As Boolean

   Set ws = ThisWorkbook.Sheets("Sheet1")
   n = 0
   With ws
       lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
       For i = 1 To lastrow
       
            ' 组的开始
            If Len(.Cells(i, "A")) > 0 Then
                bStart = True
                n = n + 1
            End If
            
            ' 组的结束前瞻
            If Len(.Cells(i + 1, "A")) = 0 Then
                bEnd = bStart
            End If
            
            ' 有效范围
            If bStart And bEnd Then
                x = i - n + 1 ' 组的第一行
                MsgBox "Processing rows " & x & " to " & i
                
                If Left(.Cells(x, "A").Value, 8) = "!JOURNAL" _
                    And Not (IsEmpty(Cells(x, "H"))) Then
                        ' 处理从x到i的行
                End If
                ' 重置标志
                n = 0
                bStart = False
                bEnd = False
            End If
                    
        Next
    End With
End Sub
英文:

Use flags to identify the start and end of the group. This deals with multiple blank rows between groups.


Sub macro()

   Dim ws As Worksheet
   Dim lastrow As Long, i As Long, n As Long
   Dim x As Long, z As Long
   Dim bStart As Boolean, bEnd As Boolean
   
   Set ws = ThisWorkbook.Sheets("Sheet1")
   n = 0
   With ws
       lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
       For i = 1 To lastrow
       
            ' start of group
            If Len(.Cells(i, "A")) > 0 Then
                bStart = True
                n = n + 1
            End If
            
            ' end of group look ahead
            If Len(.Cells(i + 1, "A")) = 0 Then
                bEnd = bStart
            End If
            
            ' valid range
            If bStart And bEnd Then
                x = i - n + 1 ' first row of group
                MsgBox "Processing rows " & x & " to " & i
                
                If Left(.Cells(x, "A").Value, 8) = "!JOURNAL" _
                    And Not (IsEmpty(Cells(x, "H"))) Then
                        ' process rows x to i
                End If
                ' reset flags
                n = 0
                bStart = False
                bEnd = False
            End If
                    
        Next
    End With
End Sub


</details>



# 答案4
**得分**: 1

以下是翻译好的部分:

```vba
所有这些答案都可以更简单。考虑以下:

    iNextBlankRow = Sheet1.Range("A" & iNextBlankRow & ":A50").SpecialCells(xlCellTypeBlanks).Cells(1, 1).Row

为了演示,运行这个宏:

    Sub BlankRowTest()
        Dim iNextBlankRow As Long
        Dim r As Long
        
        iNextBlankRow = 1
        For r = 1 To 50
            If iNextBlankRow <= r Then iNextBlankRow = Sheet1.Range("A" & iNextBlankRow + 1 & ":A50").SpecialCells(xlCellTypeBlanks).Cells(1, 1).Row
            Debug.Print r, iNextBlankRow, "'" & Sheet1.Cells(r, 1).Value & "'"
        Next
    End Sub

这段代码循环遍历前50行,寻找下一个空行。当找到它时,将其分配给变量iNextBlankRow。我们不会在当前行(r)大于或等于iNextBlankRow之前更新它。在那一点上,我们再次从下一行开始查找。
```

<details>
<summary>英文:</summary>

All these answers could be much simpler. Consider this:

    iNextBlankRow = Sheet1.Range(&quot;A&quot; &amp; iNextBlankRow &amp; &quot;:A50&quot;).SpecialCells(xlCellTypeBlanks).Cells(1, 1).Row

To demonstrate, run this macro:

    Sub BlankRowTest()
        Dim iNextBlankRow As Long
        Dim r As Long
        
        iNextBlankRow = 1
        For r = 1 To 50
            If iNextBlankRow &lt;= r Then iNextBlankRow = Sheet1.Range(&quot;A&quot; &amp; iNextBlankRow + 1 &amp; &quot;:A50&quot;).SpecialCells(xlCellTypeBlanks).Cells(1, 1).Row
            Debug.Print r, iNextBlankRow, &quot;&#39;&quot; &amp; Sheet1.Cells(r, 1).Value &amp; &quot;&#39;&quot;
        Next
    End Sub

This code loops through the first 50 rows looking for the next blank row. When it finds it, it assigns it to the variable iNextBlankRow. We don&#39;t bother updating that until our current row (r) is greater than or equal to INextBlankRow. At that point we look again starting from the next row. 

</details>



huangapple
  • 本文由 发表于 2023年2月8日 21:03:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386224.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定