简简淡单
粉丝: 36 文章: 3

本文是最近学习vba的笔记,中间借鉴网上其他人帖子,具体有:

https://www.zhihu.com/column/c_1189667517554126848

还有excelHome论坛等

https://www.excelhome.net/


发b站的笔记显示不太好,以下是原笔记,比较美观

https://cooperative-giant-fe0.notion.site/VBA-a94a732ece014a258816b6b636fe06cb


VBE是VBA的编辑窗口

  • 注释 ' 开头 或 REM

  • 运行 F5 / 查看代码步骤 F8/ 运行到某一个代码 ctrl+F8

  • 断点 F9 / 清楚所有断电 ctrl+shift+F9

  • F1帮助窗口

  • 打开编辑器 alt+F11

保存文件格式为xla/xlam

对象

对象就是存在的东西,包括工作薄、工作表、工作表上的单元格区域、图表等

Excel的对象模型

一个文件夹包含多个文件夹,而这个文件夹又可以被其他的文件夹包含,一个工作薄对象包含多个多个工作表对象,一个工作表对象又可以包含多个单元格(或图表,图形等),形成这种对象的排列模式叫做Excel的对象模型(见下图)

对象模型

方法

每一个对象都有方法,方法就是在对象上执行的某个动作

属性和方法的区别

属性表示的是对象某种状态或样子,是静态的,就像是语文里的名词、形容词和副词,而方法则是做某件事的一个动作,就像动词,对象和方法同样用点来分隔

事件

事件就是由用户或者系统触发的,可以在代码中响应的一段代码

▪️ 事件程序只能在工作表的代码窗口编写,不可以在模块窗口中编辑

▪️ 事件程序是自动运行的,不需要刻意去运行

Excel事件

工作薄事件(Workbook)

工作表事件(Worksheet)

常量、变量

常量

用于保存不会发生变化的数据

Const 常量名 As 数据类型 = 常量的值

const srr as singele = 3.14

  • 几个特殊的常数

    由于有好几种不相同的“无效值”常数,VBA语言提供了好几种方法,以检验某个变量是否为empty或null值,或者设置某个变量为empty或null值

    • vbNull

      和VarType函数一起使用,用于确定变量是否包含null。

    • vbNullChar

      赋值或检测null字符,null字符的值为Chr(0),即vbNullChar常数相当于将变量赋值为Chr(0),可用于检测变量,确定它的值是否是一个null字符。

    • vbNullString

      赋值或检测零长(空)字符串。

    • Null关键字

      将null值赋给variant变量后,可以通过调用IsNull函数来检测变量是否是Null值。

    • vbEmpty

      检测某个variant变量是否初始化。

    • Nothing关键字

      只能和对象变量一起使用,以确定变量是否具有有效的对象引用,此外,Nothing关键字还可以用于销毁当前的对象引用。

变量

用于保存在程序运行过程中需要临时保存的值或对象

Dim 变量名 As 数据类型

  • 命名规则:同C语言

    • 第一个字符必须是字母

    • 名字中可以包含字母、数字和下划线

    • 名字中不能包含空格、句号、惊叹号,也不能包含字符@、&、$和#

    • 名字中最多包含255个字符

    模块中输入Option Explicit 强制声明 (写在sub上面,避免误用未定义的变量),VBA在遇到没有声明的变量名称,该语句将导致程序停止

    直接输入“Dim 变量名”此时定义的变量将被指定为Variant类型

作用域的范围包括

第一级:工程(VBAPorject)

第二级:Microsoft Excel 对象,模块,窗体,类模块

第三级:过程

每一级都含有下一级的内容

数据类型

数据类型是变量的特性

在进行运算时也会占用不同大小的内存,所以我们在编写程序时为了提高运行效率,一般都要定义数据的类型


数据类型检查

  • 检查是否为空

    • =""

      可以判别真空,但A1有空格,但结果却为真, = ""无法判断假空

    • Len函数

      可判别真空,无法判断假空

    • IsEmpty函数

      可以判断真假空

    • TypeName函数

      也判断不了是否为假空

  • 检查是否为数字

    • IsNumeric函数

    • TypeName函数

    • Like "#" 判断其是否为一位整数

    • Like "#" 判断其是否包含整数

  • 检查是否为文本

    • IsText函数

    • 判断是否为英文字母 Like "[A-Za-z]"

    • 判断字符长度

    • 判断字符串中是否包含汉字 Like "[一-龥]"

  • 判断结果是否为错误值

    • IsError函数

    • TypeName函数

  • 判断是否为数组

    • IsArray函数

  • 判断是否为日期

    • IsDate函数

