【第10講】パス取得、別ブックの操作、Forループ(ラーメン屋さんの売上げを集計しよう!②)

Forループイメージ
スポンサーリンク

こんにちは!かいけつマクロです。記念すべき、第10講です!(何かプレゼントがあるわけではないですが。。)

さて、前回から、「ラーメン屋さんの売上げを集計しよう!」ということで、Excelマクロの恩恵を最も享受できる「ファイル操作」の学習を開始しました。

今回からは、本格的に、「ファイル操作」を勉強していきます。

それでは今回も、張り切ってまいりましょう!

スポンサーリンク

売上げ情報フォルダのパスを取得する

今回は、前回作成した、「work_get_file」プロシージャの、この部分について、解説を進めていきます。

「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の中身」が結合されたことがわかります。

「変数aの中身」と「変数bの中身」を結合した内容が出力される

そして、今回は、「path = b集計結果.path & “\売上げ情報”」としているので、

「b集計結果.pathの中身」と「\売上げ情報」を結合した内容が、変数「path」に代入されている、ということになります。

Excelブックのパスを取得する(Thisworkbook.path)

ただ、1つ分からないものがありますよね。。そうです、「b集計結果.path」です。

でも大丈夫!落ち着いてみて見れば、大したことはありません。

「b集計結果.path」という記述で、そのExcelファイルが存在するフォルダのことを表します。

イメージはこんな感じ。

Thisworkbook.pathのイメージ

丁寧に見ていけば、そんなに難しくないと思っていただけると思います。

別の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」ということを表しています。

「wb.Worksheets(1)」は、「2021年06月.xlsx」ファイルの「Sheet1」を表す

Excelブックを閉じる(Workbooks.Close)

続いて、ちょっと飛ばして、一番下のこちらの処理を見ていきます。

'Excelマクロの終了後には、必ずインプットファイルを閉じる=============
wb.Close savechanges:=False

まずは、「wb.Close」。これは、ひょっとすると、何も解説なしでも大丈夫かもしれませんね。

そのまま、「変数wbの中身を、Close(閉じる)」という意味になります。

そのお隣にはこんな記述がありますね。

savechanges:=False

こちらは少し難しく感じられるかもしれませんが、なーんてことありません。

「save:保存する」「changes:変更」ということで、以下のような意味になります。

savechangesTrueブックを閉じるときに、上書き保存する
savechangesFalseブックを閉じるときに、上書き保存しない(変更を破棄)

今回は、売上げ情報ファイル=マスタファイルであり、上書きする必要ないので、「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ループ

何やら、複雑そうですが、しっかり丁寧に解説するので、一緒に頑張りましょー

それではまず、外側のこの部分を見ていきます。

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
sampleプロシージャ

どうですか?次々に、こんなポップアップが上がりましたか?

これが、For文のほぼ全てです!

・・・といっても、

これだけじゃ全然わかんないよ!

と言われると思うので、もう少し具体的に見ていきましょう。まずはこちらの図をご覧ください。

1・2回目のループ

【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・4回目のループ

続いて、「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」という部分の説明をしていきたいと思います。

本日の学びポイント
  • 文字列の結合は、「&」を使う
  • 「ThisWorkbook.path」で、そのExcelファイルが存在するフォルダを取得できる
  • カレントディレクトリは、何もしなければ、「Excelマクロの実行ファイルの格納場所」
  • 「Workbooks.Open」でファイルを開く、「Workbooks.Close」でファイルを閉じる
  • 開いたファイルは、必ず閉じる(超重要)
  • 「Worksheets(1)」で、左から1番目のシートを表す
  • 「For文」は、大小関係が逆転したタイミングがポイント(超重要)

コメント

タイトルとURLをコピーしました