Excel VBA

Contents

開発環境

準備

標準のマクロエディタはエディタに文を書くと自動で構文チェックする。具体的にはカーソルが現在の行から離れたタイミングである。この際に、コンパイルエラーがあるとダイアログが表示される。

例えばある行の一部を切り取ってほかの行に張り付ける際は切り取った際にエラーが出てしまう。開発中はこのようなことがよくあり、毎回ダイアログを消すのは面倒である。そのため、ダイアログは非表示にする。

なお、構文エラーがあると赤字で表示されるが、ダイアログを非表示にしても赤字表示はされるのでエラーがあるとすぐに気づける。

  1. マクロエディタ
  2. ツール > オプション
  3. 編集タブ
  4. 自動構文チェックをオフにする

 

強制終了

無限ループに陥ってしまった場合などに強制終了させることができる

Escキーを押しながら、タスクバーでエクセル、マクロエディタから別のウインドウに何度か切り替える。

 

 

文法

Hello World

 

MsgBox ("Hello World")

 

プロンプト

 

inputResult = InputBox(Prompt:="Input This Form", Default:="default value")

 

コメント

' コメント

複数行のコメントはできない

 

型と値

NullはVariant 型にのみ代入可能

 

変数宣言

変数は宣言しなくても使用可能である。
宣言することも可能。その際型は省略可能であるが、型を指定することも可能。

 

 

 

行分割


行末尾を「空白+_」にすることで、次の行につなげることができる。

a = _
  b + c

 

演算

除算

ans = 5 / 2
' ans = 2.5

 

整数除算

ans = 5 \ 2
' ans = 2

 

整数剰余

ans = 5 mod 2
' ans = 1

 

累乗

ans = 5 ^ 2
' ans = 25

 

インクリメント

a = a + 1

 

比較演算

文字列

論理演算

 

条件

andやorはこちら

if

If i = 10 Then
	...
End If

 

if not

If Not i = 10 Then
	...
End If

or

If i <> 10 Then
	...
End If

 

if else

 

If i <= 10 Then
	...
ElseIf i >= 20 Then
	...
Else
	...
End If

 

ループ

 

for

For i = 1 To 10
	...
Next i

 

ループ脱出

whileループでは脱出できない(do-whileなら可能)

For i = 1 To 10
	If i = 3 Then
		Exit For
	End If
Next i

 

continue

For i = 1 To 10
	If i = 3 Then
		GoTo Continue
	End If
	
	Continue:
Next i

 

for each

For Each nextCell In Range("A1", "A3")
	Debug.Print (cell.Value)
Next

 

while

Do While i < 10
	...
Loop

 

文字列

エスケープ

ダブルクォーテーションはエスケープが必要

ダブルクォーテーション2つでダブルクォーテーションとして扱われる。

次はダブルクォーテーション1つの文字列定数である。

""""

 

改行

改行コードは次のシステム定数で表される。

vbCrLf

 

タブ

タブコードは次のシステム定数で表される。

vbTab

 

連結

文字列、”&”の間には必ず空白が必要。

"ABC" & "DEF"

 

文字列長

Len(str)

 

部分文字列

Left(str, Len(str) - N) 

 

エスケープ


ダブルクォーテーションのみエスケープが必要。
以下のように書くことで、ダブルクォーテーションと認識される。

""

"I say ""Hello"""

 

配列

宣言

Dim list(10)

 

代入

配列インデックスは0から

list(0) = 1

まとめて代入

list = Array(1, 2, 3)

 

配列長

UBound(list)

 

可変長配列

可変長配列ではあるものの、要素格納前には配列長を決定しなければならない。
配列長を与える際、ReDimでは既存の要素はデフォルトで破棄されるので、残す場合は別途Preserveオプションが必要。

Dim list() As Integer
ReDim list(10)
For i = 1 To 10
	list(i) = i
Next i

For i = 11 To 20
ReDim Preserve list(UBound(list) + 1) list(UBound(list)) = i
Next i

 

サブルーチン(プロシージャ)

