【问题标题】:ByRef argument type mismatch in Excel VBAExcel VBA中的ByRef参数类型不匹配
【发布时间】:2013-05-17 14:28:29
【问题描述】:

我正在使用 VBA。我写了一个用户定义函数,它接受一个string,处理它并返回一个干净的string。我不确定它有什么问题。我无法调用它并要求它处理我的字符串并返回它。我认为我定义或返回它的方式有误。

Public Function ProcessString(input_string As String) As String
    ' The temp string used throughout the function
    Dim temp_string As String

    For i = 1 To Len(input_string)
        temp_string = Mid(input_string, i, 1)
        If temp_string Like "[A-Z, a-z, 0-9, :, -]" Then
            return_string = return_string & temp_string
        End If
    Next i
    return_string = Mid(return_string, 1, (Len(return_string) - 1))
    ProcessString = return_string & ", "
End Function

我是这样使用这个函数的

Worksheets(data_sheet).Range("C2").Value = ProcessString(last_name)

姓氏是一个字符串变量,通常看起来像这样Lastname*****,我正在尝试删除它后面的所有星星。让它在没有星星的情况下返回Lastname

当我尝试运行它时,我收到了Compile error: ByRef arugment type mismatch。我正在使用带有 Office 2003 的 Windows XP。

编辑:我添加了我拥有的代码的基本结构,我有大约 20 行类似的代码。为我需要的每个字段做同样的事情。

Private Sub CommandButton2_Click()
' In my original production code I have a chain of these
' Like this Dim last_name, first_name, street, apt, city, state, zip As String
Dim last_name As String

' I get the last name from a fixed position of my file. Because I am 
' processing it from another source which I copied and pasted into excel
last_name = Mid(Range("A4").Value, 20, 13)

' Insert the data into the corresponding fields in the database worksheet
Worksheets(data_sheet).Range("C2").Value = ProcessString(last_name)

【问题讨论】:

  • 错误标志在哪一行?
  • 当我调用它时,它在线路上标记。 Worksheets(data_sheet).Range("C2").Value = ProcessString(last_name)

标签: vba excel


【解决方案1】:

我怀疑你没有在调用者中正确设置last_name

用声明Worksheets(data_sheet).Range("C2").Value = ProcessString(last_name)

这只有在last_name 是一个字符串时才有效,即

Dim last_name as String

出现在调用者的某处。

原因是VBA默认通过引用传入变量,这意味着调用者和被调用者之间的数据类型必须完全匹配。

两个修复:

1) Force ByVal -- 更改您的函数以传递变量 ByVal:
Public Function ProcessString(ByVal input_string As String) As String,或

2) Dim varname -- 在使用前将Dim last_name As String 放入调用者中。

(1) 之所以有效,是因为对于ByVal,在传递给函数时会获取 input_string 的副本,这会将其强制转换为正确的数据类型。由于该函数无法修改调用者中的变量,因此还可以提高程序稳定性。

【讨论】:

  • 谢谢!添加ByVal 解决了问题,现在代码运行正常!
  • 我总是用 ByVal 声明我的所有 VBA 函数,因为它提高了稳定性。使用 Java,你别无选择,一切都是按值传递的。
【解决方案2】:

我不知道为什么,但是如果你想将变量(作为变量)传递给其他过程或函数,单独声明变量是非常重要的。

例如,有一个程序对数据进行一些操作:根据 ID 返回零件编号和数量信息。 ID 为常量值,其他两个参数为变量。

Public Sub GetPNQty(ByVal ID As String, PartNumber As String, Quantity As Long)

下一个主代码给了我一个“ByRef 参数不匹配”:

Sub KittingScan()  
Dim BoxPN As String
Dim BoxQty, BoxKitQty As Long

  Call GetPNQty(InputBox("Enter ID:"), BoxPN, BoxQty) 

End sub

下一个也正常工作:

Sub KittingScan()
Dim BoxPN As String
Dim BoxQty As Long
Dim BoxKitQty As Long

  Call GetPNQty(InputBox("Enter ID:"), BoxPN, BoxQty)

End sub

【讨论】:

  • 是的,这是我的问题。 VBA - 如此混乱。一定是因为它是“可访问的”。
  • 我疯了,我不敢相信我需要这个,谢谢。
  • 一行声明不像我们想象的那样工作!!! :stackoverflow.com/a/34036529/4316542
  • 这应该是答案
  • 对,我的问题是 Dim foo,bar,my,duty,var as long。 Foo,bar(等)是变体。 var 很长。 JFC。
【解决方案3】:

我更改了一些内容以使用 Option Explicit,代码在包含 "abc.123" 的单元格上运行良好,该单元格返回 "abc.12,"。没有编译错误。

Option Explicit ' This is new

Public Function ProcessString(input_string As String) As String
    ' The temp string used throughout the function
    Dim temp_string As String
    Dim i As Integer ' This is new
    Dim return_string As String ' This is new
    For i = 1 To Len(input_string)
        temp_string = Mid(input_string, i, 1)
        If temp_string Like "[A-Z, a-z, 0-9, :, -]" Then
            return_string = return_string & temp_string
        End If
    Next i
    return_string = Mid(return_string, 1, (Len(return_string) - 1))
    ProcessString = return_string & ", "
End Function

我建议您发布更多相关代码(调用此函数)。您已经说过 last_name 是一个字符串,但似乎情况并非如此。逐行检查您的代码并确保确实如此。

【讨论】:

  • 在我添加了丢失的 Dim 语句后,它提示(突出显示)我有 Private Sub CommandButton2_Click() 的行,并且突出显示了 last_name。很奇怪的行为,我的 Sub 基本上是一个做事情列表的按钮。
【解决方案4】:

虽然一次循环一个字符的字符串是一种可行的方法,但没有必要。 VBA 为这类事情提供了内置函数:

Public Function ProcessString(input_string As String) As String
    ProcessString=Replace(input_string,"*","")
End Function

【讨论】:

  • 这是一个非常好的解决方案。但是你能告诉我如何解决这个问题吗?因为我也在试图弄清楚我做错了什么。谢谢!
【解决方案5】:

该字符串有问题,尝试如下:

Worksheets(data_sheet).Range("C2").Value = ProcessString(CStr(last_name))

【讨论】:

    【解决方案6】:

    看起来 ByRef 需要知道参数的大小。一份声明 将 last_name 暗淡为​​字符串 未指定字符串的大小,因此将其视为错误。使用前 工作表(data_sheet).Range("C2").Value = ProcessString(last_name) last_name 必须声明为 Dim last_name as string *10 ' 字符串大小由您决定,但必须是固定长度

    无需更改功能。函数不采用固定长度声明。

    【讨论】:

      【解决方案7】:

      对我来说,这里的问题是我在一行中声明了多个变量,而不是单独的行。

      例如,我试图将 i 作为整数传递给我的函数。

      Dim i,j as integer - gets me the error
      Dim i as integer - doesn't get the error
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-10
        • 2012-06-30
        • 1970-01-01
        相关资源
        最近更新 更多