0

以下のコードはExcelシートにあります。VBA を使用して特定のセルの内容を変更し、自分の仕事に合わせて正しく書式設定しています。損傷、ベイの位置、および VIN のリストを保持しています。これらの列にはそれぞれ独自の特定の形式があり、そのうちの 2 つは問題なく動作しています。このコードの一部は、損傷コードを正しくフォーマットする方法について書いた別の投稿にあることを知っている人もいるかもしれません。列はそのように並べられています

Bay Location | VIN | Damage Code(s)

VIN については、文字を大文字にするだけです。簡単です。損傷コード機能は、ニーズに合わせて少し変更した後、完全に機能します。ここで受けた最初の助けがなければ、それはできなかったでしょう。ここで事態がおかしくなり、私の上司は、私がこれを損傷コードで機能させるのを見て、ベイを自動フォーマットするためにそれを入手するように頼んだ. 私の職場のベイの場所にはいくつかの可能性がありますが、常に少なくとも 1 つの文字が前に付いています。

  1. H-5
  2. H-125
  3. HH-50
  4. 7A-70
  5. FNCE-13

英語で、私がやりたいことはこれです: 7a12 のようなフォーマットされていないベイを入力し、文字を大文字にし、数字で分割し、2 つのグループの間にダッシュを追加すると、出来上がりです。

私はこれを機能させ、上司にも見せました。しかし、その後、VIN列を大文字にするコードを追加すると、エラーが発生し始め、行が強調表示されました

Set allMatches = RE1.Execute(strSource)

RE1.test(strSource) は正常に実行されますが、一致/サブマッチを取得しようとすると、不思議なことにエラーがスローされます。私はもともとThis StackOverflow questionのテキストを使用して機能させました。私が得るエラーは、オブジェクトが設定されていないことを教えてくれるものに似ています。私はコードが現在混乱していることを知っています.私は途中で仕事を離れなければなりませんでした.(多分私の関数に何か問題があったと思います,いいえ,元のサブ関数から直接実行されたときの同じエラー).

編集:エラーは次のとおりです

実行時エラー '91' オブジェクト変数またはブロック変数が設定されていません

そして再び、それは強調します

allMatches = RE.Execute(str)

どんな助けでも大歓迎です。

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim KeyCells As Range
    Dim str As String, result As String
    Dim RE As Object
    Dim allMatches As Object

    ' The variable KeyCells contains the cells that will
    ' cause an alert when they are changed.
    Set KeyCells = Application.Union(Range("F3:F100"), Range("C3:C100"), Range("I3:I100"))
    Set RE = CreateObject("vbscript.regexp")

    If Not TypeName(Target.Value) = "Variant()" Then

        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            ' Display a message when one of the designated cells has been
            ' changed.
            ' Place your code here.
            str = ConvertString(Target)
            If (Not str = Target.Value And Not Target.Value = "") Then
                Target.Value = str
            End If

        End If

        ' Now we have to check the bays in order to auto format
        Set KeyCells = Application.Union(Range("A3:A100"), Range("D3:D100"), Range("G3:G100"))
        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            RE.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})"
            RE.Global = True

            If Not Target.Value = "" And Not RE.test(Target.Value) Then
                    str = CStr(Target.Value)
                    RE.IgnoreCase = True
                    allMatches = RE.Execute(str)
                    MsgBox allMatches.Count

                    Target.Value = str
            End If

        End If

        Set KeyCells = Application.Union(Range("B3:B100"), Range("E3:E100"), Range("H3:H100"))

        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            RE.Pattern = "[a-z]?"
            RE.IgnoreCase = False

            If RE.test(Target.Value) Then
                Target.Value = UCase(Target.Value)
            End If

        End If
    End If
End Sub
Function FormatBay(str1 As Range) As String
    Dim result As String, strSource As String
    Dim allMatches As Object
    Dim RE1 As Object
    Set RE1 = CreateObject("vbscript.regexp")
    RE1.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})"
    RE1.Global = True
    strSource = CStr(str1.Value)
    Set allMatches = RE1.Execute(strSource)
    result = "FF-12"
    If allMatches.Count <> 0 Then
        result = allMatches.Item(0)
    End If
    MsgBox result
    FormatBay = result
End Function
Function ConvertString(str1 As Range) As String
    Dim varStr As Variant
    Dim strSource As String, strResult As String
    Dim i As Integer

    For Each varStr In Split(Trim(str1.Value), " ")

            strSource = CStr(varStr)
        If InStr(strSource, ".") = 0 Then
            strResult = strResult & _
                Mid(strSource, 1, 2) & "." & _
                Mid(strSource, 3, 2) & "." & _
                Mid(strSource, 5, 1)
            If Len(strSource) > 5 Then
                strResult = strResult & "("
                For i = 6 To Len(strSource)
                    strResult = strResult & Mid(strSource, i, 1) & ","
                Next i
                strResult = Left(strResult, Len(strResult) - 1) & ")"
            End If
            strResult = strResult & " "
        Else
            strResult = strResult & strSource & " "
        End If
    Next

    If strResult = "" Then
        ConvertString = ""
    Else
        ConvertString = Left(strResult, Len(strResult) - 1)
    End If
End Function

