VBA如何实现筛选条件之“排除某些值”
小爬一般习惯使用Python来解决爬虫和某些办公自动化场景问题,不过最近却需要实现一个VBA需求:从一堆人员处理的Excel数据记录中,排除某些“用户名称”处理的数据。整个思考过程很有意思,很值得分享下。
这个需求看上去很简单,实际当我们的待排除“用户名称”数超过2时,Excel原生的筛选“自定义筛选-不等于”功能是难以支持的:


那么这类问题该怎么高效解决呢?
小爬首先排除的方法是遍历每一行的“用户名称”,然后进行remove等操作,因为小爬的数据集超过50000行,这样执着的遍历方法显然跟上文提到的“高效”不沾边,自然不应该成为我们自动化的首选方案;
小爬紧接着试了下VBA的录制宏功能:对数据进行筛选,然后手工勾选掉那些我们不想要的数据,再来看后台VBE自动生成的代码是否能稍加改造为我所用,该场景里,后台的录制的代码长这样:
Sub 宏1()
Range("I1").Select
Selection.AutoFilter
ActiveSheet.Range("$A$1:$J$141").AutoFilter Field:=9, Criteria1:=Array("User1", "User11", "User12", "User13", "User14", "User15", "User16", "User17", "User18", "User19", "User2", "User20", "User3"), Operator:=xlFilterValues
End Sub
可以看出,我们要排除的人员是User4到User10,但是录制的宏代码中,Array里提到的人员恰恰是需要保留的人员数据(即筛选时勾选的人),这里的“Operator:=xlFilterValues”指的是筛选后要保留哪些值,这里的Field:=9 指的是我们要筛选的字段是表格的第9列。
那么问题就转化成了如下形式:
如何得到某列所有的人员名单(去重重复项和空值),然后从这些名单中剔除掉我们的“排除人员名单”,从而得到我们最终的待保留人员名单,并存入一个array数组?
下图是我在ExcelHome论坛中看到的一个典型的方法:

该方法可以快速将某一列值存入列表,然后借助字典的键不重复这一特性来快速去重,最终将字典的键写入新的列。该方法非常典型,不过当我们将某一列值快速存入数组(arr=[A1:A1000])时,默认得到的是二维数组(数组的二级下标默认为1),同理,只有将某一行数据快速写入数组,得到的才是一维数组;
在这个“筛选中排除某些值”的场景,根据录制宏的代码,我们需要的应该是一个一维数组,内包含所有要筛选的结果。此时,我们可以利用excel的转置功能快速将列变成行,达到快速将某列值存入一维数组的目的,有了思路,代码就水到渠成了,下面是示例代码:
Sub test()
'基于N列的排除人员名单,对“用户名称”列进行筛选,晒除这些人
Dim max_row As Integer
max_row = Sheets("Sheet1").Cells(Rows.Count, 9).End(xlUp).Row '得到表格第九列的最大行号
Set d = CreateObject("Scripting.Dictionary")
arr = Application.Transpose(Range("I2:I" & max_row).Value)
For i = LBound(arr) To UBound(arr) '将人员名单遍历后,借助字典,筛除重复值和空值
If arr(i) <> "" Then d(arr(i)) = ""
Next
For i = 2 To 8 '将字典的键,去除人员名单,得到其他键,存入新的数组
If d.Exists(Range("N" & i).Value) = True Then
d.Remove (Range("N" & i).Value)
End If Next
newArr = d.keys '排除人员名单后的新数组
'For i = LBound(newArr) To UBound(newArr)
'Debug.Print (newArr(i))
'Next
Range("A1").Select
Selection.AutoFilter
Range("$A$1:$J$" & max_row).AutoFilter Field:=9, Criteria1:=newArr, Operator:=xlFilterValues '基于新的数组进行筛选(达到排除某些人员的效果) End Sub
通过上面的思路也可以看出来,简单的一个“筛选——不包含某些值”的VBA场景,我们需要用到录制宏功能,一维数组、二维数组功能、数组的转置方法、字典的remove方法、字典键快速存入数组方法等。看上去每个单一功能都不复杂,但是任何一个功能掌握的不好,我们很可能就解决不了一个再常见不过的场景。工作中需要学会和总结的技能点还有很多,加油吧,骚年~
欢迎扫码关注我的公众号 获取更多爬虫、数据分析的知识!

