Excel VBA事始め その2

勉強会
©いらすとや.

Excel VBA その2 1
前回の記事で「Sheet1」に書いたコードは消して、今回は左のツリーから「標準モジュール」の中の「Module1」にコードを書くことにします。

1
2
3
Sub test()
    ThisWorkbook.Sheets(2).Cells(3, 2).Value = 1 + 2
End Sub

testという名前のサブルーチンプロシージャを作成し、「ThisWorkbook (このワークブック)」の「2番めのシート」の「Cells(3,2) "B3"セル」の「値」は「1 + 2」であるという内容です。なお、1 + 2は引用符で括っていないため「計算」になります。

Excel VBA その2 2
ワークブックを確認します。コードでは「Sheets(2)」 (2番めのシート) を指定したのでこの例では「Sheet2」のワークシートになります。なお、2番めのシートが必ず「Sheet2」という名前のワークシートになるというわけではないのでご注意ください。
Cells(3, 2)は「3行目,2列目のセル」なのでワークシートでは"B3"セルになります。そして、その値が1 + 2を計算したものになるため 3 がセルに入っているのが正解です。なお、VBAのコードで1 + 2が計算された結果である3という数値が直接セルの値として入っています。「=1+2」 のようなワークシート関数がB3セルに入っているわけではありません。

ここからは次の例です。

Excel VBA その2 3
今回は先に「テスト」という名前のワークシートを(手動で)作成します。もちろんワークシートはVBAでも作成できますが、それはまた次の記事以降で。

Excel VBA その2 4
今回もコードはModule1に書きます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Sub test()
    Dim wsTest as Worksheet
    Set wsTest = ThisWorkbook.Worksheets("テスト")

    With wsTest.Cells(3, 2)
        .Value = 1 + 2
        .Interior.ColorIndex = 37        '暗めの水色
        With .Font
            .ColorIndex = 6        '黄色
            .Size = 20
        End With
    End With
End Sub
今回は変数が出てきます。wsTestは、ワークシート型というオブジェクト変数です。(2行目)
wsTest に ThisWorkbook.Worksheets("テスト")「このワークブック」の「テスト(という名前の)」ワークシートを格納します。(3行目) With ○○ から End Withの間は「○○について」です。5行目の場合は「wsTest.Cells(3,2)について」なので変数部分を仮に展開すると「このワークブックの"テスト"ワークシートの"B3"セルについて」です。(5行目)
「.」から始まっている場合は「With ○○」の対象です。つまり「.Value = △△」であれば ○○.Value = △△ になります。(6〜11行目)
なお、With ○○ 〜 End Withの中に書かれていても 「.」で始まっていない場合はWith ○○の対象外です。
.Interior.ColorIndex は セルの装飾(セルの塗りつぶし)の色番号を指定するものです。ここでは色番号37番を指定しています。(7行目)
With ○○ 〜 End Withの中に再びWithで始まるものが出てきました。(8行目)
ここでは「With .Font」 ということで「.」で始まるので5行目のWith ○○の対象です。つまり With wsTest.Cells(3, 2).Font です。これは「"テスト"ワークシートの"B3"セルの『フォント』について」ということになります。(8行目)
.ColorIndex = 6 と書かれているということは「.」で始まっているのでWith .Fontの対象です。そのColorIndex(色番号)の指定なので「フォントの色の指定」ということになります。先の7行目はセルの装飾についての色番号の指定でしたが、今回はセルのフォントの色指定です。(9行目)
.Size = 20も「.」で始まっているのでWith .Fontの対象です。"B3"セルに使用するフォントのサイズを(ポイント)指定しています。これはフォントなのでSizeというプロパティが使用できますが、例えば先の7行目のような.Interior(セルの装飾)では.Sizeプロパティはありません。「セル(の装飾)のサイズ」だと意味がわからないですしね。(10行目)
11行目のEnd Withは8行目のWith .Fontと対応します。
12行目のEnd Withは5行目のWith .wsTest.Cells(3, 2)と対応します。