編集:これが私が仕事をしなければならないことです。長くておそらく冗長であることは知っていますが、VBAを学んでいるので、より良い方法を学んだら、後で誰かを助けることを期待してこの投稿を編集します.

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim KeyCells As Range
    Dim str As String, result As String
    Dim RE As Object
    Dim allMatches As Object

    ' The variable KeyCells contains the cells that will
    ' cause an alert when they are changed.
    Set KeyCells = Application.Union(Range("F3:F100"), Range("C3:C100"), Range("I3:I100"))
    Set RE = CreateObject("vbscript.regexp")

    If Not TypeName(Target.Value) = "Variant()" Then


        ' Now we have to check the bays in order to auto format
        Set KeyCells = Application.Union(Range("A3:A100"), Range("D3:D100"), Range("G3:G100"))
        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            RE.Pattern = "([0-9]?[A-Z]{1,})\-?([0-9]{1,3})"
            RE.Global = True

            If Not Target.Value = "" And Not RE.test(Target.Value) Then
                    str = CStr(Target.Value)
                    str = FormatBay(str)

                    Target.Value = str
            End If

        End If

        Set KeyCells = Application.Union(Range("B3:B100"), Range("E3:E100"), Range("H3:H100"))

        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            RE.Pattern = "[a-z]?"
            RE.IgnoreCase = False

            If RE.test(Target.Value) Then
                Target.Value = UCase(Target.Value)
            End If

        End If

        Set KeyCells = Application.Union(Range("C3:C100"), Range("F3:F100"), Range("I3:I100"))

        If Not Application.Intersect(KeyCells, Range(Target.Address)) _
            Is Nothing Then

            ' Display a message when one of the designated cells has been
            ' changed.
            ' Place your code here.
            str = ConvertString(Target)
            If (Not str = Target.Value And Not Target.Value = "") Then
                Target.Value = str
            End If

        End If

    End If
End Sub
Function FormatBay(ByVal text As String) As String

    Dim result As String, bayLetter As String, bayNumber As String
    Dim length As Integer, i As Integer
    Dim allMatches As Object
    Dim RE As Object
    Set RE = CreateObject("vbscript.regexp")

    RE.Pattern = "([0-9]?[a-z]{1,})\-?([0-9]{1,3})"
    RE.Global = True
    RE.IgnoreCase = True

    Set allMatches = RE.Execute(text)

    If Not allMatches.Count = 0 Then
        bayLocation = allMatches.Item(0).submatches.Item(0)
        bayLocation = UCase(bayLocation)
        bayNumber = allMatches.Item(0).submatches.Item(1)
        length = Len(bayNumber)

        For i = 1 To (3 - length)
            bayNumber = "0" & bayNumber
        Next
        result = bayLocation & "-" & bayNumber
    End If

    FormatBay = result

End Function
Function ConvertString(str1 As Range) As String
    Dim varStr As Variant
    Dim strSource As String, strResult As String
    Dim i As Integer

    For Each varStr In Split(Trim(str1.Value), " ")

            strSource = CStr(varStr)
        If InStr(strSource, ".") = 0 And IsNumeric(strSource) Then
            strResult = strResult & _
                Mid(strSource, 1, 2) & "." & _
                Mid(strSource, 3, 2) & "." & _
                Mid(strSource, 5, 1)
            If Len(strSource) > 5 Then
                strResult = strResult & "("
                For i = 6 To Len(strSource)
                    strResult = strResult & Mid(strSource, i, 1) & ","
                Next i
                strResult = Left(strResult, Len(strResult) - 1) & ")"
            End If
            strResult = strResult & " "
        Else
            strResult = strResult & strSource & " "
        End If
    Next

    If strResult = "" Then
        ConvertString = ""
    Else
        ConvertString = Left(strResult, Len(strResult) - 1)
    End If
End Function
4

2 に答える 2

1

allMatchesオブジェクト (Type = MatchCollection) 変数です。Setオブジェクト変数を割り当てるときは、キーワードを使用する必要があります。

Set allMatches = RE.Execute(str)

あなたのコードが現在立っているので、あなたまたは他の誰かがコードを不注意に編集して、この変数の割り当て方法を変更しない限り、このエラーを発生させずに機能することはなかったと思います.

お役に立てれば!

于 2013-11-04T01:40:57.887 に答える
0

まず、正規表現[a-z]?は常に一致します。の最初の文字がTarget.Valueたまたま小文字の場合、正規表現はそれを消費します。それ以外の場合は、最初の文字のの空の文字列に一致します。小文字の存在をテストしていますが?、文字をオプションにすることで目的を無効にします。

しかし、なぜそのテストを行う必要があるのか​​ わかりません。とにかくすべての文字を大文字に変更しますよね?したがってUCase、文字列だけで完了です。または、変換が完了するまで待ちUCaseます。

実際の変換に関しては、あなたのコードはかなり混乱していますが、不要な作業をたくさんしていると思います。7a12個別に文字列を処理している場合は、これで十分です。

RE.Pattern = "^([0-9]?[A-Z]{1,})-?([0-9]{1,3})$"
RE.IgnoreCase = True
result = UCase(RE.Replace(source, "$1-$2"))

または、何か不足していますか?

于 2013-11-04T02:10:19.473 に答える