VBAによるプログラミング超入門講座(第3回)

By | 2015年7月27日

このページでは、以下の内容について説明しています。

文字列について

プログラムで「言葉」の情報を扱うときは、データ型として「整数型」で無く、「文字列型」を使用します。文字列型の場合も、整数型のように定数と変数が使えます。

  文字列型の定数:  "abc" のように複数の文字を並べてダブルクォーテーション(")で囲んで表します。
  文字列型の変数:  「Dim 変数名 As String」として宣言し、以後、整数型の変数のように扱います。

文字列を扱うプログラム例

文字列を扱うプログラム例を以下に示します。If文で文字列の比較を2回行い、その結果を整数型の変数cmp1とcmp2にそれぞれ1(等しい)と0(異なる)で記憶し、最後に文字列型変数の代入を実行しています。このプログラムを実行した後、変数str1、str2、cmp1、cmp2にどんな値が記憶されるか、考えながら読んでいきましょう。

Dim str1 As String

Dim str2 As String

Dim cmp1 As Integer

Dim cmp2 As Integer

str1 = "abc"

str2 = "efg"

cmp1 = 0

cmp2 = 0

If str1 = str2 Then

cmp1 = 1

End If

If str1 = "abc" Then

cmp2 = 1

End If

str1 = str2

上記のプログラムでは、変数str1に “abc” という文字列を記憶させ、変数str2に “efg” という文字列を記憶させています。その後、If文で変数str1とstr2が等しいか比較しています。この場合、変数str1には”abc”、変数str2には”efg”という異なる文字列が記憶されているので、等しくなく、次の行の「cmp1 = 1」は実行されません。

続いて、変数str1と文字列定数”abc”を比較しています。この場合、変数str1には”abc”が記憶されているので、等しいと判定され、次の行の「cmp2 = 1」が実行されます。

続いて、変数str2で記憶していた文字列を変数str1に上書きしています。このプログラムの実行後、整数型の変数cmp1には0、cmp2には1が記憶され、文字列型の変数str1、str2には共に”efg”が記憶されます。

文字列型の最大文字数は

String型の変数には、何万文字も記憶できます。

文字列型の最小文字数は

String型の最小文字数はゼロです。文字数ゼロの文字列は””として表現します。Excelでは、空のセルを探すとき、空の文字列””を使用しますので、ここで文字数ゼロの文字列の使い方を覚えておいてください。

  str1 = ""
  If str1 = "" Then

文字列型の変数の中身は

コンピューターは、画像、音声、言葉等、全ての情報を「数」に変換して記憶しますので、「str1 = “abc”」と書けば、変数str1には文字a,b,cに対応する何らかの「数」が記憶されるはずです。また記憶した文字数もどこかに数で記憶されるはずです。

ですが、こういう細かい処理はVBAが勝手に処理してくれますので、我々は意識しなくて済みます。変数str1には任意の文字列が記憶でき、後でその情報が取り出せ、比較できれば充分…と割り切って、この疑問は先送りにしましょう。

関数について

プログラミング言語の翻訳ソフトには、役立つプログラム集が付属しており、我々が作るプログラムから利用できます。その個々のプログラムは「関数」と呼ばれます。VBAで利用できる関数には、たとえば画面にメッセージを表示する関数(MsgBox)、文字列を大文字に変換する関数(UCase)、文字列の中から別の文字列を検索する関数(InStr)等があります。

関数は単独で使える「作業指示書」

関数を利用するときは、コンピューターに対して「次の作業指示は、xxxxという名前の関数の指示に従ってくれ。その作業が終わったら再び私が書いた作業指示書のここに戻ってきて、次の行以降の作業指示に従ってくれ」というように、一時的に別の作業指示書で作業を指示する事になります。

関数は、「入力」を受け取り「処理」した結果を「出力」するような小さなプログラムです。我々のプログラムから関数を利用する場合は、以下のように書きます。

str1 = "abc"

str1 = UCase(str1)

If UCase("efg") = "ABC" Then

上記の例は、VBAが用意してくれている「文字列を大文字に変換する関数」である「UCase」を利用した例です。関数UCaseは、カッコ()の中に書いた文字列を受け取って、大文字に変換した結果を返します。関数が返した情報は、’=’を使って変数に記憶させるか、記憶する必要が無い場合、たとえばIf文の中で比較するだけで良い場合は、記憶させずにその場で参照するだけにします。

「UCase(str1)」や「UCase(“efg”)」の記述は、これまで式の中に変数や定数を書いてきた書き方に似ています。この記述は、カッコ内に書いた文字列が大文字に変換された文字列を指す事になりますが、コンピューターの動きとしては、一旦、ここに書かれているプログラムから離れて、別のところに書かれている関数UCaseのプログラムを実行し、その後、再びここのプログラムに戻ってくる…という動きになります。その際、関数UCaseを実行した結果として大文字に変換した文字列を持って帰ってくる事になります。

関数は「探して」使おう

VBAがサポートする関数の数は、膨大な数に及びますので、全部覚える事は難しいと思います。ですので、最初は「何がしたいか?」という我々の要求をはっきりさせてから、インターネットやVBAの入門書の目次/索引で検索する事をお勧めします。実は私も、VBAの関数はあまり覚えておらず、上記の関数UCaseもGoogleで「VBA 文字列 大文字 変換」というキーワードで検索して見つけました。

関数の仕様、たとえば

  • その関数はどういう仕事をするための関数か
  • カッコの中にどんな情報を幾つ書けば良いか
  • 渡す情報のデータ型は何型か?(整数型か文字列型か他の型か)
  • 関数が返す情報はどんな情報か、またその型は何型か

などの仕様は、関数によって異なりますので、これらについてもインターネットや書籍で調べてください。

オブジェクトについて

ここでは引き続き、プログラミング言語の翻訳ソフトに付属している役立つプログラム集について話をします。前項では「関数」の話をしましたが、プログラミング言語はその他にも「オブジェクト」と呼ばれる仕組みを使って、役立つプログラムを提供してくれます。

オブジェクトとは

オブジェクトは、複数の変数と、それに係る関数が一体化したものです。

オブジェクトの特徴

オブジェクトの特徴を以下に示します。

  • (変数のように)情報が記憶できます。
    オブジェクトは、自身に係る情報を記憶するための変数を「所有」します。
  • (関数のように)処理や仕事が実行できます。
  • (変数のように)名前を持ちます。

Excel表のセルを扱うオブジェクト「Range」

以下ではExcel VBAが提供するオブジェクト「Range」を例に挙げて、オブジェクトの特徴について更に説明していきます。RangeはExcelの「セル」を扱うオブジェクトです。セルの特徴を記憶する変数としてValue(値)、Row(行番号)、Column(列番号)、Width(セルの幅)、Height(セルの高さ)などの変数を所有しています。これらの変数に整数や文字列等を記憶させるときは、通常の変数と同じく‘=’演算子を使います。左辺にはオブジェクト名と変数名をカンマ(.)で繋げた名前を記述し、右辺には整数、文字列等を記述します。

オブジェクトRangeを使ったプログラム例

以下に、オブジェクトRangeを使ったソースプログラム例を示します。

Dim abc As Range

Set abc = Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3,1)

