小爬一般习惯使用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如何实现筛选条件之“排除某些值”的更多相关文章

  1. sql之表连接 筛选条件放在 连接外和放在连接里的区别

    使用一个简单的例子,说明他们之间的区别 使用的表:[Sales.Orders]订单表和[Sales.Customers]客户表,和上一篇博客的表相同 业务要求:查询出 : 所有的用户 在 2012-1 ...

  2. vue的data的数据进行指定赋值,用于筛选条件的清空,或者管理系统添加成功后给部分数据赋值为空

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. jqgrid 表格中筛选条件的多选下拉,树形下拉 ;文本框清除插件;高级查询多条件动态筛选插件[自主开发]

    /** * @@desc 文本框清除按钮,如果isAutoWrap为false当前文本框父级必须是relative定位,boostrap参考input-group * @@author Bear.Ti ...

  4. 【html】前端实现筛选条件跳转

    之前与PHP的合作模式之一是前端这边负责写好静态页面交货. 那现在新进的公司,PHP说筛选由前端来实现. 嗯,好吧.实现就实现,多锻炼下咯. <div class="fliter&qu ...

  5. django orm 以列表作为筛选条件进行查询

    在Django的orm中进行查询操作时,可以通过传入列表,列表内的元素为索引值,作为一个筛选条件来进行行查询 from .models import UserInfo user_obj = UserI ...

  6. 在SharePoint列表中使用动态筛选条件[今日][Today]

    如果在SharePoint使用了日历控件或者其他列表中有时间字段,用户经常希望能够动态使用条件字段进行筛选,例如希望筛选出开始日期是今天的事件.未来三日的事件. SharePoint的列表筛选条件支持 ...

  7. sql的where条件转换成mongdb筛选条件

    解析字符串 filterModel1 and filterModel2 and (filterModel3 or filterModel4) 1.转换成mongo的筛选条件 /// <summa ...

  8. C# linq根据自定义筛选条件和所对应的数值进行筛选

    在软件应用中有时候会出现这样的界面:上面是利用多选框和下拉框组合的筛选条件.下面表格展示筛选后的数据.如下图 上面是筛选条件,表格是根据筛选条件筛选的结果. 如果表格不支持筛选功能.可以利用Linq对 ...

  9. vue 自定义 移动端筛选条件

    1.创建组件 components/FilterBar/FilterBar.vue <template> <div class="filterbar" :styl ...

随机推荐

  1. 前端后端通信初步尝试(javascript - flask)

    在某项目中,需要使用python flask做后端功能开发,web提供功能入口. 此时需要使用Ajax通信. 由于以前从未接触过网络传输,记录了一些基础知识. 资料参考<HTML5+CSS3+J ...

  2. shell2-if判断

    1.条件测试类型(判断类型): 将测试结果做为判断依据. 测试类型有以下三种   [ 命令 ] :命令测试法(最常用的)  [[ 命令 ]] : 关键字测试 test 命令 以上是三种都可以,注意单词 ...

  3. 在B站学Java

    大家好,我是大彬~ 众所周知,B站是用来搞学习的,对于学编程的小伙伴来说,B站有着非常丰富的学习资源.今天给大家分享一些质量比较高的Java学习视频,希望对大家有帮助! Java基础 首先是Java基 ...

  4. SpringBoot学习笔记四之后台登录页面的实现

    注:图片如果损坏,点击文章链接: https://www.toutiao.com/i6803542216150090252/ 继续之前完成的内容,首先创建一个常量类 常量类的内容 服务器端渲染 前后端 ...

  5. FIS 使用

    从淘宝npm镜像安装fis $ npm install -g fis --registry=https://registry.npm.taobao.org 安装less插件 $ npm install ...

  6. Centos下安装Maven私服Nexus

    dockers安装Nexus,指定访问路径(默认为/:在使用Nginx做反向代理时,最好指定访问路径),并在容器外持久化数据,避免Nexus容器升级后数据丢失. 安装并启动 docker run -d ...

  7. 树莓派和荔枝派,局域网socket 通信

    在虚拟机上面实现了socket 之间的通信之后,突发奇想,想要实现树莓派和 荔枝派zero之间的通信. 1.直接将虚拟机下面的程序复制过来,重新编译并且运行.发现是没有办法进行通信的.客户端一直报错: ...

  8. 知乎上一个关于Android面试的问题答案

    由于链接出错,这里附上原文链接:Touch Me 前段时间面试,自己以及小伙伴们简要的汇总的一些面试问题,可以对照的参考一下吧- 建议就是在面一家公司之前了解好这个公司的app是以什么为驱动的,例如电 ...

  9. dubbo泛化引发的生产故障之dubbo隐藏的坑

    dubbo泛化引发的生产故障之dubbo隐藏的坑 上个月公司zk集群发生了一次故障,然后要求所有项目组自检有无使用Dubbo编程式/泛化调用,强制使用@Reference生成Consumer.具体原因 ...

  10. 2月10日 体温APP开发总结

    1.Java代码 1.user package bean;public class User { private String name; private String riqi; private S ...