開発環境 †
Excel Visual Basic Editor †
- [ツール]-[マクロ]-[Visual Basic Editor]
- Worksheet上のボタンから起動されるプログラムの作り方
- [表示]-[ツールバー]-[フォーム] でフォームツールバーを表示するようにする
- フォームツールバーからボタンを選択してワークシート上にボタンを作る
- [新規作成]を選ぶと、このボタンが押されたときに起動されるSub()が作成され、Visual Basic Editorが起動される
VBAの基本構造 †
VBAで扱う対象 = オブジェクト †
オブジェクト := プロパティ | メソッド
- プロパティの設定・取得
Worksheets("Sheet1").Range("A1").value = "abc"
ABC = Worksheets("Sheet1").Range("A1").value
- プロパティに指定できるデータ型
型 | データ長 | 説明 |
Byte | 1 | 0 to 255 |
Boolean | 2 | "True" or "False" |
Integer | 2 | -32768 to 32767 |
Long | 4 | -2147483648 to 2147483647 |
Single | 4 | 単精度浮動小数点 |
Double | 8 | 倍精度浮動小数点 |
Currency | 8 | 通貨型。小数4桁まで扱える |
Decimal | 14 | 10進で演算を行う(2進演算の桁落ちがない) |
Date | 8 | 1900/1/1 to 9999/12/31 |
Object | 4 | Object |
String | 64KB | 仕様上は2GBまでいけるけど実装上は64KB |
Variant | | 代入や使用法によって自動的に型を割り付ける型 |
- メソッドの実行
Worksheets("Sheet1").Activate()
- オブジェクトの簡易指定
With Worksheets("Sheet1").Range("A1").Font
.Name = "MS明朝"
.Bold = True
.Color = Red
End With
オブジェクトに付属しない処理 = ステートメント †
- 演算子
- 算術演算子
演算子 | 操作 |
a^n | aのn乗 |
-a | |
a*b | |
a/b | |
a\b | 商。CInt(a/b) |
a Mod b | 余り。a - ( b * CInt(a/b) ) |
a+b | |
a-b | |
- 文字列の連結演算子
演算子 | 操作 |
a&b | +も利用可だが混乱するので&を推奨 |
- 比較演算子
演算子 | 操作 |
a=b | ==でないことに注意 |
a<>b | not equal |
a<b | 未満 |
a>b | より大きい |
a<=b | 以下 |
a>=b | 以上 |
a Is b | オブジェクトの比較 |
a Like b | 文字列aがパターンbに一致するか |
- パターンの指定方法
パターン | 意味 | "一致"と見なされる文字列 |
ab* | 任意の複数文字 | abab,abdaba,abex,... |
ab? | 任意の1文字 | aba,abb,abc,abd,... |
ab# | 任意の数字(0-9) | ab0,ab1,ab2,... |
[abc]de | []内の一文字 | ade,bde,cde,... |
[!abc]de | []以外の一文字 | dde,ede,fde,... |
[a-z]de | 範囲指定 | ade,bde,... |
- 論理演算子
演算子 | 操作 |
Not a | ( a=True ? False : True ) |
a And b | ( a=True & b=True ? True : False ) |
a Or b | ( a=True | b=True ? True : False ) |
a Xor b | ( a<>b ? True : False ) |
a Eqv b | ( a=b ? True : False ) |
a Imp b | ( a=True & b=False ? False : True ) |
- プロシージャの実行
a = Sin(x)
プロシージャと変数の定義 †
- プロシージャの種類
Sub() | サブルーチン | 値を返さない |
Function() | 関数 | 値を返す |
- 変数宣言
- [アクセス制御子] A As Type
- 定数: Public Const A As Type = [Value]
- Typeは変数の後に型識別子をつけることによっても定義できる
Dim A As Ineger | Dim A% |
Dim A As Long | Dim A& |
Dim A As Single | Dim A! |
Dim A As Double | Dim A# |
Dim A As Currency | Dim A@ |
Dim A As String | Dim A$ |
- アクセス制御子
モジュール先頭 | Dim | モジュール内からのみ使用可 |
Private | モジュール先頭のDimと同じ |
Public | ブック全体から使用可 |
プロシージャ内 | Dim | プロシージャ内からのみ使用可(プロシージャ実行後に値を破棄) |
Static | プロシージャ内からのみ使用可(プロシージャ実行後も値を保持) |
VBAの基本文法 †
Variant型を使わない †
モジュールの先頭に
Option Explicit
コメント †
Option Explicit '型定義を明示する
Sub サブルーチン定義 †
Call SubA( arg1 , arg2 )
Sub SubA( arg1 As type1 , arg2 As type2 )
'処理
if condition Then Exit Sub
'処理
End Sub
Function ファンクション定義 †
Call FuncA( arg1 , arg2 )
ret = FuncA( arg1 , arg2 )
Function FuncA( arg1 As type1 , arg2 As type2 ) As Type
'処理
if condition Then Exit Function
'処理
FuncA = 返値
End Function
IF文 †
If condition1 Then
'処理
Else If condition Then
'処理
Else
'処理
End If
Select Case文 (CのSwitch文) †
Select Case arg
Case val1
'処理
Case val2
'処理
End Select
breakやdefaultに相当するものは無い
Switch文 †
Dim SOFT As String = "EXCEL"
Dim MAKER As String
B = Switch( SOFT="SunSuite" , "Sun" ,
SOFT="Lotus123" , "IBM" ,
SOFT="EXCEL" , "MS" )
Trueになる選択肢がなければ、MAKER には Null が入る。
Do While文 †
Do While condition 'conditionがtrueの間実行
'処理
if condition2 Then Exit Do
'処理
Loop
While condition 'conditionがtrueの間実行
'処理 : 処理の中断(Exit)はできない
Wend
Do
'処理
if condition2 Then Exit Do
'処理
Loop While condition 'conditionがtrueの間実行
Do Until condition 'conditionがtrueになるまで(falseの間)実行
'処理
if condition2 Then Exit Do
'処理
Loop
Do
'処理
if condition2 Then Exit Do
'処理
Loop Until condition 'conditionがtrueになるまで(falseの間)実行
For文 †
For i = x To y Step z
'処理
If condition Then Exit For
'処理
Next i
For Each文 †
For Each C In Worksheets("Sheet1").Range("A1:A4")
'処理
If condition Then Exit For
'処理
Next C
With文 †
With Worksheets("Sheet1").Range("A1").Font
.Name = "MS明朝"
.Bold = True
.Color = Red
End With
Yes/No †
ret = MsgBox("処理を続行してよろしいですか?(ctrl+zでは元に戻りません)", vbYesNo)
Select Case ret
Case vbYes
'処理を継続します
Case vbNo
'処理を終了します
Exit Sub
End Select
文字列の制御 †
- 最初の一文字を削除する
Dim str As String
str = ""
For i = 1 To 5
str = str & "," & Cells(i,1)
Next i
str = Mid(str, 2, Len(str)))
- 大文字にする/小文字にする
str = Lcase(str)
str = Ucase(str)
- 置換する
dest = Replace( src , 置換される文字 , 置換する文字 )
- n文字繰り返し
str = String( 10 , "A" )
プログレスバー †
- グラフィカルなプログレスバーを使うのは難しいので、Excelのステータスバー(画面左下)に文字列表示する。
- 例は、doSomething()を1000回行い、10個の□で進捗を表すとき
Application.DisplayStatusBar = True
progressOld = ""
For i = 1 To 1000
doSomething(i)
black = String( i/100, "■")
white = String( (100-i)/100 , "□")
progressNew = "処理中" & i & "/1000 " & black & white
If progressNew <> progressOld Then
Application.StatusBar = progressNew
progressOld = progressNew
End If
Next i
Application.StatusBar = False
ワークシートからのソースコードの自動生成 †
セル †
Application : アプリケーション
|
+-Worksheets( No ) : ワークシート
|
+--Range("A1:C3") : セル範囲
| |
| +--Cells(row,col) : セル (row,colは、セル範囲内の位置)
|
+--Cells(row,col) : セル (row.colは、ワークシート内の位置)
すべてのワークシートのA1にワークシート名を設定 †
Sub AllWorkSheet()
For Each ws In Application.Sheets
ws.Cells(1, 1).Value = ws.Name
Next ws
End Sub
アクティブなワークシートのA列の最終行数を返す †
Function LowerRow() As Integer
'ワークシート上の最終行の列数を見つける
LowerRow = Cells.SpecialCells(xlCellTypeLastCell).Row
'空白がある限り上に上っていく
Do While Cells(LowerRow, 1).Value = ""
LowerRow = lastRow - 1
If LowerRow = 0 Then Exit Do
Loop
End Function
ブックが置かれているディレクトリにファイルを書き込む †
Sub generateSource()
'ファイルのオープン
Dim fileName As String
fileName = ThisWorkbook.Path & "\a.java"
Open fileName For Output As #1 'ファイル番号1で新規作成
' #1への書き込み
Print #1, "/**"
Print #1, " * All Rights Reserved, Copyright(C) foo Ltd (2003-2005)"
Print #1, " *"
Print #1, " * bar.xls より自動生成。"
Print #1, " * 更新履歴などはExcelファイルを参照すること。"
Print #1, " */"
Print #1, "package foo.bar;"
Print #1, ""
Print #1, "/**"
Print #1, " * xxDTO<BR>"
Print #1, " */"
Print #1, "public class xxDTO{"
Print #1, "}
'ファイルのクローズ
Close #1
End Sub
ソースコード生成プログラム †
以上の練習プログラムで学習した構文を使ってソースコード生成プログラムを書くことができる。VBAが余りきれいな言語ではないので、ボタンに対応するSubに全部押し込めるような汚いプログラムになるけど、そんなに大規模にはならないし、再利用もできないのでOK。鶏を割くに牛刀は要らぬ
すべてのワークシートに関して{
生成するファイルを開く(必要があればワークシート名やA1の値をファイル名にする);
A列の有効な最終行を取得する;
すべての有効な行に関して{
行の内容をファイルに出力する;
}
}
ブックの共有 †
- VBAプログラムの仕様変更なども考えると、できればブックは一つの方が良い
- 一つのブックで多人数が並行作業するためにはブックの共有を行えばよい
Computer