如何根据行中的值快速隐藏 VBA 中的行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18090633/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 22:35:46  来源:igfitidea点击:

How to hide rows in VBA based on values in row, quickly

excelvbashow-hide

提问by user2658468

this is my first time using the site, so forgive me for any inept explaining. I have a working macro to hide/unhide rows based on content of the rows, I just want it to be faster. Using a check box, when the box is checked, all rows with an "x" in column D get unhidden, those without an "x" get hidden. Same thing happens when it is unchecked, except it references column C, not D.

这是我第一次使用该网站,所以请原谅我的任何无能解释。我有一个工作宏可以根据行的内容隐藏/取消隐藏行,我只是希望它更快。Using a check box, when the box is checked, all rows with an "x" in column D get unhidden, those without an "x" get hidden. 未选中时会发生同样的事情,除了它引用的是 C 列,而不是 D 列。

Right now, this code works. It's just a little slower than I'd like, since I'm sharing this with a bunch of people. Any ideas for how to speed it up? I'm pretty darn new to VB (the internet is astoundingly wise and a good teacher), but that doesn't matter. I already improved the code - before it selected each row, then referenced the column, and it was awful. Any ideas to speed it up (preferably without moving the screen) would be great.

现在,此代码有效。它只是比我想要的慢一点,因为我要与一群人分享这个。关于如何加快速度的任何想法?我对 VB 非常陌生(互联网非常聪明而且是一位好老师),但这并不重要。我已经改进了代码 - 在它选择每一行之前,然后引用该列,这很糟糕。任何加速它的想法(最好不移动屏幕)都会很棒。

Thanks so much folks, DS

非常感谢各位,DS

Sub NewLuxCheck()
    Dim x As Integer
    NumRows = Range("A42", "A398").Rows.Count
    Range("A42").Select
    If ActiveSheet.Shapes("checkbox2").OLEFormat.Object.Value = 1 Then
        For x = 42 To NumRows + 41 Step 1
            If Worksheets("Base").Range("D" & x).Value = "x" Then
                Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
            Else
                Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
            End If
        Next
    Else
        For x = 42 To NumRows + 41 Step 1
            If Worksheets("Base").Range("C" & x).Value = "x" Then
            Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
            Else
                Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
            End If
        Next
    End If
    MsgBox ("Done")
End Sub

采纳答案by dee

You could use array formula and let Excel to return array with row-numbers where 'x' value occures. It will be quicker but you'll have to reorganise your code and create separate functions etc.

您可以使用数组公式并让 Excel 返回带有“x”值出现的行号的数组。它会更快,但您必须重新组织代码并创建单独的功能等。

Here example where array formula finds rows whre in column 'D' the cell has value 'x'. Then string of this row numbers is created in form of "A1,A5,A10" ...means 'x' was found in rows 1,5,10. And finally Range(rowsJoind).EntireRow.Hidden is used for all the rows to be hidden/un-hidden in one step.

这里的示例中,数组公式在列 'D' 中查找单元格值为 'x' 的行。然后以“A1,A5,A10”的形式创建此行号的字符串……意味着在第1、5、10行中找到了“x”。最后 Range(rowsJoind).EntireRow.Hidden 用于在一个步骤中隐藏/取消隐藏所有行。

For rows with value different then 'x' you'll have to use formula like '=IF({0}<>""x"", ROW({0}), -1)'.

对于值与 'x' 不同的行,您必须使用诸如 '=IF({0}<>""x"", ROW({0}), -1)' 之类的公式。

Sub test()
    Dim inputRange As Range
    Dim lastRow As Long
    Dim myFormula As String
    Dim rowsJoined As String, i As Long
    Dim result As Variant

    With Worksheets("Base")
        lastRow = .Range("D" & .Rows.Count).End(xlUp).Row
        Set inputRange = .Columns("D").Resize(lastRow)

        Application.ReferenceStyle = xlR1C1
        myFormula = "=IF({0}=""x"", ROW({0}), -1)"
        myFormula = VBA.Strings.Replace(myFormula, "{0}", inputRange.Address(ReferenceStyle:=xlR1C1))
        result = Application.Evaluate(myFormula)
        result = Application.Transpose(result)
        Application.ReferenceStyle = xlA1

        For i = LBound(result) To UBound(result)
            If (result(i) > -1) Then
                rowsJoined = rowsJoined & "A" & result(i) & IIf(i < UBound(result), ",", "")
            End If
        Next i

        .Range(rowsJoined).EntireRow.Hidden = False
    End With
End Sub