36

私はVBAで作業しています。stringを受け取って処理し、cleaned を返すユーザー定義関数を作成しました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 がデフォルトで参照によって変数を渡すためです。つまり、呼び出し元と呼び出し先の間でデータ型が正確に一致する必要があります。

2 つの修正:

1) ByVal を強制する -- 関数を変更して、変数 ByVal: を渡す
Public Function ProcessString(ByVal input_string As String) As Stringか、または

2) Dim varname --Dim last_name As String使用する前に呼び出し元を入力します。

(1)ByValは、正しいデータ型に変換する関数に渡すときに input_string のコピーが取得されるため、機能します。関数は呼び出し元の変数を変更できないため、プログラムの安定性も向上します。

于 2013-05-17T14:51:17.300 に答える
21

理由はわかりませんが、変数を (変数として) 他のプロシージャまたは関数に渡したい場合は、変数を個別に宣言することが非常に重要です。

たとえば、データを操作するプロシージャがあります。ID に基づいて、部品番号と数量の情報が返されます。ID は定数値、他の 2 つの引数は変数です。

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 は文字列であると述べましたが、そうではない可能性があります。コードを 1 行ずつ調べて、これが実際に当てはまることを確認します。

于 2013-05-17T14:42:07.777 に答える
3

一度に 1 文字ずつ文字列をループすることは実行可能な方法ですが、その必要はありません。VBA には、この種の関数が組み込まれています。

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