【问题标题】:Why first argument of subroutine must be passed ByVal为什么子程序的第一个参数必须通过 ByVal
【发布时间】:2020-05-12 10:43:56
【问题描述】:

我有以下代码:

Sub AddValidation()
   Dim ws, wsDefinitions As Worksheet
   Set ws = ThisWorkbook.Worksheets("TData")
   Set wsDefinitions = ThisWorkbook.Worksheets("Definitions")

   Call AddValidator(ws, wsDefinitions, "FaultType", FaultTypeColumn)
End Sub

Sub AddValidator(targetWs As Worksheet, definitionsWs As Worksheet, definitionTableName As String, targetColumnNumber)

    Dim definitionsRange As Range, targetRange As Range

    Set definitionsRange = definitionsWs.ListObjects(definitionTableName).ListColumns(1).DataBodyRange
    Set targetRange = targetWs.ListObjects("Table1").ListColumns(targetColumnNumber).DataBodyRange

    With targetRange.Validation
        .Delete 'delete previous validation
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, _
            Formula1:="='" & definitionsWs.Name & "'!" & definitionsRange.Address
    End With

End Sub

在编译期间,AddValidator 的第一个参数“ws”得到“ByRef 参数类型不匹配”。 当我将 ByVal 添加到定义中时:

Sub AddValidator(ByVal targetWs As Worksheet, definitionsWs As Worksheet, definitionTableName As String, targetColumnNumber)

一切编译正常。 “AddValidator”宏的两个第一个参数是工作表类型,但只有第一个需要通过值传递。

谁能告诉我为什么?

【问题讨论】:

  • 尝试声明两种变量类型:Dim ws As Worksheet, wsDefinitions As Worksheet.

标签: excel vba


【解决方案1】:

问题在于变量的声明。

Dim ws, wsDefinitions As Worksheet

这里 ws 被声明为 variant 而不是 sheet 对象,因此 Excel 会提示您更新参数。如果您解决此问题,Excel 将不会引发错误。以下子将正常工作。

Sub Test()
    Dim ws1 As Worksheet, ws2 As Worksheet
    Set ws1 = ThisWorkbook.Sheets("Sheet1")
    Set ws2 = ThisWorkbook.Sheets("Sheet2")
    mySub ws1, ws2
End Sub
Sub mySub(targetWS As Worksheet, sourceWS As Worksheet)
    MsgBox targetWS.Name
    MsgBox sourceWS.Name
End Sub

【讨论】:

  • 非常感谢。这就是答案。我认为 Dim var1, var2 as Worksheet 将两个变量都声明为 Worksheet,但显然不是。我的错和误解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2022-01-15
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多