Excel VBAのビギナーです。
本当に基本的なレベルですが、一応メモっています。
どうやって書き始めるの?
まずExcel VBAつまりExcelマクロはどうやって書き始めるの?
…というホントにしょうがないレベルですが、方法は二つあります。

  • Excelのメニューからツール⇒マクロ⇒マクロ...⇒を選び、 コンボボックスの部分にマクロ(Subプロシージャ)の名前を入力して「作成」
  • Excelのメニューからツール⇒マクロ⇒Visual Basic Editor でVisual Basic Editorを開き、 そのメニューから挿入⇒標準モジュールを選び、自分でSub文から書く。
いずれも標準モジュール「Module1」というものができます。 マクロは通常、標準モジュールに記述します。


Private Subで構造化する
Sub ○○〜End Subというプロシージャを作ると、 ○○はマクロのメニューでも選択して実行可能です。
他のプロシージャから呼ばれることを専ら想定していて、 マクロのメニューからは呼ばれたくないものがある場合、 「Private」を頭につけて「Private Sub ○○」とすればOKです。


セルの参照方法
セルを参照するには、大きくRangeとCellという二つの方法があります。

Range("E4").Value = "こんにちは"
Cells(4, 5).Value = "こんにちは"

上のRangeは「E4セル」というそのものずばりの指定方法です。
下のCellsは「4行目、5列目のセル」と数字で指定しています。


セルを選択するたびに処理を行うマクロ
Excelシートのセルをクリックすると何か処理を行うマクロを記述するには、 標準モジュール(Module1)ではなく、そのブックやワークシートの中にVBAコードを書きます。
下の例では、シートの5列目の3行目、つまりE3セルを選ぶたびにダイアログを出します。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Target.Row = 3 And Target.Column = 5 Then
        MsgBox ("こんにちは。")
        ' 何か処理をする
    End If
End Sub


タブ区切りのテキストファイルをシートに読む超基本マクロ

Sub ReadTextFile()
'
' "data.txt"ファイルをタブ区切りテキストファイルとして読み、
' "データ"シートの左上から内容を上書きします。
' データの列数は5個で固定です。
'
    Const FILE_NAME As String = "data.txt"
    Dim n As Integer
    Dim a As String
    Dim data As Variant
    Dim row As Integer

    n = FreeFile
    ' Open "C:\usr\lang\excel\test.txt" For Input As #n
    ' 相対パスで開きたい場合、カレントフォルダは、このExcelファイルがある
    ' フォルダとは限らないので、次のようにパスを明示する必要があります。
    Open ThisWorkbook.Path & "\" & FILE_NAME For Input As #n
    row = 1
    Do Until EOF(n)
        Line Input #n, a
        data = Split(a, vbTab)
        Range(Cells(row, 1), Cells(row, 5)) = data
        row = row + 1
    Loop

    Close #n

End Sub


セルを読む+他にコピーする超基本マクロ
以下のマクロは、"データ"シートの1列目の値を、 重複を省いて、"集計"シートの1列目に複製します。
コピー元の"データ"シートの値は、既に昇順に並んでいることが前提です。 また、事前にコピー先"集計"シートのクリア処理はしません。

Private Sub CreatePibSheet()
    Dim row As Integer
    Dim newRow As Integer
    Dim prevValue As String
    Dim v As String
    Const NEW_ROW_START As Integer = 3

    '"データ"シートに移動。
    Sheets("データ").Select

    '"データ"シートには見出しが1行あるので2行目から
    row = 2
    '"集計"シートには見出しが2行あるので3行目から
    newRow = NEW_ROW_START
    prevValue = "(dummy)"
    ' 1列目を縦に見ながら値がある限りループ
    Do While ActiveSheet.Cells(row, 1) <> ""
        v = ActiveSheet.Cells(row, 1)
        If v <> prevValue Then
            ' 新しい値が現れたら、"集計"シートに新しい行を作る。
            ' その際に4行目以降は、3行目をコピーすることで、
            ' 数式(VLOOKUP関数)を各セルにコピーする。
            If newRow > NEW_ROW_START Then
                Sheets("集計").Rows(NEW_ROW_START).Copy _
                  Destination:=Sheets("集計").Rows(newRow)
            End If

            ' 1列目の値をさらに上書きする。
            Sheets("集計").Cells(newRow, 1) = v
            prevValue = v
            newRow = newRow + 1
        End If
        row = row + 1
    Loop
End Sub

ポイント(本筋と関係ないものもありますが)は、
  • 「Sheets("シート名").Select」とすることで、 以降そのシートのセルを「ActiveSheet.Cells(行, 列)」で参照できる。
  • 空欄が現れるまでループするには、 「Do While ActiveSheet.Cells(行, 列) <> ""」で、 行、列の値を変数で変えながら実行すればよい。
  • 「Sheets("シート名").Rows(元行).Copy Destination:=Sheets("シート名").Rows(先行)」 で、行をコピーできる。 このとき、相対セル参照の数式が含まれる場合、 マウスでドラッグした際などと同じようにきちんと参照が変化します。


シートの最後の行番号を得るには
上の例では、シートの上から下に向かって、値がある限り(空白でない限り) 処理をするループを書きました。
それでは、途中に空白セルを挟んでさらに下に進み、 「これ以上下には値が入っているセルはない」 という一番下の行番号を知るには? 特殊な場合の制限によっていくつか方法があるようですが、 大半の場合に有効で、簡潔に書けるのは次のもののようです。

Dim maxRow As Integer
maxRow = Cells(Rows.Count,5).End(xlUp).Row

これはシートの5列目を見て、一番下の行番号を返します。


シートの背景色を変えるサンプル
マクロを使って、一部のセルの背景色を変更するサンプルです。
以下の例では、4行目から下の各行のE列を見て、 値が●ならばその行のBからD列を青色に塗り、そうでなければ白色で塗っています。
背景色はセルのInterior.Colorで指定できます。 背景色ではなく文字色を変えたい場合は、セルのFont.Colorで指定できます。

Sub ChangeBgColor()
    Dim maxRow As Integer
    Dim i

    maxRow = Cells(Rows.Count,5).End(xlUp).Row

    For i = 4 To maxRow
        If Range("E" & i).Value = "●" Then
            Range("B"&i&":D"&i).Interior.Color = RGB(0, 0, 128)
        Else
            Range("B"&i&":D"&i).Interior.Color = RGB(255, 255, 255)
        End If
    Next
End Sub

Misc. Topics Top

(first uploaded 2006/07/09 last updated 2016/11/27, URANO398)