Open11

ExcelVBAの学習

とかげとかげ

やっぱりこいつ使えた方が絶対良い(悲しい)
つまらないからって勉強してなかったから半日くらい無駄にした
つまらないけどちょっとくらいやってみよう…概念の理解が不便なんだよな…本の方が良いと思いつつ

https://excel-ubara.com/excelvba1/

型とかどこにどいつが属してるのかの把握がしづらくて苦手なんだよな。インテリも不親切だし…

とかげとかげ

Alt F11 エディターの起動
Alt I M マクロVBAを書く標準モジュールの挿入
標準モジュールの削除というのはなく、「解放」を選択することで削除(?)ができる
ツール>オプション>自動構文チェックを外し、変数の宣言を強制する
「Sub xxx ~ End Sub」これがひとつのマクロで、プロシージャと呼ぶ

プロシージャの中にカーソルがある状態で、F5を押すと実行できる
もちろんボタン等に紐づけることもできる
セルの指定:Range("A1")、Range("A1:C5")、Range("A:C")、Range("1:3")、Range("定義されたセル名")
ExcelのセルはRangeオブジェクトであると…

Cells(行番号,列番号)を使う場合
セル番号はどちらも1始まりで、行番号が縦、列番号が横(通常アルファベット表示のやつ)
Rows(行番号)、Columns(列番号)で行全体、列全体を選択可能

だいたいの型はLong(Integerは3万ちょいしか扱えないので)、Double、String、Date、Booleanあたりかな~
Dim xxx As Long
定数は「Const yyy As String = ”定数”」みたいな感じ
型宣言文字というのもあって、「Dim xxx&」とか「Const yyy$ = "定数"」とかそんな感じ。
日付の場合は「Dim day As Date = #2024/10/01#」のように指定する必要がある。

ここまで第13回の内容完了!

とかげとかげ

文字列結合は「&」を使う。「+」は数値が混ざるとよろしくないので。
1つの処理を複数行に分けて書く場合はアンダーバーで連結できる。昔のVB.NETと同じ。
割り算は「/」割り算の商は「\」割り算の余りは「Mod」べき乗は「^」
コメントはシングルコーテーション。

繰り返し処理はこう。

For i = 1 To 10 Step 2
    Cells(1, i).Value = i + 1
Next

Stepは不要な時は省略可。カウンター変数は事前に宣言してなくても使える。
「Next i」は「Next」でOK、書くものなのかと思ったが、
どっちでもいいらしいので省略かな。
途中で抜けたい場合はExit Forで。

If i = 5 Then
 Exit For
End If

他、DoLoopの場合。

Do While i < 10
    '何かする
    i = i + 1
Loop

「Loop While 条件」でも良いし、
Whileは「Until」とも書けるがまあWhileでいいでしょ
あとはExit Doで抜けられるくらいか。

簡単なとこしかやらなかったが…17回までOK
18回くらいからそれっぽくなってきそうだな。
業務でVBAぱっと書けるほうが効率的なのでぱぱっと物にしたいな。

とかげとかげ

セルの最終行を求める
・Cells(1,1).End(xlDown):Ctrl+↓と同じ。最後のセルを取得するが、途中で空欄があるとそこまでしか取得できない
・Cells(Rows.Count, 1).End(xlUp):Excelの最終行を取得した後でCtrl+↑の操作で最後のセルを取得する。
Rows.Countはシートの行数。
EndはRangeオブジェクトのプロパティで、Rangeオブジェクトを返す。引数はDirectionらしい。
Direction:上下は上記の通り。右左はxlToRight,xlToLeft
今日はちょっと無理!18回の途中で終わり…

とかげとかげ

まとめたはいいが…みたいなところあるな。でもこのサイト練習問題も載ってるし、ある程度やったら問題を解いて少しでも感覚を掴めるといいな。目標。18回の続きから少しだけ。

少し復習メモだけど、ExcelのセルはRangeオブジェクトなのね。ふむ。
で、プログラム的にはCells(1,1)の指定の方がよく使いそう。
ExcelVBAのドキュメントがあるならそれ見たいんだけど今までどうやって探せばいいかわからなかったな 多分ご親切なサイトが先に出てくるので辿り着けてなかった 自分もそれ以上突っ込んで探さなかったし
https://learn.microsoft.com/ja-jp/office/vba/api/overview/excel/object-model
普通にありましたね。これは使えるっ