abc.Value = 12345

abc.Font.ColorIndex = 5

MsgBox(abc.Value)

MsgBox(abc.Font.ColorIndex)

オブジェクト変数の宣言

オブジェクトを宣言するときは、変数のように「Dim オブジェクト変数名 As オブジェクト型名」と書きます。上記ではRange型のオブジェクト変数abcを宣言しています。

次の「Set abc = Workbooks(“成績表.xlsx”).Worksheets(“Sheet1”).Cells(3,1)」は、宣言したオブジェクト変数abcを使って、現在開いている”成績表.xlsx”のシート”Sheet1”の「3行目の1列目」のセルを扱うための記述です。この記述については後程、説明しますので、ここでは以後、オブジェクト変数abcを使って、”成績表.xlsx”のシート”Sheet1”の「3行目の1列目」のセルが扱えるようになる…とだけ理解しておいてください。

セルの中身を表す変数

「abc.Value = 12345」は、セルの値を保持する変数Valueに整数を記憶させる記述です。記憶した情報は後で取り出せます。たとえば「MsgBox(abc.Value)」と書けば関数MsgBoxに先ほど記憶した整数12345が渡せますし、整数型の変数iに取り出すときは「i = abc.Value」と書けます。

ここで重要な事は、整数型の変数なら単に情報を記憶するだけですが、オブジェクトの場合は記憶すると同時に、記憶した情報に関連する何らかの処理も併せて実行できる事です。Range型オブジェクトが所有する変数Valueに値を記憶させた場合は、セルの中身が記憶した値に変わり、Excelの表に反映されます。Excelの画面でもその変化が確認できます。

