[VBA] 实现SQLserver数据库的增删改查
[VBA] 实现 SQLserver数据库的增删改查
问题背景
用于库存管理的简单Excel系统实现,能够让库管员录入每日出入库信息并进能够按日期查询导出数据,生成简要报表,以及数据修改与删除。非科班且对VB语言和数据库语言未系统学习,有一点C语言与Python基础,有不足之处还请指教。
实现过程
数据库表单设计
出入库的数据是基于已有的Excel文件来设计的,分为出库清单与入库清单两个表,分别记录出库和入库的数据信息。表单字段结构大致如下:
| 入库日期 | 类别 | 规格 | 编码 | 数量 | 单位 | 备注 | 操作人 | PC_INFO | PC_MAC | 操作备注 |
|---|---|---|---|---|---|---|---|---|---|---|
| 出库日期 | 类别 | 规格 | 编码 | 入库日期 | 数量 | 单位 | 备注 | 操作人 | PC_INFO | PC_MAC | 操作备注 |
|---|---|---|---|---|---|---|---|---|---|---|---|
PC_INFO和 PC_MAC字段主要是通过代码获取使用者的电脑信息(MAC地址和电脑名称),操作备注是后续添加的主要用于删除记录,因为删除数据功能风险较高,所以通过在操作备注这里添加一个标志位来表示数据是"被删除"的,然后SQL语句的WHERE子句中多加入一个条件来让这部分“删除数据”不在Excel中相关表单中显示。还有一个表单是库管员姓名和密码,用于登录后进行出入库及数据修改操作,因为这个Excel工作簿中的报表还需发送给别人使用,所以添加此项专供库管员进行相关操作。
VBA 宏编写
前面说到有登录窗口和导出数据与生成报表等功能,所以是需要设计窗体和按钮的。然后再给窗体和按钮添加功能。

因为此篇文章主要是讲对数据库的增删改查实现,窗体代码此处暂不展示,主要逻辑是输入姓名与密码相匹配后点击登录按钮才会出现库管员出入库操作的表单或着相关按钮,如果各位感兴趣如何实现可评论告知,后续会单独写文如何实现窗体设计及其代码功能。
数据库连接
Public conn As ADODB.Connection
Sub ConnDB()
Dim ConnStr As String
Set conn = CreateObject("ADODB.Connection")
conn.CommandTimeout = 15
'定义数据库链接字符串
ConnStr="Provider=sqloledb;Server=yourServer;Database=yourDB;Uid=yourID;Pwd=yourPWd"
conn.CursorLocation = adUseClient
conn.ConnectionString = ConnStr
conn.Open
End Sub
定义全局变量conn是因为在多个模块和表单的代码中需要进行数据库连接来进行操作,ConnStr中的数据库连接属性需自行替换。
查询与增加数据的相关操作
先来看常用的SQL语句无非是 SELECT * FROM yourTable WHERE 入库日期 BETWEEN '2023-11-01' AND '2023-11-30'AND 入库日期 is not null 这类基本的查询语句来导出清单,复杂的汇总和报表实现我选择在SQLserver中创建存储过程再来调用,因为用VBA写长SQL会比较难编辑。
那入库日期需要如何方便别人在Excel中自行输出来查询呢?
这就需要将'2023-11-01'替换为表单对应用于更改日期的单元格,这里有点像动态SQL中一样拼接语句。
例如 : VBA 中这段代码
" strSQL = EXEC yourProcedure '" & Format(ThisWorkbook.Sheets("Sheet1").Cells(2, "I"), "yyyy-mm-dd") & "' " 其实就好比在SQLserver中的 EXEC yourProcedure @qdate (@qdate存储过程youProcedure所需的参数,此处未具体定义) 理解即可
@qdate这个参数就相当于 '" & Format(ThisWorkbook.Sheets("Sheet1").Cells(2, "I"), "yyyy-mm-dd") & "'这部分。
网上看了下 VBA 调用存储过程应该是另一种比较官方的方法,我这里没用,不知道有啥影响,目前是正常运行的。
Set ws = ThisWorkbook.Sheets("入库")
If ws.Cells(Rows.Count, "B").End(xlUp).Row > 2 Then
' 获取数据集
Set rs = CreateObject("ADODB.Recordset")
strSQL = " SELECT * FROM yourTable WHERE 入库日期 is not NULL "
rs.CursorLocation = adUseClient
rs.Open strSQL, conn, adOpenKeyset, adLockOptimistic
For i = 3 To ws.Cells(Rows.Count, "B").End(xlUp).Row
If ((Not IsEmpty(Cells(i, 2)) And Cells(i, 2) <> "") And _
(Not IsEmpty(Cells(i, 3)) And Cells(i, 3) <> "") And _
(Not IsEmpty(Cells(i, 4)) And Cells(i, 4) <> "") And _
(Not IsEmpty(Cells(i, 5)) And Cells(i, 5) <> "")) Then
rs.AddNew
rs("入库日期") = Cells(i, 2)
rs("xxx") = Cells(i, 3)
rs("yyy") = Replace(Cells(i, 4), " ", "")
rs("zzz") = Replace(Cells(i, 5), " ", "")
rs("bn") = Replace(Cells(i, 6), " ", "")
rs("fgg") = Cells(i, 7)
rs("bvs") = Val(Cells(i, 8))
rs("fgghh") = Cells(i, 9)
rs("kjll") = Cells(i, 10)
rs("bz") = Cells(i, 11)
rs("syjg") = Cells(i, 12)
rs("pc_mac") = MacInfo
rs("pc_name") = PCName
rs("操作人") = userName
rs("操作时间") = Now()
rs.Update
End If
Next i
rs.Close
Set rs = Nothing
MsgBox "入库完成!"
Range("a3:k" & Range("b65000").End(xlUp).Row + 1).ClearContents
End If
上面的代码for循环下面添加if条件判断是否是空值和空字符串是因为在Excel中,双击过单元格但是未输入任何内容,其实这个单元格内容就变成空字符串,库管员不小心点击空白单元格也可能会上传一大串空字符串的数据记录进数据库,出现下图这种情况。

