ゆるおたノート

Tomorrow is another day.

リーダブルコードへの旅 ~箇条書きを表にする~ ③コンパイル・エラーとの闘い

前回、長ーくなったモジュールを細切れにしてみたところで、動かしてみるとコンパイル・エラーが発生しました。 リーダブルコードへの旅 ~箇条書きを表にする②~ - ゆるおたノート

エラーと闘いながら、コードもちょっとだけスッキリさせてみたいと思います。

ただし、今回は「メインモジュール」以外はほぼ変えないので、そちらは省いて書きます。

コンパイルエラー

エラー文の意味

同じ適用範囲内で宣言が重複しています。

エラーメッセージによると、てやんでぃ!変数使いたいのは分かったから、何度も何度も同じことを宣言すじゃねェ!とのことです。

文字列を選択肢としたところで、それを満たす場合の処理を都度命令していましたが、選択肢ごとに同じことを書いていたので、怒られてしまいました。

修正してみました

というわけで、変数の宣言を1回に省いてみます。

Private Sub searchStrings(ByRef ThisSheet As Worksheet)
    
    Dim ListRowCounts As Long
    Dim LastRow As Long
    ListRowCounts = ThisSheet.UsedRange.Rows.Count
    LastRow = ThisSheet.UsedRange.Rows(ListRowCounts).Row
    
    Dim CurrentRow As Long
    For CurrentRow = 2 To LastRow
        
        Dim ThisStr As String
        ThisStr = Cells(CurrentRow, eCol.Inputs).Value
        
        Dim SearchKey As String
        Dim hasSearchKey As Boolean
        hasSearchKey = InStr(1, ThisStr, SearchKey)
        
        Select Case SearchKey
            
            '全角コロン+全角スペース
            Case ": "
                
                If hasSearchKey = True Then
                    Dim arrSplitedStr As Variant '←ここだけ残す。
                    arrSplitedStr = Split(ThisStr, SearchKey)  
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
            '全角+半角
            Case ": "
                If hasSearchKey = True Then
                    arrSplitedStr = Split(ThisStr, SearchKey)
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
            '全角コロンだけ
            Case ":"
                If hasSearchKey = True Then
                    arrSplitedStr = Split(ThisStr, SearchKey)
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
            '半角+全角
            Case ": "
                If hasSearchKey = True Then
                    arrSplitedStr = Split(ThisStr, SearchKey)
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
            '半角+半角
            Case ": "
                If hasSearchKey = True Then
                    arrSplitedStr = Split(ThisStr, SearchKey)
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
            '半角コロンだけ
            Case ":"
                If hasSearchKey = True Then
                    arrSplitedStr = Split(ThisStr, SearchKey)
                    Call outputStrArray(arrSplitedStr, CurrentRow)
                End If
            
        End Select
    
    Next CurrentRow
        
    Call formatThisSheet
    
End Sub

またエラー…

エラー文の意味

これを実行してみると…

またコンパイル・エラー…

またコンパイル・エラーが出ました…

今度は、

変数が定義されていません。

とのこと。

「なんか当然のように知らない名前が出てきましたけど、どっかで教えてくれましたっけ?」という意味みたいです。
個人的に、よくやるミスです…

犯人探し

で、上の画像ではThisSheetがハイライト(強調)されているので、コードを上にさかのぼって確認してみると…

いた!宣言ごと他のプロシージャに切り出したんだった…

またコンパイル・エラー…

しかも、別のプロシージャではちゃんと変数を引き渡していました…
うーん、ケアレスミスということですね…

でもちゃんと警告してくれるので、うっかり人間には助かります…

修正してみました。

というわけで、ちゃんと変数の引き渡しをして、

'~前略~
    End With

    Call searchStrings(ThisSheet)

End Sub

Private Sub searchStrings(ByRef ThisSheet As Worksheet)

    Dim ListRowCounts As Long
'~後略~

もう1回F8を押して、ステップインで実行してみます。

お。今度はちゃんと最後まで動いてくれました。

一応最後まで動きました

…と思ったら、文字列の分割してくれてないじゃん!おいー!! ><
チクチク注意する割に自分の仕事は飛ばすなんて…まるで私のようだ。

でも、こういう時は、ほぼ100%指示者の命令が不明確、もしくは間違っているワケで。
手順と指示の仕方をもう少し検討する必要がありそうです。

少し整理します。

条件を枝分かれするより、選択肢を丸ごとひとつのハコに放り込んで指示を1回にしたら、処理を飛ばされる原因が見えてくるかもしれないな…?

というわけで、視点を変えて苦手な配列を使ってコードを整理してみることにしました。

Sub searchAndSplitStrings(ByRef ThisSheet As Worksheet)
    
    Dim ListRowCounts As Long
    Dim LastRow As Long
    ListRowCounts = ThisSheet.UsedRange.Rows.Count
    LastRow = ThisSheet.UsedRange.Rows(ListRowCounts).Row
    
    Dim CurrentRow As Long
    For CurrentRow = 2 To LastRow
        
        Dim arrSearchKey(1 To 6) As String
        arrSearchKey(1) = ": " '全角コロン+全角スペース
        arrSearchKey(2) = ":  " '全角コロン+半角スペース
        arrSearchKey(3) = ":"   '全角コロンだけ
        arrSearchKey(4) = ": "  '半角+全角
        arrSearchKey(5) = ": "   '半角+半角
        arrSearchKey(6) = ":"    '半角コロンだけ
        
        Dim Item As Variant
        For Each Item In arrSearchKey
        
            Dim ThisStr As String
            ThisStr = Cells(CurrentRow, eCol.Inputs).Value
            
            If hasSearchKey(ThisStr, Item) = True Then
                Dim arrSplitedStr As Variant
                arrSplitedStr = Split(ThisStr, Item)
                Call outputStrArray(arrSplitedStr, CurrentRow)
            
        Next Item
        
    Next CurrentRow
        
    Call formatThisSheet(ThisSheet)
End Sub
 
Function hasSearchKey(ByVal ThisStr As String, _
                      ByVal Item As Variant) As Boolean
                
    hasSearchKey = InStr(1, ThisStr, arrSearchKey)
    
End Function

配列に代入する部分があまり綺麗じゃないけど、だいぶスッキリしました。

ついでに、こちら↓で勉強したFunctionプロシージャも練習として使っています。
【ExcelVBA】Functionプロシージャとは?(図解付き)|もりさんのプログラミング手帳

(使い方あってるのかな…???)

結果と推測

試しに実行してみると…

Next に対する For がありません。

え、またコンパイルエラー…

Next に対する For がありません。

今度はFor文のあたりが間違えているみたいです。ガックシ(古い)。

一つ潰せばまた問題が出てくる…世の中そんなモンでしょうか。
でも、これも学びのタネと思って、頑張ります。

そんなわけで、次回につづく…?

このシリーズについて

VBAの文法を勉強しながら、長~い処理をスッキリ書く方法を学んでいます。
間違い探しのほうが時間掛かってますが、果たして終わるのか…

次回をお楽しみにネ

それでは、また次の記事をお待ちくださいませ~
目指せ脱初心者。

連載目次

  1. リーダブルコードへの旅 ~箇条書きを表にする①~ - ゆるおたノート
  2. リーダブルコードへの旅 ~箇条書きを表にする②~ - ゆるおたノート
  3. 当記事リーダブルコードへの旅 ~箇条書きを表にする③~ - ゆるおたノート