Excel VBAにはSubプロシージャとFunctionプロシージャと2種類の関数相当の機能がある。それぞれ下記の違いがある。

値渡しと参照渡し

プロシージャの引数はデフォルトでは参照渡しである。

ByValをつけることで値渡しにできる

Sub Proc(Str As String)
    Str = "XXX" ' Strは上書きされない
End Sub

ByRefをつけることで、明示的に参照渡しにできるので、混在する場合は宣言するとわかりやすい

 

Subプロシージャ

定義

Sub <プロシージャ名>(<変数名> As <型>)
    ' 処理の内容
End Sub

 

Functionプロシージャ

定義

 

呼び出し

()で引数を囲ってはいけない

subA str1, num1


ただし、先頭にCallをつける場合は囲ってもよい。

Call subA(str1, num1)

 

返り値を受け取る場合

val = funcA()

 

返り値無

Sub subA(arg1 As String, arg2 As Long)
	MsgBox ( arg1 & "+" & arg2 )
End Sub

 

途中終了

Exit Sub

 

返り値有

関数名に戻り値を代入する

Function funcA(arg1 As String, arg2 As Long)
	funcA = ( arg1 & "+" & arg2 )
End Function

 

その他

マクロ終了

Exit Sub

 

関数

文字列

substring

Mid( str, start, [length] )

開始位置は1から始まる。
文字列長を省略した場合は、開始位置から末尾までを切り出す。

 

Split

Split("a,b,c", ",")

配列を返す

 

日付

この関数はWindowsの設定により返すフォーマットが異なる。
その為、この関数で取得した値を元に処理を行う場合、下記の別の関数をし

Date()

 

YYYYの形式で返る

Year (Date)

 


Mの形式で返る

Month (Date)


MMで取得する場合

mm = "0" & Month(Date)
mm = Mid(mm, Len(mm) - 1)

 

日付検査

targetDate = InputBox(Prompt:="年月", Default:=targetDate)
If Not IsDate(targetDate) Then
	MsgBox "日付形式が不正です(2001/8)"
End If

 

現在時刻

Now関数を用いる

nowStr = Format(Now, “yyyy年mm月dd日 hh時mm分ss秒”)

セル

Cells

単一のセルを指定する場合に使用する。
列番号をアルファベットではなく、数値で指定しなければならない。

' B1のセルの値を取得
Cells(1, 2).Value

Range

主に複数のセルを指定する場合に使用する。

' A1:B2のセルの値を取得
array = Range("A1:B2").Value
' B1のセルの値を取得
val = array(1,2)

以下は同じ

val = Range("B1").Value

 

 

選択セル

※変数宣言は不要

row = Selection.Row
column = Selection.Column

範囲選択している場合は、左上のセルのアドレスが格納される

 

シート

コピー

末尾に追加

Sheets("copied").Copy After:=Sheets(Worksheets.Count)

 

クリップボード

ライブラリの参照

クリップボードを扱う”DataObject”型は標準では使用できないので、参照設定が必要である。

  1. マクロのエディタを開く
  2. ツール > 参照設定
    ※参照設定がグレーアウトしている場合、おそらくマクロが実行中なので、停止すること
  3. 参照
  4. C:\Windows\System32\FM20.DLL を開く
  5. Microsoft Forms 2.0 Object Libraryが選択されるのでOK

 

クリップボードへコピー

    Dim ClipBoard As New DataObject
Dim str As String
str = "clip board test"
With ClipBoard
.SetText str
.PutInClipboard
End With

 

Tips

数値から列名取得

colName = Cells(1, <列番号>).Address(True, False)
colName = Mid(colName, 1, Len(colName) - 2)

 

長い行の途中で改行する

途中で改行するには半角スペースとアンダースコアを行末に書く

list = Array( _
"A", _
"B", _
"C" _
)

Notice: Trying to get property 'queue' of non-object in /usr/local/wordpress/wp-includes/script-loader.php on line 2876

Warning: Invalid argument supplied for foreach() in /usr/local/wordpress/wp-includes/script-loader.php on line 2876