当前位置: 首页 > news >正文

深圳专业o2o网站设计公司/职业培训学校

深圳专业o2o网站设计公司,职业培训学校,如何做网站的维护工作,网站开发的经费预算/目录 前言什么是VBA如何使用Excel中的VBA简单基础入门控制台输出信息定义过程(功能)定义变量常用的数据类型Set循环For To 我的需求开发过程效果演示文件情况测试填充源文件测试填充目标文件 全部完整的代码sheet1中的代码,对应A公司工作表Us…

目录

  • 前言
  • 什么是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这样的数据),最好是再做一个控件。

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

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

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

相关文章:

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

目录 前言什么是VBA如何使用Excel中的VBA简单基础入门控制台输出信息定义过程(功能)定义变量常用的数据类型Set循环For To 我的需求开发过程效果演示文件情况测试填充源文件测试填充目标文件 全部完整的代码sheet1中的代码,对应A公司工作表Us…...

算法记录——链表

2.链表 2.1判断是否是回文链表 1.方法一:利用栈反转链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode…...

EasyExcel实现百万数据批量导出

当数据量比较大时,例如数据量达到百万级,传统的一次读取到内存中在写入excel文件的方法便不再适用了,可能会导致内存溢出;而且一次性将数据写入一张sheet工作表也不太好。 但我们可以选择数据分片的方式批量写入多个工作表。 测试…...

兆易GD32E508的SHRTIM配置 主从定时器 产生2对相位可调互补PWM 带死区

如有技术问题及技术需求请加作者微信! GD32E5系列MCU是基于Arm Cortex-M33处理器的32位通用微控制器。Cortex-M33处理器基于Armv8架构,处理器主频最高可达180MHz,支持强大的可扩展指令集,包括通用数据处理I/O控制任务、增强的数据处理位域操作、DSP和浮点运算器(FPU)。 GD…...

数据归组工具

利用C#将数据 [ {"name":"A","fzh":1}, {"name":"A","fzh":2}, {"name":"A","fzh":3}, {"name":"B","fzh":4}, {"name":"B",&…...

JavaScript 中的闭包的形成及使用场景

JavaScript 中的闭包 闭包(Closure) 是 JavaScript 中一个非常重要且独特的概念,它指的是 函数能够记住并访问其词法作用域内的变量,即使这个函数在其词法作用域之外执行。 通俗地说,闭包是 一个函数可以“记住”它在…...

后端返回内容有换行标识,前端如何识别换行

<br/>的话 用 v-html \n 可以用css样式 white-space: pre-wrap 后端返回结果 前端...

服务器被挂马,导致网站首页被更改怎么解决

当服务器被挂马并导致网站首页被篡改时&#xff0c;说明服务器或网站的安全性遭到破坏。为了修复并防止未来的攻击&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 立即下线网站 目的&#xff1a;防止恶意软件进一步传播&#xff0c;保护用户数据和防止攻击者继续对网…...

Android 利用OSMdroid开发GIS

1、地址 Github地址&#xff1a;https://gitee.com/mirrors/osmdroid Git地址&#xff1a; GitCode - 全球开发者的开源社区,开源代码托管平台 Git下载包地址&#xff1a;Releases osmdroid/osmdroid GitHub 新建项目 osmdroid在线&#xff1a; &#xff08;1&#xff09…...

一文上手skywalking【上】

一、skywalking预览 1.1 skywalking 概述 ​ Apache SkyWalking, 适用于分布式系统的应用程序性能监控工具&#xff0c;专为微服务、云原生和基于容器的 &#xff08;Kubernetes&#xff09; 架构而设计。官方地址: https://skywalking.apache.org/ 适用于分布式系统的应用程…...

【JavaScript】JQuery基础知识及应用

一、JQuery的导入方法 https://editor.csdn.net/md/?articleId132214798 二、JQuery介绍 JQuery(JQ)&#xff1a;JS的一个类库&#xff08;方法库&#xff1a;包含了大量的、有助于项目开发的属性和方法&#xff09; 第一代版本1.xx.xx: 1.11.3 兼容所有浏览器的&#xff0…...

初始爬虫9

1.元素定位后的操作 “find_element“仅仅能够获取元素&#xff0c;不能够直接获取其中的数据&#xff0c;如果需要获取数据需要使用以下方法”。下面列出了两个方法&#xff1a; 获取文本 element.text 通过定位获取的标签对象的 text 属性&#xff0c;获取文本内容 获取属性…...

从细胞到临床:表观组学分析技术在精准医疗中的角色

中国科学院等科研院所的顶尖人才发起&#xff0c;专注于多组学、互作组、生物医学等领域的研究与服务。在Nature等国际知名期刊发表多篇论文&#xff0c;提供实验整体打包、免费SCI论文润色等四大优势服务。在表观组学分析技术方面&#xff0c;提供DAP-seq、ATAC-seq、H3K4me3 …...

带你0到1之QT编程:二十、QT与MySQL喜结连理,构建数据库应用开发

此为QT编程的第二十谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …...

梯度下降法及其性能评估

梯度下降法 梯度下降法是一种一阶迭代优化算法&#xff0c;用于寻找函数的局部最小值。在机器学习中&#xff0c;它通常用来最小化损失函数&#xff08;也称为成本函数或误差函数&#xff09;&#xff0c;以提高模型对数据的拟合程度。梯度下降法的基本思想是沿着目标函数当前…...

