Visual Basic for Applications/シートからの読み書き
※ エクセルのシートの見方については、後半で付録として別記。本書では、すでにシートの読み方を知っていることを前提に説明を始める。
シートからの読み取り
[編集]では、まずマクロの練習用に、数値データを下記のように(マクロ側ではなく)excel・calc本体のシートに入れよう。
A | B | C | |
---|---|---|---|
1 | 5 | 14 | |
2 | 3 | 20 | |
3 | |||
4 |
次に、このシートを読み取りましょう。当然ですが、読めない問題を計算することは人間もコンピュータも不可能です。
Microsoft Excel の場合、シートの読み取りのために、Cells(行番号, 列番号).Value
を使います。ただしExcel では、左上のセルA1を、(1行目、1列目) だとして位置を数えることに注意してください。
LibreOffice および OpenOffice の場合、シートの読み取りのために、下記コードのようにThisComponent.Sheets(シート番号).getCellByPosition(列番号, 行番号).Value
を使います。Office の場合、左上A1セルを(0,0) としており、また (列,行) の順番です。(※ Microsoft Excel とは、関数名および位置の数え方が違います。)
また、読み取った値を格納するために、変数を定義します。ここは Excel も LibreOffice なども基本的に同じです。どちらも
Dim 変数名 As 型
で定義できます。整数の型(「整数型」という)を定義する必要がありますので、整数型を意味する Integer (なおインテジャーと読む)で下記のように定義します。
- Excel VBA のコード例
Sub test()
Dim a As Integer
x = Cells(1, 2).Value
MsgBox "B1 の値は " & x
Dim b As Integer
y = Cells(2, 2).Value
MsgBox "B2 の値は " & y
End Sub
- 実行結果
新規ダイアログウィンドウに「
B1 の値は 14
」と表示される。
それをOKすると、次に別の新規ウィンドウが現れ、「
B2 の値は 20
」と表示される。
- (※ windows11 用 office 2021 版 excel で動作を確認ずみ)
- LibreOffice のコード例
REM ***** BASIC *****
Sub Main
Dim x As Integer
x = ThisComponent.Sheets(0).getCellByPosition(0, 0).Value
MsgBox "A1 (0, 0) の値は " & x
Dim y As Integer
y = ThisComponent.Sheets(0).getCellByPosition(0, 1).Value
MsgBox "A2 (0, 1) の値は " & y
End Sub
- 解説
シート番号は、LibreOfficeを立ち上げた初期のままの状態では「0」です。
(列番号, 行番号)という順序については、これは数学のx-y座標の (x, y) という並びと同じだと考えてください。
「列」も x軸 も、横の並びです。
「行」も y軸 も、縦の並びです。
シート側では行は1を起点に数え始めますが、しかしLibreOfice マクロのコード側では0を起点に数え始めます。
また、列「A」は、y座表の「0」に相当します。要するにLibreOffice では一番左上のシートは (0, 0) です。
- 実行結果
新規ダイアログウィンドウに「
A1 (0, 0) の値は 5
」と表示される。
それをOKすると、次に別の新規ウィンドウが現れ、「
A2 (0, 1) の値は 3
」と表示される。
シートへの書き込み
[編集]Excelの場合
[編集]- コード例
Sub test()
Dim x As Integer
x = Cells(1, 2).Value
MsgBox "B1 の値は " & x
Dim y As Integer
y = Cells(2, 2).Value
MsgBox "B2 の値は " & y
Dim z As Integer
z = x + y
Cells(3, 2).Value = z
MsgBox "A3 の値は " & z
End Sub
- 実行結果
- ※ セルB3に数値「34」が書き込みされる。
- 解説
x = Cells(1, 2).Value
のようにCells 以下を右辺にすれば、それは読み取りです。
一般的に、プログラミングにおいて イコール記号 = の意味は、「代入」(だいにゅう)という意味です。
イコール記号「 = 」は、 「右辺の計算結果の値を、左辺に代入しろ」という意味です。
「Value」とは「値」という意味の英単語です。
「Cells(1, 2).Value」の意味は、「1行2列目のセル(B1) に格納されている値」という意味です。
上記のような読み取り加算の処理をしたい場合、「Cells」 や「Value」の部分は、この名前でないと、いけません。
ただし、小文字で「cells」や「value」と入力しても動作しますが、Excel VBA のエディタが自動的に「Cells」や「Value」の表記に修正します。
LibreOfficeの場合
[編集]シートからの読み込みでは、
x = ThisComponent.Sheets(0).getCellByPosition(0, 0).Value
のようにThisComponent
が右辺に来ました。
シートへの書き込みは、単に
ThisComponent.Sheets(0).getCellByPosition(0, 2).Value = z
のように、ThisComponent
を左辺にするだけで可能です。
- コード例
REM ***** BASIC *****
Sub Main
Dim x As Integer
x = ThisComponent.Sheets(0).getCellByPosition(0, 0).Value
MsgBox "A1 (0, 0) の値は " & x
Dim y As Integer
y = ThisComponent.Sheets(0).getCellByPosition(0, 1).Value
MsgBox "A2 (0, 1) の値は " & y
Dim z As Integer
z = x + y
ThisComponent.Sheets(0).getCellByPosition(0, 2).Value = z
MsgBox "A3 (0, 2) の値は " & z
End Sub
- 実行結果
- ※ セルA3に数値「8」が書き込みされる。
これを実行して、ダイアログ「A3 (0, 2) の値は 8」が表示されたのを確認してOKした後、シート側を見に行ってください。
A3の位置のセルに、加算の結果の数値「8」が書き込みされているはずです。
うまくいかない場合
[編集]文字列データとして誤認識の場合
[編集]エクセルなどは、入力値が数値データか文字列データかを区別する。読み取りの際、
- もしセルに数値が右(みぎ)詰めなら、それは数値データとして判定されている。
- もしセルに数値が左(ひだり)詰めなら、文字列データとして判定されている。
これから計算の読み書きに使いたいセルが文字列データとして判定されてしまっていると、マクロ操作の失敗の原因になる。
文字列データに判定されたセルを数値データにするには、
- いったんDeleteキーでそのセルの内容を全部消す。
- そのあと、再度、数値を入力すればいい。
その他
[編集]LibreOfice
[編集]セル名で読み書き
[編集]LibreOffice での読み書きのセル位置の指定の方法は、getCellByPosition 以外の方法もあります。
たとえば getCellRangeByName( )
を使うと、セル名("A1"とか"A2"とかのこと)で読み書きの位置指定ができます。
ByPosition ではなく RangeByName に変わっていることに注意してください。
セル名と言っても、別にmyFavoriteCellとかの命名はできないので、誤解なきよう。
- コード例
REM ***** BASIC *****
Sub Main
Dim x As Integer,y As Integer
x = ThisComponent.Sheets(0).getCellRangeByName("A1").Value
y = ThisComponent.Sheets(0).getCellRangeByName("A2").Value
Dim z As Integer
z = x + y
ThisComponent.Sheets(0).getCellRangeByName("A3").Value = z
MsgBox "計算しました。セルA3を確認してください。"
End Sub
まとめて変数宣言
[編集]変数の宣言では、下記のように、カンマ( , )で区切ることで、まとめて宣言することも可能です。
- コード例
Excel
Sub test()
Dim x, y, z As Integer
x = Cells(1, 2).Value
MsgBox "B1 の値は " & x
y = Cells(2, 2).Value
MsgBox "B2 の値は " & y
z = x + y
Cells(3, 2).Value = z
MsgBox"計算しました。セルB3を確認してください。"
End Sub
確認のため、B3のセル値「34」を消して空白にしておき(B1 = 14 と B2 = 20 はそのまま)、上記コードを実行してみましょう。
LibreOffice
REM ***** BASIC *****
Sub Main
Dim x As Integer,y As Integer
x = ThisComponent.Sheets(0).getCellByPosition(0, 0).Value
y = ThisComponent.Sheets(0).getCellByPosition(0, 1).Value
Dim z As Integer
z = x + y
ThisComponent.Sheets(0).getCellByPosition(0, 2).Value = z
MsgBox "計算しました。セルA3を確認してください。"
End Sub
確認のため、A3のセル値「8」を消して空白にしておき(A1 = 5 と A2 = 3 はそのまま)、上記コードを実行してみましょう。
8がまたA3に書き込みされているはずです。
さらに、
Dim x, y As Integer
と短くまとめる事も可能です。(結果の紹介は省略する。)
※付録: エクセルの復習
[編集]※ 知っていれば、下記は読む必要なし。
エクセルのセルの位置の見方
[編集]さて、表計算ソフト中のシートと、VBAのコードとの、データの読み書きを勉強しよう。これが出来ないとVBAを使い意味が無い。(もし単にWindowsでVisual Studioを使わずにプログラミングしたいだけなら、PowerShell という別の機能がある。)
ともかく、表計算ソフトとVBAによる読み書き話をする。
まず、エクセルの画面は一般に下記のように、行と列に番号がついている。
A | B | C | |
---|---|---|---|
1 | |||
2 |
「行」とは、A,B,C、・・・ のように横の並びである。漢字の「行」の右上の部分が横2本の棒になっているので、関連付けて覚えよう。
「列」とは、1,2,3,・・・ のように、縦の並びである。漢字の列の右側が、縦2本の棒になっているので、関連づけて覚えよう。
エクセルの復習になるが、
A | B | C | |
---|---|---|---|
1 | 1A | 1B | 1C |
2 | 2A | 2B | 2C |
のように、それぞれのセルの位置は、行と列の組み合わせで指定される。