Excel VBA

Microsoft Office XP (Excel 2002)が対象。必要に迫られないと使わないので、備忘録を作成。
[最終更新日: 2008/05/03]

1. 全体的な設定

| INDEX
Option Base 0
配列の添え字の基準値を設定できます。デフォルトでは他の言語と同じく0ベースですが、1も設定できるようです。
Option Explicit
変数を明示的に宣言するよう強制します。

2. ブック、シート、セルへの参照を得る

| | INDEX

VBAからExcelの各部品への参照を得るには様々な書き方がある。以下、その例。

ワークブック(Workbook)への参照
ThisWorkbook                'スクリプトが埋め込まれたブック
Workbooks("ブック名")       '同時に開かれている"ブック名.xls"という名前のブック
ワークシート(Worksheet)への参照
ActiveSheet                 ' 現在アクティブなシート
Worksheets("シート名")      '"シート名"という名前のシート 
Worksheets(1)               'インデックス番号 1 のシート
セル範囲(Range)への参照
Range("A1:C3")              'A1からC3の範囲

Range("A1:C3").ClearContentで、指定したセル範囲の内容を消去、というような利用が可能

セル(Cell)への参照
Cells(1, 1)                 'セルの座標を用いた指定。(行, 列)の指定で、(1, 1)が左上になる
Range("A1")                 'Range関数で単一のセルを指定することもできる

なお、指定したセルの値を利用したい場合は、Cells(1, 1).Value や Range("A1").Value を使用することができる。

' 例
Dim mySheet As Worksheet
Dim i As Integer
Set mySheet = ThisWorkbook.Worksheets("Sheet1") 'オブジェクトの代入 Setステートメント
mySheet.Cells(1 ,1).Value = "インクリメント"
For i = 1 To 20 Step 1
	mySheet.Cells(1+i, 1).Value = i;
Next i

3. 配列を扱う

| | INDEX

配列の扱いが覚えにくかったので以下にメモしておく。

配列の宣言
Dim sArray(9) As String ' 文字列型の一次元配列
Dim sArray(2, 2) As String ' 文字列型の二次元配列
配列のサイズを得る
UBound(sArray)
配列の動的な拡張
' ReDim句で再宣言, Preserve句で値を保持
Dim sArray() As String
ReDim Preserve sArray(1)
sArray(0) = "一個目"
ReDim Preserve sArray(2)
sArray(1) = "二個目"
ReDim Preserve sArray(3)
sArray(2) = "三個目"
MsgBox UBound(sArray)
二次元配列をシートのセルへ出力
Dim sArray(2, 2) As String
sArray(0, 0) = "A1のセル"
sArray(0, 1) = "B1のセル"
sArray(1, 0) = "A2のセル"
sArray(1, 1) = "B2のセル"
Worksheets("Sheet1").Cells(0, 0).Resize(2, 2).Value = sArray 'A1を起点に出力

4. 各種ダイアログ

| | INDEX

各種のダイアログの例。

OKボタンのみのダイアログ
MsgBox("メッセージ") 'デフォルがvbOKOnlyなので第二引数以降を省略可能
MsgBox("メッセージ", vbOKOnly, "ウィンドウタイトル")
ユーザにYesかNoかを選択してもらう確認ダイアログ
Dim result As vbMsgBoxResult
result = MsgBox("メッセージ", vbYesNo, "ウィンドウタイトル")
If result = vbYes Then
    ' Yesが選択された場合の処理
End If
入力ボックスを表示する
Dim res As String
res = InputBox("何か入力してください", "ウィンドウタイトル")
If res = "" Then
    MsgBox "EMPTY!"
End If

5. ファイルダイアログからファイルを開く

| | INDEX

ファイルダイアログからユーザの指定したExcelファイルを開く。

    ' GetopenFilenameが、文字列ないしはFalseを返すのでVariant型
    Dim filePath As Variant

    ' ファイルダイアログの初期位置を現在のフォルダにする
    ChDrive (Left(ThisWorkbook.Path, 1))
    ChDir (ThisWorkbook.Path)

    ' Excelファイルのみをリストアップするダイアログを作成
    filePath = Application.GetOpenFilename("Microsoft Excelブック,*.xls")
    
    If filePath = False Then
        MsgBox "ファイルが存在しません"
        End
    End If
    
    ' 指定されたファイルを開く
    Workbooks.Open Filename:=filePath

開いたブックへは、Workbooks(Dir(filePath))で参照可能。

6. データの存在する最終列/最終行を取得する関数

| | INDEX

ExcelのCells.SpecialCells(xlCellTypeLastCell).Rowなどでは、Excelの記憶力がよすぎて使いにくいので、データの存在する最終行を取得する関数を作成する。

' データの存在する最終列数を取得
Function GetLastCol(mySheet As Worksheet, trow As Long) As Long
    With mySheet
        Dim lastColNumber As Long
        lastColNumber = .Cells.SpecialCells(xlCellTypeLastCell).Column
        While lastColNumber > 1 And .Cells(trow, lastColNumber).Value = ""
            lastColNumber = lastColNumber - 1
        Wend
        GetLastCol = lastColNumber
    End With
End Function

' データの存在する最終行数を取得
Function GetLastRow(mySheet As Worksheet, tcol As Long) As Long
    With mySheet
        Dim lastRowNumber As Long
        lastRowNumber = .Cells.SpecialCells(xlCellTypeLastCell).Row
        While lastRowNumber > 1 And .Cells(lastRowNumber, tcol).Value = ""
            lastRowNumber = lastRowNumber - 1
        Wend
        GetLastRow = lastRowNumber
    End With
