VBA:尽管没有阵列,但仍会出现预期的阵列错误

时间:2019-07-13 08:10:05

标签: arrays excel vba

在VBA中创建的一个子代码中,每次工作表更改时都会执行该子代码,该子代码调用一个函数来确定用户是否删除或更改了他们不应该拥有的内容。该函数返回一个布尔值,以告知子程序是否已删除/编辑了这样的临界值。这样,子程序就知道不会继续执行代码。

但是,无论何时执行代码,VBA都会返回Compile Error: Expected array错误,以调用criticalDataIntact()函数,尽管没有使用任何数组。

这是我的相关代码,

Private Sub Worksheet_Change(ByVal target As Range)
    Worksheets(CONFIG).usedRange 'Refresh UsedRange
    Dim criticalDataIntact As Boolean: criticalDataIntact = criticalDataIntact()

    If Not criticalDataIntact Then
        Exit Sub
    End If

    'Irrelevant code
End Sub

Private Function criticalDataIntact() As Boolean
    Dim criticalDataIntact As Boolean: criticalDataIntact = True
    Set warnWorkloadCell = ThisWorkbook.cell(CONFIG, WARNING_WORKLOAD, 0, 0)
    Set dangerWorkloadCell = ThisWorkbook.cell(CONFIG, DANGER_WORKLOAD, 0, 0)
    Dim table3Exists As Boolean: table3Exists = tableExists("Table3")

    If warnWorkloadCell = Null Or dangerWorkloadCell = Null Or table3Exists = False Then
        criticalDataIntact = False
    End If
End Function

cell函数通过MsgBox输出错误消息,如果无法在特定工作表中找到具有特定值的单元格,则返回Null

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

  • 考虑将您的CriticalDataIntact函数重命名为IsCriticalDataIntact
  • 如果您的Worksheets(CONFIG)工作表与包含Worksheet_Change代码的工作表相同,请考虑将Worksheets(CONFIG)替换为Me
  • 如果您没有在criticalDataIntact子例程中的其他任何地方(即“无关代码”中的任何地方)引用Worksheet_Change变量,请考虑删除该变量,而直接使用返回值。

基于上述情况,您的Worksheet_Change例程可能类似于:

Private Sub Worksheet_Change(ByVal target As Range)
    Worksheets(CONFIG).UsedRange ' Doesn't this give you a syntax error? If this is the same worksheet as the worksheet storing this procedure, consider using Me.UsedRange -- although maybe there a better alternatives to UsedRange.

    If Not IsCriticalDataIntact() Then
        Exit Sub
    End If

    'Irrelevant code
End Sub
  • 请考虑模块顶部的Option Explicit。我之所以这样说,是因为您的CriticalDataIntact函数包含看似未声明的变量:warnWorkloadCelldangerWorkloadCell(除非这些是非局部变量)。

  • 我无权访问您的自定义函数cell,但假定它是ThisWorkbook的成员。考虑将名称cell更改为更具描述性的

  • 关于cell函数的返回类型,您已经说过它返回了RangeNull。这听起来像Variant的行为(我的理解是只有Variants才能将Null存储在VBA中)。但我认为这将导致调用站点的语法无效,因为您无法SetVariant Null(据我所知)。
  • 类似于您想要的声音的返回类型为Range -如果无法返回Range,则会返回Nothing(您仍然可以测试)。
  • 基于上述情况,自定义函数cell的更好名称可能是GetCellOrNothing

所以您的函数可能类似于:

Private Function IsCriticalDataIntact() As Boolean

    Dim warnWorkloadCell As Range ' Declare if a local variable.
    Set warnWorkloadCell = ThisWorkbook.cell(CONFIG, WARNING_WORKLOAD, 0, 0) ' Consider renaming to "GetCellOrNothing" -- depending on how much work that is for you.

    Dim dangerWorkloadCell As Range ' Declare if a local variable.
    Set dangerWorkloadCell = ThisWorkbook.cell(CONFIG, DANGER_WORKLOAD, 0, 0) ' Consider renaming to "GetCellOrNothing" -- depending on how much work that is for you.

    Dim table3Exists As Boolean
    table3Exists = tableExists("Table3")

    IsCriticalDataIntact = table3Exists And Not ((warnWorkloadCell Is Nothing) Or (dangerWorkloadCell Is Nothing)) 

End Function

未经测试。

答案 1 :(得分:0)

在criticalDataIntact之后删除(),否则您说criticalDataIntact =变体变量,因为criticalDataIntact()是名称为criticalDataIntact的隐式变体变量。这就是您的错误的根源。

Dim criticalDataIntact As Boolean: cIntact = criticalDataIntact '<remove the () which is implicit variant

然后为避免混淆编译器,请使用其他名称的变量来保存返回值

Dim cIntact As Boolean: cIntact = criticalDataIntact

If warnWorkloadCell = Null Or dangerWorkloadCell = Null Or table3Exists = False Then
    criticalDataIntact = False
End If

可以成为

criticalDataIntact = Not (IsNull(warnWorkloadCell) Or IsNull(dangerWorkloadCell) Or table3Exists = False)

并删除对本地布尔值的需要。就个人而言,我将table3Exists更改为tableNotExists并在该函数内进行必要的更改,这样我就可以

criticalDataIntact = Not (IsNull(warnWorkloadCell) Or IsNull(dangerWorkloadCell) Or table3NotExists)

我看不到您的单元格方法,所以我不知道它返回什么,但是对于对象,我通常会执行If Not x Is NothingIf x Is Nothing