【2.使用VBA自动填充Excel工作表】

目录

  • 前言
  • 什么是VBA
  • 如何使用Excel中的VBA
  • 简单基础入门
    • 控制台输出信息
    • 定义过程(功能)
    • 定义变量
    • 常用的数据类型
    • Set
    • 循环
      • For To
  • 我的需求
  • 开发过程
    • 效果演示
    • 文件情况
      • 测试填充源文件
      • 测试填充目标文件
    • 全部完整的代码
      • sheet1中的代码,对应A公司工作表
      • UserForm1的代码
  • 待续
    • 基础逻辑完善
      • 获取行号
      • 遍历日期算法逻辑
      • 提升对单元格等对象的操作知识
    • 功能升级

前言

上一篇文章我使用了Excel中的Index和Match函数实现可以根据之前打过的数据去自动填充内容。在对账的时候可以帮助我们节省很多时间。但是,这样不够直接、更不够快
做过对账单和送货单的人都知道,送货单在出货的时候要打,可能一天一个公司打个一两次。要是我在打送货单的时候,对账单也能自动根据送货单的内容自动填充就好啦

如此细致的功能,我目前只想到了使用Python和VBA。

如果要实现日常的使用,VBA应该就够用了。

什么是VBA

VBA是Visual Basic for Applications的缩写,它是一种事件驱动的编程语言,由微软公司开发。VBA主要用于Microsoft Office套件中的应用程序,如Excel、Word、Access、PowerPoint等,允许用户通过编写宏和自定义函数来自动化任务和扩展应用程序的功能

VBA基于Visual Basic编程语言,它提供了一套丰富的编程工具和对象模型,使得开发者可以创建复杂的自动化脚本和自定义用户界面。使用VBA,用户可以:

自动化重复性任务:通过编写宏来减少手动操作,提高工作效率。
数据处理和分析:在Excel中进行复杂的数据操作和分析。
用户界面定制:在Word或Excel中创建自定义的对话框和表单
与其他应用程序交互:通过VBA编写的代码可以与其他应用程序或数据库进行交互

发明背景

VBA的发明时间可以追溯到1994年左右,当时随着Office 95的发布,VBA作为其宏语言的一部分被引入。它与传统的宏语言不同,提供了面向对象的程序设计方法,并拥有相当完整的程序设计语言。VBA易于学习掌握,可以使用宏记录器记录用户的各种操作并将其转换为VBA程序代码,从而实现工作自动化

VBA与Visual Basic(VB)具有相似的语言结构,从语言结构上讲,VBA是VB的一个子集,它们的语法结构是一样的。VB是一种独立的开发工具,而VBA则必须依附于Office应用程序。VBA专门用于Office的各应用程序中,如Word、Excel、Access等,它与主应用程序之间的通信变得简单而高效。

VBA的编程能力介于低级语言和高级语言之间,它继承了Visual Basic的部分特性和语法,因此具有更强的编程能力和灵活性。然而,VBA的运行速度相对较慢,因为它是通过解释执行而非编译执行的。此外,VBA主要用于Office软件的宏编程和自动化处理,对于其他领域的开发可能不太适用。

如何使用Excel中的VBA

参考链接小步教程
首先,要想使用VBA,需要新建启用宏的工作簿文件后缀名是xlsm
然后再文件-选项中-自定义功能区 选中开发工具

在这里插入图片描述

简单基础入门

控制台输出信息

使用

Debug.Print ""

以及立即窗口(控制台)

定义过程(功能)

Sub 函数名End Sub

定义变量

Dim 变量名 As 数据类型
Dim a As String

常用的数据类型

  • Workbook 工作簿 表示整个Excel文件,包括所有的工作表
  • Worksheet 工作表 表示单个工作表
  • String 字符串
  • Long 存储大整数,比如行号 (-2,147,483,648 到 2,147,483,647)

Set

给自己定义的变量指向一个对象

' 设置源工作表Set wsSource = ThisWorkbook.Sheets(sourceSheetName)' 打开目标工作簿Set wbTarget = Workbooks.Open("C:\Users\Administrator\Desktop\nosee\EXCEL\测试填充目标文件.xlsm")