End Function

なお、連続データであることが保証されている表相手なら、Range("A1").End(xlToRight).ColumnRange("A1").End(xlDown).Rowを使うほうが早いかも。

7. セルに数式を入れる

| | INDEX

CellのFormulaプロパティに設定することで可能。

単純な例としては、以下のようにする。

Cells(1, 1).Formula = "=A2+A3"

VBAからセルに数式を入れる場合、R1C1形式の参照のほうが便利かもしれない。

' 例: =SUM(A2:B4) と同等
Cells(1, 1).FormulaR1C1 = "=SUM(R[1]C:R[3]C[1])"

8. セルの書式を設定する

| | INDEX
列の幅を設定する
' mySheetの1列目の列幅を12に設定する
mySheet.Columns(1).ColumnWidth = 12
行の幅を設定する
' mySheetの1行目の行幅を20に設定する
mySheet.Rows(1).RowHeight = 20
セルの文字色
Range("A1").Font.Color=RGB(255,255,255)  
Range("A1").Font.ColorIndex=3 
セルの背景色・パターン
Range("A1").Interior.Color=RGB(255,0,0)
Range("A1").Interior.ColorIndex=3 
Range("A1").Interior.Pattern = xlGrid
Range("A1").Interior.PatternColor = RGB(255,0,0)  
Range("A1").Interior.PatternColorIndex = 3

9. 指定したシートを印刷する

| | INDEX
' アクティブなシートを印刷する
ActiveSheet.PrintOut
' すべてのシートを印刷する
Sheets.PrintOut
' 指定したシートを印刷する(単数シート)
Sheets("Sheet1").PrintOut
' 指定したシートを印刷する(複数シート)
Sheets(Array("Sheet1", "Sheet2")).PrintOut
' プリンタ設定を表示後、印刷する
Application.Dialogs(xlDialogPrinterSetup).Show
ActiveSheet.PrintOut

10. プリンタ設定を表示する

| | INDEX

プリンタ選択ボックスを表示する。

Application.Dialogs(xlDialogPrinterSetup).Show

11. ワークシート関数をVBAのなかで使う

| | INDEX

SUM関数とかをVBAの中で呼び出す方法。

Application.WorksheetFunction.Sum(Range("A1:A3"))

12. 選択したセル上に矢印のオートシェイプを作成

| | INDEX

状況がわかりにくいと思われるので、右の図解をどうぞ。[ 図解:選択したセル上に矢印のオートシェイプ ]

' 標準モジュールにでもどうぞ

Sub MakeYajirushiClip()
    ' 選択されているのが「セル範囲」でなければサブルーチンを終了する
    If TypeName(Selection) = "Range" And Selection.Count < 1 Then
        Exit Sub
    End If
    ' 描画位置の設定
    Dim nWidth As Double
    Dim nTop As Double
    Dim nStartCellWidth As Double
    Dim nLastCellWidth As Double
    nWidth = Selection.Left + Selection.Width
    nTop = Selection.Top + (Selection.Height / 2)
    nStartCellWidth = Selection.Cells(1, 1).Width / 4
    nLastCellWidth = Selection.Cells(Selection.Rows.Count, Selection.Columns.Count).Width / 4
    ' 図(オートシェイプ)の描画
    ActiveSheet.Shapes.AddLine(Selection.Left + nStartCellWidth, nTop, nWidth - nLastCellWidth, nTop).Select
    Selection.ShapeRange.Line.EndArrowheadStyle = msoArrowheadTriangle
    Selection.ShapeRange.Line.EndArrowheadLength = msoArrowheadLengthMedium
    Selection.ShapeRange.Line.EndArrowheadWidth = msoArrowheadWidthMedium
    ' 左向矢印にしたい場合は次の行を有効に
    'Selection.ShapeRange.Flip msoFlipHorizontalEnd Sub

Lineを引いてから、矢印の形状スタイルを与えている。

13. シートの保護と保護の解除

| | INDEX

Worksheet.Protect と Worksheet.UnProtect でできる。以下はコード例。

' ブック内のすべてのシートを保護する
Sub ProtectAllSheets()
    Dim mySheet As Worksheet
    For Each mySheet In ThisWorkbook.Sheets
        mySheet.Protect
    Next
End Sub

' ブック内のすべてのシートの保護を解除する
Sub UnProtectAllSheets()
    Dim mySheet As Worksheet
    For Each mySheet In ThisWorkbook.Sheets
        mySheet.Unprotect
    Next
End Sub

Protect("password")として保護パスワードを設定することも可能。

14. 正規表現の利用

| INDEX

VBScript.RegExpを利用して正規表現のマッチや置換を行う。

正規表現によるマッチ

文字列strが/hoge/にマッチするか調べる。

Set re = CreateObject("VBScript.RegExp")
re.Pattern = "hoge"
If re.Test(str) Then
    MsgBox "Matched."
End If
Set re = Nothing
正規表現による置換

文字列str中の"hoge"をすべて"foo"に置換する例。

Set re = CreateObject("VBScript.RegExp")
re.Global = True
re.Pattern = "hoge"
str = re.Replace(str, "foo")
Set re = Nothing

なお、参照設定で、Microsoft VBScript Regular Expressions 5.5が登録されていれば、CreateObjectを使わずにSet re = New RegExpという記述が可能。

.