【问题标题】:Find row indices of empty cells in a given range查找给定范围内空单元格的行索引
【发布时间】:2019-05-04 00:41:16
【问题描述】:

是否可以编写一个 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所以我对此知之甚少,如果我的思维过程过于复杂,请见谅。

【问题讨论】:

  • 你需要什么输出?消息框?
  • 我认为这并不重要,我只需要能够复制行号并将它们粘贴到某个地方。

标签: excel vba readxl


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢!理想情况下,我想取消合并文档中的所有单元格,并用之前合并的单元格的内容填充每个拆分单元格。但是我在互联网上找到了应该完全做到这一点的宏,但它们不适用于我的文件,所以我想我可以确定空白单元格,然后在 R 中处理它们。我通常不使用 Excel所以我对此知之甚少。
  • @Florian 查看我的编辑
  • 非常感谢,在示例文件中,宏的工作方式与我想象的完全一样,现在我将尝试我的大文件。硬编码范围很好,我只需要在几列上运行宏,这样我就可以指定范围。
【解决方案2】:

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

您可以使用Cell.Row 获取行号。如何返回或显示取决于您 - 可以是消息框、分隔字符串或数组,甚至是多区域范围。

Sub 一旦被调用就不能返回任何东西,所以你可能想要一个Function,例如Public Function EmptyRed() As String

(另外,我建议您养成明确声明所有变量的习惯,并可能也使用Option Explicit,然后再遇到基于错字的错误。只需添加@ 987654330@现在在子的顶部)

【讨论】:

    【解决方案3】:
    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
    

    【讨论】:

    • 感谢您的建议,但宏也将拆分合并的单元格计为空,这是我想要避免的。抱歉,如果我的表述不清楚。
    【解决方案4】:

    有几种方法:

    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:我在手机上编辑了代码,有电脑后会进一步调试。我只是更习惯使用“范围”而不是“单元格”。

    【讨论】:

      【解决方案5】:

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

      • 循环浏览工作表的 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
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多