数据类型转换

  • 类型转换函数

  • Format函数

    F ormat函数用法等同于工作表中的text函数,可以格式化显示数字或文本

    Format (值,格式(可选参数))

    格式的写法类似设置单元格格式中的自定义类型

数据连接符

  • & 连接变量与字符串,前后有空格

  • <> 不等于

  • not/and/or 优先级从左往右

字符串截取

  • Left,Right,Mid,Len

    Left(字符串,截取长度)  返回从字符串左边算起指定截取长度的字符

    Right(字符串,截取长度) 返回从字符串右边算起指定截取长度的字符

    Mid(字符串,截取起始位置,截取长度)  返回从字符串左边算的截取起始位置起的指定截取长度的字符

    Len(字符串) 返回字符串长度

  • Split

    Split 将字符串按特定的字符分开,返回的是一个一维数组,数组的起始下标为0

    Split(字符串, [需要拆分的分隔符, [返回字符串的数量, [拆分子字符串时的比较类型]]])

  • Join

    Join(数组,连接的字符) 连接字符串

  • Val

    返回字符串内的数字,遇到非数字字符结束运算

    Val(字符串)

    val是函数,value是属性,引用value需要对象

  • &

    连接两个字符串

字符串查找与替换

  • Instr

    instr(字符串,要查找的字符) 在字符串里从前向后查找,从左到右计数,找到之后就停止

    巧用:如果得出的结果大于0,就证明字符存在,可以替代search和Find使用

  • InStrRev

    InStrRev (字符串,要查找的字符) 在字符串里从后向前查找,从左到右计数,找到之后就停止。(查找和计数方向相反)

  • Replace

    Replace(字符串,要查找的字符串,把要查找的替换成某个字符串) 替换字符串的特定字符

  • mid

    mid(字符串,截取的起始位置,截取长度) 从字符串中的某个位置开始截取字符

    如果截取长度和替换的字符串长度不一致,以替换的字符串长度为准。譬如上例,如果改为:

过程

  • 判断语句

    ▪️ IF判断

    If 表达式1 Then

    语句块1

    ElseIF 表达式2 Then

    语句块2

    ...

    Else

    语句n

    End If

    ▪️ Select判断

    Select Case 判断区间()

    Case 表达式1

    语句块1

    Case 表达式2

    语句块2

    Case Else

    语句块n

    End select

  • 循环语句

    ▪️ For-to/each-next

    在一个集合里选择对象去循环

    For 循环变量 初值 to 终值 step 步长

    循环体1

    [exit for]

    循环体2

    Next 循环变量


    For each 变量 in 对象集合

    Next

    ▪️ Do-loop

    Do while

    ...

    Loop 当“条件”成立时,执行“语句体”

    Do Until...Loop 当“条件”不成立,执行循环体

    Do ...Loop While 当条件成立,才返回执行

    Do ...Loop Until 当条件不成立,就返回执行

  • 调用语句

    ▪️ Call 函数

  • 跳转

    ▪️ Goto

    标记:

    语句

    Goto 标记

    ▪️ Gosub...Return

    跳过去,再跳过来

    GoSub 标记

    语句

    return

  • 退出语句

    ▪️ Stop 中断

    ▪️ End 退出所有程序

    ▪️ Exit 退出当前对应的sub,function,for,do

数组

数组是具有相同数据类型并且共享一个名字的一组变量的集合,数组也是变量

直接调用内存运行时间更快

声明

Dim/Public 数组名 (a to b) as 数据类型

数组元素最小值为a,最大值为b,元素个数为(b-a+1),直接输入数字后,元素个数为(b+1)

存在形态

  • 常量数组

    array(array(1,2,3),array("a","b","c"))    ‘在函数使用中

  • 静态数组

    arr(1 to 10 , 1 to 10)                          ’在声明中显示

  • 动态数组

    arr() 不知有多少行多少列                 ’在声明中显示

得知数组后,需要重新声明数组大小 Redim arr(x to y)

写入

  • 常量写入

    常量数组导入,不定义变量类型,直接赋值静态数组,变量就被定义为数组

  • 单元格导入

读取

  • 一维数组

  • 二维数组

