instr函数达到in效果_ExcelVBA_实例讲解_005 浅谈函数与过程

小伙伴反馈的问题

1、前面文章代码里出现的Debug.Print X,干嘛用的?

Debug.Print语句主要是用来调试的、功能是在立即窗口里打印出内容X,按下组合键【Ctrl+G】,显示【立即窗口】,运行包含Debug.Print的程序,就可以看到效果了。在文章里主要就是为了演示代码运行效果而已。

ba24121bb6bf006c285ed2ac5ba80032.png

2、分享的内容有些深奥

        经营这个订阅号的初心就是想分享一些实用的代码,给稍微懂点VBA的小伙伴,稍作修改就可以满足自己的使用需求。分享任务基本已经结束。

        接下来,分享自己学习VBA学习心得,希望帮助部分小伙伴初窥VBA门径。只看其中一篇,或许真的有点云里雾里,我唯一能做的就是尽量把我的心得写得通俗一些。感谢小伙伴的支持和建议。

3、一开始写VBA代码无从下手

        万事开头难。个人觉得初学应该把录制宏功能和F1键用好。录制一些简单的操作,然后查看代码,看看代码如何实现你的操作的,多改、多试、多问。

        遇到不懂的内置对象、属性、方法,只需要把鼠标放在你不懂的地方,按下F1键,就可以查看相应在线帮助了。

    Application属性的实例

紧接上一篇,我们来尝试在实例中体会Application属性的使用。

如:以批量删除包含“Sheet”字符的工作表为例,体会开、关警告的使用

思路

    1、在程序运行之初,关闭警告,可以避免删除过程中出现的警告弹窗

edf9e12f152952f5136263036766ff57.png

   2、在程序运行结束前,恢复警告,可以避免错过其他警告

实现代码

Sub DeleteSheets()    '声明一个工作表类型的变量——作为临时存放的容器    Dim sht As Worksheet                            '关闭警告,包括删除工作表的警告    Application.DisplayAlerts = False        '循环当前工作簿的全部工作表    For Each sht In ThisWorkbook.Worksheets            '使用Instr(源文本,查找文本)函数,判断查找文本是否包含在源文本中        '比如 sht.Name为"Sheet1",那么InStr("Sheet1", "Sheet")会得到1        '就是Sheet 在Sheet1出现的首个字符的位置1        ' 源文本      S h e e t 1        ' 查文本      S h e e t        ' 字符位置    1 2 3 4 5 6        '因此使用语句Instr(源文本,查找文本)>0作为判断查找字符是否存在的一个常用方法        'InStr应该就是In-String的缩写,判断查找字符string是否包含在In源字符string里面        If InStr(sht.Name, "Sheet") > 0 Then                   '删除工作表           sht.Delete                   End If            Next sht '下一个工作表        '恢复警告,恢复的不止是删除工作表的警告,切记恢复    Application.DisplayAlerts = True        '释放变量——把工具放回货架,工作台清空    Set sht = Nothing    End Sub

图解Instr函数

8ea3690ac07ac2b48ee87bee620920c1.png

实际上,Instr()函数的功能比本篇所提及的更丰富。

啥是函数

        有关函数,这里举个简单的例子:比如有一个函数,名称叫做“厨房烹饪”,鱼的品种有很多(石斑、桂花、生鱼),烹饪的方式有很多(红烧、清蒸、水煮、煎炸),餐厅经理通过点菜单,准确地把顾客要求传递给厨房,厨房把相应的菜品烹饪出来或者报告餐厅经理发生其他什么情况。那么这个函数的外观就可以表示为:

厨房烹饪(食材,烹饪方式,[份量有大中小可选,默认中份])

当顾客点了水煮生鱼,那么餐厅经理就吩咐厨房,即是调用这个函数,形式为

厨房烹饪(生鱼,水煮,中份)参数1    食材      生鱼  是不可省略的,称为必选参数参数2    烹饪方式  水煮  是不可省略的,称为必选参数参数3    份量      中份  事先约定,没有提份量就是默认中份,称为可选参数省略可选参数份量的话,经理只需要吩咐厨房:厨房烹饪(生鱼,水煮)

在厨房内部,厨师首先需要查看还有没有生鱼、有的话还要杀鱼、切片、烹饪等等,最终完成一道水煮生鱼,并把菜品端到传菜窗口,或者告诉经理生鱼没有了。

也就是X = 厨房烹饪(生鱼,水煮)反馈结果X 可以是:一道按要求完成的菜品,也可以是:一条“生鱼没有了”的消息而厨房内部从接菜单到反馈结果经历了哪些具体环节,餐厅经理不需要关心。也就是函数内部,怎么去实现,用户不需要去关心。餐厅经理只需要关心,如何去传递消息给厨房就可以了,然后得到厨房反馈就可以了。

同样地,经理还能以类似的方式,吩咐其他不同的部门和人员去做相应的事情,具体怎么去做,经理并不关心,他只需要一个反馈的结果。比如上菜的函数,可以这么写。

上菜(传菜员姓名,菜品,传到第几桌)调用方式就是:X = 上菜("翠花","水煮生鱼",3号桌)就是经理吩咐翠花把水煮生鱼传到3号桌,之后翠花反馈传菜的结果X“菜上好了”,或者“下错单了”至于翠花怎么端的、走的什么路线、传菜时怎么问候客人经理并不关心

接下来,我们就来看看InStr函数的语法

