查找给定范围内空单元格的行索引

Find row indices of empty cells in a given range

是否可以编写一个 vba 宏来确定给定范围内是否有任何空单元格以及 returns 该单元格的行号?

我是 vba 的新手,我在搜索互联网后设法写的所有内容都是采用范围并将其中的每个空单元格着色为红色的内容:

Sub EmptyRed()
    If TypeName(Selection) <> "Range" Then Exit Sub
    For Each cell In Selection
        If IsEmpty(cell.Value) Then cell.Interior.Color = RGB(255, 0, 0)
    Next cell
End Sub 

该宏基本上可以满足我的要求,但我不想将空单元格着色为红色,而是想知道空单元格的行索引。

一点背景信息:我有一个非常大的文件(大约 80 000 行),其中包含许多合并的单元格。我想用 readxl 将它导入 R。 Readxl 拆分合并的单元格,将值放入第一个拆分单元格中,将 NA 放入所有其他单元格中。但是一个完全空的单元格也会被分配 NA,所以我认为最好的办法是用 Excel 找出哪些单元格是空的,这样我就知道哪个 NA 表示合并的单元格或空单元格。非常欢迎任何关于如何解决这个问题的建议,谢谢!

编辑:澄清一下:理想情况下,我想取消合并文档中的所有单元格,并用先前合并的单元格的内容填充每个拆分单元格。但是我在网络上发现了应该完全做到这一点的宏,但它们对我的文件不起作用,所以我想我可以只确定空白单元格,然后在 R 中处理它们。我通常不使用 Excel所以我对此知之甚少,如果我的思维过程太复杂,请见谅。

完全按照您在标题中所说的去做:

If IsEmpty(cell.Value) Then Debug.Print cell.Row

但也有 Excel 方法来确定合并的单元格并对其进行操作。所以我不确定你想用这些信息做什么。

编辑

添加您所说的要对结果执行的操作,也许这段 VBA 代码可能会有所帮助:

Option Explicit
Sub EmptyRed()
    Dim myMergedRange As Range, myCell As Range, myMergedCell As Range
    Dim rngProcess As Range

With Application
    .ScreenUpdating = False
    .Calculation = xlCalculationManual
    .EnableEvents = False
End With

Set rngProcess = Range("A1:B10")
    For Each myCell In rngProcess
        If myCell.MergeCells = True Then
            Set myMergedRange = myCell.MergeArea
            With myMergedRange
                .MergeCells = False
                .Value = myCell(1, 1)
            End With
        End If
    Next myCell

With Application
    .ScreenUpdating = True
    .Calculation = xlCalculationAutomatic
    .EnableEvents = True
End With
End sub

请注意,我明确声明了所有变量,并且我硬编码了要检查的范围。有多种方法可以声明要检查的范围;通常很少首选使用 'Selection'。

首先:从频谱的另一端,您可以使用 Range.MergeCells or Range.MergeArea 来确定单元格是否是合并区域的一部分。但是,我离题了...

您可以使用Cell.Row 获取行号。 return 或显示方式由您决定 - 可以是消息框、定界字符串或数组,甚至是多区域范围。

A Sub 一旦调用就不能 return 任何东西,所以你可能需要一个 Function 来代替,例如Public Function EmptyRed() As String

(此外,我建议您养成显式声明 所有 变量的习惯,也许还可以使用 Option Explicit,然后再 运行 变成了基于拼写错误的错误。现在只需在 sub 的顶部添加 Dim cell As Range)

Sub FF()
    Dim r, wksOutput As Worksheet
    Dim cell As Range, rng As Range, rngArea As Range
    With Selection
        .UnMerge
        '// Get only blank cells
        Set rng = .SpecialCells(xlCellTypeBlanks)
        '// Make blank cells red
        rng.Interior.Color = vbRed
    End With
    '// Create output worksheet
    Set wksOutput = Sheets.Add()
    With wksOutput
        For Each rngArea In rng.Areas
            For Each cell In rngArea
                r = r + 1
                '// Write down the row of blank cell
                .Cells(r, 1) = cell.Row
            Next
        Next
        '// Remove duplicates
        .Range("A:A").RemoveDuplicates Array(1), xlNo
    End With
End Sub

有几种方法:

Sub EmptyRed()

Dim rgn,targetrgn as range 
Dim ads as string ‘ return rgn address
Set targetrgn= ‘ your selection
For Each rgn In Targetrgn
    If IsEmpty(rgn.Value) Then 
        ‘1. Use address function, and from there you can stripe out the column and row
        Ads=application.worksheetfunction.addres(cell,1)’ the second input control the address format, w/o $
        ‘2. Range.row & range.column
       Ads=“row:” & rgn.row & “, col: “ & rgn.column

    End if
Next rgn

结束子

Ps:我在 phone 上编辑了代码,当我有电脑时会进一步调试。而且我只是更习惯使用“范围”而不是“单元格”。

To clarify: Ideally, I want to unmerge all cells in my document and fill each split cell with the content of the previously merged cell.

  • 循环遍历工作表 UsedRange 中的所有单元格
  • 如果合并,取消合并并用以前合并区域的值填充未合并区域。
  • 如果没有合并为空,则收集地址输出。

    Sub fillMerged()
    
        Dim r As Range, br As Range, mr As Range
    
        For Each r In ActiveSheet.UsedRange
            If r.Address <> r.MergeArea.Address Then
                'merged cells - unmerge and set value to all
                Set mr = r.MergeArea
                r.UnMerge
                mr.Value = mr.Cells(1).Value
            ElseIf IsEmpty(r) Then
                'unmerged blank cell
                If br Is Nothing Then
                    Set br = r
                Else
                    Set br = Union(br, r)
                End If
            End If
        Next r
    
        Debug.Print "blank cells: " & br.Address(0, 0)
    
    End Sub