VBA如何实现筛选条件之“排除某些值”的更多相关文章
- sql之表连接 筛选条件放在 连接外和放在连接里的区别
使用一个简单的例子,说明他们之间的区别 使用的表:[Sales.Orders]订单表和[Sales.Customers]客户表,和上一篇博客的表相同 业务要求:查询出 : 所有的用户 在 2012-1 ...
- vue的data的数据进行指定赋值,用于筛选条件的清空,或者管理系统添加成功后给部分数据赋值为空
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- jqgrid 表格中筛选条件的多选下拉,树形下拉 ;文本框清除插件;高级查询多条件动态筛选插件[自主开发]
/** * @@desc 文本框清除按钮,如果isAutoWrap为false当前文本框父级必须是relative定位,boostrap参考input-group * @@author Bear.Ti ...
- 【html】前端实现筛选条件跳转
之前与PHP的合作模式之一是前端这边负责写好静态页面交货. 那现在新进的公司,PHP说筛选由前端来实现. 嗯,好吧.实现就实现,多锻炼下咯. <div class="fliter&qu ...
- django orm 以列表作为筛选条件进行查询
在Django的orm中进行查询操作时,可以通过传入列表,列表内的元素为索引值,作为一个筛选条件来进行行查询 from .models import UserInfo user_obj = UserI ...
- 在SharePoint列表中使用动态筛选条件[今日][Today]
如果在SharePoint使用了日历控件或者其他列表中有时间字段,用户经常希望能够动态使用条件字段进行筛选,例如希望筛选出开始日期是今天的事件.未来三日的事件. SharePoint的列表筛选条件支持 ...
- sql的where条件转换成mongdb筛选条件
解析字符串 filterModel1 and filterModel2 and (filterModel3 or filterModel4) 1.转换成mongo的筛选条件 /// <summa ...
- C# linq根据自定义筛选条件和所对应的数值进行筛选
在软件应用中有时候会出现这样的界面:上面是利用多选框和下拉框组合的筛选条件.下面表格展示筛选后的数据.如下图 上面是筛选条件,表格是根据筛选条件筛选的结果. 如果表格不支持筛选功能.可以利用Linq对 ...
- vue 自定义 移动端筛选条件
1.创建组件 components/FilterBar/FilterBar.vue <template> <div class="filterbar" :styl ...
随机推荐
- gogs安装与说明(docker)
作为一个开发,少不了和git打交道,像github,gitee是很流行的git线上托管平台,而我们也搭建自己的git托管平台,有条件的可以使用gitlab,它对硬件有要求,像博主这种没条件用虚拟机的, ...
- 【17MKH】我在框架中对.Net依赖注入的扩展
说明 依赖注入(DI)是控制反转(IoC)的一种技术实现,它应该算是.Net中最核心,也是最基本的一个功能.但是官方只是实现了基本的功能和扩展方法,而我呢,在自己的框架 https://github. ...
- Linux 中安装、升级、配置 Swoole 扩展
从源码编译安装 # 下载Swoole wget http://pecl.php.net/get/swoole-4.5.2.tgz tar -zxvf swoole-4.5.2.tgz cd swool ...
- laravel源码分析-队列Queue
laravel 源码分析具体注释见 https://github.com/FX-Max/source-analysis-laravel 前言 队列 (Queue) 是 laravel 中比较常用的一个 ...
- 『无为则无心』Python函数 — 34、lambda表达式
目录 1.lambda的应用场景 2.lambda语法 3.快速入门 4.示例:计算a + b 5.lambda的参数形式 6.lambda的应用 lambda表达式的主要作用就是化简代码. 匿名函数 ...
- notepad++加到右键
win10系统左下角点击"开始"->运行->regedit,打开注册表编辑器 在HKEY_CLAsssEs_RooT→ * → shell 下,在shell下,新建项命 ...
- MySQL删除数据库或表(DROP DATABASE/table语句)
DROP DATABASE [ IF EXISTS ] <数据库名> DROP table[ IF EXISTS ] <数据库表名> 语法说明如下: <数据库名>: ...
- vs2017 快捷键 - 总结
1.格式化代码 先选中需要格式的代码,一般是全选[Ctrl+A]后,Ctrl+K+F[按定Ctrl不动,依序点击 K和F,然后再放开 Ctrl ] 2.多行注释 注释: 先CTRL+K,然后CTRL+ ...
- vmware快速扩容虚拟磁盘
在使用vmware进行虚拟化的时候,会遇到虚拟磁盘不够用的情况,以前的办法都是使用lvm进行管理扩容,目前在linux上可以实现快速扩容了,具体方法如下: 该方法参考阿里云在线扩容文档:文档地址 其中 ...
- 备忘录——基于rdlc报表实现打印产品标签
目录 0. 背景说明 1. 条形码生成 2. 获取产品的小程序码 3. 报表设计器设计标签模版 3.1 为WinForm控件工具箱添加ReportViewer控件 3.2 为VS2019安装RDLC报 ...