背景
Excel VBA を書く機会がたまにあるのですが,C#やpython出身の僕がVBAを書いていて悩んだところを備忘録として残します.
悩んだところ
コメントが ' である
' がコメントなんです
' #でも //でもありません
変数の定義は強制されない
VBAではデフォルトで変数の定義をせずに使えてしまうので(pythonやrubyと同じ),複雑なコードを書いていく場合は
Option Explicit
a = 1 ' エラーになる
Dim a As Integer
a = 1 ' エラーにならない
Option Explicit で定義を強制しましょう
変数定義時に値を代入できない
' 変数は定義と同時に代入できません
Dim a As Integer
a = 10
' 定数は定義時にしか代入できない
Const b As Integer = 10
return がない
Public Function RetStr()
RetStr = "返り値" ' メソッド名に値を代入すると返り値になる
End Function
返り値の型の指定の仕方
Public Function Hoge(str As String) As Integer
Dim i As Integer
i = 1
Hoge = i
End Function
返り値のないメソッドでは () を使わない
Public Function RetStr()
RetStr = "返り値がある"
End Function
Public Sub NonRetStr()
Debug.Print "返り値が無い"
End Sub
Public Function Hoge()
Dim a As String
a = RetStr() ' 返り値があるメソッドの呼び出し
Debug.Print a
Call NonRetStr '返り値が無いメソッドの呼び出し
End Function
++が使えない
Dim idx As Integer
idx = 0
idx = idx + 1
同じ型の変数を同時に定義できない
' 以下の定義だと a は Variant型になります
Dim a, b As Integer
' 両方ともIntegerにするには以下の通りです
Dim a As Integer, b As Integer
値型と参照型では代入の仕方が異なる
' 値型の代入
Dim a As Integer, b As Integer
a = b
' c と dが参照型である場合 Set を使う
Dim c As Worksheet, d As Worksheet
Set c = d
参照を意識すると言うのは,僕は大切だと思うのですが個人的には好きなのですが,
c = d
とすると例外メッセージ「オブジェクト変数またはWithブロック変数が設定されていない」が
と出てきて,理解しにくいのが難点です.
For i = 1 To 1 でも式の中に入ってしまう
もし入らないようにしたければ、Whileを用いましょう
Continueがない
For文内でcontinueする場合は GoToを用いましょう
ForやIf内でスコープがない
SubやFunctionの中で宣言した変数は,その中でしか使えないというスコープを持っていますが,For文やIf文などの中で宣言した変数はSub内Function内で使えてしまいます。
例えば For文用のIndexを定義すると、そのIndexはモジュール内のどこからでもアクセスできてしまいます(単語補完でも表示されます)
Dim で初期化されない
まず、Dimで二度同じ変数を宣言するとエラーを吐きます
Dim a(1 To 10)
Dim a(1 To 10) ' エラー
しかし,For文ではエラーになりません
Dim idx as integer
For idx = 1 To 10
Dim a(1 To 10) ' エラーにならない
Next idx
しかし、このaは初期化されておらず、前に格納された値を保持します
Dim idx as integer
For idx = 1 To 10
Dim a(1 To 10)
a(idx) = idx
Next idx
' aは1から10の値を持った配列となる.不思議!
配列のIndexが1から始まる場合と0から始まる場合がある
Dim a As Variant
a = Array(1,2,3) ' indexは 0,1,2
ReDim a(1 To 3) ' indexは 1,2,3
Option Base 1を先頭につけることで、Array()で生成される配列のindexを1から始められるようになります.
(こちらのほうがセルの参照時などに相性がいいのでお勧めです)
Option Base 1 ' defaultでは 0
細かな話(時間があれば,きちんとまとめます)
WindowsとMacで使えるメソッドと引数が決まっている
特にファイル選択など入出力系ではMac版は不便で、Apple Scriptを使わなければダメです
WorkSheetのActivateの注意点
Sheet(“シート名”).Activate でアクティベーション(参照などが行える)できますが、アクティベートしたSheetのWithコンテキストの中で他のシートに書き込みは出来ないので注意です
Emptyの値が0を取る
Cellが空であるかどうかをちゃんとIsEmptyで確認しないと、普通に空のセルの数値を0として計算が通ってしまいます.
ソートがないため、自分で実装する
C#などでは arr.OrderBy()で簡単にソートできるのですが,そう言ったデータ配列をソートする関数は標準で用意されていないようです.
(ご存知の方はご教示ください...)
Dictionary, Collectionなどの型は他のDllを参照する必要があり、デフォルトでは使えない
これらは複雑なコードを書いていく上で必須ですので,dllを参照しましょう.
勉強法
Excel はビジュアライゼーションと操作性が優れているので便利なのですが,VBAには色々つまずきました.
VBAを学ぶのであれば,まずマクロの記録をしてみて,それで記録されたマクロがどういうコードなのかを理解することです.
あとは,ググりましょう!