VBA:使用过滤的行和 SpecialCells(xlCellTypeVisible) 与将数据复制到新工作表中

2024-04-11

我有一个包含 250,000 行和 10 列的 Excel 工作簿,我想将数据拆分到不同的工作簿中。我的想法是过滤列表,以便 Excel/VBA 不必在每次我的代码要求在数据中查找某些内容时都遍历所有 250,000 行。

但是,我遇到了一个具体问题Sort还有一个关于隐藏行的一般问题SpecialCells(xlCellTypeVisible)。首先,这是代码:

Option Explicit

Sub Filtering()
   Dim wsData As Worksheet
   Dim cell As Variant
   Dim lRowData As Long, lColData As Long

'filter
   Set wsData = ThisWorkbook.Sheets(1)
   lRowData = wsData.Cells(Rows.Count, 1).End(xlUp).Row
   wsData.Range("A:A").AutoFilter Field:=1, Criteria1:="Name1"
   For Each cell In wsData.Range(wsData.Cells(2, 1), wsData.Cells(100, 1)).SpecialCells(xlCellTypeVisible)
       Debug.Print cell.Value 
   Next cell

'sort
   lColData = wsData.Cells(1, Columns.Count).End(xlToLeft).Column   
   wsData.Range(wsData.Cells(1, 1), wsData.Cells(lRowData, lColData)).SpecialCells(xlCellTypeVisible).Sort Key1:=wsData.Range("B1:B100"),   Order1:=xlDescending, Header:=xlYes ' returns error because of SpecialCells

End Sub
  1. “运行时错误‘1004’:无法在选择多个范围时执行此操作。选择单个范围并重试。”这发生在最后一行,在wsData.Range(wsData.Cells(1, 1), wsData.Cells(lRowData, lColData)).SpecialCells(xlCellTypeVisible).Sort Key1:=wsData.Range("B1:B100"), Order1:=xlDescending, Header:=xlYes。仅当我使用时才会发生SpecialCells(xlCellTypeVisible), so wsData.Range(wsData.Cells(1, 1), wsData.Cells(lRowData, lColData)).Sort Key1:=wsData.Range("B1:B100"), Order1:=xlDescending, Header:=xlYes works.

我的使用思路SpecialCells(xlCellTypeVisible)是只有这样 VBA 才会跳过过滤的单元格。不过我已经尝试过了,对我来说似乎.Sort不管有没有,都会跳过它们SpecialCells(xlCellTypeVisible)- 有人可以证实这一点吗?

  1. 这引出了我更普遍的问题:我不太清楚的一件事是 Excel/VBA 何时跳过筛选行,何时不跳过。要循环遍历可见单元格,我需要使用SpecialCells(xlCellTypeVisible). With .Sort我(也许)不知道?对于我在这些过滤列表上执行的任何操作,都会弹出这个问题。

这让我想知道:我应该使用隐藏部分数据的原始工作表,还是应该临时创建一个新工作表,仅复制我需要的数据(= 排除我用过滤器隐藏的行),然后工作接着就,随即?这张新的工作表会让它变得更快或更容易吗?根据您的经验,什么是更好的?


  1. 当您尝试复制不相邻的单元格或范围选择时,例如同一列(A1、A3、A5)中的多个不相邻的行,就会出现第一个错误。这是因为 Excel 将范围“滑动”在一起并将它们粘贴为单个矩形。您的可见特殊单元格不相邻,因此无法作为单个范围进行复制。

  2. 看起来 Excel 正在循环遍历范围内的所有单元格,而不仅仅是可见的单元格。您的 debug.print 返回的行数不仅仅是可见的行数。

我会采取不同的方法通过使用数组来解决您的问题,与工作表相比,VBA 能够非常快速地循环遍历。

Using this approach, I was able to copy 9k rows with 10 columns based on the value of the first column from a sample size of 190k in 4.55 seconds:

EDIT:我对数组进行了一些修改,使用以下命令将基于第一列从初始 190k 行复制 9k 行的时间缩短至 0.45 秒:

Option Explicit

Sub update_column()

Dim lr1 As Long, lr2 As Long, i As Long, j As Long, count As Long, oc_count As Long
Dim arr As Variant, out_arr As Variant
Dim start_time As Double, seconds_elapsed As Double
Dim find_string As String

start_time = Timer

' change accordingly
find_string = "looking_for"

With Sheets("Sheet1")

    ' your target column in which you're trying to find your string
    lr1 = .Cells(Rows.count, "A").End(xlUp).Row
    lr2 = 1

    ' all of your data - change accordingly
    arr = .Range("A1:J" & lr1)

    ' get number of features matching criteria to determine array size
    oc_count = 0
    For i = 1 To UBound(arr, 1)
        If arr(i, 1) = find_string Then
            oc_count = oc_count + 1
        End If
    Next

    ' redim array
    ReDim out_arr(oc_count, 9)

    ' write all occurrences to new array
    count = 0
    For i = 1 To UBound(arr, 1)
        If arr(i, 1) = find_string Then
            For j = 1 To 10:
                out_arr(count, j - 1) = arr(i, j)
            Next j
            count = count + 1
        End If
    Next

    ' write array to your target sheet, change sheet name and range accordingly
    Sheets("Sheet2").Range("A1:J" & (oc_count + 1)) = out_arr

End With

seconds_elapsed = Round(Timer - start_time, 2)
Debug.Print (seconds_elapsed)

End Sub

