每每提到Excel办公自动化,我们脑海里能想到的就是公式、数据透视表、宏、VBA,这也是我们大部分人数据分析的进阶之路。当我们对于常用VBA技巧已经相当熟练后,往往会有一种“我的VBA知识够用啦”的错觉,其实那只是因为我们收到的实际需求还不够复杂和多样化。

  一旦哪天碰到略显复杂的业务需求时,我们才知道VBA变量、循环、条件判断、数组、字典、窗体,这些还只是VBA的基础知识罢了,会了这些,远达不到【蒂花之秀】的水准。我们今天的主角,SQL(结构化查询语言),通过嵌入VBA代码中,就可以解决很多复杂的实际问题。

  考虑到写VBA的大军主要还是办公人员,如财务岗、行政岗,并非科班程序员出身,他们往往觉得SQL是后端程序员才使用的语言,并不那么容易掌握,其实这不过是另一种认知的偏差。我们今天就通过一个简单例子,看看在VBA中如何写SQL,是一种什么体验。

  想要在VBA中使用SQL,我们就不得不先认识下ADO。

ADO,其实是ActiveX Data Objects的简称,说人话,它其实是几个ActiveX对象(类),用于提供数据(Data)之间的访问。

Connection:ADO Connection 对象用于创建一个访问某个数据源的开放连接。基于此开发连接,我们可以对一个数据库进行访问和相关操作;

Recrodset:ADO Recordset 对象用于存储一个来自数据库表的记录集。一个 Recordset 对象由记录和列(字段)组成。它也是我们最常用的操作数据库的对象。

  我们数据库的数据源(dataSource)可以是Access、SQL Server、Oracle 等数据库,也可以是简单的text文件,甚至可以是一个excel文件。考虑到办公人员的主要数据来源都是通过excel本身。我们先来看看如何连接excel文件作为我们的数据源。

03版本Excel(.xls)

Provider=Microsoft.jet.OLEDB.4.0;Extended Properties=’Excel 8.0;HDR=yes;IMEX=0’;Data Source=带路径的Excel工作簿完整名称;

07~19版本Excel(.xlsx 或.xlsm)

Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=’Excel 12.0; HDR=yes;IMEX=0’;Data Source=带路径的Excel工作簿完整名称。

如何理解【Data Source=带路径的Excel工作簿完整名称】这句话?

  翻译成程序语言,就是要这个文件的完整路径,如果我们要控制的数据源就是我们当前的xlsm宏文件,那么就是Data Source=thisworkbook.FullName,如果是同目录下某个'test.xlsx'文件,我们则可以写作:Data Source=thisworkbook.path &"\test.xlsx".

  有了这些基础知识,我们还需要知道SQL的一些基础语法,此处推荐SQL 教程 (w3school.com.cn) 进行入门。

现在我们就可以使用SQL Select语句做一个最基础的查询了。

场景一:利用SQL将【表一】数据拷贝到【表二】

代码如下:

 1 Sub myFirstQuery()
2 '将表一的数据查询到后,返回到表二中,包含字段名
3 Dim CONN As Object, sht As Worksheet, RS As Object, i As Integer
4 Set CONN = CreateObject("ADODB.Connection")
5 Set sht = ThisWorkbook.Sheets("表二")
6 CONN.Open "provider=Microsoft.Ace.oledb.12.0;Extended Properties=Excel 12.0;data source=" & ThisWorkbook.FullName
7 Sql = "SELECT * FROM [表一$]" '查找表一的所有数据,*默认指查找所有字段内容
8 Set RS = CONN.Execute(Sql)
9
10 For i = 0 To RS.Fields.Count - 1 '输出字段名,也就是excel列名,索引从0开始,而Excel行列索引号均从1开始计数
11 sht.Cells(1, i + 1).Value = RS.Fields(i).Name
12 Next
13 sht.Cells(2, 1).CopyFromRecordset RS '将查询到的recordset数据集粘贴到表二的A2单元格
14 CONN.Close
15 End Sub

场景二:筛选【表一】中 姓名为‘温宁’的数据到【表二】中

其实,有了sql基础,我们只需要对上面的代码加上Where条件判断子句即可。

代码如下:

 1 Sub myFirstQuery()
2 '将表一的数据查询到后,返回到表二中,包含字段名
3 Dim CONN As Object, sht As Worksheet, RS As Object, i As Integer
4 Set CONN = CreateObject("ADODB.Connection")
5 Set sht = ThisWorkbook.Sheets("表二")
6 CONN.Open "provider=Microsoft.Ace.oledb.12.0;Extended Properties=Excel 12.0;data source=" & ThisWorkbook.FullName
7 Sql = "SELECT * FROM [表一$] WHERE 姓名='温宁'" '查找表一中姓名='温宁'的所有数据
8 Set RS = CONN.Execute(Sql)
9
10 For i = 0 To RS.Fields.Count - 1 '输出字段名,索引从0开始,而Excel行列索引号均从1开始计数
11 sht.Cells(1, i + 1).Value = RS.Fields(i).Name
12 Next
13 sht.Cells(2, 1).CopyFromRecordset RS '将查询到的recordset数据集粘贴到表二的A2单元格
14 CONN.Close
15 End Sub

  通过以上两个场景不难看出,核心的逻辑只需要一句SQL就足以,SQL并不是什么程序员才能掌握的东西,我们完全不用担心无法掌握它。不过我们每次使用前都要提前定义CONNECTION、RECORDSET等对象,包括输出字段名等必要操作。因此,当如果我们的业务足够简单时,使用VBA中的基础功能反而写起来更快,当业务逻辑复杂时,我们才会重点考虑SQL,永远不用为了用SQL而刻意写SQL。用对了地方,SQL就是六脉神剑;用错了地方,就真成了花里胡哨的炫技,Duck不必。

