Excel VBA的一个总结

本文分享了作者在Excel VBA编程中遇到的两个bug及解决方案,强调了代码检查的重要性,并提出了使用Option Explicit减少变量拼写错误的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我以前的VBA都是满足我自己的一个小小的需求的,他们通常都比较简单,属于自娱自乐型的,都很简单,今天终于写了一个稍微复杂一点的, 程序有两个bug, 在写这篇博客之前, 我刚花费两个小时把它们解决掉, 趁着还没忘, 对吸取到的一些经验教训加以总结.

 

下面是部分excel代码,代码后面是总结, 总结的地方已使用"- == BUG == -"标出:

' -- ==  BUG == --
' use this option, the interpreter will help you~~~
' Option Explicit


'used in step 01
Dim st
Dim et
Dim maxrow
Dim count

'used in step 02
Dim waste

Private Sub CommandButton1_Click()
    
    st = DateValue("2008-08-29")
    et = DateValue("2008-9-06")
    maxrow = 61000
    count = 1

    
    'MsgBox DateValue(Cells(2, 1))

    Call processSheet(Sheet2)
    Call processSheet(Sheet3)
    Call processSheet(Sheet4)

    MsgBox (count)
    
End Sub

Private Sub processSheet(sheet)

    sheet.Activate
    
    For i = 2 To maxrow
        If sheet.Cells(i, 1) <> "" Then
            t = DateValue(sheet.Cells(i, 1))
            If t >= st And t <= et Then
                count = count + 1
                sheet.Rows(i).Copy
                Sheet5.Rows(count).Insert Shift:=xlDown
            End If
        End If
    Next


   
    'MsgBox (Cells(2, 1))
    'MsgBox (count)
    
End Sub


Private Sub CommandButton2_Click()

    
    For i = 2 To 5815
        d = DateValue(Cells(i, 1))
        t = TimeValue(Cells(i, 1))
        
        Call findPos(d, t, Cells(i, 2), Cells(i, 3))
        Cells(i, 14) = waste
        
        If waste = Cells(i, 13) Then
            Cells(i, 15) = "Yes"
        Else
            Cells(i, 15) = "NO"
        End If
    Next
    
End Sub


Sub findPos(d, t, asset, serial)

    'Sheet5.Select
    waste = "-"
    
    For i = 2 To 60000
        'asert date is not null
        If Sheet5.Cells(i, 1) = "" Then
            Exit For
        End If
        
        'find waste box
        td = DateValue(Sheet5.Cells(i, 1))
        tt = TimeValue(Sheet5.Cells(i, 1))
        diff = DateDiff("n", t, tt)
        
        If d = td And (diff > -10 And diff < 10) And asset = Sheet5.Cells(i, 2) And serial = Sheet5.Cells(i, 3) Then
            waste = Sheet5.Cells(i, 14)
            Exit For
        End If
        
    Next
    
    'Sheet1.Select
    
End Sub

Private Sub CommandButton3_Click()

    
    For i = 2 To 5815
        
        If "NO" = Cells(i, 15) Then
            d = DateValue(Cells(i, 1))
            t = TimeValue(Cells(i, 1))
            
            Cells(i, 1).Select
        
            Call findFuzzy(d, t, Cells(i, 2), Cells(i, 3))
            Cells(i, 14) = waste
        
            If waste = Cells(i, 13) Then
                Cells(i, 15) = "Yes"
            Else
                Cells(i, 15) = "NO"
            End If
        End If
    Next
    

End Sub



Sub findFuzzy(d, t, asset, serial)

    Min = DateValue("2099-08-29")
    mintime = TimeValue("23:59:59")
    mintimebeh = TimeValue("23:59:59")

    waste = "-"
    flag = True
    
    For i = 2 To 60000
        'asert date is not null
        If Sheet5.Cells(i, 1) = "" Then
            flag = False
            Exit For
        End If
        
        'judge wheather is the same printer
        If asset = Sheet5.Cells(i, 2) And serial = Sheet5.Cells(i, 3) Then
        
        
            'find waste box
            td = DateValue(Sheet5.Cells(i, 1))
            tt = TimeValue(Sheet5.Cells(i, 1))
            diff = DateDiff("n", t, tt)
        
                
            'record the min date before last day
            If DateDiff("d", d, td) = 1 Then
                    If tt < mintimebeh Then
                        mintimebeh = tt
                        ' -- ==  BUG == -- i spell mpbeh as mpben by mistake
                        ' -- ==  BUG == -- pay more attantion on the spelling of the var
                        mpbeh = i
                    End If
            End If
            
            'record the min value today
            If DateDiff("d", d, td) = 0 Then
                    If tt > t And tt < mintime Then
                        mintime = tt
                        mp = i
                    End If
            End If
            
        'end judge
        End If

    Next
    
    
    If mintime <> TimeValue("23:59:59") Then
        ' -- ==  BUG == --  waste = Cells(mp, 14)
        ' -- ==  BUG == --  when use the cells that are not in the same sheet of the button ,you must use  "Sheet5" to modify it.
        waste = Sheet5.Cells(mp, 14)
    Else
        waste = Sheet5.Cells(mpbeh, 14)
    End If
    
    'Sheet1.Select
    
End Sub

Private Sub CommandButton4_Click()

    d1 = DateValue("2008-08-29")
    d2 = DateValue("2008-7-06")
    

    MsgBox DateDiff("d", d1, d2)
    
End Sub

 

总结两点:

1. 第一个bug的原因是我误将mpbeh拼写成了mpben,以至于我没有得到我想要的值, 该死的键盘设计的有问题, h & n靠的那么近, 还张得那么像, 在一堆字符里错误的出现通常很难辨识,尤其在脑袋大的时候.

 

为此MrLiu建议使用:"Option Explicit"来减少,变量拼写的错误, 恩,不错,thx

 

2. 在引用了不和空间在一个sheet里面的cells的时候,没有使用sheet进行限定.

虽然通篇我都很小心的注意了这一点, 但我还是漏掉了一处, 为此我也付出了应有的代价. 以后只有更加留神,或者写vba的时候尽量避免这种情况出现. 毕竟你想我刚开始那样直接写上一个Cells, 他在解释器看来是再合法不过的了, 虽然你可能并不想这么做.

 

另:玩具一样的例子中学到的东西也有限, 如果我有一个机会出一个实际题目, 让自己或者别人通过这个例子强化一下vba, 我会出什么? 刚才想了一下这个问题, 一个答案是做一个:"SQL学习环境", 毕竟他和数据库还都挺关系的. 还有别的更好的答案吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值