情報学入門(データ演習) / 第 3 章

変数とデータ型

値を入れる箱に、名前と大きさを決める

この章のねらい

1. 変数とは

値を格納する変数(variable)という。
変数は主記憶装置に作られる(割り当てられる)。
値を変数に格納することを代入(assignment)という。

代入は数学の等式とは違います。i = -1 + 4 * 2 は 「右側を計算して、その結果(7)を左の箱に入れる」という操作です。 だから i = i + 1 と書けます ── 数学の等式なら成り立ちませんが、「いまの i に 1 を足したものを、i に入れ直す」という意味になります。

動かす① 代入は「箱に入れ直す」こと 1 行ずつ進める

1.1 宣言する

Dim 変数名 As データ型
Dim 変数名1 As データ型, 変数名2 As データ型

この書き方に注意。元資料の書式 Dim 変数名1 As データ型, 変数名2 As データ型 は正しいのですが、 実際には次のように途中の As を省いて書いてしまう間違いが非常に多いです。

Dim a, b, c As Integer  ← c だけが Integer。a と b は Variant
Dim a As Integer, b As Integer, c As Integer  ← これが正しい

動いてしまうので気づきにくく、後の章で 「なぜか計算結果が合わない」という形で表に出ます。 この教材の処理系は、この書き方をすると橙色の警告を出しますので、 下のモデルで一度見ておいてください。

Sub Macro1()
    ' わざと危ない書き方をしてみる
    Dim a, b As Integer

    a = 1
    b = 2
    Cells(1, 1) = "a + b"
    Cells(1, 2) = a + b

    ' 直すとこうなる(上の Dim をこちらに書き換えてみてください)
    ' Dim a As Integer, b As Integer
End Sub

2. データ型

元資料 11・12 枚目のデータ型(値は正しい)
データ型型名大きさ範囲・説明
Byteバイト型1 バイト0〜255
Integer整数型2 バイト−32,768〜32,767
Long長整数型4 バイト−2,147,483,648〜2,147,483,647
Single単精度浮動小数点型4 バイト有効桁は約 7 桁
Double倍精度浮動小数点型8 バイト有効桁は約 15 桁。小数はふつうこれ
Currency通貨型8 バイト小数第 4 位まで正確。金額用
String文字列型1 文字 2 バイト最大約 20 億文字
Date日付型8 バイト西暦 100 年 1 月 1 日〜9999 年 12 月 31 日
Booleanブール型2 バイトTrue または False
Variantバリアント型16 バイト以上何でも入る。型を決めないとこれになる

元資料の表で String の「大きさ」が 「2 バイト」となっていますが、これは1 文字あたりの大きさです。 他の型は「変数 1 個あたり」の大きさなので、同じ欄に並べると読み違えます (可変長の文字列変数は、実際には管理用に 10 バイトほど+文字数×2 バイトを使います)。 表の中で単位が揃っていないので、注記を入れました。

2.1 なぜ型を決めるのか

元資料 10 枚目に、大事な一文があります ── 「元々は、データ型はエラーを発見するために用いられた」

型を決める利点は 3 つあります。

逆に Variant ばかり使うと、 何を入れる箱なのかが分からず、誤りも見つかりません。 「面倒でも型を書く」ほうが、あとの手間が減ります。

Sub Macro2()
    Dim i As Integer
    Dim n As Long

    ' Integer に入る大きさ
    i = 32767
    Cells(1, 1) = "Integer の上限"
    Cells(1, 2) = i

    ' Long なら平気
    n = 2000000000
    Cells(2, 1) = "Long なら"
    Cells(2, 2) = n

    ' ここを実行するとエラーになる(' を外して試してください)
    ' i = 40000
End Sub

3. 文字列

"(ダブルクォーテーション)で囲まれた文字の並びを文字列(string)といいます。 "ABC""法政大学" はどちらも文字列です。

Sub Macro3()
    Dim Str As String
    Dim gakubu As String

    ' セルから読む
    Str = Cells(3, 1).Value
    gakubu = "経営学部"

    ' & でつなぐ
    Cells(4, 1) = Str & gakubu
    Cells(5, 1) = Str & " " & gakubu & " 情報学入門"

    ' 数値もつなげる(数値は自動で文字列になる)
    Cells(6, 1) = "受講者は " & 120 & " 名です"

    ' 文字数を数える
    Cells(7, 1) = "文字数"
    Cells(7, 2) = Len(Str & gakubu)
End Sub

+ ではなく & を使ってください。 VBA では文字列を + でつなぐこともできますが、 数値と混ざったときに足し算をしてしまうことがあります。 "5" + 3 は 8 になり、"5" & 3 は "53" になります。 つなぐつもりなら必ず & ── これで事故が防げます。

4. 練習:円と球

元資料 23 枚目の課題です。半径 r を入力して、次の 4 つを計算します。

円の円周 = 2πr   円の面積 = πr2
球の表面積 = 4πr2   球の体積 = 43 πr3

π の値は Application.WorksheetFunction.Pi で取れます (元資料 23 枚目のとおりです)。3.14159265 と書いてもかまいません。

Sub Macro4()
    Dim r As Double
    Dim pi As Double

    r = Cells(1, 2).Value
    pi = Application.WorksheetFunction.Pi

    Cells(2, 1) = "円の円周"
    Cells(2, 2) = 2 * pi * r

    Cells(3, 1) = "円の面積"
    Cells(3, 2) = pi * r ^ 2

    Cells(4, 1) = "球の表面積"
    Cells(4, 2) = 4 * pi * r ^ 2

    Cells(5, 1) = "球の体積"
    Cells(5, 2) = 4 / 3 * pi * r ^ 3
