Excel / VBA:检查Cell Reference是否返回0

时间:2012-08-05 22:07:12

标签: excel vba excel-vba

我编写了一个VBA脚本,该脚本应该隐藏在另一个工作表中引用空单元格的行。可以这么说,Sheet 1包含单元格A1,它是空的。 Sheet 2的单元格A1包含“Sheet1!A1”,但打印为0.我的脚本应该遍历所有行并隐藏包含空引用的行,但似乎没有这样做。 如果你能帮助我弄清楚我的错误,那就太棒了。到目前为止,这是我的代码:

Sub Hide()
Application.ScreenUpdating = False
Dim i As Integer
For i = 1 To 1000
If IsEmpty(Cells(1, i)) Then
Rows(i).EntireRow.Hidden = True
End If
Next i
Range("A1").Select
Application.ScreenUpdating = True
End Sub

我非常感谢任何帮助。

致以最诚挚的问候,

亚历

2 个答案:

答案 0 :(得分:1)

亚历克斯这是一个稍微复杂的方法。但它有效:)

注意:这仅适用于引用同一工作簿中的工作表或打开的工作簿工作表的公式。

<强>逻辑

  1. 此代码标识具有公式然后循环遍历它们的单元格
  2. 然后在循环遍历具有公式的所有单元格时,它会检查该单元格的.Precedents。这是最棘手的部分。没有简单的方法来获取位于另一个工作表或工作簿上的.Dependents.Precedents。您可以将其称为此属性的限制。所以我正在使用另一种方法来获取这些:)
  3. 一旦我得到那个单元格的地址,我正在检查它们是否为空,然后根据条件,我隐藏了单元格。
  4. <强> CODE

    Sub Sample()
        Dim ws As Worksheet
        Dim rng As Range, acell As Range, bcell As Range
    
        '~~> This is the sheet which has the formula
        Set ws = Sheets("Sheet1")
    
        With ws
            '~~> Get the address of all the cells which have formulas
            Set rng = .Cells.SpecialCells(xlCellTypeFormulas)
    
            '~~> Loop through the cells
            For Each acell In rng
                If acell.EntireRow.Hidden = False Then
                    If acell.Value = 0 Then
                        On Error Resume Next
                            '~~> Clear any precedents/dependent arrows if any
                            .ClearArrows
                            '~~> Show precedents
                            acell.ShowPrecedents
                            '~~> Navigate to the relevant cell in the other worksheet
                            acell.NavigateArrow True, 1
                            '~~> Compare address and name to check if they are not from ws
                            If ActiveCell.Address <> rng.Address Or ActiveCell.Worksheet.Name <> .Name Then
                                Set bcell = Sheets(ActiveCell.Worksheet.Name).Range(ActiveCell.Address)
                                '~~> Check if it not empty
                                If Len(Trim(bcell.Value)) = 0 Then
                                    '~~> If empty, hide the row
                                    .Rows(acell.Row).EntireRow.Hidden = True
                                End If
                            End If
                            '~~> Clear any precedents/dependent arrows if any
                            .ClearArrows
                            .Activate
                        On Error GoTo 0
                    End If
                End If
            Next
        End With
    End Sub
    

    <强>快照

    运行宏之前的工作表1

    enter image description here

    这是表2的外观

    enter image description here

    这就是Sheet1在宏

    之后的样子

    enter image description here

答案 1 :(得分:0)

在循环中使用Cells(1, i)意味着您正在使用第1行中的列而不是A列中的行。我怀疑您需要Cells(i, 1)代替。

由于对CellsRows的来电不合格,他们会参考有效表。根据您的描述,两者是否应该引用同一张纸并不是100%清楚。很明显,例如Sheet2!A1不能为空,因为它包含引用Sheet1!A1的公式。

因此,您可能希望检查Sheet1上的空单元格,但实际上隐藏Sheet2上的行。这会将调用更改为Worksheets("Sheet1").Cells(i, 1)Worksheets("Sheet2").Rows(i)

如果事情变得更复杂,你需要检查空虚并隐藏Sheet2上的行,那么你需要隐藏A列中所有行的值为零(如果有的话,这可能是一个问题) Sheet1上的行实际上包含零作为值)或更改Sheet2上的公式以明确处理Sheet1上的空单元格。

例如,Sheet2!A1中的公式可以是:=IF(ISBLANK(Sheet1!A1),#N/A,Sheet1!A1)

您的宏中的检查将是:

If IsError(Cells(i, 1).Value) Then
  If (Cells(i, 1).Value = CVErr(xlErrNA)) Then
    Rows(i).EntireRow.Hidden = True
  End If
End If

您可以使用IsError检查,但这可能会隐藏源数据的真正错误(例如,除以零)