数据修改与删除
在我这里的的删除和修改其实变成了一回事,在开头有提到过,直接给出删除的权限有一定风险,所以被要求保留修改的数据记录,这样可以知道删除之前的数据信息。
数据修改的思路是出库和入库的数据记录都有主键ID,将待修改记录的ID输入到修改界面,然后导出对应的数据,直接在单元格中编辑最后点击修改按钮实现数据修改,数据删除是在操作备注这里的下拉选框中选填上“删除数据”。然后数据库中的SQL语句加上where 操作备注 is null的条件来去除“被删除”的数据。
需要修改的数据有出库和入库两个表单,这里就在M1单元格中通过选择数据来源,然后VBA中进行条件判断在进行相关操作。

也就是在删除操作这里出现了上面更新数据一样的问题,那就是双击了操作备注列的单元格未输入任何值后点击修改,就会出现在数据库中的操作备注其实是空字符串,那么上面的where 操作备注 is null就不起作用了
此时我回过头来修改数据的UPDATE语句,使用NULLIF()函数来解决这个问题。
strSQL = " UPDATE TABLE1 SET 操作备注 = NUllIF('" & Cells(i, 14) & "','') WHERE ID = '"& Cells(i, 1) & "' “
数据修改的UPDATE语句如上,更新语句相关字段值特别长就以操作备注来举例了。
记录一下这个不断踩坑的过程。
[VBA] 实现SQLserver数据库的增删改查的更多相关文章
- ThinkPHP实现对数据库的增删改查
好久都没有更新博客了,之前老师布置的任务总算是现在可以说告一段落了,今天趁老师还没提出其他要求来更新一篇博客. 今天我想记录的是我之前做项目,自己所理解的ThinkPHP对数据库的增删改查. 首先要说 ...
- Android学习---数据库的增删改查(sqlite CRUD)
上一篇文章介绍了sqlite数据库的创建,以及数据的访问,本文将主要介绍数据库的增删改查. 下面直接看代码: MyDBHelper.java(创建数据库,添加一列phone) package com. ...
- Android 系统API实现数据库的增删改查和SQLite3工具的使用
在<Android SQL语句实现数据库的增删改查>中介绍了使用sql语句来实现数据库的增删改查操作,本文介绍Android 系统API实现数据库的增删改查和SQLite3工具的使用. 系 ...
- Android SQL语句实现数据库的增删改查
本文介绍android中的数据库的增删改查 复习sql语法: * 增 insert into info (name,phone) values ('wuyudong','111') * 删 delet ...
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- 【转载】通过JDBC对MySQL数据库的增删改查
通过JDBC进行简单的增删改查(以MySQL为例) 目录 前言:什么是JDBC 一.准备工作(一):MySQL安装配置和基础学习 二.准备工作(二):下载数据库对应的jar包并导入 三.JDBC基本操 ...
- 利用API方式进行数据库的增删改查
/* 将数据库的增删改查单独放进一个包 */ package com.itheima28.sqlitedemo.dao; import java.util.ArrayList; import java ...
- MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Asp.net MVC4 使用EF实现数据库的增删改查
EF的使用 步骤: (1)将EF添加到项目:在Model右击添加新建项 找到ADO.NET实体数据模型,接着... (2)实现数据库的增删改查 查询 (因为在Model中已经添加EF实体了 ...
- PHP程序中使用PDO对象实现对数据库的增删改查操作的示例代码
PHP程序中使用PDO对象实现对数据库的增删改查操作(PHP+smarty) dbconn.php <?php //------------------------使用PDO方式连接数据库文件- ...
随机推荐
- GIT提交修改的项目到远程仓库
1.在项目目录下右键选择Git Bash. 2.执行提交命令三部曲 git add . //文件-暂存区,即将所有新增的文件添加到提交索引中,,add后面是"空格 点"就表示当前目 ...
- Vmware中的centos7突然连接不上网络了,网络适配器采用的是NAT模式,解决办法?
进入Windows操作系统,然后右键点击我们的电脑,进入到管理界面 计算机-> 管理->服务和应用程序->服务,找到如下服务进程 VMware DHCP Service, VMwar ...
- C# MySqlHelp类 "DbModel.MySql"数据库操作类
以前做易语言/PHP的. 最近刚入门C#, 就简单的封装了一个类库, 边学边玩才容易学到东西嘛, 比起sqlserver, 我还是觉得mysql更加有亲切感; 于是模仿ThinkPHP编写了一个&qu ...
- 记一次 Redisson 线上问题 → ERR unknown command 'WAIT' 的排查与分析
开心一刻 昨晚和一个朋友聊天 我:处对象吗,咱俩试试? 朋友:我有对象 我:我不信,有对象不公开? 朋友:不好公开,我当的小三 问题背景 程序在生产环境稳定的跑着 直到有一天,公司执行组件漏洞扫描,有 ...
- 问题总结:浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals来判断
浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用equals来判断. 说明:浮点数采用"尾数+阶码"的编码方式,类似于科学计数法的"有效数字+指数& ...
- 5.0 CRC32校验技术概述
CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏.通过运用本校验技术我们可以实现对特定内存区域以及磁 ...
- Building-Mobile-Apps-with-Ionic-2中文翻译工作
最近没啥工作量, 然后学完了这本书, 接着又茫然找不到该干啥, 所以想着何不翻译这个书呢. 这本书首先给我们普及了Ionic 2的基础知识, Ionic 2和Ionic 1有本质上的区别, Ionic ...
- Ds100p -「数据结构百题」21~30
21.P4172 [WC2006]水管局长 SC 省 MY 市有着庞大的地下水管网络,嘟嘟是 MY 市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从 \(x ...
- centos7.9 扩容swap分区
情况说明:在VMware vsphere的虚拟化平台下,为了快速部署虚拟服务器,我们常常使用模板部署虚拟机.但真实业务有时要求的文件系统分区和大小常常与模板不同,这时便需要自定义硬件资源和使用 LVM ...
- 在Go中如何实现并发
Go语言的并发机制是其强大和流行的一个关键特性之一.Go使用协程(goroutines)和通道(channels)来实现并发编程,这使得编写高效且可维护的并发代码变得相对容易.下面是Go的并发机制的详 ...