LoginSignup
24
23

More than 5 years have passed since last update.

[備忘録]C#出身の僕がExcel VBAで悩んだところ

Last updated at Posted at 2016-01-14

背景

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ブロック変数が設定されていない」が

ref_insert.PNG

と出てきて,理解しにくいのが難点です.

For i = 1 To 1 でも式の中に入ってしまう

for.PNG

もし入らないようにしたければ、Whileを用いましょう

Continueがない

For文内でcontinueする場合は GoToを用いましょう

for_continu.PNG

ForやIf内でスコープがない

SubやFunctionの中で宣言した変数は,その中でしか使えないというスコープを持っていますが,For文やIf文などの中で宣言した変数はSub内Function内で使えてしまいます。
例えば For文用のIndexを定義すると、そのIndexはモジュール内のどこからでもアクセスできてしまいます(単語補完でも表示されます)

scope.PNG

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を参照しましょう.
ref.PNG

勉強法

Excel はビジュアライゼーションと操作性が優れているので便利なのですが,VBAには色々つまずきました.
VBAを学ぶのであれば,まずマクロの記録をしてみて,それで記録されたマクロがどういうコードなのかを理解することです.
あとは,ググりましょう!

24
23
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
23