VBA,如何做出一个延时执行,且能动态显示延时的秒数呢?

问题:想做出延时执行的效果,同时还显示了经过的时间

 

1 简洁版代码

代码

Sub test200e()
    time0 = Timer()
    For i = 1 To 10
        time1 = Timer()
        Debug.Print i
        Do
           Worksheets("sheet4").Labels("label 1").Caption = "数到了" & i & " ,时间已经过去秒数:" & Int(Timer() - time0) & "秒"
           DoEvents
           Loop While Timer < time1 + 3   '注意直接就是秒数
    Next
End Sub

 

2 优化版:两种时间显示格式:

第1种一直即时,第2种每跳1个数字才计时1次

  • label 1的显示是 从结尾到开始花费的总时间,会一直计时跳秒
  • label 2 只有每次跳数字的时候才会跳秒,把这次新的延迟时间,加到总延迟时间里去。

 Sub test200d()
    time0 = Timer()
    For i = 1 To 10
        time1 = Timer()
        Debug.Print i
        Do
           Worksheets("sheet4").Labels("label 1").Caption = "数到了" & i & " ,时间已经过去秒数:" & Int(Timer() - time0)
           Worksheets("sheet4").Labels("label 2").Caption = "数到了" & i & " ,时间已经过去秒数:" & Round(C, 1)
           DoEvents
        Loop While Timer < time1 + 3   '注意直接就是秒数
        C = C + Timer() - time1
    Next
End Sub

 

3 提出来写成专用的延迟函数+ 计时函数, 不香么?

3.2 第1种独立出来的写法(需要声明几个非过程变量)

  • 这里先声明了几个公共变量来传递参数的值
  • 其实也可以用3.2的方法,主函数直接调用 delay 函数时 当参数传递就可以

 

  • 拆分逻辑,写专用函数挺锻炼人的
  • 本来想拆成 主函数,延迟函数,计时函数的,但是感觉也写的不好
  • 现在拆两部分
  • 主函数:走循环业务逻辑和打印显示逻辑
  • delay函数:专门负责delay

 

  • 一个特殊情况
  •  delay函数本来不需要下面这句
  • Worksheets("sheet4").Labels("label 1").Caption = "New数到了" & i & " ,时间已经过去秒数:" & Int(Timer() - time0)
  • 但是如果想计时是持续的,必须放到 do loop里,所以就这样了
Dim time0, i, time1
 
Sub test200f()
    time0 = Timer()
    For i = 1 To 10
        time1 = Timer()
        Debug.Print i
        'i先出来再延时,显示函数应该早于delay函数
         Worksheets("sheet4").Labels("label 2").Caption = "New数到了" & i & " ,时间已经过去秒数:" & Round(C, 1)
        test200f1_delay (3)
        C = C + Timer() - time1
    Next
End Sub


Function test200f1_delay(t)
    Do
        DoEvents
        'delay函数本来不需要下面这句,但要让时间一直计时得用这句
        Worksheets("sheet4").Labels("label 1").Caption = "New数到了" & i & " ,时间已经过去秒数:" & Int(Timer() - time0)
    Loop While Timer < time1 + t

End Function

 

3.2 不声明模块级变量,而是直接调用函数时传递参数

Sub test200f()
    time0 = Timer()
    For i = 1 To 10
        time1 = Timer()
        Debug.Print i     '是延迟后打印还是打印后延迟都可以,如果是i先出来再延时,显示函数应该早于delay函数
        Worksheets("sheet4").Labels("label 2").Caption = "New数到了" & i & " ,时间已经过去秒数:" & Round(C, 1)
        Call test200f1_delay(3, time1)
        C = C + Timer() - time1
    Next
End Sub


Function test200f1_delay(t, time1)
    Do
        DoEvents
    Loop While Timer < time1 + t
End Function

 

3.3 思考:两种传递参数方式的思考:公用杯子 和  私人单向传递

  • 第1种方法(公用杯子--间接传递东西):这里先声明了几个公共变量,多个函数过程都可以直接用,间接传递参数的值
  • 第2种方法(两人之间1对1单向传递东西):主函数直接调用 delay 函数时,直接当参数传递就可以
  • 暂时看起来,可以达到一样的效果
  • 估计参数太多的话,用的函数多,可能更得倾向于第一种? 大家谁都可以改,方便但是有可能出问题。
  • 如果是求安全的话,可能倾向第2种,只是1对1的单向传递。

 

4 原始完整版代码和一些思考心得

4.1 原始完整版代码(没精简)

  • 这里是原始版本的
  • 有很多当时的摸索过程