フォント色を表す変数

「abc.Font.ColorIndex = 5」は、フォントの情報を持つ変数Fontに色情報を記憶させています。ここで注目して頂きたいのは、変数Fontもオブジェクト変数であり、フォントの色情報を保持する変数ColorIndexを持っているという点です。この場合は前記のように、オブジェクト変数名をピリオド(.)で区切って並べて書きます。値5は、青を示す番号なので「abc.Font.ColorIndex = 5」を実行した後は、「3行目の1列目」のセルのフォントは青に変わります。

ブック、シート、セルを表すオブジェクトについて

Excel VBAでは、そのときに既に開いているExcelのファイル(Excelではファイルの事をブックと呼びます)や、その中のシート、更にその中のセルに相当するオブジェクトは、プログラム開始の時点で既に存在しています。これらのオブジェクトの間には「所有」の関係があり、ブックはシートを所有し、シートはセルを所有しています。ですので、たとえば現在開いているブック” 成績表.xlsx”のシート”Sheet1”の中に存在する「3行目の1列目」のセルに整数1234を入れる場合は、以下のように書きます。

 Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3, 1).Value = 1234

上記のオブジェクト変数「Workbooks」、「Worksheets」、「Cells」は、それぞれブック、シート、セルの情報を扱うオブジェクトですが、いずれも複数のオブジェクトから成るオブジェクトです。したがって複数のオブジェクトの中から所望のオブジェクトを特定するために、カッコを付けてブック名、シート名、行列番号を指定する必要があります。

上記の例では、カッコの中は全て文字列および整数の「定数」で指定しましたが、変数で指定する事も可能です。

Dim fname As String

Dim sname As String

Dim i As Integer

Dim j As Integer

fname = "成績表.xlsx"

sname = "Sheet1"

i = 3

j = 1

Workbooks(fname).Worksheets(sname).Cells(i, j).Value = 1234

プログラムの中でこれらの変数の値を書き換えれば、同じ式で異なるファイル、シート、セルが扱えるようになります。

オブジェクトの「参照」について

前項では、Excelのセルを扱う際、以下のような長い文を書きました。

  Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3, 1).Value = 1234

しかしセルを操作する度に、毎度このような長い文を書くのは大変です。よってVBAや他のプログラミング言語では、オブジェクト変数を使って別のオブジェクトを「参照」できるようになっています。「オブジェクトRangeを使ったプログラム例」で説明した下記プログラムは、Range型のオブジェクト変数を使って別のセルを参照している例です。

  Dim abc As Range
  Set abc = Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3,1)

以下では、シートを扱うWorksheet型オブジェクトを使って、ブック”成績表.xlsx”の中のシート”Sheet1″を参照するプログラム例を紹介します。

  Dim table As Worksheet
  Set table = Workbooks("成績表.xlsx").Worksheets("Sheet1")
  table.Cells(3,3).Value = “xyz”