数组空间

  • 获得数组大小

    Lbound(数组) 可以获取数组的最小下标(编号)

    Ubound(数组) 可以获取数组的最大上标(编号)

    Ubound(数组,1) 可以获得数组的行方面(第1维)最大上标

    Ubound(数组,2) 可以获得数组的列方向(第2维)的最大上标

  • 动态数组扩充

    如果一个数组无法或不方便计算出总的大小,而在一些特殊情况下又不允许有空位。这时我们就需要用动态的导入方法

    可以声明一个动态大小的数组,而且可以保留原来的数值

    ReDim Preserve arr()

处理

  • 最值

    求最大值:application.Max(数组)

    求最小值:application.Min(数组)

    求第几大值:application.Large(数组, 几)

    求第几小值:application.Small(数组, 几)

  • 求和

    application.Sum (数组)

  • 统计个数

    统计VBA数组的数字个数:application.Count(数组)

    统计VBA数组已填充内容的个数:application.CountA(数组)

  • 数组内查找

    application.Match((lookup_value, lookup_array, [match_type]))

可生成数组的函数

  • Split 函数

    字符串截取 - Split函数

  • Index 函数

    调用该工作表函数可以把二维数组的某一列或某一行截取出来,构成一个新的数组。

    application.Index(二维数组,0,列数))    → 返回二维数组

    application.Index(二维数组,行数,0))    → 返回一维数组

  • Vlookup函数

    查找值

    application.WorksheetFunction.vlookup( lookup_value , table_array , column_index , range_lookup )

    lookup_value:查找的值是什么 table_array:查找的值在哪个表中寻找,对应值需要在第一列 column_index:需要取得的值在第几列,列号 range_lookup: false为精确匹配,true为模糊匹配

  • Sumif函数和Countif函数

    计算合计

字典

介绍

字典(dictionary)是一个储存数据的小仓库,共有两列

第一列叫key , 不允许有重复的元素

第二列是item,每一个key对应一个item,本列允许为重复

注意字典是从0开始排序的。

创建

  • 直接创建法

    Dim d  As Object Set d = CreateObject("scripting.dictionary")

  • 引用法

    工具-引用-浏览-找到scrrun.dll-确定

    Dim d as new dictionary

类模块

设计一个模块,方便调用

相关语句

  • Property Let

    生成对象的可写入属性

    Property Let 属性名称(参数)

    语句

    End Property

  • Property Get()

    生成对象的可读取属性

    Property Get 属性名称(参数)

    语句

    End Property

  • Property Set

    生成子对象

    Property Set 子对象名称(对象)

    语句

    End Property

调用

Dim 变量 As New 类模块名称

类模块事件

调用其他模块事件

Public WithEvents 变量 As 对象


窗口

显示窗体

显示窗体可以调用窗体的Show方法

窗体的显示模式有两种

  • 模式窗体

    窗体显示后将停显示之后的代码直到退出或隐藏此窗体,并且必须退出或隐藏此窗体后,才可以操作非此窗体的其他界面元素,也就是说,当你使用模式窗体显示某窗体的时候,当程序执行完“显示窗体”这条命令后,将暂停执行程序里剩余的语句,真正这个窗体被隐藏或退出。关且当窗体显示出来以后,你不能激活该窗体以外的任何区域

    🔹 模式窗体的显示代码 窗体名称.Show  vbModal 窗体名称.Show 1

  • 无模式窗体

    窗体显示后会继续执行程序里余下的语句,而其他的窗体或界面也可以进行操作

    🔹 无模式窗体的显示代码 窗体名称.Show  vbModeless 窗体名称.Show 0

Shape 对象

该对象代表工作表或图形工作表上的所有图形,它是sheets和chart的子对象(属性)

窗体控件的集合 Controls

投诉或建议
【花师小哲】鉴定网络热门(?)AI(8)——计算机视觉也要终结了?
虽然最近真的很忙,我也在动态提过专栏会暂缓更新。虽然真的最近有些有意思的论文,但现在还是先放一放。不过昨天各路公众号都在发一篇论文,标题一般是取“CV(计算机视觉)终结了”之类的,嗯,我发到朋友圈后有师弟还信了。所以我们还是讲一讲这篇论文到底是在干什么1.大模型与大统一随着现在模型规模的急剧扩大,另一个趋势就是大统一。很多人都在说(包括这篇论文自己也在说)自然语言处理(NLP)已经率先迈向大统一模型了,其实指的就是ChatGPT和GPT-4等模型。不过要说大统一,其实更早就有了,即T5从上面这张图其实可以