Sub test200c()

    Worksheets("sheet4").Labels("label 1").Visible = True  '这个只是为了确定控件名的
    Worksheets("sheet4").Labels("label 2").Visible = True
    
    time0 = Timer()
    
    For i = 1 To 10
        time1 = Timer()
        Debug.Print i
        Do
           Range("a1") = Int(Timer() - time0)  '这里用round(,1)还是会有多位小数
           Worksheets("sheet4").Labels("label 1").Caption = Int(Timer() - time0)   ' 写这样会更新慢"已经过去时间:" & Int(Timer() - time0)
           
           time2 = Timer()
           Cells(i, 4) = time2 - time1
           DoEvents
        Loop While Timer < time1 + 3   '注意直接就是秒数
        C = C + time2 - time1   '实测这里timer()代替 time2就可以, time2多余
        Range("a2") = Round(C, 1)  '先累加
        Cells(i, 3) = C
       
         Worksheets("sheet4").Labels("label 2").Caption = Round(C, 1)  ' 写这样会更新慢"已经过去时间: "已经过去了" & Round(C, 1)    ' 这句放的位置不对,应该放在前面,这已经数到2了
    Next
End Sub

 

4.2 中间变量很重要

4.2.1 中间变量的作用

  • 传递变量更简洁
  • 固定 一些变量的某一时刻的值(特别注意 中间变量 赋值的时机,差别很大)

 

4.2.2 中间变量的用法技巧:注意取值的时机,时间点等等

  • 这次学会了在大循环开始前,固定时间点time0=timer()
  • 每个for 循环开始前,固定时间点 time1=timer()
  • 而for循环内部,每个 do...loop循环结束时,固定时间点time2=timer()  ( 实际上这时候直接用timer()也可以)

 

4.3 循环外保存数据,进行累加等计算

  • 记录每次的时间
  • Timer() - time1  写在do...loop之外,但是for next之内,就是为了,保存当时的while 结束时的时间timer() (time2) 和和每次for 循环开头都要重置的 time1
  • 这样就记录了每次 do..loop的好费时间

 

  • 记录 累计时间
  • 而  C = C + Timer() - time1 这个是为了在do...loop 循环外累加时间

 

5  为什么不用 now() 和 time() 做延时和显示延时时间呢?

  • 我当时想,因为这2个是返回的时间点,而不是持续的累积的时间数。
  • 但是时间相减应该也可以
  • 试了下,确实可以,不过比timer () 麻烦一些

 

5.1 差别点1:

  • 注意如果C是format()返回的string类型,不能用int 或 round去修正了

 

5.2 差别点2:

  • timer()返回的是描述,是single方便运算
  • 但是time now date返回的是date格式,本质是double,如果是date之间的减法,需要用cdate中转下
  • C = CDate(C + Time() - time1)
  • C + Time() - time1 本身也没错,但是看不懂,得变成时间格式
  • 如果用format 得配合 cdate() 用才行---其实感觉用cdate() 更好
  • C = Format(CDate(C) + Time() - time1, "hh:mm:ss")

 

5.3 差别点3: 传递延迟的参数值

  • 并且是时间格式(小时:分:秒)
  • 不是秒数
  • 比如timevalue("00:00:03")
Sub test200f()
    C = TimeValue("00:00:00")    'TimeValue("00:00:00")  '0
    time0 = Timer()
    For i = 1 To 10
        time1 = Time()
        Debug.Print i
        Worksheets("sheet4").Labels("label 2").Caption = "New数到了" & i & " ,时间已经过去秒数:" & C
        Call test200f1_delay(TimeValue("00:00:03"), time1)
        
        '正确写法1:时间-时间=结果,必须先用 cdate转下,追问那时间+时间呢,超过范围呢
        'C = C + CDate(Time() - time1)
        '正确写法2:
        'C = Format(CDate(C) + Time() - time1, "hh:mm:ss")    '也正确,必须先用cdate转下C
         '正确写法3: cdate() 简洁,cdate()转正常时间好像就等于本身
         C = CDate(C + Time() - time1)
         
         '错误写法1
'        C = C + Time() - time1     '不报错,但是无法阅读
         '错误写法2
'         C = Format(C + Time() - time1, "hh:mm:ss")  'format返回的string,无法与date一起运算

    Next
End Sub


Function test200f1_delay(t, time1)
    Do
        DoEvents
    Loop While Time < time1 + t
End Function

 

5.4 报错备忘

  •  c在fomat之后变成了一个字符串
  • 必须先转为  cdate 才可以进行 date 运算(实际是double运算)

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值