前回、長ーくなったモジュールを細切れにしてみたところで、動かしてみるとコンパイル・エラーが発生しました。 リーダブルコードへの旅 ~箇条書きを表にする②~ - ゆるおたノート
エラーと闘いながら、コードもちょっとだけスッキリさせてみたいと思います。
ただし、今回は「メインモジュール」以外はほぼ変えないので、そちらは省いて書きます。
コンパイルエラー
エラー文の意味
同じ適用範囲内で宣言が重複しています。
エラーメッセージによると、てやんでぃ!変数使いたいのは分かったから、何度も何度も同じことを宣言すンじゃねェ!とのことです。
文字列を選択肢としたところで、それを満たす場合の処理を都度命令していましたが、選択肢ごとに同じことを書いていたので、怒られてしまいました。
修正してみました
というわけで、変数の宣言を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 がありません。
今度はFor文のあたりが間違えているみたいです。ガックシ(古い)。
一つ潰せばまた問題が出てくる…世の中そんなモンでしょうか。
でも、これも学びのタネと思って、頑張ります。
そんなわけで、次回につづく…?
このシリーズについて
VBAの文法を勉強しながら、長~い処理をスッキリ書く方法を学んでいます。
間違い探しのほうが時間掛かってますが、果たして終わるのか…
次回をお楽しみにネ
それでは、また次の記事をお待ちくださいませ~
目指せ脱初心者。