循环

VBA循环结构包括四类结构:For To、For Each、While、Do While。

For To

在这里插入图片描述
在这里插入图片描述
退出当前循环

在这里插入图片描述
退出整个循环
在这里插入图片描述

我的需求

要有图形化界面

  • 可以自己选择需要对账的工作表和送货表
  • 自己可以选择要对账的日期和范围 (可能要用到正则表达式)
  • 使用用户界面交互 选择送货单的位置和工作表 对账单的位置和表

开发过程

效果演示

视频如下:

文件情况

测试填充源文件

(这是代码里的名称,在实际工作中就对应送货单)
在这里插入图片描述

如上图,比较值得注意的点是:

  • 序号那种字段名称居然占了两行,这就导致有效数据是日期行加3,不知道做这个送货单的人怎么想的🙄,当时没注意看坑死我了。
  • 还有就是第九行的内容看起来横跨了很多单元格,但是其实只是在A列而已,只是没有展开
  • 还有一个细节就是,对比一下可以看出,在DATE 2024/8/31的下面三行就是有用的数据,而且有用的数据那一行的C、D列都有数据,这些都是我后面用来判断数据有效性的依据

测试填充目标文件

(这个也是代码里的名称,实际中对应的是对账单)
在这里插入图片描述
这个没什么好说的,以后希望也能把日期附在内容前以方便分开

全部完整的代码

sheet1中的代码,对应A公司工作表

    '全局变量 用来接收文件信息Public targetSheetName As StringPublic sourceSheetName As StringPublic targetFilePath As StringPublic dateToCheck As StringSub UserForm_Initialize()UserForm1.Show '打开用户界面
End SubSub CopyDataBasedOnDate() '定义函数  用户界面Dim wsSource As Worksheet '定义变量 Worksheet 是Excel中工作表的对象类型,表示单个工作表。源工作簿不用设置Dim wbTarget As Workbook  'Workbook 是Excel中工作簿的对象类型,表示整个Excel文件,包括所有的工作表。Dim lastRow As LongDim targetRowA As LongDim targetRowC As LongDim targetRow As Long 'Long 是VBA中的一种数据类型,用于存储较大的整数(-2,147,483,648 到 2,147,483,647)' 设置源工作表Set wsSource = ThisWorkbook.Sheets(sourceSheetName)' 打开目标工作簿Set wbTarget = Workbooks.Open(targetFilePath)' 找到目标工作表Dim wssTarget As Worksheet' ############设置异常?On Error Resume Next '这行代码是一个错误处理语句,它告诉VBA在遇到错误时不要显示错误消息,而是继续执行下一行代码。这是错误处理的开始。Set wssTarget = wbTarget.Sheets(targetSheetName) '通过 wsTarget 工作簿对象来访问名为 targetSheetName 的工作表,If wssTarget Is Nothing Then ' Nothing 表示一个变量没有引用任何对象。MsgBox "目标工作表不存在"Exit Sub  '这行代码会立即退出当前正在执行的子程序(Sub)。如果没有找到工作表,程序将不会继续执行后面的代码。End IfOn Error GoTo 0 '这行代码用于关闭之前启用的错误处理。在遇到错误时停止执行并显示错误消息。这行代码通常放在错误处理代码的最后,以确保错误处理的范围仅限于特定的代码块。' ############获取源工作表的最后一行  这里可能要调lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).RowtargetRowA = wssTarget.Cells(wssTarget.Rows.Count, "A").End(xlUp).RowtargetRowC = wssTarget.Cells(wssTarget.Rows.Count, "C").End(xlUp).RowtargetRow = Application.Max(targetRowA, targetRowC) + 2    '因为最后一行也是两行合并' ##############遍历源工作表中的所有行  应该要换个判断条件或者方式 根据日期,直到下一个日期Dim i As LongFor i = 1 To lastRow '遍历循环If wsSource.Cells(i, "A").Value = dateToCheck Then '如果第i行是要对账的日期For j = i + 3 To lastRow '日期内循环If j - i > 13 Then '3是必要的内容 因为有客套话 假如内容十行的话 就够了'最好的办法还是判断日期内循环有没有到下一个日期 到了就直接跳 结束了i = j - 1Exit ForEnd IfIf wsSource.Cells(j, "A").Value = dateToCheck Then '如果已经碰到下一个日期 比如同一天的 还有可能不是同一天的i = j - 1 '节省遍历循环的时间 跳出循环Exit ForEnd IfIf Not IsEmpty(wsSource.Cells(j, "C").Value) And Not IsEmpty(wsSource.Cells(j, "D").Value) Then'如果没有到下一个日期并且数据有效  c列d列不都为空就可以了wsSource.Rows(j).Copy Destination:=wssTarget.Rows(targetRow) 'targetRow = targetRow + 1End IfNext jEnd IfNext i' ############保存并关闭目标工作簿wbTarget.Save
'    wbTarget.CloseMsgBox "数据复制完成"
End Sub

