获取列中第一个空单元格的行号,并将该值存储在其他单元格中。

问题描述 投票:0回答:1

我想找到列中第一个空单元格的行号,并将该行号存储在单元格Z1中。

我试着用下面的宏代码,但它永远进入了循环,当它试图在单元格Z1中设置值时,它又再次进入worksheet_change事件,然后再次进入for循环。

Private Sub Worksheet_Change(ByVal Target As Range)
Dim ws As Worksheet
    Set ws = ActiveSheet
    For Each cell In ws.Columns(3).Cells
        If IsEmpty(cell) = True Then Range("$Z$1").Value = cell.Row: Exit For
      Next cell
End Sub

enter image description here

请帮助解决这个问题。

谢谢你的帮助

excel vba excel-vba
1个回答
2
投票

也许这段代码对你有帮助

    Option Explicit

    Function firstEmptyCell(col As Long, Optional ws As Worksheet) As Range

    If ws Is Nothing Then
        Set ws = ActiveSheet
    End If

    Dim rg As Range
    Set rg = ws.Cells(1, col)

    If Len(rg.Value) = 0 Then
        Set rg = rg.Offset
    Else
        If Len(rg.Offset(1).Value) = 0 Then
            Set rg = rg.Offset(1)
        Else
            Set rg = rg.End(xlDown)
            Set rg = rg.Offset(1)
        End If
    End If
    Set firstEmptyCell = rg

End Function

而事件代码是

    Private Sub Worksheet_Change(ByVal Target As Range)

        On Error GoTo EH

        If Target.Column <> 12 Then
            Exit Sub
        End If

        Application.EnableEvents = False
        Range("Z1").Value = firstEmptyCell(12).Row

    EH:
        Application.EnableEvents = True
    End Sub

更新: 根据关于变更事件缺陷的评论意见,我们可以改变: firstEmptyCell 略,只使用UDF

Function firstEmptyCellA(col As Long, Optional ws As Worksheet) As Long

    On Error GoTo EH
    If ws Is Nothing Then
        Set ws = ActiveSheet
    End If

    Application.Volatile

    Dim rg As Range
    Set rg = ws.Cells(1, col)

    If Len(rg.Value) = 0 Then
        Set rg = rg.Offset
    Else
        If Len(rg.Offset(1).Value) = 0 Then
            Set rg = rg.Offset(1)
        Else
            Set rg = rg.End(xlDown)
            Set rg = rg.Offset(1)
        End If
    End If
    firstEmptyCellA = rg.Row
    Exit Function
EH:
    firstEmptyCellA = 0

End Function

1
投票

棘手的启用事件

只有当第12列中的一个单元格(L)进行修改,否则就没有必要了。如果你在那里有公式,那么这将不起作用,你必须使用 Worksheet_Calculate 事件。

列中第一个空单元格的行

Option Explicit

' Row of First Empty Cell in Column
Private Sub Worksheet_Change(ByVal Target As Range)

    Const TargetCell As String = "Z1"
    Const TargetColumn As Variant = 12   ' (or "L")
    Dim rng As Range

    If Intersect(Columns(TargetColumn), Target) Is Nothing Then Exit Sub

    Application.EnableEvents = False
        Set rng = Columns(TargetColumn).Find(What:="", _
          After:=Cells(Rows.Count, TargetColumn), LookIn:=xlValues)
        If rng Is Nothing Then
            Range(TargetCell).Value = 0  ' Full column. No empty cells.
        Else
            Range(TargetCell).Value = rng.Row
        End If
    Application.EnableEvents = True

End Sub

列中最后一个非空单元格后第一个空单元格的行。

Option Explicit

' Row of First Empty Cell After Last Non-Empty Cell in Column
Private Sub Worksheet_Change(ByVal Target As Range)

    Const TargetCell As String = "Z1"
    Const TargetColumn As Variant = 12   ' (or "L")
    Dim rng As Range

    If Intersect(Columns(TargetColumn), Target) Is Nothing Then Exit Sub

    Application.EnableEvents = False
        Set rng = Columns(TargetColumn).Find(What:="*", LookIn:=xlFormulas, _
          SearchDirection:=xlPrevious)
        If rng Is Nothing Then           ' Empty column. No non-empty cells.
            Range(TargetCell).Value = 1
        Else
            If rng.Row = Rows.Count Then ' Last (bottom-most) cell is not empty.
                Range(TargetCell).Value = 0
            Else
                Range(TargetCell) = rng.Offset(1).Row
            End If
        End If
    Application.EnableEvents = True

End Sub

0
投票

不需要循环。把这个粘贴在模块中,而不是工作表事件中,除非你想让它在每次工作表变化时都出现。

Sub Macro1()
    ActiveSheet.Range("Z1") = ActiveSheet.Columns(3).SpecialCells(xlCellTypeBlanks)(1).Row
End Sub

如果你想在每次更改后使用,那么就把它贴在工作表中。这段代码不会每次都运行。它将检查Z1是否为空,然后输入值。如果Z1不为空,它将检查目标单元格是否在C列。

Private Sub Worksheet_Change(ByVal Target As Range)
Dim Rng As Range
Set Rng = ActiveSheet.Columns(3)

If IsEmpty(Range("Z1")) Then
    Range("Z1") = Rng.SpecialCells(xlCellTypeBlanks)(1).Row
Else
If Not Intersect(Range("C1:C" & Range("Z1").Value), Target) Is Nothing Then
    Range("Z1") = Rng.SpecialCells(xlCellTypeBlanks)(1).Row
End If
End If
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.