End Sub

体積の式を 4 / 3 * pi * r ^ 3 と書きました。 ここを 4 / (3 * pi * r ^ 3) と書くとまったく違う値になります。 掛け算と割り算は左から順に計算されるので、 4 / 3 * pi は「(4÷3)×π」です。 迷ったら (4 / 3) * pi * r ^ 3 と括弧を書いてください ── 括弧は多いほうが安全です。

5. 練習:時間の計算

秒数を「○時間○分○秒」に直します。ここで \(整数の割り算)と Mod(余り)が活きます。

Sub Macro5()
    Dim byou As Long
    Dim h As Integer, m As Integer, s As Integer

    byou = Cells(1, 2).Value

    h = byou \ 3600           ' 何時間ぶんあるか(整数の割り算)
    m = (byou Mod 3600) \ 60  ' 残りから何分ぶんか
    s = byou Mod 60           ' さらに残った秒

    Cells(2, 1) = "時間": Cells(2, 2) = h
    Cells(3, 1) = "分":   Cells(3, 2) = m
    Cells(4, 1) = "秒":   Cells(4, 2) = s

    Cells(6, 1) = "まとめて"
    Cells(6, 2) = h & " 時間 " & m & " 分 " & s & " 秒"
End Sub

\/ を間違えないでください。 7325 / 3600 は 2.034… ですが、 7325 \ 36002 です。 時分秒のような「割った商と余りを両方使う」計算では、 \Mod が対になって働きます。

6. 練習:2 点間の距離

点 A(x1, y1) と点 B(x2, y2) の距離は

d = √( (x2x1)2 + (y2y1)2 )

平方根は Sqr 関数です(Sqrt ではありません)。

Sub Macro6()
    Dim x1 As Double, y1 As Double
    Dim x2 As Double, y2 As Double
    Dim d As Double

    x1 = Cells(2, 2).Value
    y1 = Cells(2, 3).Value
    x2 = Cells(3, 2).Value
    y2 = Cells(3, 3).Value

    d = Sqr((x2 - x1) ^ 2 + (y2 - y1) ^ 2)

    Cells(5, 1) = "距離 d"
    Cells(5, 2) = d

    ' 3, 4, 5 の直角三角形になっているか確かめる
    Cells(6, 1) = "x の差":  Cells(6, 2) = x2 - x1
    Cells(7, 1) = "y の差":  Cells(7, 2) = y2 - y1
End Sub

括弧を落とすとどうなるか。 Sqr(x2 - x1 ^ 2 + ...) と書くと、 ^- より先に計算されるので 「x2x12」になってしまいます。 上のプログラムで括弧を 1 つ外して実行し、値がどう変わるか見てみてください ── エラーにならずに間違った答えが出るのがいちばん厄介だ、と体験できます。

7. まとめ

  1. 変数は値を入れる箱。代入は「右を計算して左に入れる操作」。だから i = i + 1 と書ける
  2. Dim 変数名 As データ型。省略すると Variant になる
  3. Dim a, b As Integer では a が Variant になる。1 つずつ書く
  4. 型を決めるのは誤りを早く見つけるため、必要な記憶量を決めるため、意図を伝えるため
  5. 文字列をつなぐのは &+ は数値と混ざると足し算になる
  6. 掛け算と割り算は左から順に^ はいちばん先。迷ったら括弧
  7. \(商)と Mod(余り)は対で使う。平方根は Sqr

章末問題

付録:元資料からの修正一覧

もとにしたのは「情報学入門(VBA)115-2019」全 33 枚です。

元資料この教材種別
データ型の表で String の大きさが「2 バイト」 これは1 文字あたりの値で、他の型(変数 1 個あたり)と単位が揃っていない。注記を追加不正確
Dim 変数名1 As データ型, 変数名2 As データ型 という正しい書式は示しているが、 途中の As を省くと Variant になるという最大の落とし穴に触れていない 警告つきで実演できるようにした。資料 165 では実際にこの書き方(Dim I, S, SS As Integer)が使われている不足
演算子の優先順位と括弧の必要性に触れていない 球の体積(4 / 3 * pi * r ^ 3)と距離(^- より先)で具体的に示した不足
文字列の連結について &+ の違いに触れていない "5" + 3 は 8、"5" & 3 は "53"。つなぐなら必ず &不足
33 枚のうち多くが Excel 画面と数式の画像で、プログラムが本文になっていない 7 つの実行できるプログラムにした体裁
代入と数学の等号の違いが明示されていない 1 行ずつ箱の中身が変わる様子を追えるモデルを追加(i = i + 1 が書ける理由)不足

元資料で正しかったこと。 データ型の範囲(Integer −32768〜32767、Long ±約 21 億、Boolean 2 バイトなど)、 「宣言直後の値は 0 または ""」、「As を省略すると Variant」、 「データ型はもともと誤りを発見するために用いられた」という説明、 円・球・距離の数式(πr2、4πr2、(4/3)πr3、√の中の 2 乗の和)、 π を Application.WorksheetFunction.Pi で取ること ── いずれも正確です。数式は元資料では上付き文字や根号つきで正しく書かれています (PDF から文字を取り出すと落ちてしまうため、この教材で組み直しました)。