ブックを閉じて別フォルダに移動する(Excel)
Excelブックを移動する
この時期、あちこちから集めたデータ(笑)を集約するという作業が頻発する。
この手の業務は、VBAを使って瞬殺する私にとっては痛くも痒くもない。しかしながら、職場全体で見ると、この手のアホみたいな作業に膨大な時間を費やすというのが多数派。
別に人助けというわけではないけれど、最近は進んで他人のためにコードを書いている。本業の大半がクソつまらないものなので、却ってストレス解消にもなるし。
ブックを閉じて別のフォルダへ移す
近況報告はこのぐらいにして本題。
あちこちから集めたデータ(笑)を集約する、という作業に必ずつきまとうのが、
ブックを閉じる→別のフォルダに移動する
という操作。
集まってくるExcelブックが、ろくに下処理をしていない(データの入力規則を当てたり、ブックやシートの保護をかけたり、といった処理をろくにしていない)ものなので、フルオートにするよりも、
一つ一つのブックを開いて確認するところまでは手動、集約用シートへの転記以降は自動
にする方が安全なんである。
よって、「ブックを閉じる→別のフォルダへ移動する」という操作はやたら出てくるのであった。
別にその都度書いてもそれほどメンドウでもないんだけれど、メソッド化してみたというわけ。
ブックを閉じて別フォルダに移動するメソッド
リスト1 標準モジュール
Public Function moveBook(ByVal targetBook As Workbook, _ ByVal oldFullPath As String, _ ByVal newFullPath As String, _ Optional ByVal canSaveChanges As Boolean = False) As Boolean '……(1)' On Error GoTo errorHandler Application.DisplayAlerts = False '……(2)' Call targetBook.Close(SaveChanges:=canSaveChanges) '……(3)' Name oldFullPath As newFullPath '……(4)' moveBook = True '……(5)' errorHandler: '……(6)' Application.DisplayAlerts = True If Not moveBook Then moveBook = False End Function
まず(1)の
Public Function moveBook(ByVal targetBook As Workbook, _ ByVal oldFullPath As String, _ ByVal newFullPath As String, _ Optional ByVal canSaveChanges As Boolean = False) As Boolean
で引数と返り値を設定。
第1引数targetBook
は、処理対象のWorkbook
オブジェクト。
第2引数oldFullPath
は、処理対象ブックの移動前のフルパス。
第3引数newFullPath
は、処理対象ブックの移動後のフルパス。
第4引数canSaveChanges
は、処理対象ブックを閉じるときに保存するかどうか。通常、転記処理後に上書き保存などする必要はないと思うので、省略可にして既定値をFalse
にしてある。
返り値はBoolean
型。無事ブックの移動が出来たらTrue
、失敗したらFalse
を返す。
コード自体はアホみたいに簡単なので、特に説明の必要はないと思うが、一応簡単に。
(2)の
Application.DisplayAlerts = False
で、一旦警告表示を止める。通常、転記処理では処理対象ブックに変更を加えることなどないと思うが、今回手伝った事案で処理対象ブックに加工しないと集約できない、というケースがあったのでw
次に(3)の
Call targetBook.Close(SaveChanges:=canSaveChanges)
で処理対象ブックを閉じる。
targetBook.Close SaveChanges:=canSaveChanges
でも良いと思うが、引数がハダカになるのはやっぱりキモチワルイので……。
「ママー、裸じゃイヤ!」みたいな感じです。
(4)の
Name oldFullPath As newFullPath
はおなじみName
ステートメント。
「旧フルパス」と「新フルパス」の順序がよくごっちゃになる(いや、「As」の意味を考えたら割とすぐに分かるんですけどね!)ので、メソッドの中に閉じ込めてしまったわけですよ。
そもそも、なんで「As」なんているんでしょうねえ? 「Name 目的語 補語」で「○○を××と名づける」なんだから、別にName [OldFullName], [NewFullName]
でいいと思うんですけど。
(4)が無事実行できたら(エラーにならなければ)、無事フォルダ移動が終わったということなので、(5)の
moveBook = True
で返り値をTrue
にする。
普通だったら、ここで即returnすりゃいいってもんだが、
Application.DisplayAlerts = True
を2回も書きたくないので、エラーキャッチ用のブロックである(6)からの3行を
errorHandler: Application.DisplayAlerts = True If Not moveBook Then moveBook = False
こんなふうにした。
途中でエラーが出た場合も、エラーが出なかった場合も、このブロック内を実行するようにした。
かといって、すでにブックの移動が無事に終わった場合にFalse
を返されてはたまらないので、
If Not moveBook Then moveBook = False
この時点で返り値がTrue
でない場合にのみFalse
を返すようにした。
おわりに
まあ、メリットといえば、Name
ステートメントとApplication.DisplayAlerts
まわりをラップしてメインのコードから隔離できることぐらいですけど。