906. 超级回文数

1. 题目 906. 超级回文数 2. 解题思路 题目意思很简单&#xff0c;在给定范围中找到所有满足&#xff0c;它本身是回文&#xff0c;且它的平方也是回文的数字个数。 这题需要注意题目给定的范围&#xff0c;后面很有用&#xff1a; 因为回文范围是有限的&#xff0c;那么我…...

代码随想录算法训练营||二叉树

前/中/后序遍历 递归方式 参考文章 题目 思路&#xff1a;其实递归方式的前中后序遍历的方式都差不多&#xff0c;区别是在父节点的遍历时间。 前序代码 class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> result new…...

线上报名小程序怎么做

在这个数字化、智能化的时代&#xff0c;信息技术的发展正以前所未有的速度改变着我们的生活。无论是学习、工作还是娱乐&#xff0c;互联网都成为了我们不可或缺的一部分。而在线上报名这一领域&#xff0c;小程序的出现更是为广大用户带来了前所未有的便捷与高效。今天&#…...

【测试岗】手撕代码 - 零钱兑换

322. 零钱兑换 题目描述 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种…...

菱形继承的类对父类的初始化、组合、多态、多态的原理等的介绍

文章目录 前言一、菱形继承的类对父类的初始化二、组合三、 多态1. 构成多态2. 虚函数3. 虚函数的重写4. 虚函数重写的两个例外1. 协变2. 析构函数的重写 5. C11 final 和 override1. final2. override 6. 设计不想被继承的类7. 重载、覆盖&#xff08;重写&#xff09;、 隐藏…...

React Native 在 build 的时候如果出现 `babel.config.js` 配置文件的错误

React Native 在 build 的时候如果出现以下错误, 就是 babel.config.js 配置文件的错误. Showing Recent Issues node:internal/process/promises:289triggerUncaughtException(err, true /* fromPromise */);^Error: .plugins[0][1] must be an object, false, or undefineda…...

【Linux】包管理器、vim详解及简单配置

&#x1f680;个人主页&#xff1a;小羊 &#x1f680;所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 前言一、包管理器1.1 apt1.2 yum 二、Linux编辑器——vim2.1 vim的三种模式2.2 vim普通模式常用命令2.2.1 移动…...

AVL树实现

1.AVL的概念 1.AVL树属于二叉搜索树的一种&#xff0c;但它不同与普通的二叉搜索树还具有以下的性质&#xff1a; 每一个根的左右子树的高度差的绝对值不超过1。AVL树是通过高度差去控制平衡的&#xff0c;所以又称作为平衡二叉搜索树。 2.AVL树实现我们引入了一个平衡因子的概…...

初始MYSQL数据库(6)—— 事务

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; MYSQL 目录 事务的概念 事务的ACID特性 使用事务 查看支持事务的存储引擎 事务的语法 保存点 自动/手动提交事务 事务的隔离性和…...

0基础学习PyTorch——GPU上训练和推理

大纲 创建设备训练推理总结 在《Windows Subsystem for Linux——支持cuda能力》一文中&#xff0c;我们让开发环境支持cuda能力。现在我们要基于《0基础学习PyTorch——时尚分类&#xff08;Fashion MNIST&#xff09;训练和推理》&#xff0c;将代码修改成支持cuda的训练和推…...

这款免费工具让你的电脑焕然一新,专业人士都在用

HiBit Uninstaller 采用单一可执行文件的形式,无需复杂的安装过程,用户可以即刻开始使用。这种便捷性使其成为临时使用或紧急情况下的理想选择。尽管体积小巧,但其功能却异常强大,几乎不会对系统性能造成任何负面影响。 这款工具的一大亮点是其多样化的功能。它不仅能够常规卸…...

Java高级Day52-BasicDAO

138.BasicDao 基本说明&#xff1a; DAO&#xff1a;data access object 数据访问对象 这样的通用类&#xff0c;称为 BasicDao&#xff0c;是专门和数据库交互的&#xff0c;即完成对数据库(表)的crud操作 在BasicDao 基础上&#xff0c;实现一张表对应一个Dao&#xff0c;…...

【OceanBase 诊断调优】—— SQL 诊断宝典

视频 OceanBase 数据库 SQL 诊断和优化&#xff1a;https://www.oceanbase.com/video/5900015OB Cloud 云数据库 SQL 诊断与调优的应用实践&#xff1a;https://www.oceanbase.com/video/9000971SQL 优化&#xff1a;https://www.oceanbase.com/video/9000889阅读和管理SQL执行…...

微服务Redis解析部署使用全流程

目录 1、什么是Redis 2、Redis的作用 3、Redis常用的五种基本类型&#xff08;重要知识点&#xff09; 4、安装redis 4.1、查询镜像文件【省略】 4.2、拉取镜像文件 4.3、启动redis并设置密码 4.3.1、修改redis密码【可以不修改】 4.3.2、删除密码【坚决不推荐】 5、S…...

C++之STL—常用排序算法

sort (iterator beg, iterator end, _Pred) // 按值查找元素&#xff0c;找到返回指定位置迭代器&#xff0c;找不到返回结束迭代器位置 // beg 开始迭代器 // end 结束迭代器 // _Pred 谓词 random_shuffle(iterator beg, iterator end); // 指定范围内的元素随机调…...