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」が書き込みされているはずです。

うまくいかない場合 編集

文字列データとして誤認識の場合 編集

エクセルなどは、入力値が数値データか文字列データかを区別する。読み取りの際、

もしセルに数値が右(みぎ)詰めなら、それは数値データとして判定されている。
もしセルに数値が左(ひだり)詰めなら、文字列データとして判定されている。

これから計算の読み書きに使いたいセルが文字列データとして判定されてしまっていると、マクロ操作の失敗の原因になる。

文字列データに判定されたセルを数値データにするには、

  1. いったんDeleteキーでそのセルの内容を全部消す。
  2. そのあと、再度、数値を入力すればいい。

その他 編集

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

のように、それぞれのセルの位置は、行と列の組み合わせで指定される。