我的Excel中无法执行“对象必需”代码

时间:2019-09-12 16:03:53

标签: excel vba

每次尝试执行代码时,都会显示“需要对象”。我是编码的新手,我真的不知道该如何很好地排除故障。这行代码较早起作用,我所做的就是将其复制并粘贴到相同excel的副本中。我基本上只希望我的excel在我打开它时创建一个msgbox(如果生日列表中的某个日期与今天匹配)。生日列表从b2扩展到b100,我希望它能够浏览整列以找到生日。这是我从YouTube视频中获取的一段代码,我已经对其进行了一百次检查。现在,无论生日是否匹配,每次我打开excel时,msgbox都会弹出。

Private Sub Workbook_Open()
    Dim cl As Range
    Set cl = ThisWorbook.Sheets("Birthdays").Range("B2:B100")
    If IsDate(cl) Then
        If Now >= cl Then
            MsgBox "Somebody's had a birthday!"
        End If
    End If
End Sub

2 个答案:

答案 0 :(得分:3)

由于输入错误ThisWorbook应该是ThisWorkbook

,您收到需要对象错误

遇到此类错误是很正常的。因此,请始终使用Option Explicit。我已经在To ‘Err’ is Human

中介绍了它

所以我可以将其自动添加到代码中吗?

可以。要将其添加到您创建的所有新文件中,只需在VBE中选择“工具”->“选项”,然后选中“需要变量声明”框即可。

注意:这只会影响您创建的新文件。您需要将其自己添加到现有文件中。

  

如果生日列表上的某个日期与今天匹配,我基本上只是希望我的excel在打开它时创建一个msgbox。

您可以使用Application.WorksheetFunction.CountIf检查范围中是否有今天的日期。

Sub Sample() 
    Dim ws As Worksheet
    Dim rng As Range
    Dim matchFound As Long

    Set ws = ThisWorkbook.Sheets("Birthdays")
    Set rng = ws.Range("B2:B100")

    matchFound = Application.WorksheetFunction.CountIf(rng, Date)

    If matchFound > 0 Then
        MsgBox "Birthday Found"
    Else
        MsgBox "Birthday Not Found"
    End If
End Sub

屏幕截图

enter image description here

答案 1 :(得分:1)

cl是一个Range对象,代表99个 dalmatians 单元,每个单元封装了一个Variant值。

IsDate函数很乐意接受 a Variant,但不知道如何处理其中的99个。

由于Range具有隐藏的默认属性,因此您可以使用它,就像它是一个值一样-但是,特别是对于刚开始学习的人VBA,它使混淆的,隐式的,“魔术”的代码能够说一件事,而又做另一件事

If IsDate(cl.Value) Then

此处隐式的Range.Value成员调用会产生一个Variant,它表示单元格值本身如果范围仅表示单个单元格,否则(即,如果范围是一个以上的单元格)会产生一个Variant,指向一个保存着每个单一值的二维Variant数组(在本例中为99x1)。

IsDate想要一个一个值,因此,如果我们有99个,则需要一个循环。但这就是问题:我们要做的最后一件事是迭代单个单元格,获取它们的Value并进行验证-因为那会非常慢。

因此,我们改为获取2D Variant数组,并迭代那个

If cl.Count = 1 Then
    'single-cell range: not a 2D array 
    If Now >= cl.Value Then
        MsgBox "Somebody's had a birthday on " & Format(cl.Value, "yyyy-mm-dd")
    End If
    Exit Sub
End If

Dim values As Variant
values = cl.Value

Dim currentRow As Long
For currentRow = LBound(values, 1) To UBound(values, 1)
    Dim currentCol As Long
    For currentCol = LBound(values, 2) To UBound(values, 2)
        Dim currentValue As Variant
        currentValue = values(currentRow, currentCol)
        If IsDate(currentValue) Then
            If Now >= currentValue Then
                MsgBox "Somebody's had a birthday on " & Format(currentValue, "yyyy-mm-dd")
                Exit Sub
            End If
        End If
    Next
Next

  

现在,无论生日是否匹配,每次我打开excel时,msgbox都会弹出。

听起来像您的实际代码在某处有On Error Resume Next,这使VBA忽略了任何运行时错误,并愉快地继续运行,而……您绝对不希望这样。根据经验,切勿使用On Error Resume Next来避免出现错误。通常,在出现“需要对象”错误时,执行会停止:无条件弹出MsgBox意味着允许执行在错误状态下继续进行,这不是一件好事。

As Sid found out类型不匹配是由错字引起的-不允许发生这种情况:确保您在每个模块中键入任何代码的地方都{{1} },并且永远不会再发生……对于您早期绑定的代码(后期绑定的代码仍然容易受到拼写错误的影响,但这又是另一回事了。)

最后,请注意,Rubberduck的代码检查会报告上述几个问题(免责声明:我管理这个开源项目)-包括错字,隐式默认成员调用和没有Option Explicit