UserForm1的代码

Sub dateToCheckCommandButton_Click()Sheet1.dateToCheck = dateToCheckTextBox.Text
End SubSub sourceSheetNameCommandButton_Click()Sheet1.sourceSheetName = sourceSheetNameTextBox.Text ' 把文本框的内容赋值给源工作表名字变量
End Sub
Sub targetFilePathCommandButton_Click()Sheet1.targetFilePath = targetFilePathTextBox.Text
End SubSub targetSheetNameCommandButton_Click()Sheet1.targetSheetName = targetSheetNameTextBox.Text ' 把文本框的内容赋值给目标工作表名字变量
End SubSub CommitCommandButton_Click()Sheet1.CopyDataBasedOnDate '调用复制程序
End Sub

待续

基础逻辑完善

获取行号

获取源文件行号是从下往上找获取A、C两个必定会有内容的列的单元格不为空的逻辑,但是别人的工作表不一定是这样的

  • 现在使用的是cell和max函数
lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
targetRowA = wssTarget.Cells(wssTarget.Rows.Count, "A").End(xlUp).Row
targetRowC = wssTarget.Cells(wssTarget.Rows.Count, "C").End(xlUp).Row
targetRow = Application.Max(targetRowA, targetRowC) + 2    '因为最后一行也是两行合并

搜了一下还可以用下面这些方法,日后试试

  • 使用UsedRange属性:
    UsedRange属性可以返回工作表中使用过的范围,然后可以通过这个范围来找到最后一行。
Dim lastRow As Long
lastRow = ThisWorkbook.Worksheets("Sheet1").UsedRange.Rows.Count
  • 使用SpecialCells方法:
    这个方法可以用来找到最后一行,特别是当表格中有空行时。
Dim lastRow As Long
On Error Resume Next ' 如果没有找到单元格,避免错误
lastRow = ThisWorkbook.Worksheets("Sheet1").Cells.SpecialCells(xlCellTypeLastCell).Row
On Error GoTo 0 ' 重新启用错误报告

遍历日期算法逻辑

For i = 1 To lastRow '遍历循环If wsSource.Cells(i, "A").Value = dateToCheck Then '如果第i行是要对账的日期For j = i + 3 To lastRow '日期内循环If j - i > 13 Then '3是必要的内容 因为有客套话 假如内容十行的话 就够了'最好的办法还是判断日期内循环有没有到下一个日期 到了就直接跳 结束了i = j - 1Exit ForEnd IfIf wsSource.Cells(j, "A").Value = dateToCheck Then '如果已经碰到下一个日期 比如同一天的 还有可能不是同一天的i = j - 1 '节省遍历循环的时间 跳出循环Exit ForEnd IfIf Not IsEmpty(wsSource.Cells(j, "C").Value) And Not IsEmpty(wsSource.Cells(j, "D").Value) Then'如果没有到下一个日期并且数据有效  c列d列不都为空就可以了wsSource.Rows(j).Copy Destination:=wssTarget.Rows(targetRow) 'targetRow = targetRow + 1End IfNext jEnd IfNext i

