Excel
VBA
More than 1 year has passed since last update.

概要・用語

Excelを自動化するためのプログラミング言語

  • オブジェクト
  • ワークブック
  • ワークシート
  • セル
  • プロパティ(属性): フォント、色
  • メソッド(処理): セルの削除、挿入

Visual Basic Editor

ツール -> マクロ -> Visual Basic Editor
プロパティウインドウ
プロジェクト、挿入、標準モジュール

Hello World

実行すると「Hello World」のメッセージボックスを出力する

Sub HelloWorld() ' 開始にはSubが必要
  MsgBox("hello world")
End Sub

Sub HelloWorld2()
  MsgBox _
  ("hello world2") ' _を付けると一行と認識
End Sub

セルの値の表示

Sub CellChange()
  Worksheets("Sheet1").Range("A1").Value = "hello"
  Range("A2").Value = "hello2"
  Cells(3, 1).Value = "hello3"
  Cells(3, 1).Offset(1, 0).Value = "hello4" ' 相対的な位置指定
End Sub
Sub CellChange()
  Range("A1", "B3").Value = "hello" ' 範囲の指定方法
  Range("A5:C7").Value = "hello2" ' 範囲の指定方法2
  Range("4:4") = "row4" ' 4行目全てという意味
  Range("C:C") = "columnC" ' C列全てという意味
  Cells.Clear ' セルが全てクリアされる
End Sub

With

' Range("A1")が何度も出ていて冗長
Sub WithTest()
  Range("A1").Value = "hello"
  Range("A1").Font.Bold = True
  Range("A1").Font.Size = 16
  Range("A1").Interior.Color = vbRed
Ebd Sub
' 何度も書かなくて良くなる
Sub WithTest()
  With Range("A2")
    .Value = "hello"
    With Font
      .Bold = True
      .Size = 16
    End With
    .Interior.Color = vbRed
  End With
Ebd Sub

値の取得

Sub GetTest()
  MsgBox(Range("A1").Value)
  MsgBox(Range("A1").Font.Size)
Ebd Sub

メソッド

Sub MethodTest
  ' B2の値を消去する
  Range("B2").Clear

  ' B5を消して全体を1つ上につめる
  ' shift:=xlShiftUpはオプション
  Range("B5").Delete shift:=xlShiftUp

  ' Sheet2の後ろに2枚シートを追加する
  ' after、countはオプション
  Worksheets.Add after:=Worksheets("Sheet2"), count:=2
End Sub

VBAとマクロの関係

VBAにコードを書く = Excelのマクロを作る
マクロを作る = VBAのコードを生成する

変数を使用

Sub VariableTest()
  Dim x As Integer ' 変数の宣言
  x = 10
  Range("A1").Value = x
  Debug.Print x ' イミディエイトウィンドウに表示される

  ' x = 10 + 5
  ' x = x + 1
  ' + = / * mod ^  
End Sub
Sub VariableTest()

 Dim y As Double
 Dim s As String
 Dim d As Date
 Dim z As Variant ' 何かデータが入って初めて型が決まる
 Dim f As Boolean
 Dim r As Range 

 y = 10.5
 s = "hello"
 d = "2012/04/23"
 f = True
 Set r = Range("A1") ' Setが必要

 r.Value = d + 7 ' A1に2012/04/30が入る
End Sub

配列の利用

Sub VariableTest()
  Dim sales(2) As Integer
  sales(0) = 200
  Sales(1) = 150
  Sales(2) = 300

  Debug.Print sales(1) ' 150が表示される
End Sub
Sub VariableTest()
  Dim sales As Variant
  sales = Array(200, 150, 300)
End Sub

If文

Sub IfTest()
  If Range("A1").Value > 80 Then
    Range("A2").Value = "OK"
  ElseIf Range("A1").Value > 60 Then
    Range("A2").Value = "SoSo"
  Else
    Range("A2").Value = "NG"
  End If

  ' = > < => <= <> and not or
End Sub

Select文

Sub SelectTest()
  Dim signal As String
  signal = Range("A1").Value

  Dim result As Range
  Set result = Range("A2") ' Setを忘れない

  Select Case signal
  Case "red"
    result.Value = "STOP"
  Case "green"
    result.Value = "GO"
  Case "yellow"
    result.Value = "CAUTION"
  Case Else
    result.Value = "N/A"
  End Select 
End Sub

ループ処理

  • While文
Sub WhiteTest()
  Dim i As Integer
  i = 1

  Do While i < 10
    Cells(i, 1).Value = i
    i = i + 1
  Loop
End Sub
  • For文
Sub ForTest()
  Dim i As Integer

  For i = 1 To 9
    Cells(i, 1).Value = i
  Nest i
End Sub
  • Each文
Sub EachTest()
  Dim names As Variant
  names = Array("taguchi", "fkoji", "dotinstall")

  For Each Name in names
    Debug.Print Name
  Nest Name
End Sub

Call

  • Subプロシージャー: 返り値を返さない
Sub CallTest()
  Dim names as Variant
  names = Array("taguchi", "fkoji", "dotinstall")

  For Each Name in names
    Call SayHi(Name) ' 別のプロシージャーを使用する
  Nest Name  
End Sub

Sub SayHi(ByVal name As String) ' 引数を書く
  Debug.Print "hi, " & name 
EndSub
  • Functionプロシージャー: 返り値を返す
Sub CallTest()
  Dim names as Variant
  names = Array("taguchi", "fkoji", "dotinstall")

  For Each Name in names
    Debug.Print SayHi(Name)
  Nest Name  
End Sub

Function SayHi(ByVal name As String)
  SayHi = "hi, " & name
EndSub

総復習

以下のようなテーブルがあった時に成績が低いセルを出力する

name score
taguchi 52
fkoji 82
dotinstall 99
Sub FindLowScores()
  Dim i As Long
  Dim n As Long
  i = 2
  n = 0

  For While Cells(i, 1).Valie <> ""
    If Cells(i, 2).Value < 60 Then
      Cells(i, 2).Interior.Color = vbRed
      n = n + 1
    End If
    i = i + 1
  Loop

  MsgBox(n & "件該当しました")
End Sub