このようにWith ○○ 〜 End Withを使うとスッキリ書けて見通しが良くなります。

Excel VBA その2 5
ワークブックに戻り、「テスト」という名前のワークシートを開きます。
そのワークシートの「B3」セルに3という値が入り、通常より大きい文字になっていて、文字の色が黄色、「B3」セルが水色に塗りつぶされていれば、VBAで書いたとおりになったということです。画像では3行目全体の高さが他の行より大きくなっていますが、今回VBAでは行の高さは指定していないのでExcelが自動調整して表示がこうなったものです。

注意

1
2
3
4
5
Sub test()
    With ThisWorkbook.Worksheets("テスト")
        .Cells(3, 2).Value = 1 + 2
    End With
End Sub

このように書いた場合、3行目は「.」で始まっているので2行目の対象です。つまりThisWorkbook.Worksheets("テスト").Cells(3, 2).Value = 1 + 2 と なるので、「このワークブック」の「テスト」という名前のワークシートの"B3"セルに3という値が入ります。(期待通りの動作)

1
2
3
4
5
Sub test()
    With ThisWorkbook.Worksheets("テスト")
        Cells(3, 2).Value = 1 + 2
    End With
End Sub

この例では3行目が「.」で始まっていません。この場合は2行目のWith ThisWorkbook.Worksheets("テスト")とは関係ない指定となります。 ワークブックやワークシートの指定無しの「"B3"セルの値は1+2である」と書いたのと同じ状態なので好ましくありません。
「テスト」ワークシートが選択(アクティブに)された状態でこのコードを動作させてみると「テスト」ワークシートの"B3"セルに3という値が入るかもしれませんが、他のワークシートが選択(アクティブに)された状態で動作させてみるとそのアクティブなワークシートの"B3"セルに3という値が入ります。(期待していない動作)。
なお、ワークシートのコード窓に書いた場合はアクティブなワークシートではなく、そのコード窓のワークシートのB3セルになります。また、コード内でワークシートをアクティブ(.Activate)にする指定を行った後であればそのアクティブなワークシートになります。

今回のような僅か数行のコードであればおそらく間違えることもないでしょうし、仮に間違って書いたとしてもすぐに気付けるでしょう。しかし、コードが増えると気付きにくくなるので記述の際は十分にご注意ください。

Excel VBA事始め その1

仕事猫
©いらすとや.

「がとらぼ」では5年ほど前にExcel&Access VBAの記事をホンの幾つか書いたことがあるけど、忙しくなってその後が続けられず取り下げた。今回改めてExcelやAccessでのVBAの触りから何か実用的なものを作るというのをやっていきたいかなと思っている。個々の細かいことは他所の詳しいサイトを見て貰うとして「がとらぼ」ではコツみたいなのを主にやりたい。のんびりとね。

個人でたとえば家計簿や趣味のことでデータを一覧や表にするというのをやっている人はいるとは思う。でも、データ集計というのはあまり個人でやることはないかな。
一方で会社の業務ではとにかくデータを集めて集計というのをずっとやっている人もいるでしょう。Excelはデータ集計では非常に便利というか必須のツールです。
業務といえど新卒で雇われてから定年で退職までずっと異動もなく同じ集計をやり続けるということはない筈で、異動もあれば中途退職、逆に中途採用で入ってくることもあるでしょう。「この集計は俺でないとダメだぁ」とかじりついたままで居られても困ります。集計という仕事も次々に別の人に引き継いでいくことでしょう。また、集計自体も変わっていく筈で「勤続30年ですが毎日/毎週/毎月/毎年、何一つ変わりません」ということはないでしょう。
そこで、集計を誰でもできるようにレシピ化するというのが必要になります。

