共通機能はFunctionプロシージャに
Sub CSVデータ取り込み()
Dim buf As String
Dim v As Variant
Dim 日付 As String, 数量 As String
Dim i As Long, r As Long, c As Long
Open ThisWorkbook.Path & "\Sample.csv" For Input As #1
Do Until EOF(1)
Line Input #1, buf
v = Split(buf, ",")
r = 製品行取得(v(0))
If r <> 0 Then
For i = 1 To UBound(v)
If v(i) <> "" Then
日付 = Mid(v(i), 1, InStr(v(i), ":") - 1)
数量 = Mid(v(i), InStr(v(i), ":") + 1)
c = 日付列取得(日付)
If c <> 0 Then
Cells(r, c) = 数量
End If
End If
Next i
End If
Loop
Close #1
End Sub
Function 製品行取得(ByVal 製品 As String) As Long
Dim r As Long
For r = 6 To Cells(Rows.Count, 1).End(xlUp).Row
If Cells(r, 1) = 製品 Then
製品行取得 = r
Exit Function
End If
Next r
End Function
Function 日付列取得(ByVal 日付 As String) As Long
Dim c As Long
For c = 4 To Cells(4, Columns.Count).End(xlToLeft).Column
If Format(Cells(4, c), "yyyymmdd") = 日付 Then
日付列取得 = c
Exit Function
End If
Next c
End Function
「うん。これでいい。
製品番号の行を探す処理を製品行取得プロシージャに、
日付を探す処理を日付列取得プロシージャに、それぞれ外だししたよ。
これらのプロシージャは、引数に製品番号、日付を渡してやると、
該当する行番号、列番号を戻り値として返してくれるんだ。
これなら、他の処理からも共通機能として呼び出せるだろ?」
「う~ん!これは、いいね!
………でも製品番号や日付を見つけた後、Exit Functionで終了させているのはなぜだい?」
「こうしないと製品番号や日付が見つかった後も、最後の行、列まで繰り返し処理をしてしまうだろ?
引数の値が見つかり、行、列番号が取得できたら、それ以上の繰り返し処理は必要がない。
ここで処理を抜ければ、ムダな動作を省くことができるよ」
「…そっか、じゃあ俺が最初に作ったコードは…」
「うん、Exit Forしてないから、無駄に最後までループしているね」
星くんはがっくりとうなだれます。
まだまだ、八木くんには到底かなわないと思いました。
「ちなみに星、もしこのとき製品番号や日付が見つからなかったとき、どうなると思う?」
むむむ…。星くんは答えに詰まり、ブラッシュアップしたコードをのぞきこみました。
今回のエピソードはいかがでしたか?
第12話「フレキシブルなコードとは」に続きます
文・イラスト / 武藤 玄