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

时间:2018-12-02 15:14:16

标签: excel vba excel-vba readxl

是否可以编写一个vba宏来确定给定范围内是否有空单元格并返回该单元格的行号?

我是vba的新手,在搜索互联网后设法写的所有东西都具有一定的范围,并且将其中的每个emty单元格都染成红色:

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所以我对此知之甚少,对不起,如果我的思考过程过于复杂。

5 个答案:

答案 0 :(得分:0)

要完全按照标题中的说明进行操作:

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

请注意,我明确声明了所有变量,并且对要检查的范围进行了硬编码。有多种方法可以声明要检查的范围:通常很少选择“选择”。

答案 1 :(得分:0)

先于其他:从频谱的另一端开始,您可以使用Range.MergeCellsRange.MergeArea来确定某个单元格是否属于合并区域。但是,我离题了...

您可以使用Cell.Row获取行号。返回或显示的方式取决于您-可能是消息框,定界字符串或数组,甚至是多个区域。

Sub一经调用就无法返回任何内容,因此您可能希望使用Function,例如Public Function EmptyRed() As String

(此外,我建议您养成显式声明所有变量的所有的习惯,并在遇到基于错字的错误之前也可以使用Option Explicit。现在在子标题的顶部添加Dim cell As Range

答案 2 :(得分:0)

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

答案 3 :(得分:0)

有几种方法:

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:我编辑了手机上的代码,如果有电脑,将进行进一步调试。而且我更习惯于使用“范围”而不是“单元格”。

答案 4 :(得分:0)

  

要澄清一下:理想情况下,我想取消合并文档中的所有单元格,并使用先前合并的单元格的内容填充每个拆分的单元格。

  • 在工作表的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