で、日本の会社だと「では誰でもできるように手順書を作りましょう」とやってしまうところが多いかな?そんなおバカな会社は今後は淘汰されていくと思うけど。
ホンの数分の手順でできる程度の集計ならともかく数百のデータソースファイルやデータベースからデータを集めて手作業で数日かかるようなのは注意しても間違いもあるし正確にできるにしてもそもそも時間の盛大な無駄。人間のために「手順書」というレシピを作るくらいならコンピューターにやらせるレシピを作って更新していってね。ExcelやAccessならVBAでどうぞ。

でも、小さな会社であっても会社の誰か1人だけがExcel VBAを触れますというのはダメよ。ホント難しいものではないので何人かができるように。ワークシート関数ウィザードには相当スキルが高くて才能がある人でないとなれないけどVBAで何か書ける/読める/データの振り分け/データの集計程度ならPC触るの初めての人でも1週間も研修すればほぼ誰でもなんとかなりそうなレベルになるかと。
エクセレントなコードにこだわって他人が理解できないようなのじゃなくて泥臭くても良いので何をしたいのかが判るように書くのが大事と思う。でないと、後から何か変更の要があったときに、かつて自分で書いたものであってもじっくり読まないと丸っきり解らないなんてことも。まして他人の書いたのなんて小難しいことがしてあるとメモがあってもチンプンカンプン。これじゃダメ。

以下はWindows 11とExcel 2021の画面での説明になりますがやってること/やること/できることはほぼ20年以上前のExcelから大して変わりません。(Excel 2007から拡張された部分を除く)

Excelの起動から

Excel VBA事始め 1
Excelはスタートメニューから起動します。またはExcelのファイルをダブルクリックすれば起動しますね。

Excel VBA事始め 2
Excelのホーム画面です。今回、Windows 11のダークテーマが有効のPCでExcelを起動したところExcelもダークテーマで起動したのでこれを変更します。
左下の「オプション」をクリック。

Excel VBA事始め 3
「Excelのオプション」画面の左列で「全般」を選択した状態で、右列の「Officeテーマ」を変更します。このページの以下の画像では「カラフル」のテーマを有効にした画面になっています。
右下の[OK]をクリックして変更を確定させてからホーム画面に戻ります。

Excel VBA事始め 4
今回は新規ワークブックを使って操作してみるので「空白のブック」をクリックします。
ExcelではExcelの1つのファイルをワークブック(Workbook)といいます。(次の画像でも)

Excel VBA事始め 5
Excelの基礎の基礎ですが、今後VBAで何かしようと思ったら幾つかの用語を認識することが非常に重要です。
Excelのファイルがワークブック、Workbook(s)です。
1つのワークブックには罫線のページであるワークシート(Worksheet)が1つ以上含まれます。ワークシートは追加や削除や並べ替えが可能です。罫線のページ以外にグラフなどのシートもあります。VBAでは罫線のページであるWorksheet(s)と、ワークシート&の他のシートを区別しないSheetsがあります。
罫線のワークシートの罫線の1マスをセル Cell(セル)といいます。Excel VBAではCells(アドレス)として指定すると1つのセルのことを指し、Cells だけを指定するとワークシート内の全てのセル(1つのワークシート全体)を指します。

Excel VBA事始め 6
横に端から端までが「行」(Row ロー/ロウ)。上から1行目,2行目と上下に並ぶ。Excel 2003までは最大で65535行。(xlsファイル)
Excel 2007以降は拡張されて100万行(1048576行)。(xlsx, xlsmファイル)
6万5千行というのはかなり厳しい制限だったので拡張されたことは喜ばしいけどExcelが重く不安定になったのでそれが凄いデメリット。(Excel 2021でも変わらず)
xlsxファイルがVBAマクロ無し、xlsmファイルがVBAマクロ有りのファイルの拡張子です。