d7141b807fce5e2b6e3dbd96893765f9.png

       其中有两个必选参数和两个可选参数,可选参数省略时就按默认情况处理。查找的起始位置,默认就是从源文本的第一个字符开始,比较的方式,默认按文本字面意思来比较。反馈的值就是在查找文本在源文本中出现的具体开始位置,如果没有找到就返回0。

       前面代码中的语句就是省略可选参数的写法

InStr(sht.Name, "Sheet")

啥是过程

        在VBA里,若说过程和函数联系,过程可以理解为是不需要反馈(返回值的)函数,就是比函数还要简单一点,调用过程除了不关心具体细节以外,也不需要过程反馈结果。

        当然二者还是在调用方式上有区别

a46571ff68604eb9dd780297a607a1c2.png

    就是你不能把一个过程作为一个结果直接赋给一个变量,y=过程因此出错。而函数无论有没有返回值,都可以直接赋给一个变量 x=无返回值运行也没有问题。

    接下来就举个现实中的例子来增进理解:经理吩咐保洁扫地。

扫地(保洁员姓名,打扫区域,[什么时候:默认马上])调用的具体方式:扫地("张三",走道,马上)或者扫地("张三",走道)等于经理叫张三 马上 打扫 走道。张三怎么扫的,经理不关心,扫成啥样,也不需要回禀(经理坚信张三不会和工资过不去,可以清洁到位)

之前所分享的代码基本都是过程sub。

模块化思想

        假如我们要实现一些复杂的操作,具体的实现步骤会很多,使用一个过程来实现的话,代码会很长,结构会比较复杂,代码可读性就会变差,具体的代码细节很容易就掩盖了我们的思路、逻辑,后期维护也比较困难。

        此时,让们可以把实现的过程划分成很多功能单一的小步骤,每个小步骤封装起来,作为一个过程。在主程序中,只需要按逻辑去调用小步骤就可以,不用关心小步骤内部具体怎么实现。

        就像餐厅经理一样,他不能事无巨细亲力亲为,一头扎进在各种细节里面,没人传菜自己去传,没人去扫地自己去扫,而应该纵观全局,统领各个部门。

        这其实就是模块化思想,把一个大而复杂的业务分割成多个小而独立模块,主程序只需要按照业务逻辑去调用模块。这样,在主程序里,就可以呈现出清晰的业务逻辑。而独立的模块里面代码也比较少,后期维护就很方便。同时达到了复用的作用。比如经理既可以叫张三去打扫,也可以叫李四去打扫。一个扫地的过程就可以重复利用很多次,整体编写的代码量就会下降很多。

       主程序和子程序之间通过参数和返回值来进行通信。

       了解这个思想之后,我们来改造一下删除指定工作表的代码。

Sub Main() '主程序  'Call为调用       当前工作簿的工作表集合对象  查找文本  Call DeleteSheets(ThisWorkbook.Worksheets, "Sheet")    '在主程序里面,调用子程序 只需要传入合适的参数即可  '不需要关心 子程序实现功能的细节  '这样就提高了子程序的重复使用率  '同时子程序代码少,功能单一,可维护性就比较好。  End Sub
Sub DeleteSheets(AllSheets, Findtext) '被调用的子程序'AllSheets 参数 接收一个工作表集合对象'Findtext   参数 接收查找文本    '声明一个工作表类型的变量    Dim sht As Worksheet                            '关闭警告    Application.DisplayAlerts = False        '循环传入的工作表集合对象包含的所有工作表    For Each sht In AllSheets            '包含传入的查找文本 则        If InStr(sht.Name, Findtext) > 0 Then                   '删除工作表           sht.Delete                   End If            Next sht '下一个        '恢复警告    Application.DisplayAlerts = True        '释放变量    Set sht = Nothing    End Sub

再举一个给选定单元格区域添加内外边框的例子

Public Sub MainTest()    '在确认工作表存在内容的情况下,传入一个单元格区域进行调用    '括号内传入一个单元格Range对象    '给活动工作表已用单元格区域设置边框    Call SetBorders(ActiveSheet.UsedRange)    End Sub
'设置单元格边框的过程Sub SetBorders(ByVal Rng As Range)'Rng参数  接收一个Range对象    With Rng.Borders '对Rng对象的边框集合进行操作        .LineStyle = xlContinuous '线条样式:直线        .ColorIndex = xlAutomatic '颜色值:自动        .Weight = xlThin '线条粗细:细    End WithEnd Sub

      设置边框算是一个比较高频的操作,当你的一个程序需要反复给不同单元格设置内外边框的时候,SetBorders(ByVal Rng As Range)这个过程只需要在代码里出现一次,需要它的时候,调用它即可,这就是减少代码量、提高代码复用程度了。所以当我们想实现一个想法的时候,不妨先规划一下,将完整的想法拆解成很多功能独立、单一的部分,分别写成过程、函数。

      诸如此类的高频操作,还有单元格内容水平居中、单元格排序、定位等等,大家不妨用录制宏的方式,录下设置单元格内容水平居中的操作,然后把它修改为一个能给外部调用的过程。参数是一个单元格区域,愿意一试的请把代码贴在留言里。

374c1b0b3211c85d2c6321772c8301e2.png

小格子试用版下载地址,有效期至6月30日

链接:https://pan.baidu.com/s/1jHvzo6TUOzralrfxGJVHBw

提取码:it3g

分享交流:Q群

49af87c7e4400bd93ec328d6f651ab35.png

以前觉得挣钱不重要,现在才明白,星辰和大海都需要门票。本文若对您有用,能否赠我一张门票?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值