さて続き。
Endプロパティで取得したRangeオブジェクトはセルそのものであり、セルの値が取得されるらしい。
最後のセルの行数を取得するためには、RangeオブジェクトのRowプロパティを使う。
(これがややこしかった気がするな……Rowsとは違うわけね)
で、Direction指定については、セル自体が非表示になっている場合、非表示セルは無視されるとのこと。
非表示セルを含めた取得の方法もあるらしいが、まあそちらは必要になってからでいいかな。

って19回は総合演習問題だ。簡単そうだしつまらないからってすっ飛ばしてきたけど、なめてかかってないでちゃんと取り組んでみようかな。

    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
        Cells(i, 3).Value = Cells(i, 1).Value * Cells(i, 2).Value
    Next

ということで楽々クリア!文法にも引っかからず単価数量の計算OKです。えらい!
さすがに20回は飛ばしていいかな。21回もElseIfなので、文法メモだけ。

IfThen
ElseIfThen
Else
End If

ElseIfくっつけるタイプ。ElseはThen要らない(これは他のもそうだったような気もするが)…この辺はちょいちょいミスりそうだけど。
では次回は22回から!

とかげとかげ

22回

Select Case 変数
    Case 1 To 2
        '処理1
    Case 3, 5
        '処理2
    Case Is >= 10
        '処理3
    Case Else
        '処理4
End Select
Select Case True
    Case 条件式1
        '処理1
    Case 条件式2
        '処理2
    Case Else
        '処理3
End Select

ふも。23回はMsgBox。返り値は列挙体。Integerの変数で受け取りが可能。
表示するボタンの種類やアイコンは2つ目の引数に加算の形で渡していくとのこと。
ビットフラグみたいな管理してるのかな。
ちょっと適当に済ませてしまったが、まあ、これはあまり使わないだろう。次は24回。

とかげとかげ

24回:InputBox:ユーザー入力の受付…もしないな。
25回:名前付き引数:「:=」で指定することが可能ということだけ触れておけば良いか。
練習問題だ!RangeとCellsを何故か逆で覚えてしまった。Rangeオブジェクトとは言うが、プログラミングするときはほぼCellsしか使わないので、Range関数のことは忘れたらどうか??はい。
ということでできた。出力箇所は適当。入力受付やメッセージ表示は使わないので、前回とほぼ変わらず。

Sub func1()
    Dim sum As Long
    For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
        If Cells(i, 1).Value >= Cells(13, 4).Value Then
            sum = sum + Cells(i, 1).Value
        End If
    Next
    If sum > 0 Then
        Cells(14, 4).Value = sum
    End If
End Sub

でもやっぱり空で書くのは大事。こういう勘違いが積み重なってVBA嫌いやわ~になるので…。エラーメッセージも不親切すぎてぱっとわからないのもしんどいね。
普段IDEに頼り切りなのできつい
明日から大事なところ!27回から~

とかげとかげ

仕事の資料作りで間が空いたで!(最近推しVの配信よく見てるから関西弁が移った)
27回から。

ここまでのVBAはあくまでアクティブブックのアクティブシートを対象としてきた。
これを切り替えることで、別のブック、別のシートの操作を行うことが可能。
アクティブである対象は常に一つ。複数シートを選択することはできるが、メインで選択されているシートがひとつであるように。
ActiveWorkbook, ActiveSheetがそれぞれアクティブなブックとシートを指定している。

指定したオブジェクトをアクティブにする場合、以下のように記載する。
Workbooks("ブック名").Activate
・ブックには拡張子も指定する必要がある。
Sheets("シート名").Activate
Sheets(インデックス).Activate
・インデックスは一番左のシートを1とした時の番号
・Activateの他にSelect(選択)という指定もあるが、複数選択した場合の挙動が異なるため、今はSelectについてはいいかな。
・WorksheetsとSheetsも違うようだが、特殊なシートを使わない限りは特に気にすることはない。今は特殊なシートを使うことはないので、これも今はいいかな

