问题:想做出延时执行的效果,同时还显示了经过的时间
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运算)