Excel VBA CSVデータ読み込み オブジェクト指向
今回はExcel VBAでクラスを利用して、CSVデータを読み込む方法を紹介します。
まず、図1のように、標準モジュール「Mdl」、クラスモジュール、「Item」、
「Calculator」、「ReadCsv」を用意します。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/1-1.png)
また読み込みに使用するCSV データは図2のようになっています。1レコード目は
見出しとなっており、2レコード目から果物の商品名、個数、値段がデータとして
記述されています。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/31ab8c46c9d522ceda939f49b1617f49.png)
まず最初に、果物のデータを格納するエンティティクラスである、Itemクラスを
作成します。Itemクラスは図3のようになっています。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/2-1.png)
Itemクラスには商品名「name」と商品の個数「num」、商品の価格「price」を
用意します。またフィールドのセッター、ゲッターを準備します。これでCSVデータ
のレコードを格納するクラスの準備ができました。
次にCSVデータを実際に読み込むクラス、「ReadCsv」クラスを作成します。
「ReadCsv」クラスは図4、図5のようになっています(長いので分割して表示)。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/3-2.png)
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/4-1.png)
図4では、CSVデータを格納したインスタンスを入れる、「itemcollec」という
Collection型の変数を準備します。これでインスタンスの集合を扱えるように
なります。また、この「itemcollec」を利用できるように、「getItemcollec」
というゲッターを用意します。
さらに「getFilePath」というメソッドを用意して、ファイルパスを取得できる
ようにします。このメソッドは「ReadCsv」クラスの中でしか使わないので、
「private」で修飾しています。これで公開されないメソッドになります。
次に図5は「read」メソッドの中身です。Item型の「obj」、CSV データ
を読み込む際に一旦格納する配列「buf (3)」、ファイルパス用変数の「path」
を用意します。Option Base 1としているので、配列の下限値が1となっています。
そして、クラス内のメソッドを使用し、「path = getFilePath」として、
CSVファイルのパスを取得します。ここでpathの中身が空文字の時は処理を
中断するようにしてあります。
次に「itemcollec」のインスタンスを生成します。次にデータの見出し行は
読み取りたくないので、「linenumber」という変数を用意します。
そして、「Open path For Input As #1」と 「Do Until EOF(1)〜Loop」
の中身を記述します。この中で、「linenumber」が1以外の時は、item型の
「obj」インスタンスを生成します。そして、セッターを呼び出して、CSV
データをインスタンスのフィールドに格納します。
「linenumber」が1の時は、「obj」インスタンスのフィールドには値をセット
しないので、見出しをフィールドに持ったインスタンスが生成されません。
さらに、「itemcollec.Add obj」としてインスタンスをコレクションである
itemcollecに加えています。インスタンスの集合を作っていきます。
これをデータレコード分、新しいインスタンスを生成しコレクションに追加します。
例外処理のHandleErrは、オープンしたファイルを確実に閉じるために記述
しています。これをしないと、例外が発生したときにCSVファイルが開いたままに
なります。
最後に、読み取ったCSVデータを計算するクラス、「Calculator」を作成します。
「Calculator」クラスは図6のようになります。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/5-1.png)
まず、フィールドにReadCsv型の変数「reader」を用意します。そして、
「setReader」というセッターを用意し、CSVデータを読み取ったインスタンス
をセットします。
次に「getTotal」メソッドです。ここでは、「reader.getItemcollec」として
CSVデータをフィールドにセットしたインスタンスの集合から、For Each
構文でItem型のインスタンスを一つずつ取り出します。
そしてItemクラスに定義したゲッター「getPrice」と「getNum」を呼び出し、
「個数×値段」を商品分繰り返し、合計を算出します。
次に「getItemListMsg」では同様に、For Each構文を利用し、商品名を
変数「str」に格納します。これにより商品リストを作成します。
そしてMsgBox関数で表示します。これで全てのクラスの準備は終了です。
それでは実際に、これらのクラスを使ってみましょう。標準モジュールMdlに
処理を記述します。処理内容は、図7のようになります。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/6.png)
図7では、ReadCsv型の「readobj」のインスタンスを生成します。そして
「readobj.read」として、CSVデータ読み取りのメソッドを呼び出します。
実際に呼び出してみると、図8のようになります。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/7.png)
ここで、図2のデータが記述してある、sample.csvを選択します。正常にファイル
が開くと、次の図8のメッセージが表示されます。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/8.png)
そして、Calculator型の「calcobj」のインスタンスを生成し、
「Set calcobj.setReader = readobj」として、ReadCsv型のインスタンスを
セットします。最後に、「Debug.Print calcobj.getTotal」として、
イミディエイトウィンドウに商品の合計金額を表示します。さらに、
「calcobj.getItemListMsg」として商品名をメッセージとして画面に表示
します。
実行結果は、図9と図10になります。
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/10.png)
![](https://nekoni-gohan.com/wp-content/uploads/2021/08/9.png)
今回はExcelVBAでオブジェクト指向を使い、セルにCSVデータを読み込む
事なくデータ処理を行いました。インスタンスのフィールドにデータを読み込む
ことで、データを展開するシートを用意しなくても処理ができるようになります。
今回の記事が皆様の参考になれば幸いです。