它不是超级干净,可能需要进行一些改进,但如果速度很重要(通常看起来很重要),那么这应该可以很好地满足您的要求。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VBA:使用过滤的行和 SpecialCells(xlCellTypeVisible) 与将数据复制到新工作表中 的相关文章

  • Excel VBA 过滤和复制粘贴数据

    给定一个数据集 假设有 10 列 在 A 列中我有日期 在 B 列中我有 我想仅过滤 A 列 2014 年的数据 B 列 ActiveSheet Range A 1 AR 1617 AutoFilter Field 5 Operator x
  • Apache poi setformula 不适用于 SE

    我正在尝试在 XSSFCell With POI 中设置公式 Cell setFormula SE D87 0 D80 D87 错误是 名称 SE 在当前工作簿中完全未知 Why 看起来您正在尝试创建一个IF公式 我发现这一页 http w
  • MS Access - 粘贴确认事件后

    当用户将记录直接粘贴到数据表子报表中时 是否可以在显示粘贴确认消息后捕获事件 我需要它能够在审计表中创建新记录时进行记录 通过捕获更新前 更新后和插入事件 我可以轻松创建已添加的记录集合 准备将详细信息插入审核日志 但是在所有这些事件触发后
  • 在应用程序创建完成时设置 Spark DataGrid 列的默认排序(Flex 4.5)

    我有一个包含多个列的 Spark DataGrid 组件 我希望我的应用程序默认按 DataGrid 中第一列的降序排列 我想使用单击顶部标题一次时发生的内置默认排序 我不需要对我正在使用的 ArrayCollection 进行排序或更改比
  • 如何使用 PHP 查找目录中的前 5 个文件?

    如何使用 PHP 列出按字母顺序排序的目录中的前 5 个文件或目录 Using scandir array slice array filter scandir path to dir is file 0 5 The array filte
  • 我可以用文本框设置变量名称吗? excel

    我可以使用 TextBox Vba Excel 设置变量的名称吗 我必须以在文本框中写入组名称并单击命令按钮的方式输入新的产品组 代码必须从文本框中获取字符串 并将该字符串设置为新创建的数组的名称 我只想在运行时创建一个新变量 或数组 据信
  • 根据单元格值向用户窗体添加复选框

    我对 VBA 很陌生 只有 3 天 但我发现它非常有用且易于使用 但现在我面临一个问题 我需要制作一个具有不同复选框的用户窗体 但我需要根据工作表某一列中使用的信息自动添加它们 我相信我可以使用 For Each Next 但我真的不知道如
  • 将ADODB二进制流转换为字符串vba

    我有以下问题 我有一个存储在服务器上的 CSV 文件 但它有 3 个字符作为分隔符 我想从 URL 加载数据并使用 作为分隔符将数据填充到 Excel 页面的列中 到目前为止 我找到了使用 ADODB 记录集从网站加载文件的代码 但我无法进
  • 定义 js-xlsx 单元格范围

    我正在尝试使用 js xlsx 读取 Excel 值 我可以使用以下代码从工作簿工作表中获取单元格值 if typeof require undefined XLSX require xlsx var workbook XLSX readF
  • 负整数的基数排序

    我正在尝试对整数 包括负整数 实现基数排序 对于非负整数 我计划为数字0 9创建一个10个队列的队列 并实现LSD算法 但我对负整数有点困惑 我现在的想法是继续为它们创建另一个包含 10 个队列的队列 并分别对它们进行排序 然后在最后 我将
  • 读取R中打开的Excel文件

    有没有办法将打开的Excel文件读入R 当Excel中打开一个excel文件时 Excel会对文件加锁 比如R中的read方法无法访问该文件 你能绕过这个锁吗 Thanks 编辑 这发生在带有原始 Excel 的 Windows 下 发生错
  • 在 O(n) 时间内排序?

    我被这个问题困扰了 2周 知道如何处理它吗 令 L 为 n 个不同整数的列表 假设 L 的 x 的元素在 1 750 范围内 设计线性排序算法对 L 的元素进行排序 我已经尝试过插入排序 但我不确定我的方法是否正确 Construct an
  • 在 VBA Excel 中查找、剪切和插入行以匹配借项和贷项值

    我在 Sheet1 中有以下设置数据 并从第 4 行 A 列开始 其中标题位于第 3 行 No Date Code Name Remarks D e b i t Cr e d i t 1 4 30 2015 004 AB 01 04 15
  • 将html表格保存到excel中[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我必须编写一个程序 定期读取网页并将
  • 在java中使用BUBBLE SORT对二维字符串数组进行排序

    类似的问题已经被问过 但从来没有关于二维字符串数组 因此在尝试了很长时间之后我找不到我想要的 我正在尝试使用 BubbleSort 对 java 中的 2D 字符串数组进行排序 作为输入 我收到一个二维字符串数组 一个表 以及您应该排序的
  • python中如何对多个条件进行排序?

    我有一个包含子列表的列表 如下所示 result helo 10 bye 50 yeah 5 candy 30 我想用三个条件来排序 首先 按子列表索引 2 中的最高整数 然后按子列表索引 1 中单词的长度 最后按子列表第 1 个索引中的字
  • 重新排列数组键 php [重复]

    这个问题在这里已经有答案了 我有这个数组 Array 15 gt 13 1 16 gt Mark one answer 19 gt You see a car on the hard shoulder of a motorway with
  • Excel工作簿关闭后反复打开

    我使用了 Application ontime 方法来调度一些宏 关闭工作簿后 它会一次又一次地打开 为了解决这个问题 我在工作簿上设置了另一个事件 BeforeClosed 现在它显示运行时错误 1004 Object Applicati
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 如何在不声明新数据的情况下更改类型(String,Int)元组的 Ord 实例?

    我正在尝试对类型列表进行排序 String Int 默认情况下 它按字符串排序 然后按整数排序 如果字符串相等 我希望它是相反的 首先比较整数 然后如果相等则比较字符串 另外 我不想切换到 Int String 我找到了一种通过定义实例来实

随机推荐