こんにちは!かいけつマクロです。記念すべき、第10講です!(何かプレゼントがあるわけではないですが。。)
さて、前回から、「ラーメン屋さんの売上げを集計しよう!」ということで、Excelマクロの恩恵を最も享受できる「ファイル操作」の学習を開始しました。
今回からは、本格的に、「ファイル操作」を勉強していきます。
それでは今回も、張り切ってまいりましょう!
売上げ情報フォルダのパスを取得する
今回は、前回作成した、「work_get_file」プロシージャの、この部分について、解説を進めていきます。
それではまず、最初の3行。こちらは、大丈夫ですかね。
'取込対象の「2021年06月.xlsx」を定義================================
Dim wb As Workbook
Dim ws As Worksheet
Dim path As String
忘れちゃったよー
という方は、Excelブック・シートの定義について、前回解説しているので、もう一度振り返ってみましょう。
文字列の結合は、「&」を使う
続いては、こちらのコマンドです。
path = b集計結果.path & "\売上げ情報"
1つ1つ見ていきましょう。まず、「=」で結ばれていますね。
・・・そう!これは、「代入」を表すコマンドです。(代入について不安な方は、第2講をご覧ください。)
そして、左側を見ると、変数「path」に代入しています。変数「path」は、上で定義している通り、「String型(文字列)」なので、右側の「b集計結果.path & “\売上げ情報”」も文字列ということがわかります。
このあたり、Excelを少し触ったことがあるだと、なんとなく馴染みがあるかもしれませんが、文字列の結合は、「&」を使って行います。
大事なことなので、もう一度。
文字列の結合は、「&」を使って行う
例えば、以下のようなコードを考えます。
Sub hello()
Dim a As String
Dim b As String
Dim c As String
a = "こんにちは!"
b = "かいけつマクロです。"
c = a & b
MsgBox c
End Sub
String型の変数a、b、cを用意して、変数cには「a & b」を代入します。
すると、実行結果はこのようになり、「&」によって、「変数aの中身」と「変数bの中身」が結合されたことがわかります。
そして、今回は、「path = b集計結果.path & “\売上げ情報”」としているので、
「b集計結果.pathの中身」と「\売上げ情報」を結合した内容が、変数「path」に代入されている、ということになります。
Excelブックのパスを取得する(Thisworkbook.path)
ただ、1つ分からないものがありますよね。。そうです、「b集計結果.path」です。
でも大丈夫!落ち着いてみて見れば、大したことはありません。
「b集計結果.path」という記述で、そのExcelファイルが存在するフォルダのことを表します。
イメージはこんな感じ。
丁寧に見ていけば、そんなに難しくないと思っていただけると思います。
別のExcelブックを操作する
さてここからは、いよいよ「売上げ情報」フォルダの下にある、月別の売上げ情報ファイルを操作していきます。
それでは見ていきましょう!
Excelブックを開く(Workbooks.Open)
まずは、この2行です。
Set wb = Workbooks.Open(path & "\" & "2021年06月.xlsx")
Set ws = wb.Worksheets(1)
「path & “\” & “2021年06月.xlsx”」という部分については、かなりの方が、
今見たばっかりじゃーん。
これならわかるよ!
と言っていただけるのではないでしょうか。そうです!
次の3つを「&」で結合しているので、「2021年06月.xlsx」ファイルのパスを表しています。
- String型の変数path
- 「\」
- 「2021年06月.xlsx」
そして、そのファイルのパスが、何やら「Workbooks.Open()」というもので囲われています。
・・・これって、なんとなく想像ついた方もいらっしゃるのではないでしょうか??
そうなんです。このコマンドで、Excelブックを開いています。
超余談ではありますが、、、
Excelマクロを使って、別のExcelブックを開けられた時って、なんかメチャクチャ感動しませんか?
私かいけつマクロは、マクロを使って初めてExcelブックを開いた時、
とっても興奮したのを、今でも覚えています
開いたExcelブックは、「Set ~ = ~」とすることで、変数wb(Workbook)に代入しています。
Workbookの代入処理、また、次のWorkSheetの代入処理については、第9講で詳しく解説しているので、こちらもぜひ、併せてご覧ください。
ただ、1つだけ見慣れないものがあると思います。それは、「wb.Worksheets(1)」
(1)ってなんだー!!!
おっ、久しぶりのご登場ですね。(頭でレンガを割る方、第3講でも登場されてました)
この(1)は、Excelブック内のシートに、左から番号を振ったときの番号のことを表しています。
今回の場合でいうと、一番左側にあるのは「Sheet1」なので、「wb.Worksheets(1)」で、「2021年06月.xlsx」ファイルの「Sheet1」ということを表しています。
Excelブックを閉じる(Workbooks.Close)
続いて、ちょっと飛ばして、一番下のこちらの処理を見ていきます。
'Excelマクロの終了後には、必ずインプットファイルを閉じる=============
wb.Close savechanges:=False
まずは、「wb.Close」。これは、ひょっとすると、何も解説なしでも大丈夫かもしれませんね。
そのまま、「変数wbの中身を、Close(閉じる)」という意味になります。
そのお隣にはこんな記述がありますね。
savechanges:=False
こちらは少し難しく感じられるかもしれませんが、なーんてことありません。
「save:保存する」「changes:変更」ということで、以下のような意味になります。
savechanges | True | ブックを閉じるときに、上書き保存する |
savechanges | False | ブックを閉じるときに、上書き保存しない(変更を破棄) |
今回は、売上げ情報ファイル=マスタファイルであり、上書きする必要ないので、「savechanges:=False」としています。
なお、「:=」という表記があまり見慣れないと思いますが、とりあえず、
そういうものもあるんだなー
くらいの軽い気持ちで、次に進んでいきましょう。(どうしても気になる方は、各自ググっていただく程度で十分と思います。)
ここで、非常に重要な補足をさせてください。
実は、このClose処理は、最悪無くても、処理自体は動きます。
ただ、以下のような良くないことが起こる可能性があり、絶対にやめたほうがいいです。
- 開いたままにして、別の処理で誤って使われると、意図しない更新がかけられてしまう恐れがある
- Excelマクロから開いたファイルの数が増えるにつれ、稼働中のアプリケーションの数も多くなり、パソコンがメチャメチャ重くなる可能性がある
そのため、
開いたファイルは、必ず閉じる
これを習慣化して、絶対に守るようにしましょう。
かいけつマクロとの約束ですよー
さて、ここまでが、ファイルのOpen、Closeについての処理になります。
次の章からは、実際に、バラバラに散らばったデータを、1か所に集める部分について、どのように実現しているか見ていきましょう!
「2021年06月.xlsx」のデータをコピーする
それでは、「2021年06月.xlsx」から、「集計結果.xlsm」の「wk_売上げ情報一覧」シートにデータをコピーしていきます。
次の章では、まず、ヘッダの情報をコピーする方法を見ていきます。
ヘッダ情報をコピーする
'「2021年06月.xlsx」から「集計情報.xlsm」へ、ヘッダをコピー--------
sWk_売上げ情報一覧.Cells(1, 1).Value = ws.Cells(1, 1).Value
sWk_売上げ情報一覧.Cells(1, 2).Value = ws.Cells(1, 2).Value
sWk_売上げ情報一覧.Cells(1, 3).Value = ws.Cells(1, 3).Value
この処理を理解するには、第9講で解説した、「インプット・アウトプットを確認する」が非常に重要になります。
・・・ということで、見てみましょう。
「インプット・アウトプット」を確認すれば、一目瞭然ですね!
明細行の情報をコピーする
次の処理では、Long型(整数)の変数i、jを定義し、jには「2」を代入しています。
Dim i As Long '「2021年06月.xlsx」の取得元の行番号
Dim j As Long '「wk_売上げ情報一覧」シートの書込み先の行番号
j = 2 '変数jを初期化
さて、ここからが、本日のメイントピック、明細行をコピーするセクションになります。
まずは、こちらのコードを書いていきます。
'「2021年06月.xlsx」から「集計情報.xlsm」へ、データをコピー--------
For i = 2 To ws.Cells(Rows.Count, 1).End(xlUp).Row
sWk_売上げ情報一覧.Cells(j, 1).Value = ws.Cells(i, 1).Value
sWk_売上げ情報一覧.Cells(j, 2).Value = ws.Cells(i, 2).Value
sWk_売上げ情報一覧.Cells(j, 3).Value = ws.Cells(i, 3).Value
j = j + 1
Next
何やら、複雑そうですが、しっかり丁寧に解説するので、一緒に頑張りましょー
それではまず、外側のこの部分を見ていきます。
For i = 2 To ws.Cells(Rows.Count, 1).End(xlUp).Row
Next
いきなりこれを理解するのは、結構大変なので、次は、さらに2つに分けて見ていきます。
指定した回数だけ、同じ処理を繰り返す(For~Next)
まずは例として、こちらのsampleプロシージャを作成し、実行してみましょう。
Sub sample()
Dim i As Long
For i = 1 To 3
MsgBox i
Next
End Sub
どうですか?次々に、こんなポップアップが上がりましたか?
これが、For文のほぼ全てです!
・・・といっても、
これだけじゃ全然わかんないよ!
と言われると思うので、もう少し具体的に見ていきましょう。まずはこちらの図をご覧ください。
【1回目のループ】
処理がForの部分まで到達すると、「i=x」の「x」の値を、iに代入します。(上のsampleだと「1」です)
今まで見てきた代入処理と、同じ「=」の使い方ですね。
続いて、「For」と「Next」の間に書かれた処理が実行されます。
今回のsampleでいうと、「MsgBox i」としているため、iの中身である「1」がポップアップで表示されました。
そして、「Next」まで到達すると、以下の処理を行います。
- iに1を加える(今回のsampleだと、i=2になります)
- Forに戻る
【2回目のループ】
さて、続けて、左側の図をご覧ください。先ほどの1回目のループでForに戻った直後、と思ってください。
まずは、「To y」の「y」と、「i」の、大小関係を比較します。
今回の場合、iが2であり、「To 3(≧ 2 )」であることから、次の処理を実行します。
ここからは、「1回目のループ」と全く同じで、
- MsgBoxでiを表示
- Nextまで行くと、iに1足して、Forに戻る
となります。
なんとなく見えてきましたかね?
うーん、よくわかんないなー
という方は、ここまでの1回目・2回目のループが非常に重要なので、ちょっと大変ですが、もう一度、1回目のループに戻りましょう。
その時、ぜひ、ゆっくり・丁寧に読んで、手を動かすようにしてみてください!
なんとなーくでもいいので、流れが掴めた方は、3回目のループに進みましょう!
【3回目のループ】
続いて、「3回目のループ」ですが、これは、2回目と全く同じです。
少し詳しく見ておくと、
- 2回目のループでForに戻った直後からスタート
- iが3であり、「To 3(≧ 3)」であることから、MsgBoxでiを表示
- Nextまで行くと、iに1足して、Forに戻る
【4回目のループ】
最後、4回目のループです。
まずは、2回目、3回目と同様、前回のループが終わった直後だと思ってください。
前回のループで、iには「4」が格納されており、「To 3(< 4)」の状態になります。
この大小関係が逆転した、というのがポイントです。
大小関係が逆転すると、次のMsgBoxは実施せず、「Next」の下までジャンプします。
この一連が、「For文(Forループ)」の全てです。
ちょっと難しくて頭こんがらがってきたー
という方も大丈夫!
こちらの「For」は、Excelマクロのプログラミングで、メチャメチャ使うので、きっと、使っているうちに自然に覚えてきます。
なので、なんとなく・ぼんやーりとでも把握できた方は、全く問題ありません!
さて、少し長くなってきたので、今回はここまでにしようと思います。
本日のまとめ
今回は、For文について、学んできました。
For文は、本当によく使うので、もし、
ちょっと不安だなーという方
や
ちょっとよくわかんなくなっちゃった
という方は、こちらのブログを、何度も見返してもらえるとよいと思います。
次回は、For文の復習を少しして、「Cells(Rows.Count, 1).End(xlUp).Row」という部分の説明をしていきたいと思います。
コメント