複数のシートに同じ処理をする場合も、複数選択ではなく、ループで対応可能なので、今は上記くらいで良いのではないか。
28回はセルの選択等について書いてあるが、あんまり使わないだろうし使わない方が良いものも紹介しているのでここも良いかな。
ちなみにSelectとActivateはメソッド。次は29回から。

とかげとかげ

・削除、挿入について
これもそんな使わない気がするから軽くでいいかな
Cells().Delete:セルを削除する時、左/上方向にシフト、行/列全体などの指定がある。
Cells().Delete Shift := xlToLeft (xlUp)
Cells().EntireColumn.Delete(EntireRow)
挿入の場合はDelete>Insertにする。挿入の場合はシフト方向が右/下方向になるのでDirection指定も変わるよ。
行列全体の削除挿入はRows(1).Delete/Columns(1).Insertの方が楽そう。

総合練習問題3!行の最後から削除していく。デバッグで見ると最初に実行したときに行の最後が取得できていないように見えた(ループ変数の初期値が1)が、Step-1の記述が足りないだけだった。

    Dim sum As Long
    For i = Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1
        If i Mod 2 = 0 Then
            Rows(i).Delete
        End If
    Next
    Rows(1).Insert
    Columns(1).Insert

休日の朝、いいか?がんばれるか?とりあえずでVBAやってるし業務に役立つからいいけど、これが終わってから転職にも役立つような技術を身につけたいな…
でも絶対デザインパターンとかさ…その方がさ…えーわからん!!

とかげとかげ

あ~~~わりとこの辺いいかもな。今日あんまり時間ないし、内容ざっとさらって…でいいかな。
31回からセルの書式、表示形式の話をしている。書式はRangeオブジェクトのNumberFormatLocalのプロパティにセットして設定する。
……が、やはり書式は基本的にセルの設定であらかじめやっておいた方が良いとのことなので、これもすっとばして大丈夫かな。
基本的な書式の設定方法が以下に載っているので、一応リンクを。

https://excel-ubara.com/excelvba1/EXCELVBA331.html

普段セルの内容を取得するときはValueプロパティを使用するが、書式を設定された(表示通りの)値を取得する場合はTextプロパティを使用する。
ふむ。総合演習問題4までは、色や罫線などの話のようなので、飛ばしても大丈夫でしょ。Alignment,Font,Interior(塗りつぶし)、Border(罫線)をマクロでいじることはあんまりないかと。

第37回はシート指定。Workbooks("ブック名"),Worksheets("シート名").Range("セル番地")でアクティブでないブックやシートのセルを操作できる。(もちろん同じブックならWorkbooksの指定は不要)

あー……なるほど。マクロを使うときは、自分で使う分にはいいけど、シートの指定は最初にしておいた方が良いとのこと。誰が使うかわからないようなマクロだと、必ず操作対象のシートがアクティブになっているとは限らないってことか。おk
次は38回から!…と思ったけど、38回目のページがない。ので、39回から。

https://excel-ubara.com/excelvba1/EXCELVBA339.html

とかげとかげ

第39回
Clear():セルの内容を削除。書式など含めて、初期状態に戻す。RowやColumnなど、行列全体のClearも可能。Rangeオブジェクトのメソッドってことかと思う
ClearContentsなど、削除方法は他にいろいろあるが、あんまり使うことないかな。
Copy,Cut,Pasteや形式を選択して貼り付けなどもある。単純にはできないということだけ覚えておくか。
この辺り仕事では使うことないなぁ~。そろそろ終わりかな。と思ったけど、第42回がちょっと良さげな話題かも。

セルはRangeオブジェクトであり、オブジェクトそのものをコピーすることはできない。
オブジェクトのプロパティの値をコピーしている…ああなるほどね!?
値の貼り付けだったら、RangeオブジェクトのValueプロパティをコピーしているってことかあ…うんうん。
第44回以降は使えそうだろうか。また明日以降見て判断しようかな。これをやめたところで他にさらっと勉強できること見つけるところからなんだよね…。
まあJavascriptでもしてみようかな。TypeScriptかしら。