2013-05-17 32 views
12

Tôi đang làm việc với VBA. Tôi đã viết một hàm xác định người dùng cần có một string, xử lý nó và trả về một string được làm sạch. Tôi không chắc điều gì sai với nó. Tôi không thể gọi nó và yêu cầu nó xử lý chuỗi của tôi và trả lại nó. Tôi nghĩ rằng có một sai lầm trong cách tôi xác định hoặc trả lại nó.Loại đối số ByRef không khớp trong Excel 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 

Và tôi sử dụng chức năng này như

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

tên cuối này là một biến chuỗi, thường trông giống như Lastname***** này, và tôi đang cố gắng để loại bỏ tất cả các ngôi sao đằng sau nó. Trả lại Lastname mà không cần sao.

Tôi đã nhận được Compile error: ByRef arugment type mismatch khi tôi cố gắng chạy ứng dụng này. Tôi đang sử dụng Windows XP với Office 2003.

EDIT: Tôi đã thêm cấu trúc cơ bản của mã tôi có, tôi có khoảng 20 dòng mã tương tự. Làm điều tương tự cho từng lĩnh vực tôi cần.

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

Trên dòng nào, công cụ xóa r cờ? – Gaffi

+0

Nó chạy trên đường khi tôi gọi nó. 'Worksheets (data_sheet) .Range (" C2 ") Giá trị = ProcessString (last_name)' – George

Trả lời

29

Tôi nghi ngờ bạn chưa thiết lập last_name đúng cách trong người gọi.

Với tuyên bố Worksheets(data_sheet).Range("C2").Value = ProcessString(last_name)

này sẽ chỉ làm việc nếu last_name là một chuỗi, ví dụ:

Dim last_name as String 

xuất hiện trong người gọi nơi nào đó.

Lý do cho điều này là VBA chuyển các biến theo tham chiếu theo mặc định có nghĩa là các kiểu dữ liệu phải khớp chính xác giữa người gọi và callee.

Hai sửa:

1) Thay đổi chức năng của bạn để Public Function ProcessString(ByVal input_string As String) As String

2) đặt Dim last_name As String trong người gọi trước khi bạn sử dụng nó.

(1) hoạt động vì đối với ByVal, một bản sao của input_string được thực hiện khi chuyển đến hàm sẽ ép nó vào đúng loại dữ liệu. Nó cũng dẫn đến sự ổn định chương trình tốt hơn vì hàm không thể sửa đổi biến trong người gọi.

+0

Cảm ơn bạn! Thêm 'ByVal' đã khắc phục được sự cố, bây giờ mã chạy tốt! – George

+1

Tôi luôn khai báo tất cả các hàm VBA của mình với ByVal vì nó cải thiện sự ổn định. Với Java bạn không có sự lựa chọn, mọi thứ đều được truyền theo giá trị. – Bathsheba

2

Trong khi lặp qua từng chuỗi một ký tự cùng một lúc là phương pháp khả thi, không cần thiết. VBA đã được xây dựng trong các chức năng cho các loại hình điều:

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

Đó là một giải pháp thực sự tốt. Nhưng bạn có thể vui lòng chỉ cho tôi cách khắc phục sự cố không? Bởi vì tôi cũng đang cố gắng tìm ra những gì tôi đã làm sai. Cảm ơn bạn! – George

3

tôi đã thay đổi một số điều cần làm việc với Option Explicit, và mã chạy tốt chống lại một ô chứa "abc.123", mà trở "abc.12,". Không có lỗi biên dịch.

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 

Tôi sẽ đề nghị bạn đăng nhiều mã liên quan hơn (gọi hàm này). Bạn đã tuyên bố rằng last_name là một String, nhưng có vẻ như đó không phải là trường hợp. Bước qua dòng mã của bạn bằng dòng và đảm bảo rằng đây thực sự là trường hợp.

+0

Sau khi tôi thêm câu lệnh Dim bị bỏ lỡ, nó nhắc (đánh dấu) dòng nơi tôi có 'Private Sub CommandButton2_Click()', và cả 'last_name' được tô đậm. Hành vi rất lạ, Sub của tôi về cơ bản là một buttom làm một danh sách những thứ. – George

+0

Cảm ơn bạn đã chỉ ra câu lệnh Dim bị bỏ lỡ! – George

5

Tôi không biết tại sao, nhưng nó rất quan trọng để khai báo các biến riêng biệt nếu bạn muốn chuyển các biến (như biến) vào thủ tục hoặc hàm khác.

Ví dụ: có quy trình thực hiện thao tác với dữ liệu: dựa trên ID trả về thông tin về Số lượng và Số lượng. ID là giá trị không đổi, hai đối số khác là các biến.

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

mã chính tiếp theo mang lại cho tôi một "ByRef luận không phù hợp":

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

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

End sub 

và người tiếp theo đang làm việc cũng như:

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

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

End sub 
+1

Vâng, đây là vấn đề của tôi. VBA - rất khó hiểu. Phải vì nó là 'có thể truy cập'. – Eric

+0

Tôi đã mất trí, tôi không thể tin rằng tôi cần điều này, cảm ơn bạn. –

0

Cái gì là sai với điều đó chuỗi thử như thế này:

Worksheets(data_sheet).Range("C2").Value = ProcessString(CStr(last_name)) 
Các vấn đề liên quan