読者です 読者をやめる 読者になる 読者になる

マクロができるまで

VBAの書き方

はじめに

世の中には、VBAについて書かれた、非常に為になるページがたくさんあります。

googleで検索すればわからないことはないと言ってもいいくらい。

ただ、「こうするためにはどう書けばいいのか」「こう書けばいい」ということがわかっても、正解にたどりつく過程がわかる情報に出会ったことがあまりありません。


なぜか。


理由としては108個くらいしか思いつきませんが、ひとつだけ挙げるとすれば「めんどい」からではないでしょうか。

「めんどい」を乗り越えて成し遂げる原動力は何か。

そう、情熱か打算です。


ブログを始めたてで打算情熱にあふれているうちに、自分がマクロを組み立てるまでの手順を書いてみたいと思います。


VBAでやりたいことを思いつく

普段繰り返している作業の最中に思いつくのが最高ですが、上司的な人か同僚的な人に「これ、できるよね」と投げられるのもまあ、アリでしょうか。

とりあえず、今回は下に書いたようなことを思いついて、頭の斜め上に電球がついた状態から始めることにします。

開いているExcelファイルのシートをそれぞれ1つのExcelファイルにできないかな?

そんな時ってありますよね。


実現するために、クリアすべきハードルを考える

正直、あとからどんどんハードルが増えることもありますが、最初に思いつくなら思いついたほうがいいかな、という感じです。

  1. 新しいExcelファイルを作る
  2. 新しいブックのシートに、開いていたブックのシートをコピーする
  3. コピー先のブックを保存して閉じる
  4. 開いているExcelファイルのシートの分だけ処理を繰り返す

大体、こんな感じでしょうか。


調べながらやってみる

google先生、お世話になります。

新しいExcelファイルを作る

vba 新しいExcelファイル」とでも検索しましょう。

すると、次の書き方で新しいExcelファイル(ブック)が作成できることがなんとなくわかります。

Workbooks.Add
テスト

実際に、適当なモジュールを作り、動作を確認してみます。

Sub aaa()
  Workbooks.Add
End Sub

テスト用のモジュールはあとで消すので、名前はテキトーです。

新しいブックのシートに、開いていたブックのシートをコピーする

ここに2つのExcelブックがあります。

ファイルの名前 シート
コピー元.xlsx コピー元1 コピー元2 コピー元3
Book2.xlsx Sheet1 Sheet2 Sheet3

[コピー元.xlsx]の[コピー元1]シートを[Book2.xlsx]にコピーすることを考えます。

とりあえず「vba シート 別のブックにコピー」とでも検索しましょう。

Worksheets("[シート名]").Copy After:=Worksheets("[シート名]")

これでできるかな?

テスト

ここ、単純に見えますが、実際に試すと問題がわんさか出てきます。
複数のブックを扱うため)


しかし、ここは全体の流れを重視して一旦カット。

Sub bbb()
  ThisWorkbook.Worksheets("[シート名]").Copy _
    before:=Workbooks("[コピー先ブック名]").Worksheets(1)
End Sub

なんだかんだ調べて、試してを繰り返すうちに、上の書き方にたどり着いたとして進めます。

それはまた、別の記事...

コピー先のブックを保存して閉じる

ここもなんだかんだで

Sub ccc()
  ActiveWorkbook.SaveAs Filename:="[保存先パス&ファイル名]"
  ActiveWorkbook.Close
End Sub

にたどり着いたとします。

それはまた、別の記事...

一旦、通しでやってみよう

ここまでの情報をつなぎあわせると、とりあえず一つのシートを新しいファイルにコピーすることができます。

Sub test()
  Workbooks.Add
  Workbooks("コピー元.xlsx").Worksheets(1).Copy Before:=ActiveWorkbook.Worksheets(1)
  ActiveWorkbook.SaveAs Filename:="C:\test\test.xlsx"
  ActiveWorkbook.Close
End Sub

ここに至るまでの経緯もまた以下略

それはまた、別の記事...

開いているExcelファイルのシートの分だけ処理を繰り返す

さて。

1つのシートがコピーできたなら、繰り返しのfor文を使えば一気に処理ができるはずですね。

全てのシートに対して処理していることが確認できる簡単なテストとして、全シート名を出力することを考えます。

vba シート 一覧」くらいでしょうか。

Sub ddd()
  Dim ws As Worksheet
  For Each ws In Worksheets
    Debug.Print ws.Name
  Next
End Sub

はい。できました。


イミディエイトウィンドウに

コピー元1
コピー元2
コピー元3

と表示されることを確認し、次に進みます。

とりあえず完成?

ここまで来たら、for each の中に先ほどの処理を入れてみましょう。

Sub copyAllSheets()
  Dim ws As Worksheet
  Dim wb As Workbook
  For Each ws In ThisWorkbook.Worksheets
    Set wb = Workbooks.Add
    ws.Copy before:=wb.Worksheets(1)
    wb.SaveAs Filename:=ThisWorkbook.Path & "¥" & ws.Name
    wb.Close
  Next
End Sub


はい、できました。


それはまた、別の話...

なんだか色々省いた気がしますが、また情熱が戻ったら書きたいと思います(残0)

あと、シンタックスハイライトだと円マーク(¥)が出せないことに気づきました。

なんかいい方法あるんかな...