Help us understand the problem. What is going on with this article?

Excel VBA

More than 3 years have 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
finc
健康寿命を伸ばすアプリFiNCの開発・運営を行うモバイルヘルステクノロジーベンチャー
https://finc.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away