VBA-自定义面板,使用SQL查询Excel数据

news/2024/7/21 5:04:23 标签: sql, excel, 数据库, vba, 窗体

需求

定制插件,实现用户打开任意一个工作簿,写sql对Excel中的数据进行查询

sql_3">案例sql需求场景:

需求

筛选日期小于’2023-4-24’,按group分区,求和各分组下的销售额,返回结果集新建工作表写入

数据源

现在有两个表,

一个用户的销售金额表,记录用户不同日期的销售金额,其中date字段是日期字段,数据在表格名为“Sheet1”的sheet页里
在这里插入图片描述

一个是用户分组表,表的数据第一个格子不在a1单元格

在这里插入图片描述

SQL语句

select t2.group,sum(t1.销售额) as sales from [Sheet1$] as t1 inner join [分组$c4:d7] as t2 on t1.姓名=t2.姓名 where format(date,'yyyy/m/dd')<'2023/4/24' group by t2.group

如果单元格的格式是日期,在判断时先format格式成字符串传入判断

sql中的数据表表示,如果数据左上角第一个格子是a1单元格,可以直接指定sheet名,比如:[Sheet1$]
如果不是,可以指定具体的数据范围,比如:[分组$c4:d7] 表格名后面跟一个$符号,后面紧跟单元格范围;

VBA代码

vba">Sub sql_query()
' 使用sqlexcel进行查询
Dim con, rs As Object
Dim query_sql, str As String
Dim i, cols As Long

Application.ScreenUpdating = True

' 创建对象
Set con = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")

' 数据连接
con.Open "Provider=Microsoft.ace.Oledb.12.0;" _
    & "Extended Properties=Excel 12.0;" _
    & "Data Source=" & ThisWorkbook.FullName
    
' sql 查询语句,如果单元格是日期,再判断时先format格式成字符串传入判断
query_sql = "select t2.group,sum(t1.销售额) as sales from [Sheet1$] as t1 inner join [分组$c4:d7] as t2 on t1.姓名=t2.姓名 where format(date,'yyyy/m/dd')<'2023/4/24' group by t2.group "
' query_sql = "select 姓名,date,销售额 from [Sheet1$] where format(date,'yyyy/m/dd')<'2023/4/24' "
' 执行sql语句
rs.Open query_sql, con, 1, 1


' 数据写入
Worksheets.Add    ' 新建工作表
With ActiveSheet
    cols = rs.Fields.Count
    For i = 0 To cols - 1
        .Cells(1, i + 1).Value = rs.Fields(i).Name  ' 写入表头
    Next
    .Cells(2, 1).CopyFromRecordset rs    ' 数据写入
End With

rs.Close
con.Close
Set con = Nothing

' 恢复屏幕刷新|工作表自动计算
Application.ScreenUpdating = True

End Sub

返回结果

一共两个组,筛选日期后,组1销售加总40,组2销售加总30
在这里插入图片描述

使用案例代码,只针对当前工作簿生效,如果打开其他工作簿,代码要一行一行重写

下面制作简易插件,先把基本功能搭起来,造个mvp产品

插件制作

1. 新建xlam插件文件

新建工作簿,另存为xlam插件格式的文件,这里命名为UDL.xlam
在这里插入图片描述

2. 编辑xml文件

编辑xml文件,具体请参考EXCEL自定义功能区制作:https://blog.csdn.net/me_to_007/article/details/118260245
如下,新增了功能组"SQL",功能组里边有一个命名为SQL_QUERY的按钮,按钮回调了函数query

<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
<ribbon>
    <tabs>
        <tab id="myTab" label="my tab">
            <group id="group1" label="worksheet">
                <button id="button1" label="show name" size="large" onAction="show_activesheet_name" />
            </group>
            <group id="group2" label="SQL">
                <button id="button2" label="SQL_Query" size="large" onAction="query" />
            </group>
        </tab>
    </tabs>
</ribbon>
</customUI>

定义了回调函数:按钮点击会执行该函数

vba">'Callback for button2 onAction
Sub query(control As IRibbonControl)
End Sub

这样就把功能面板做上去了,设置加载插件后,打开任意一个工作簿,我们可以看到功能该自定义按钮:
在这里插入图片描述

3. 制作窗体,定义窗体控件函数

弹出文本框,让用户输入sql查询,这里制作了一个简易的样例:两个文本标签+一个文本框+3个按钮
<a class=窗体" />

三按钮的default属性都设置为false,不然回车会触发按钮执行;
文本控件的ScrollBars属性设置为2:文本框内容过长,会有垂直滚条可以拉动

定义按钮函数-清空输入sql

vba">Private Sub CommandButton2_Click()
UserForm1.TextBox1.Value = ""     ' 把文本框内容设置为空字符串即可
End Sub

定义按钮函数-生成样例sql

vba">Private Sub CommandButton3_Click()
' 生成一个sql样例,供用户参考
UserForm1.TextBox1.Value = "select t2.group,sum(t1.销售额) as sales from [Sheet1$] as t1 inner join [分组$c4:d7] as t2 on t1.姓名=t2.姓名 where format(date,'yyyy/m/dd')<'2023/4/24' group by t2.group"
End Sub

定义按钮函数-执行sql
用户输入sql后,提交运行,这里我们只需要将上面的案例sql改下就好了,sql串使用用户文本框输入的内容,代码如下:

vba">Private Sub CommandButton1_Click()
' 使用sqlexcel进行查询
Dim con, rs As Object
Dim query_sql, str As String
Dim i, cols As Long

