見出し画像

マクロのある暮らし(6回) - 開いているワークブックへの操作

こんにちは!なるーらぼです!
なんとか続いておりますが、今回は開いているワークブックへの操作についてです。マクロを使っているとエラーが発生したときにほかの開いているブックを安全に閉じたいですよね。

今回はそうしたときにどうやって開いているワークブックを操作しようかな、ということをお話ししていきます。

別のワークブックを新規に開く

まずは基本?の新規にワークブックを開くところから行きます。新規にワークブックを開くには「Workbooks.Add」を使います。

Sub note_mu()
 With Workbooks.Add
  .Worksheets(1).Range("A1").Value = "こんにちは!"
  .Close False
 End With
End Sub

とりあえず保存しないのでCloseメソッドに「False」を渡して「保存しないで」と言ってあります。ですからこのサブルーチンを実行しても見た目上は何も起きません。

上記の例では「With~End With」を使っているので新規に開いたブックはこの中で閉じています。もっと柔軟に扱うのであれば「WorkBook」オブジェクトへアサインしておくのがよいでしょう。

Sub note_mu()
 Dim newbook As Workbook
 Set newbook = Workbooks.Add
 With newbook
  .Worksheets(1).Range("A1").Value = "こんにちは!"
  .Close False
 End With
 Set newbook = Nothing
End Sub

こうしておくとWithを使わなくてもいいですし、使ってももちろんいいです。ただ、できればオブジェクトを入れておいた変数には「Nothing」を入れておいて「もう使わない」「もういらない」とExcelへ伝えましょう。

既にある別のブックを扱う

さて、基本的なお話しを済ませたところで既存のブックを開いて操作することにしていきます。次のようなブックが2つあるとします。片方は書式が設定されているもので、だれかに提出するようなものだったとします。

まぁなんというか、よくあるアレですよね…即興でつくったのでちょっと左に寄ってますが、とりあえずいいでしょう。

もう片方はこのブックをひな形として最終的なブツを作り出すための表形式のデータだったとします。

別にここから出さなくても、請求書の方がいいんじゃないかと思い始めましたが項目数が少ない方が説明しやすいのでこれでいきたいと思います。

これからやっていくものは領収書を売上データが入ったブックからひとつずつ取り出しては領収証テンプレートブックの該当セルへセット、別名のブックとして領収番号と名前を付けたファイル名で保存していくということをしたいと思います。

ではレッツトライ。まずは2つのブックを扱うためのブックオブジェクトを用意して、あとは「もう使わない」のおまじないだけ先に書いておきます。

Sub note_mu()
 Dim soldbook As Workbook
 Dim tempbook As Workbook
 Set soldbook = Nothing
 Set tempbook = Nothing
End Sub

そんでもってですね、この間にコードを書いていきます。まずは2つのブックを開いてブックオブジェクトへ放り込みます。そしてついでに忘れないように閉じるところも書いておきましょう。
なお、これら2つのブックで保存が必要なのは領収書ブックが作成できたときにだけ「売上データ」ブックのみです。

ということでひとまず両方とも保存しない方法で閉じるコードを書いておきます。

Sub note_mu()
 Dim soldbook As Workbook
 Dim tempbook As Workbook
 Set soldbook = Workbooks.Open("")
 Set tempbook = Workbooks.Open("")
 soldbook.Close False
 tempbook.Close False
 Set soldbook = Nothing
 Set tempbook = Nothing
End Sub

おいおい、ファイル名がないじゃないですか…いえ、大丈夫ですよ。あとからつけますので。今回は領収書のひな形が「領収証ひな形.xlsx」、売上データが「売上データ.xlsx」というファイル名だったとしましょう。そして、2つのファイルともにドキュメントフォルダにおいてあって、作成した領収書もそこに保存することにしておきます。

ファイルパスなどの操作はVBA組み込みの「Dir関数」などを利用する方法とFileSystemObjectを使う方法があります。今回は横着をして組み込み関数で行きたいと思います。

まずはドキュメントフォルダですが、WindowsXPは無視しまして「Documents」というフォルダが各ユーザーフォルダにあると仮定してそうすることにします。ユーザーフォルダのパスを取り出すには環境変数「UserProfile」を使うと簡単なので、そちらから取り出して「Documents」と結合します。

しかし、ここでフォルダの区切り記号「¥」が環境変数から取り出した末尾についているかどうか不安になりませんか?でも気にしないでDocumentsの頭の方につけておいてください。なぜなら、区切りの記号は2つ以上あっても関係ないのですから!!もしも気持ち悪い…という方はFileSystemObjectのメソッドであるBuildPathメソッドを使うといい感じに仕上げてくれます。

