どうも。つじけ(tsujikenzo)です。こちらのシリーズではノンプロ研VBA初級講座3期で学んだことをアウトプットしております。本日は6回目です。いよいよ最終回ですね。
Day6 セル・シート・ブックの操作
今日のアジェンダ
- セル範囲を動かす
- データの抽出
- ブックの作成と保存
- 構造化データ
です。
セルの範囲指定
Rangeオブジェクトは知れば知るほど謎なことが増えてきて嫌になっちゃう為になるけど、私の最大の謎が言語化されていて助かりました。
Rangeオブジェクトを参照するにはRangeオブジェクトを返すプロパティの戻り値を使わなければなりません。言い方を変えれば、Rangeオブジェクトを返すプロパティを経由してRangeオブジェクトを参照するという事です。下表は、Rangeオブジェクトを参照するためのプロパティです。
私の気持ちを代弁するかのごとく、ご親切に次のステップまで示されていました。まずは太字のプロパティを操作する方法を徹底して覚えることからですね。(考察はその後でもいい)
Rangeオブジェクトに、Rangeプロパティがあるあたりが、ちょっと理解しづらいかもしれません。まずは、上表の太字が使えるようになること目指してください。
ちょっと脱線しましたが、WorksheetクラスのRangeプロパティには引数でカンマ区切りでRangeオブジェクト(恐らく単体セル)を渡すと、範囲を取得できるみたい。
Worksheetオブジェクト.Range(Rangeオブジェクト1, Rangeオブジェクト2)
Offsetプロパティ
Rangeオブジェクトに対して移動することができる。(レコーディングマクロだとよく出てくる)
Rangeオブジェクト.Offset(行方向、列方向)
Rowsプロパティ、Columnsプロパティ
割と直感的に操作できそうなプロパティ
Worksheetオブジェクト.Rows(行番号)
Worksheetオブジェクト.Columns(行番号)
今私、直感的に操作できるって言いました?では貼り付け先の指定はどうですか?Rowsは行全体なので、張り付け先の指定先はA列(のどこか)を指定します。
.Rows(行番号).Copy Sheet2.Cells(‘自由に’, 1(A列指定))
Columnsは列全体なので、張り付け先の指定先は1行目(のどこか)ですね。
.Columns(列番号).Copy Sheet2.Cells(1(1行目指定), ‘自由に’)
これ、納得いかない不思議で、Rows & Columnsプロパティで取得したオブジェクトはRows & Columnsオブジェクトなんでしょうけど、行・列全体ってことはきっと要素の長さを持ってないってことでしょうかね。でも長さを持ってないクセにA列とか1行目をRangeオブジェクトで指定できるのは不思議じゃないですか?(不思議じゃない、あ、そうですか。すみません💦)
F2[オブジェクトブラウザー]でちゃんと確認しましょう。あれ?Property Rows As Range?そっか、Rows & Columnsオブジェクトなんてこの世に無いんですね。相変わらず2つのクラスにRowsプロパティがあるのは初学者の私の範疇ではないのでいちおどちらも掲載しておきます。
ノンプロ研に入会したての時にVBA板で自分のマクロを投稿して質問した時に、「処理対象が行全体になってますね。」とご指摘いただいたことを思い出しました。確かにRangeオブジェクトの最大値はXFD列1048576行だと思いますので、使わないのにその分のメモリを確保してるのは無駄ですね。
データの抽出
Do Whileの中にif文を置く(ワンライナーで書くとEnd Ifが省略できる)のが基本。貼り付け先のシートの行数指定に別のカウント変数を用意するのもテクニックです。
With Sheet1
Dim i As Long: i = 1
Dim j As Long: j = 1
Do While .Cells(i, 1).value <> ""
If .Cells(i, 2).value <= 25 Then
.Rows(i).Copy Sheet2.Cells(j, 1)
j = j + 1
End If
i = i + 1
Loop
End With
ブックの作成と保存
ブックの作成
AddメソッドはWorkbooksコレクションのメンバーです。Workbookオブジェクトのメンバーではありません。F2[オブジェクトブラウザー]で確認しましょう。
確かにありませんね。むしろ「新規Workbookを作成する」ということはExcelライブラリのApplicationクラスにありそうじゃないですか?
ないですね~。(だからWorkbooksコレクションのメンバーって言ってるでしょ💦)
ちなみにExcelライブラリでAddメソッドを検索すると沢山のAddメソッドが用意されているようです。ちゃんとクラスを確認して使用した方がバグに出会ったときなどにリカバリが早いでしょうね。ちなみにWorksheetsクラス(コレクション)にもAddメソッドがあるようですね。きっとシートを追加する時はWorksheetsコレクション.Addメソッドを使うんでしょうね(まだやったことない)。
新規ブックを作成した時は、新規ブックがアクティブなブックになるのでシートを掴む時に便利です。
ブックの保存・閉じる
Workbookオブジェクト.Save
Workbookオブジェクト.SaveAs ファイルパス
全ての引数がオプションになっていて、ブックを閉じる際にオプションでファイル形式を保存したりパスワード指定したりできるみたいです。
ブックを閉じるのはCloseメソッドです。
Workbookオブジェクト.Close
新規作成したBookをそのままwith構文のオブジェクトに指定することができて便利
Dim filePath As String: filePath = ThisWorkbook.Path & "\hoge.xlsx"
With Workbooks.Add
.Worksheets(1).Range("A1").value = "★"
.SaveAs filePath
.Close
End With
ブックを開く
Workbooksコレクション.Open ファイルパス
作成の時と同様に、開いたブックはアクティブなブックになります。OneDriveなどのクラウド上のファイルを操作する際はURLになるらしいですが、まだ使ってないので今回は覚えません💦
最終行を取得
ノンプロ研の講座を受けているのによそ様のブログを紹介してばっかりなのも憚れるのですが、どこからコピペしてきたのか、どこまで理解してるのか、今は全てオープンで語られるようになったのもノンプロ研のお陰だと思ってます。(以前ならコピペコードをさも自分の知識のごとくひけらかしていたと思います💦)
Worksheetオブジェクト.Cells(Rows.count, 1).End(xlUp).row
これは「沢山のプロパティが詰まっていて大変勉強になる」とのことです。確かに。そもそもまだ慣れない私にとってはEnd()がメソッドなのかプロパティなのかも見分けがつかないですが、しかしF2[オブジェクトブラウザー]も授業で習いましたのでもう大丈夫ですね。しかもこれ読み取り専用のプロパティですって。なんとなく分かってきましたね。
そしてまだ疑問が沢山残っていますが、私がずっと感じてた違和感は正しかったんだと思えて安心しました。
『今は、プロパティには、値の設定・取得をするものと、 オブジェクトを返すプロパティがあると言う事だけ知っておいて下さい。EndはRangeオブジェクト返すプメロパテイであるということです。』
まとめ
以上で第6回目のまとめでした。closeやsaveなどのメソッドはバリバリ使ってましたが、対象のオブジェクトがなんなのかとか意識したことがなく、基礎がわかってないままずっと使ってたんだなと改めて認識しました。また、最後の最後では「プロパティには、値の設定・取得をするものと、 オブジェクトを返すプロパティがある」という腹落ちも得まして、大変学ぶことの多かった最終回となりました。次回卒業LTでこのシリーズは終わりです。
気付けば2020年大みそかの投稿となりました。皆さん良いお年をお迎えください。来年もプログラミングライフ楽しんでいきましょう~。