我在源文件遍历日期的方法是从第一行查找到最后一行,如果遇到匹配的字符串,就再内嵌一个循环,因为一个日期内有很多数据需要一行行地复制过去,还要判断数据的有效性

这里解释一下
For j = i +3是因为序号那一行是两行合并,所以有效数据是日期+3行 ,j-i>13是因为一般来说一次送货不会超过十种货,也就是对应十行数据了

提升对单元格等对象的操作知识

可以看出我对对单元格本身不了解 内置函数和属性不熟 所以判断数据有效性的条件很抽象

功能升级

  • 目前可以实现在页面不关闭的情况下一次插入一天的对账信息,但是这样也不够快,要是能一次插入一个时间范围内的对账信息就好了,估计要新增很多判断逻辑,以及对字符串的一些操作处理(因为有时候你的源工作表不一定就是2024/8/31这样的数据),最好是再做一个控件。

  • 输入文件路径有点麻烦,尝试改进成浏览文件的方式选中。

  • 未来要加入判断插入的数据是否是已有数据的逻辑才行,否则会重复插入 而且最好能提示用户“重复插入了”

  • 从送货单复制的数据到对账单并不是会完美一一对应,因为对账单和送货单所需要的信息不一定是一一对应的,可能会多或者少或者顺序不对,还有一些比较奇葩的是粘贴的目标列合并了,所以要怎么匹配列去进行粘贴 是一个问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简易CPU设计入门:取指令(一),端口列表与变量声明

取指令这一块呢,个人觉得,不太好讲。但是呢,不好讲,我也得讲啊。那就尽量地讲吧。如果讲得不好的话,那么,欢迎大家提出好的意见,帮助我改进讲课的质量。 首先呢,还是请大家去下载本…

ip 地址查看cmd命令

ip 地址查看cmd命令 在不同的操作系统中,查看IP地址的命令可能会有所不同。以下是一些常见操作系统中查看IP地址的命令: Windows: 打开命令提示符(CMD),然后输入 ipconfig 命令。 Linux/Unix: 打开终端&#xff0…

【ARM 嵌入式 编译系列 2.8 -- GCC 编译优化参数 位置无关码】

请阅读【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 文章目录 ARM GCC 位置无关码-fpic 编译选项无位置相关码(PIC)为什么使用 PIC?代码示例编译为目标文件链接为共享库使用共享库ARM 汇编中位置无关码编译为目标文件链接为共享库使用共享库详细解释ARM GCC 位置无关码 …

【AI大模型-文心-思维树解读-仓颉精通之路-4】

提问:对于每个解决方案,加深思考过程。生成潜在场景、实施策略、任何必要的资源、如何克服障碍与风险以及意外结果和意外结果的处理 回答:如下 版本:文心大模型3.5 解决方案一:系统化自学方案 潜在场景: …

【专题】2024年中国白酒行业数字化转型研究报告合集PDF分享(附原数据表)

原文链接:https://tecdat.cn/?p37755 消费人群趋于年轻化,消费需求迈向健康化,消费场景与渠道走向多元化,这些因素共同驱动企业凭借数据能力来适应市场的变化。从消费市场来看,消费群体、需求、场景及渠道皆展现出与…

Android中的Activity生命周期和启动流程及优化策略

目录 第一章 Activity生命周期概述 1.1 生命周期概念及状态 1.1.1 生命周期概念 1.1.2 状态转换 1.2 生命周期回调方法 1.2.1 关键回调方法 1.2.2 回调方法的作用 1.3 生命周期管理策略 1.3.1 合理管理资源 1.3.2 优化加载过程 第二章 Activity启动流程详解 2.1 Ac…

GIS中的投影坐标系

投影说明 GIS操作过程中,不可避免的涉及到处理数据的问题 而数据中有一个极为重要的东西就是其空间参考(见下图) 地理坐标系与投影坐标系 这里给出一些重要概念的简单定义 地理坐标:就是用经纬度表示地面点位的球面坐标。 地理…

Java项目实战II基于Java+Spring Boot+MySQL的新闻稿件管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 前在信息爆…

