2013-05-17 38 views
12

我正在使用VBA。我寫了一個用戶定義函數,它需要一個string,處理它並返回一個清理的string。我不確定它有什麼問題。我無法調用它並要求它處理我的字符串並將其返回。我認爲我定義或返回它的方式存在錯誤。Excel中的ByRef參數類型不匹配VBA

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當我試圖運行這個。我使用Windows XP與Office 2003

編輯:我加了我的代碼的基本結構調查,我有大約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) 
+3

在哪條線上錯誤標誌? – Gaffi

+0

當我打電話時,它在線上閃現。 '工作表(data_sheet).Range(「C2」)。Value = ProcessString(last_name)' – George

回答

29

我懷疑你沒有在調用者中正確設置last_name

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

這一點,如果last_name是一個字符串只會工作,即

Dim last_name as String 

出現在來電者的地方。

這樣做的原因是,在VBA變量經過由默認參照這意味着數據類型必須確切呼叫者和被叫方之間匹配。

兩個定位:

1)改變你的函數Public Function ProcessString(ByVal input_string As String) As String

2)把Dim last_name As String在來電者在使用它之前。

(1)因爲對於ByVal有效,所以在傳遞給函數時會採用input_string的副本,將函數強制爲正確的數據類型。由於該函數無法修改調用者中的變量,因此它還可以提高程序的穩定性。

+0

謝謝!添加'ByVal'解決了問題,現在代碼運行良好! – George

+1

我總是用ByVal聲明所有的VBA函數,因爲它提高了穩定性。用Java你沒有選擇,一切都是按價值傳遞的。 – Bathsheba

2

雖然在字符串中循環一次一個字符是一種可行的方法,但沒有必要。 VBA內置函數,用於這種事情:

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

這是一個非常好的解決方案。但是,請你告訴我如何解決這個問題?因爲我也想弄清楚我做錯了什麼。謝謝! – George

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是一個字符串,但看起來可能並非如此。逐行掃描您的代碼並確保實際情況如此。

+0

在我添加了錯誤的Dim語句之後,它提示(突出顯示)我有'Private Sub CommandButton2_Click()'的行,並且'last_name'突出顯示。非常奇怪的行爲,我的Sub基本上是一個按鈕,可以列出所有事情。 – George

+0

感謝您指出錯過的Dim語句! – George

5

我不知道爲什麼,但如果要將變量(作爲變量)傳遞到其他過程或函數中,則分別聲明變量非常重要。

例如,有一個程序會對數據進行某些操作:根據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 
+1

是的,這是我的問題。 VBA - 很混亂。必須是因爲它是'可訪問的'。 – Eric

+0

我失去了理智,我不敢相信我需要這個,謝謝。 –

0

東西是不對的字符串嘗試像這樣:

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