上記の例では、Worksheet型のオブジェクト変数tableに対して「Set オブジェクト変数名 = オブジェクト変数名」という文を使って、ブック”成績表.xlsx”の中のシート”Sheet1″の「参照」を記憶させています。以後、このオブジェクト変数tableを使えば、ブック名”成績表.xlsx”とシート名”Sheet1″は書かずに、同じシートが参照できるようになります。

「値」の記憶と「参照」の記憶の違いについて

前項で説明したオブジェクト変数の「参照」を記憶する…という意味について、もう少し説明します。これまで整数型や文字列型の変数に対して、’=’ の演算子を使って「変数名=別の変数名」と書いた場合は、右辺の変数が記憶していた「値」がコピーされるだけでした。この事を改めてプログラム例で見てみましょう。

Dim i1 As Integer

Dim i2 As Integer

i1 = 10

i2 = i1

i1 = 20

MsgBox i2    '10が表示される

前記のプログラムでは、最初に整数型の変数i1に10を記憶させた後、「i2 = i1」という文を使って、変数i1が記憶していた値を変数i2に記憶させています。その後、変数i1を「i1 = 20」という文で書き換えていますが、この記述は変数i2が記憶している値には影響しません。故に次の「MsgBox i2」を実行した場合、10が表示されます。

これに対して、オブジェクト変数に対して「Set」と’=’ の演算子を使って「Set オブジェクト変数名 = オブジェクト変数名」と書いた場合は、先程の動きとは違ってきます。

Dim t1 As Worksheet

Set t1 = Workbooks("成績表.xlsx").Worksheets("Sheet1")

t1.Cells(3,3).Value = “xyz”

Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3,3).Value = “abc”

MsgBox t1.Cells(3,3).Value   ' abc が表示される

「Set t1 = Workbooks(“成績表.xlsx”).Worksheets(“Sheet1”)」の文によって、オブジェクト変数t1に対して、「ブック”成績表.xlsx”の中のシート”Sheet1″」の「参照」が記憶されます。これは右辺の記憶していた「値」がコピーされるのでは無く、右辺の存在自体が記憶される…という意味になります。よって以後、左辺のオブジェクト変数と右辺のオブジェクト変数は、同じ実体「ブック”成績表.xlsx”の中のシート”Sheet1″」を指すようになります。

演習問題(その2)

では、オブジェクトを使った演習問題をやってみましょう。Excelで作成した以下のような”成績表.xlsx”が既に開かれているとします。

成績表

この既に開かれている”成績表.xlsx”のシート”Sheet1”を操作して、60点以上の生徒の「名前」と「点数」を青色に変えるプログラムを作成してください。

ヒント

  • セルのフォントの色を青色に変える方法は「フォント色を表す変数」のソースプログラム例を参考にしてください。
  • シート”Sheet1″の2列(B列)目に着目して、2行目から最後の行まで、60点以上かどうか繰り返し確認してください。
  • 表の終わりは、セルが空かどうかで判定してください。
    空のセルでは、セルが所有する変数Valueが空の文字列(ダブルクォーテーション2つ “”で表す)になります。
  • If~Else~End If の中で「Else~End If」間の文が不要なときは、省略して「If~End If」だけで書けます。

解答例

以下、解答例です。

Dim table As Worksheet  ' シートの参照を記憶するオブジェクト変数

Dim row As Integer    ' シートの行番号を記憶する変数

Set table = Workbooks("成績表.xlsx").Worksheets("Sheet1")

row = 2                   ' 2行目から調べる

Do

If table.Cells(row, 2).Value = "" Then  ' 最後まで調べ終わったら終了

Exit Do

End If

If table.Cells(row, 2).Value >= 60 Then

table.Cells(row, 1).Font.ColorIndex = 5

table.Cells(row, 2).Font.ColorIndex = 5

End If

row = row + 1

Loop

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です