記事を書こうと思ったきっかけ
引き出しに眠っていたUSBメモリに生まれて初めて書いたコードが入っていたので、
当時のコードにダメ出しして修正して成長を確認してみたいと思います。
5年前の私のスペック
・工場の機械オペレーター 特別なスキルなし 20代半ば
・実務でPCを殆ど触ったことがない
・もちろんプログラミングに触れるのも初めて
・ExcelはIF関数も書式の概念も分かってない。
もう本当にまっさらな状態です。果たしてこんなハナタレ小僧が書いた初めてのプログラムはどんなものでしょうか?
当時実現したかった処理
当時勤めていた会社(製造業)の機械の実績集計を業務システムから抽出して
どの機械がどれだけのストロークを行ったか、手作業で足し算して(SUMIF関数も知らなかった)
実績集計ファイルにコピペする業務がありました。
集計する頻度は毎日で、1回の集計作業が20分くらいだったかな。
その間機械の面倒も見なければいけなかったので
PCの前にずっと居て機械のアラームを無視したりしてるとサボってる扱いされるような環境でした。
でもある日、データ処理を自動化できるマクロというものがあるのを知ります。
これが本を読んでもどうにも理解できません。
で?これって目の前の実務に対してどうやって応用すればいいの?とか思いながらパラ読みしてました。
結局本では問題解決にならなかったので、ネットで検索→コピペ→エラー→ネット検索のループをしながら
休み時間になったら即PCに向かってコードを書き、分からないところはYahoo知恵袋で質問し、
ヒィヒィ言いながら3週間くらいかけて完成したコードがこちらです。
改行もインデントも当時書いたそのままのものを乗せています。(ファイル名等はぼかしています。)
ただ長いだけなので読み飛ばして貰って全然構いません。むしろ恥ずかしいので飛ばして欲しい。
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'2016/2/10作成
Sub あああ()
Dim UN As Range
Set UN = Range("e45")
Call searchBook
Application.DisplayAlerts = False
Workbooks("機械実績(" & UN & "月).xlsx").Save
Workbooks("機械実績(" & UN & "月).xlsx").Close
Application.DisplayAlerts = True
Application.DisplayAlerts = False
Workbooks("機械入力システム(マクロ有効).xlsm").Close
Application.DisplayAlerts = True
End Sub
Sub searchBook()
For Each 須藤 In Workbooks
If (須藤.Name Like "HKD*.csv") Then
'searchBook = 須藤.Name
Exit For
End If
Next
Dim い As Range
Set い = Range("e45")
Windows(須藤.Name).Activate
Range("A1:N150").Select
Selection.Copy
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("H").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Sheets("入力フォーム").Select
Range("A1").Select
Dim あ As Range
Dim う As Range
Set あ = Range("e39")
Set う = Range("e40")
Range("d8:o8").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("CR").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d11:i11").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("CR").Select
Range("c" & う).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d15:s15").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("RS").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d19:o19").Select
Selection.Copy
Windows("新選別出来高表(" & い & "月).xlsx").Activate
Sheets("M").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d23:i23").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("R").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d27:q27").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("G").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("d31:q31").Select
Selection.Copy
Windows("機械実績(" & い & "月).xlsx").Activate
Sheets("DL").Select
Range("c" & あ).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Windows("機械入力システム(マクロ有効).xlsm").Activate
Sheets("入力フォーム").Select
Range("a1").Select
Application.DisplayAlerts = False
Workbooks(須藤.Name).Close
Application.DisplayAlerts = True
Application.Quit
End Sub
。。。なんだこの目を覆いたくなるようなクソコードは(;´Д`)
典型的なとりあえず動けばいいや的なコピペコードの連投ですね。
しかしこれだけ汚いコードでもシーケンスとしては立派に成立しており、当時実務で大活躍してましたから世の中分からないものです。
このコードを書いた数年後に転職しましたが、驚くことに当時の先輩にたまたま合って聞いたところ、
5年経った今でもこのプログラムは毎日動いているそうです。
5年後の私が過去の自分にダメ出し
「初っ端にSleep関数を使おうとしてるけど、Sleep関数どこにも使ってないよね?使ってないなら消そうぜ?
というか業務PCなのに32ビットExcelで動いてたんかい!そっちの方が驚きだわ」
「インデント付けようぜ!改行も規則性ないからある程度統一しようぜ!」
「コメントが無え!修正を想定していないポイ捨てのようなコードだ」
「纏められるところはWithとかで纏めようぜ」
「Select無駄に使い過ぎ」
「Exit Forで抜けた後に残されたループ変数をそのまま使い続けるって発想は逆になかったわ。」
「というかなんで変数名があ、とかう、とか自分の名前とか使ってんの」
・・・しょうがねえ。5年後の俺がこのコードを書き直してやるぜ。
書き直すだけだから10分もかからなかったぜ。
Option Explicit
'2021/2/23編集
'-----------------------集計転記処理メインモジュール--------------------------
Sub DataMoveMain()
'-------------------------------------------------
Dim csvbook As Workbook, copybook As Workbook, pastebook As Workbook
Dim copySheet as Worksheet
Dim copyR As Range, pasteR As Range
Dim maxRow As Long, maxCol As Long
Dim pasteBookName as String
Dim tarCellRow as Integer, tarCellRow2 as Integer
pasteBookName = Month(Now)'実績入力ファイルのブック名
'-----------------------オブジェクトの定義--------------------------
Set csvbook = Windows(searchBook("HKD*.csv"))
Set copybook = Windows("機械入力システム(マクロ有効).xlsm")
Set copySheet = copybook.Worksheets("入力フォーム")
Set pastebook = Windows("機械実績(pasteBookName).xlsx")
'-----------------------csvファイルをコピペ--------------------------
With csvbook
.Activate
maxRow = .Cells(Rows.Count, 1).End(xlUp).Row
maxCol = .Cells(1, Columns.Count).End(xlToLeft).Column
.Range(Range("A1"), Cells(maxCol, maxRow)).Copy
End With
With copybook
.Activate
.Sheets("H").PasteSpecial Paste:=xlPasteValues
copySheet.Range("A1").Select
End With
'-----------------------実績データのコピペ--------------------------
tarCellRow = copySheet.Range("E39")
tarCellRow2 = copySheet.Range("E40")
Call CopyPaste(pastebook.Worksheets("CR").Range("C" & tarCellRow), copySheet.Range("D8:O8"))
Call CopyPaste(pastebook.Worksheets("G").Range("C" & tarCellRow2), copySheet.Range("D11:I11"))
Call CopyPaste(pastebook.Worksheets("RS").Range("C" & tarCellRow), copySheet.Range("D15:S15"))
Call CopyPaste(pastebook.Worksheets("M").Range("C" & tarCellRow), copySheet.Range("D19:O19"))
Call CopyPaste(pastebook.Worksheets("R").Range("C" & tarCellRow), copySheet.Range("D23:I23"))
Call CopyPaste(pastebook.Worksheets("DL").Range("C" & tarCellRow), copySheet.Range("D27:Q27"))
'-----------------------転記終了後にブックを閉じる--------------------------
Application.DisplayAlerts = False
pastebook.Save
pastebook.Close
copybook.Close
csvbook.Close
Application.DisplayAlerts = True
'-----------------------アプリケーション終了--------------------------
Application.Quit
End Sub
'-----------------------指定の文字列を含むブックの名前を返す関数--------------------------
Function searchBook(searchword as String) As String
For Each wb In Workbooks
If (wb.Name Like searchword) Then
searchBook = wb.Name
Exit For
End If
Next
End Function
'-----------------------コピペするメソッド--------------------------
Sub CopyPaste(copyR As Range, pasteR As Range)
copyR.Copy
pasteR.PasteSpecial Paste:=xlPasteValues
End Sub
どうでしょうか。かなりすっきりしましたね。
もう抽出されたCSVデータと転記先のファイルがないのでテストは出来ませんが、止まったとしてもすぐ修正出来るでしょう。
コピペ元のフォーマットは特に制約はなかったはずなので、フォーマットそのものを作り変えれば
もっと短いコードになると思います。
結局何が言いたかったか
初心者の頃は、みんなこんな感じ
コードの綺麗さなんかよりも、とにかく目の前の処理を自動化する為に、調べまくって闇雲にコピペして動かした結果、
なんとか動くものができたぞ!やったね!
・・・という軌跡を辿ったわけですが、これはこれでプログラミングを習得する最初の足掛かりとしてとても良かったのではと思います。
でも当時の私が前述のような突っ込みが入ったとしても何言ってんのか理解できなかったでしょう。
当時の私にとっては転記処理が問題なく出来ればOKなので、コードの綺麗さとか処理の内容なんか理解する気もなかったと思います。
あれから5年経ちましたが、過去と今と根本的に違う所は、処理の完成形やシーケンスの流れが全くイメージできていなかった所です。
闇雲に手あたり次第コピペしたコードと、完成形をイメージしながらどの手段を使った方が効率的か探索しながら
コードを組むのとでは、ここまで差が出ます。
コードを書くのも経験が大事、ということですね。
とりあえず分からなければとりあえず作って動かすことの大切さを再認識した今日この頃でした。
この記事を見た独学でプログラミングを学び始めた方が「なんだ、こんな感じでいいんだ」と思って
モチベーションを上げてくれることを祈っています。