ゆるおたノート

Tomorrow is another day.

リーダブルコードへの旅 ~箇条書きを表にする③~

前回、長ーくなったモジュールを細切れにしてみたところで、
動かしてみるとコンパイル・エラーが発生しました。 yuru-wota.hateblo.jp

こちらと闘いながら、ここももうちょっとスッキリさせてみたいと思います。
今回は「メインモジュール」以外はほぼ変えないので、そちらは省いて書きます。

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

エラーメッセージによると、てやんでぃ!分かったから何度も何度も(型を)宣言すンじゃねェ!とのことです。

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

というわけで、変数の宣言を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

修正してみました。

これを実行してみると…
f:id:yuricks7:20180602135156p:plain

今度は、その先で変数が定義されていませんと出ました…

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

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

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

いた!
f:id:yuricks7:20180602140019p:plain

しかも上のプロシージャではちゃんと伝言(変数を引き渡し)している…
うーん、ケアレスミスということですね…

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

修正してみました。

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

'~前略~
    End With

    Call searchStrings(ThisSheet)

End Sub

Private Sub searchStrings(ByRef ThisSheet As Worksheet)

    Dim ListRowCounts As Long
'~後略~

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

お。今度はちゃんと最後まで動いてくれました。
f:id:yuricks7:20180602141554p:plain

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

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

少し整理します。

条件を枝分かれするより、選択肢を丸ごとひとつのハコに放り込んで、
指示を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プロシージャも、練習のために使ってみる。 moripro.net

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

結果と考察

試しに実行してみると…
f:id:yuricks7:20180602163802p:plain

今度はFor文が間違えているみたいです。ガックシ…(古い)
一つ潰せばまた問題が出てくる…世の中そんなモンでしょうか。

でも、これも学びのタネと思って、頑張ります。

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