では2つのファイルパスを作ってしまいましょう。

Sub note_mu()
 Const soldname As String = "売上データ.xlsx"
 Const tempname As String = "領収証ひな形.xlsx"
 Const mydocuments As String = "\Documents\"
 Dim userdoc As String
 Dim soldbook As Workbook
 Dim tempbook As Workbook

 userdoc = Environ("UserProfile") & mydocuments
 Set soldbook = Workbooks.Open(userdoc & soldname)
 Set tempbook = Workbooks.Open(userdoc & tempname)
 soldbook.Close False
 tempbook.Close False
 Set soldbook = Nothing
 Set tempbook = Nothing
End Sub

環境変数から値を取り出すときは組み込みの「Environ関数」を使います。どうしても文字列で取り出したいときは「Environ$関数」を使いましょう。

ここまででとりあえず開いて閉じるだけはできるようになりましたよね?かなり重厚な感じになってきましたが、まだまだですよ!次は売上データを取り出します。いきなりすべての行をさらっていくのは難しいので、まずは1行だけ行ってみましょう。

えーっと…売上データってどんなレイアウトでしたっけ?覚書にコメントを書いておくと自分がコードを書く時にも助かりますね。

セルからの値の取り出しは1回目でも見た通り、いろんなやり方がありました。今回は配列で一気に取り出してしまいますか。

'' 売上データのレイアウト
'' A:領収番号、B:名前、C:金額、D:日付、E:発行済み
Dim dataline As Variant
dataline = soldbook.Worksheets(1).Range("A2:E2")

コードが長くなってきたので抜粋してお送りします。このブックはシートが1枚のみで、そのシートにデータがあったのでこのまま配列で取り出しました。
変数「dataline」はインデックスが1から始まる2次元の配列になっていて、領収番号を取り出すには「dataline(1, 1)」とすればいいですね。

あとは同じようにひな形ブックの該当の箇所へデータを当てはめれば、ひとまず1つ目は完成します。

Sub note_mu()
 Const soldname As String = "売上データ.xlsx"
 Const tempname As String = "領収証ひな形.xlsx"
 Const mydocuments As String = "\Documents\"
 Dim userdoc As String
 Dim soldbook As Workbook
 Dim tempbook As Workbook
 userdoc = Environ("UserProfile") & mydocuments
 Set soldbook = Workbooks.Open(userdoc & soldname)
 Set tempbook = Workbooks.Open(userdoc & tempname)
 '' 売上データのレイアウト
 '' A:領収番号、B:名前、C:金額、D:日付、E:発行済み
 Dim dataline As Variant
 dataline = soldbook.Worksheets(1).Range("A2:E2")
 With tempbook.Worksheets(1)
  .Range("E2").Value = dataline(1, 1)
  .Range("C4").Value = dataline(1, 2)
  .Range("C6").Value = dataline(1, 3)
  .Range("C11").Value = Format(dataline(1, 4), "yyyy年mm月dd日")
 End With
 tempbook.SaveCopyAs userdoc & dataline(1, 1) & "_" & dataline(1, 2) & ".xlsx"
 soldbook.Close False
 tempbook.Close False
 Set soldbook = Nothing
 Set tempbook = Nothing
End Sub

ちょっと長いですが、とりあえず1つ目のデータは完成しました。

ファイル名もこの通りです。

今回は長くなってきたので、次回さらにつくりこんでいきたいと思います。また、マクロの途中でエラーが発生したときについても対処していきたいと思います。

最後に

今回はちょっとしたマクロではありますが細かくいろんなことをご覧いただきました。おさらいして終わりにしたいと思います。

・新規ブックを開くには「Workbooks.Add」を使う
・既存ブックを開くには「Workbooks.Open」を使う
・ブックを握っておきたいときは「WorkBook」オブジェクトへ放り込む
・保存せずに閉じるには「False」を渡して「Workbook.Close」を使う
・コピーを保存するには「WorkBook.SaveCopyAs」を使う
・環境変数から値を取り出すには「Environ関数」を使う
・使い終わったオブジェクトを放り込んでいた変数にはNothingを入れておく

ひとまずはこんなところでしょうか。次回は次のようなこともしていきたいですね・・・

・セルのアドレスをわかりやすくする
・複数行のデータをそれぞれファイル保存する
・エラーが起きたときに安全にブックを閉じていく

この記事が気に入ったらサポートをしてみませんか?