Excel VBA事始め 7
縦に端から端までが「列」(Column カラム/コラム)。左から1列目2列目と左右に並ぶ。Excel 2003までは最大256列。(xlsファイル)
Excel 2007以降は拡張されて16384列。(xlsx, xlsmファイル)
Excelでは標準状態でA列,B列のようにアルファベットの列名になっています。行との混同を防ぐために判りやすいですがアルファベットの列名というのはプログラムでは使いにくいかも。(VBAでは多くは数字の列番号を使うと思います)

Excel VBA事始め 8
範囲は(基本的には)ワークシート内で任意で選択できます。Range (レンジ)。
VBAでは単純な計算時にはあまり使わないかもしれませんが、コピーや集計や装飾等では意外とよく使用します。

Excel VBA事始め 9
ワークシートのセルに埋める計算式がワークシート関数です。VBAを使わなくても自動計算できて大変便利なので好きな人は多用します。「宣言」等を使うことで他のワークブックも参照して計算できます。
しかし、自身の不注意や他人の無知によって破壊されやすく破壊されたことが判りにくく、メンテナンス性が良くないという問題があるため「がとらぼ」の中の人は嫌いです。(特定のセルをロックしたりワークシートの保護をしていても何故か壊されるよね、会社のExcelあるある)
VBAからワークシート関数を変更することが可能です。

VBEで何か書いてみる

Excel VBA事始め 10
Visual Basic Editor (VBE)を開きます。[Alt]+[F11]です。
おそらくVBEを開く前にアクティブになっていたワークシートのコード窓が開きます。上の画像ではSheet1のコード窓が開いています。

Excel VBA事始め 11
今回はあえてsheet1のコード窓にコードを書く。
ワークシートのコード窓にコードを書くとワークシートの指定を省略してもそのワークシートであると認識されます。
ただし、ワークシートというのは削除されることがあり、ワークシートが削除されるとそこに書かれたコードも失われるため、ワークシートにコードを書くのはあまりオススメはしません。
コードを書いたら[F5]で実行。

1
2
3
Sub test()
    Cells(1,1).Value = "Hello Excel VBA!"
End Sub

「サブルーチン」プロシージャを使用し、プロシージャ名はtest。 (1行目)
セル(1行目,1列目)の値(Value)に「Hello Excel VBA!」を指定。(2行目)
testサブルーチンプロシージャを終了。(3行目)。

VBAでは戻り値のない関数をサブルーチン(Sub)に、戻り値のある関数をファンクション(Function)というプロシージャに書きます。

部品/要素(オブジェクト)には階層があります。「事務所」の「3番目の机」の「右の1番上の引き出し」の「ボールペン」のように「book1.xlsmワークブック」の「Sheet1ワークシート」の「A1セル(1行目/1列目)」。
そして「プロパティ」とその「内容」があります。
〜の「ボールペン(オブジェクト)」の「インクの色(プロパティ)」は「赤(内容)」というのはありますが、〜の「ボールペン」の「芯の濃さ(プロパティ)」は「2B(内容)」というのがありえないように、〜の「A1セル(オブジェクト)」の「値(プロパティ)」は「ホニャララ(内容)」というのはありますが、〜の「A1セル」の「高さ(プロパティ)」は「16ポイント(内容)」というのはありません。Excelでセルが個別に高さを持つことはできません。ワークシートで「高さ」プロパティを持つのは「行(Row)」です。

今回はSheet1のコード窓に書いたので Thisworkbook.Worksheets("Sheet1").Cells(1,1).Value = "〜" のようにワークブックやワークシートの指定を行うことをせず、いきなり Cells(1,1).Value = "〜" のように省いて書くことができるが、複数のワークブック、ワークシートを扱うときはワークブックやワークシートを明示するようにする方が無難。(次回以降はワークブックやワークシートを明示する書き方をします)

Excel VBA事始め 12
VBAに書いたコードを実行したらSheet1ワークシートを確認する。
A1セルに「Hello Excel VBA!」が入っているので成功。

次回以降、業務に使えそうなことを少しずついろいろやっていこうと思います。

2021年11月28日: 記事題名に「その1」を追加

Up