飞腾CPU运行RTEMS6.0

1. 介绍 RTEMS (Real-Time Executive for Multiprocessor Systems) 是一个开源实时操作系统,可以用于太空飞行、医疗、网络和各类嵌入式设备。本项目发布了 Phytium 系列 CPU 的 RTEMS内核/RTEMS-LibBSD 源码使用工具,参考例程以及配置构建工具。 飞腾R…

在 NodeJs 里面如何获取 APK 的名称和 icon

最近想用 electron 写一个 adb 的可视化客户端,在展示安装的应用时遇到了如何获取 APK 的名称和 icon 的问题。下面就是一些解决问题的思路。 前提:在这里默认大家已经下载好 apk, 下面 localApkPath 就是你下载好的 apk 的路径。 小提示,示…

js采用覆盖键、覆盖鼠标滑动事件实现禁止网页通过 ctrl + +/- 和 ctrl + 滚轮 对页面进行缩放

一、兼容电脑端的禁止通过 ctrl /- 和 ctrl 滚轮 对页面进行缩放 const keyCodeMap {// 91: true, // command61: true,107: true, // 数字键盘 109: true, // 数字键盘 -173: true, // 火狐 - 号187: true, // 189: true, // -};二、覆盖ctrl||command ‘’/‘-’ // 覆…

基于Springboot+Vue的视频点播系统设计与实现登录 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统中…

Html CSS 布局,位置处理 居中 对齐

Html CSS 布局&#xff0c;位置处理 1、居中布局 1、div 让内部div居中对齐 html <div class"container"><div class"item">I am centered!</div> </div>style .container {border: 2px solid rgb(75, 70, 74);border-radius:…

基于Spring Boot的校园管理系统

目录 前言 功能设计 系统实现 获取源码 博主主页&#xff1a;百成Java 往期系列&#xff1a;Spring Boot、SSM、JavaWeb、python、小程序 前言 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自…

GPT与大模型行业落地实践探索

简介 本课程探讨GPT和大模型技术在行业中的实际应用和发展。课程将涵盖GPT的基础知识、原理、及其在行业中的应用案例&#xff0c;如财报分析和客服机器人。重点在于结合实际案例中的使用效果&#xff0c;讲解如何利用GPT的API开发企业级应用以及利用更高级的功能构造AI Agent。…

iOS 提取图片的主题色,并支持灵活提取

遇到一个需求&#xff0c;要提取图片中的色调&#xff0c;但还有一点特殊的需求&#xff0c;就是不是提取颜色最多的色调&#xff0c;也不是平均的色调&#xff0c;是图片中偏暗的色调 这就需要我们动态的调整我们提取的算法&#xff0c; 下面就看代码 dispatch_async(dispatch…

Prompt技巧总结和示例分享

"Prompt"&#xff08;提示&#xff09;在人工智能中通常指的是输入给模型的文本&#xff0c;用于引导模型生成预期的输出。在使用人工智能助手时&#xff0c;有效的提示技巧可以帮助你获得更准确和有用的回答。 以下是一些单轮对话提示时的技巧&#xff1a; 明确具体…

C++ 机器人相关面试点

C 机器人相关面试点 多功能聊天乐园 1. 功能实现&#xff1a; 用户管理&#xff1a;实现了用户注册与登录、头像上传与下载功能&#xff0c;用户密码通过OpenSSL加密&#xff0c;用户数据存储在MySQL数据库中&#xff0c;并通过XML文件进行本地持久化配置。 音乐播放与下载&a…

中国移动手撕代码 - 二叉搜索树删除节点

题目描述 已知二叉搜索树,数据不重复,提供 root 和 value, 遍历查找二叉树节点相等的值并删除,删除后剩余节点任然是二叉搜索树 Java 代码 class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int val)

react-native-Windows配置

一&#xff1a;官网&#xff1a; React Native for Windows macOS Build native Windows & macOS apps with Javascript and React 二&#xff1a;安装依赖 需要以管理员身份运行powershell,然后粘贴下面代码&#xff0c;注意&#xff1a;要安装淘宝镜像&#xff0c;要…