欢迎扫码关注我的公众号 获取更多爬虫、数据分析的知识!



在Excel VBA中写SQL,是一种什么体验的更多相关文章

  1. Excel VBA中写SQL,这些问题的方法你一定要牢记

    小爬之前的文章 [Excel VBA中写SQL,这些问题你一定为此头痛过]中详细讲诉了一些常见的VBA 中使用SQL遇到的问题,这里再补充两个常见的问题场景及对应的解决方案,希望你们看了后能够思路开阔 ...

  2. 在Excel VBA中使用SQL到底优势在哪儿

    小爬在之前的博文中多次提到,可以在VBA中写SQL来操作Excel文件,实现各类数据处理和分析需求.那么,你可能有这样的疑问:Excel原生的VBA,数据透视表,数据分析功能不够吗,为啥一定要用SQL ...

  3. 转 mysql mysql命令行中执行sql的几种方式总结

    https://www.jb51.net/article/96394.htm 1.直接输入sql执行 MySQL> select now(); +---------------------+ | ...

  4. 在mybatis中写sql语句的一些体会

    本文会使用一个案例,就mybatis的一些基础语法进行讲解.案例中使用到的数据库表和对象如下: article表:这个表存放的是文章的基础信息 -- ------------------------- ...

  5. Excel vba中访问ASP.NET MVC项目,记录访问时间,文件名称

    每30秒连接一次服务器,连接成功单元格变绿色,连接失败变红色,状态单元格为17行,2列 1,打开excel文件,进入vba编辑器,新建一个modules模块,在里面先写一个每30秒执行一次ConnSe ...

  6. 关于在Java代码中写Sql语句需要注意的问题

    最近做程序,时不时需要自己去手动将sql语句直接写入到Java代码中,写入sql语句时,需要注意几个小问题. 先看我之前写的几句简单的sql语句,自以为没有问题,但是编译直接报错. String st ...

  7. SSM框架中写sql在xml文件中

    第一种(用Mapper.xml映射文件中定义了操作数据库sql) 注意点: 1.#{}与${} #{}表示一个占位符,使用占位符可以防止sql注入, ${}通过${}可以将parameterType传 ...

  8. SSM框架中写sql在dao文件中以注解的方式

    1以注解方式 //两个参数其中一个是对象需写,对象.属性 @Update("update delivery_address set consignee = #{address.consign ...

  9. 在myeclipse中写sql语句的细节问题

    注意类型,varchar 和int  在java中表示为sql语句中的细微区别!! 下面的REGISEAT_NUM为int 类型       custid为varchar类型 String sql1= ...

随机推荐

  1. JAVAWEB进行PC支付宝支付、查询订单支付状态

    官方文档:https://opendocs.alipay.com/open/270/105899 本地开发环境支付回调调试方法可以参考:https://www.cnblogs.com/pxblog/p ...

  2. 【九度OJ】题目1153:括号匹配问题 解题报告

    [九度OJ]题目1153:括号匹配问题 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1153 题目描述: 在某个字符串(长度不超过1 ...

  3. 【LeetCode】1007. Minimum Domino Rotations For Equal Row 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历一遍 日期 题目地址:https://leetc ...

  4. LeetCode118. Pascal's Triangle 杨辉三角

    题目 给定行数,生成对应的杨辉三角 思考 同一行是对称的,最大的下标为(行数+1)/2;1,1,2,3,6;下标从0开始,则对应分别为0.0.1.1.2.2 对于第偶数行,个数也是偶数,对于奇数行,个 ...

  5. PLSQL到期处理

    一.输入指令"regedit"打开注册表 二.指令输入完毕后,按回车键,会进入这个界面. 三.注册表里按HKEY_CURRENT_USER\Software\Allround Au ...

  6. 第二十四个知识点:描述一个二进制m组的滑动窗口指数算法

    第二十四个知识点:描述一个二进制m组的滑动窗口指数算法 简单回顾一下我们知道的. 大量的密码学算法的大数是基于指数问题的安全性,例如RSA或者DH算法.因此,现代密码学需要大指数模幂算法的有效实现.我 ...

  7. Chapter 4 Effect Modification

    目录 4.1 Definition of effect modification 4.2 Stratification to identify effect modification 4.3 Why ...

  8. EDP转LVDS屏转接线或者转接板方案|CS5211替代PS8625|PS8622|CS5211

    PS8625 (DP至LVDS)是一款DisplayPort到LVDS转换器方案芯片, 可实现双通道DP输入,双链路LVDS输出.同时PS8625是一个显示端口到LVDS转换器设计的PC机,利用GPU ...

  9. 比例阀驱动电路后级PWM滤波尖刺如何消除?PWM通过RC低通滤波器模拟DAC

    双头比例阀驱动电路,采用单片机输出2路PWM,分别驱动功率器件(U100的2和4脚),经过U100的8和10脚输出供电电源的高压PWM波形,这个高压PWM经过R104和R114分别采样后经过电流放大器 ...

  10. pytest 一个测试类怎样使用多种fixture前置方法

    fixture()方法写在哪里? @pytest.fixture(scope="范围")写在conftest文件中,如下图 怎么使用fixture()呢?分为一个类中使用一个前置或 ...