On Error GoTo line1

Application.ScreenUpdating = True   ' 关闭屏幕刷新

' 创建对象
Set con = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")

' 数据连接
con.Open "Provider=Microsoft.ace.Oledb.12.0;" _
    & "Extended Properties=Excel 12.0;" _
    & "Data Source=" & ThisWorkbook.FullName
    
' 传入用户输入的sql
query_sql = UserForm1.TextBox1.Value
rs.Open query_sql, con, 1, 1


' 数据写入
Worksheets.Add    ' 新建工作表
With ActiveSheet
    cols = rs.Fields.Count
    For i = 0 To cols - 1
        .Cells(1, i + 1).Value = rs.Fields(i).Name  ' 写入表头
    Next
    .Cells(2, 1).CopyFromRecordset rs    ' 数据写入
End With

rs.Close
con.Close

Set con = Nothing
Set rs = Nothing



' 恢复屏幕刷新|工作表自动计算
Application.ScreenUpdating = True

MsgBox "query done", vbInformation, "温馨提示"

line1:
If Err <> 0 Then
    UserForm1.TextBox1.Value = Err.Description
    MsgBox "请检查异常", vbQuestion, "Error"
End If

End Sub

4. 编辑回调函数

展示窗体即可,插入模块,在模块里编辑该函数

vba">Sub query(control As IRibbonControl)
UserForm1.Show
UserForm1.TextBox1.MultiLine = True    ' 文本框多行显示
UserForm1.TextBox1.EnterKeyBehavior = False ' 文本框允许回车换行
End Sub

5. 效果展示

点击"SQL_Query"按钮弹出窗体,再点击"生成样例sql"按钮,生成了样例sql
加粗样式
点击"执行sql"按钮,弹出了异常提示,这里我只打开了插件,没找到相关工作簿数据;
在这里插入图片描述

插件下载及加载

下载插件:

微云链接:https://share.weiyun.com/eVg9FeWV 密码:fn8k43

加载插件

打开任意一个工作簿,加载路径如截图:

在加载项里浏览找到插件加载确定即可

在这里插入图片描述


http://www.niftyadmin.cn/n/272011.html

相关文章

【应急响应】挖矿脚本检测指南威胁情报样本定性文件清除入口修复

文章目录 挖矿样本-Win&Linux-危害&定性Linux-Web安全漏洞导致挖矿事件Windows-系统口令爆破导致挖矿事件Linux-个人真实服务器被植入挖矿分析 挖矿样本-Win&Linux-危害&定性 危害&#xff1a;CPU拉满&#xff0c;网络阻塞&#xff0c;服务器卡顿、耗电等 定性…

P4394 [BalticOI 2008]选举 Easy(背包DP+贪心)

P4394 [BalticOI 2008]选举 Easy&#xff08;背包DP&#xff09; 一、问题题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 二、分析1、状态定义2、状态转移3、空间优化 三、代码 一、问题 题目描述 N个政党要组成一个联合内阁&#xff0c;每个党都有自己的席位…

Spring boot结合SkyWalking-Trace工具类实现日志打印请求链路traceid

背景&#xff1a; 随着业务的复杂化、解耦化&#xff0c;运维人员和开发人员需要对请求链路跟踪来快速发现和定位问题&#xff0c;基于应用已经集成了SkyWalking的前提下&#xff0c;如何通过获取SkyWalking生成的统一traceId并加入打印日志中&#xff0c;方便开发人员能够根据…

Python采集二手车数据信息实现数据可视化展示

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 环境使用&#xff1a; Python 3.8 Pycharm 专业版是付费的 <文章下方名片可获取魔法永久用~> 社区版是免费的 模块使用&#xff1a; 第三方模块 需要安装的 requests >>> pip install requests p…

人类 vs AI:玩梗大作战,看看谁是最后的赢家?

能解释人类玩梗的 AI 究竟能多大程度地理解人类的「梗」&#xff1f; 五一假期就在眼前&#xff0c;LigaAI 小编每天都在「调休好烦」和「快放假啦」两种情绪间反复横跳&#xff0c;还会忍不住思考「AI 能不能理解调休和放假的情绪差异&#xff1f;」&#xff08;一些精神世界高…

MetaERP系统主要干什么的,华为自研ERP的路子是否可以效仿?

近日&#xff0c;华为成功研发出自主可控的MetaERP系统&#xff0c;并完成了对旧有ERP系统的替换。该系统采用全栈自主可控技术&#xff0c;基于华为欧拉操作系统、GaussDB等根技术&#xff0c;采用云原生架构、元数据多租架构、实时智能技术等&#xff0c;提高业务效率&#x…

制作自己的镜像并且推送到docker hub上去。

1、在docker hub(Docker)注册账号&#xff1a;比如我的账号是:zhangyi0833 2、在本机上制作自己已经安装了自己想要的工具的镜像&#xff0c;比如我这里安装了cgdb在centos8上面。通过命令制作自己的镜像&#xff1a; docker commit -m"提交的描述信息" -a"镜像…

Linux 下判断一个字符串ip是否合法

文章目录 前言一、inet_pton函数简介二、使用例子三、其他例子3.1 python3.2 c11 前言 要判断一个IP地址是否合法&#xff0c;可以使用C语言标准库中的inet_pton()函数。 inet_pton() 函数是一个标准的C库函数&#xff0c;用于将一个IPv4或IPv6地址的字符串表示转换为网络字节…