Excel 2013macros只显示基于一个单元格值的特定行

我是新的excelmacros和vba。 我有一个excel文件,第一个表格中有大约300000行,第一列中有项目标识符(它们可能是几个具有相同值的),第二个表格中大约有1000行(第一列也包含项目标识符,但它们是唯一的这里)。 我需要编写一个基于第二个表格隐藏第一个表中的行的macros。 我的意思是我需要循环抛出第一张表中的所有行,如果第一个单元格的值不匹配第二张表的第一列的任何单元格,然后隐藏此行。

我知道这将是非常缓慢的,因为每次我需要比较另一个1000单元值的cellvalue,我有30万行。 我该怎么做? 你能build议最快的方法吗? 任何帮助将不胜感激,提前感谢。

编辑后,我search了很多我自己的macros

Sub hide() Dim MyCell, Rng As Range, Rn2 As Range Dim MyCell2 Dim id(1 To 1392) As String Set Rng = Sheets("Sheet0").Range("C162403:C339579") Set Rng2 = Sheets("IT stuff").Range("A1:A22031") i = 1 For Each MyCell2 In Rng2 If Not MyCell2.EntireRow.Hidden Then id(i) = MyCell2.Value i = i + 1 End If Next MyCell2 j = 0 For Each MyCell In Rng For A = 1 To 1392 If MyCell = id(A) Then j = 1 End If Next A If j = 0 Then MyCell.EntireRow.Hidden = True ElseIf j = 1 Then j = 0 End If Next MyCell End Sub 

它现在正在处理我的Excel文件,但它是非常缓慢的…我怎么能改善呢?

调用Excel对象模型会大大降低速度,所以最好将要检查的值加载到字典或数组中,然后引用它。 你也可以加载你在另一个字典中检查的行的行号和值,并在logging你需要隐藏的行时交叉引用这两个数据结构。 以这种方式工作将占用相当多的内存,但肯定会比直接交叉引用表更快…

心连心

为什么selectVBA? 而不是Excel Formula(Vlookup) + Autofilter

假设你的Sheet 1看起来像这样

在这里输入图像说明

而表2是这样的

在这里输入图像说明

简单地添加一个列如下所示,并把公式,然后使用自动filter来隐藏相关的行。

在这里输入图像说明

I2中使用的公式是

 =IF(ISERROR(VLOOKUP(A2,Sheet2!A:A,1,0)),"","True") 

下面的代码对你的问题采取了一些不同的方法。 您将注意到,它假定Sheet1在列A中具有一组值,加上未指定数量的数据列,并且Sheet2在列A中只有一组值,Sheet1列A值与之匹配。

代码执行以下操作:

  • 创build工作表1中最后一个数据列右侧列中的匹配值(1 =不匹配,0 =匹配)
  • 在工作表1数据范围上设置自动filter,匹配列中的条件值为1(即filter仅显示不匹配)
  • 将过滤的行分配给范围variables
  • 删除filter并清除匹配列
  • 批量隐藏范围variables中标识的行

我用一列Sheet1数据集testing了A列中300,000行代码值和B列和C列中的随机数字数据,Sheet2中只有超过1000个匹配值。 随机生成的10个字符的代码和匹配值被构build,使得Sheet1列A值的20%不匹配。

在两分钟内对这些数据平均运行时间。

 Sub MatchFilterAndHide2() Dim calc As Variant Dim ws1 As Worksheet, ws2 As Worksheet Dim ws1Name As String, ws2Name As String Dim rng1 As Range, rng2 As Range Dim hideRng As Range Dim lastRow1 As Long, lastRow2 As Long Dim lastCol1 As Long Application.ScreenUpdating = False calc = Application.Calculation Application.Calculation = xlCalculationManual ws1Name = "Sheet1" Set ws1 = Worksheets(ws1Name) With ws1 lastRow1 = .Range("A" & .Rows.Count).End(xlUp).Row lastCol1 = .Cells(1, ws1.Columns.Count).End(xlToLeft).Column + 1 Set rng1 = .Range(.Cells(1, 1), .Cells(lastRow1, lastCol1)) End With ws2Name = "Sheet2" Set ws2 = Worksheets(ws2Name) With ws2 lastRow2 = .Range("A" & .Rows.Count).End(xlUp).Row Set rng2 = .Range("A2:A" & lastRow2) End With 'add column of match values one column to the right of last data column '1 = no-match, 0 = match With ws1.Range(ws1.Cells(2, lastCol1), ws1.Cells(lastRow1, lastCol1)) .FormulaArray = "=N(ISNA(MATCH(" & ws1Name & "!" & rng1.Address & _ "," & ws2Name & "!" & rng2.Address & ",0)))" .Value = .Value End With 'set autofilter on rng1 and filter to show the no-matches With ws1.Range(ws1.Cells(1, 1), ws1.Cells(1, lastCol1)) .AutoFilter .AutoFilter field:=lastCol1, Criteria1:=1 End With With ws1 'assign no-matches to range object Set hideRng = .Range("A2:A" & lastRow1).SpecialCells(xlCellTypeVisible) 'turn off autofilter, clear match column, and hide no-matches .AutoFilterMode = False .Cells(1, lastCol1).EntireColumn.Clear hideRng.EntireRow.Hidden = True .Cells(1, 1).Select End With Application.Calculation = calc Application.ScreenUpdating = True End Sub