36

我正在使用 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)
4

7 回答 7

61

我怀疑你没有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) 有效,因为 for ByVal,在传递给函数时会获取 input_string 的副本,这会将其强制转换为正确的数据类型。由于函数不能修改调用者中的变量,因此它还可以提高程序的稳定性。

于 2013-05-17T14:51:17.300 回答
21

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

例如,有一个程序对数据进行一些操作:根据 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
于 2016-12-09T11:13:42.570 回答
4

我更改了一些要使用的东西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 是一个字符串,但似乎情况并非如此。逐行检查您的代码并确保确实如此。

于 2013-05-17T14:42:07.777 回答
3

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

Public Function ProcessString(input_string As String) As String
    ProcessString=Replace(input_string,"*","")
End Function
于 2013-05-17T14:34:38.143 回答
0

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

Worksheets(data_sheet).Range("C2").Value = ProcessString(CStr(last_name))
于 2017-12-28T19:09:01.277 回答
0

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

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

于 2021-02-15T00:45:12.717 回答
0

对我来说,这里的问题是我连续声明多个变量而不是单独的行。

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

Dim i,j as integer - gets me the error
Dim i as integer - doesn't get the error
于 2021-08-23T16:50:53.347 回答