3.2 データの読み込み

この節では、さまざまなデータを読み込み、ASTERIAで取り扱う方法を学んでいきます。

3.2.1 テキストファイルを読み込む

ここでは、テキストファイルを読み込んでそのまま表示するフローを作ります。

すでに「Hello ASTERIA world!」で作ったフローとほぼ同じフローですが、確認の意味も込めてもう一度フローを作ってみましょう。

以下のようにコンポーネントを配置して、フローを作ってください。

ここで使用するコンポーネントは、以下の通りです。

Component Tab Description
(1) FileSystem(Get) Storage ファイルを読み込む
(2) EndResponse Control 終了(レスポンス)
コンポーネントのプロパティを、設定していきましょう。 (以下、既定値のままでいいプロパティについては説明を省略します。)

(1) FileSystem(Get)
FilePath input_data/ryoma.txt
OutputStreamFormat Text
Encoding Windows-31J

これでテキストファイルを読み込むフローが完成しました。

それでは、さっそく実行してみましょう。

実行結果を見ると、ryoma.txtの内容が表示されていることがわかります。

FileGetコンポーネントに設定したプロパティの、それぞれの意味を見ていきましょう。

- FilePath = input_data/ryoma.txt
読み込むファイルのパスを指定します。 ここに相対パスを指定した場合、ユーザのホームディレクトリからの相対パスとして扱われます。 (この場合は、guestユーザのホームディレクトリからの相対パス指定になります。)
- OutputStreamFormat = Text
読み込んだファイルをどのようなデータ形式とみなすかを指定します。 (この場合は、テキスト形式です。)
- Encoding = Windows-31J
読み込むファイルの文字コードを指定します。 文字コードの詳細については、コラム「文字コードとは」を参照してください。 (この場合は、Windows-31J いわゆる ShiftJIS を指定しています。)

文字コードとは

(1) 文字コードとは

いわゆる「文字コード」とは、文字集合とエンコーディング方式の組み合わせのことです。

このうち、文字集合とは「含まれる文字を明示した集まり」のことです。文字集合に入っていない文字は、コンピュータ上で使用することができません。もう一方の、エンコーディング方法とは、文字集合に含まれるすべての文字を「どのように数値に対応づけるか」という対応表のことです。

つまり、文字集合とエンコーディング方法の組み合わせが決まれば、それぞれの文字に対応する数値が決まります。

(2) 日本語の文字コード

日本では、Shift_JIS、EUC-JP、ISO-2022-JPという文字コードが使われてきました。

Shift_JISは、主にWindowsとMacintoshで利用されている文字コードです。

Shift_JISの文字集合は、基本的にJIS X 0208という規格で定められていますが、実態としては各ベンダーによる独自拡張が重ねられており、規格外の文字を含むデータが大量に存在します。そのためWindowsでは、本来のShift_JISで扱える文字集合に加えて、NEC独自拡張とIBM独自拡張を含む形で文字集合、エンコーディング方法の実装がされているので、規格と実際のずれが生じる状況が長く続きました。その後、このWindowsの独自拡張は、Windows-31Jとして規格化され、混乱状況は改善しています。

EUC-JPは、LinuxやSolarisなどで広く用いられる文字コードです。 漢字の2バイト目がASCIIとかぶらないという特徴があるので、プログラムから日本語データを扱うときに非常に処理がわかりやすくなるというメリットがあります。

ISO-2022-JPは、主にメールに利用されている文字コードです。 7ビットの文字コードで、8ビット目を使わないという特徴があります。 その反面、エスケープシーケンスによって扱う文字集合を切り替えるため、プログラムでの文字列処理には不向きで、主にネットワーク上でのデータ交換に利用されています。

(3) Unicode

まずISOが、世界中の主要な文字を含む統一文字集合ISO 10646の策定をはじめました。それとほぼ同時に、アメリカのコンピュータメーカーが集まるUnicodeコンソーシアムは、同じ目的でそれとは別にUnicodeという文字集合を策定しました。議論の末に、類似の国際規格が2つあってはまずいので、両者が歩み寄る形でUnicode 1.1がISO 10646-1として成立し、統合されることになりました。

ISO 10646-1は、UCS(Universal Character Set)と呼ばれています。UCSには2バイト方式のUCS-2と、4バイト方式のUCS-4があります。このうち、UCS-2はUnicodeとほぼ同じものになっています。

既存のテキスト処理のプログラムは、ASCIIやShift_JISなどの従来の文字コードのデータを処理することを前提にしています。したがって、そこにUCSのデータをそのまま通すと、制御文字などと誤認されたりする問題が生じてしまいます。そのために、UTF(UCS Transfer Format)と呼ばれるいくつかのエンコーディング方法が用いられてます。これらは、UCSのASCII相当部分(0000〜007F)は通常の1バイトのASCII文字に変換し、それ以外の文字をそれぞれの方法でエンコードします。

UTFの一つに、UTF-8があります。UTF-8は、UCS-2/4の1文字を、1〜6バイトの可変長バイト列にエンコードします。ただし、UCSの非ASCII文字はA0〜FFのみを使ってエンコードするため、ASCII以外の文字がASCIIと誤認されるおそれがないという特徴があります。また、UCS-2/4とUTF-8の間のエンコード、デコードは、ビットシフトだけで行うことができるので、データの変換効率の面で有利なエンコード方式と言えるでしょう。

UTF-16は、他のUTF群と目的が異なるUTFです。UTF-16の目的は、UCS-2のテキストにUCS-4の一部の文字を埋め込むことにあります。UTF-16にUCS-4の文字を埋め込むために、UCS-4の1文字を4バイトのサロゲートペアに変換して、UCS-2のテキストに埋め込みます。これにより、1文字が2バイトという前提条件を捨てる変わりに、UCS-2で表現可能な文字数がUTF-16で大幅に増やすことができるようになったわけです。

(4) EBCDIC

EBCDICについては、「レガシーシステムと固定長フォーマット」の項に詳しい解説をしていますので、そちらを参照してください。

(5) ASTERIAでの文字コードの扱い

ASTERIAは、以下の文字コードに対応しています。

  • Shift_JIS / Windows-31J
  • EUC-JP
  • ISO-2022-JP
  • US-ASCII
  • UTF-8
  • UTF-16
  • EBCDIC

ASTERIAでは、基本的にストリームのEncodingプロパティに使用するエンコードを指定することで、文字コードの指定を行います。

また、FileSystem(Get)コンポーネントの場合には、読み込むファイルがどのようなエンコーディングで保存されているのかを FileEncodingプロパティで指定することができます。

このように、ASTERIA上でデータの処理をするときには、かならず文字コードの問題に触れることになりますので、頭の片隅に入れておいてください。

(6) Shift_JISとWindows-31Jの違い

すでに述べたように、Shift_JISとWindows-31Jでは、扱える文字集合とエンコーディング方法が異なります。そのため、Unicodeとの間の相互のマッピングコンバータについても、別のマッピングを利用することになります。

以下に、Shift_JISとWindows-31Jが異なるところをまとめてみました。

  • Shift_JIS/Windows-31J → Unicode のマッピング

JIS X 0208の文字 Shift_JIS/Windows-31Jのコード Shift_JIS→Unicode Windows-31J→Unicode
〜 (1-33, WAVE DASH) 8160 U+301C U+FF5E
‖ (1-34, DOUBLE VERTICAL LINE) 8161 U+2016 U+2225
− (1-61, MINUS SIGN) 817C U+2212 U+FF0D
¢ (1-81, CENT SIGN) 8191 U+00A2 U+FFE0
£ (1-82, POUND SIGN) 8192 U+00A3 U+FFE1
¬ (2-44, NOT SIGN) 81CA U+00AC U+FFE2
IBM独自拡張 ×
NEC独自拡張 ×

ユーザ定義文字は、Unicodeの私用領域にマップされます。 そのときの表は、以下のようになります。

コンバータ Shift_JIS範囲 Unicodeの範囲
Windows-31J F040〜F9FC E000〜E757

  • Unicode → Shift_JIS/Windows-31J のマッピング

Unicodeの文字 Unicodeのコード Shift_JIS Windows-31J
‖ (DOUBLE VERTICAL LINE) U+2016 8161 ×
− (MINUS SIGN) U+2212 817C ×
〜 (WAVE DASH) U+301C 8160 ×
− (FULLWIDTH HYPHEN-MINUS) U+FF0D × 817C
〜 (FULLWIDTH TILDE) U+FF5E × 8160
¢ (FULLWIDTH CENT SIGN) U+FFE0 × 8191
£ (FULLWIDTH POUND SIGN) U+FFE1 × 8192
¬ (FULLWIDTH NOT SIGN) U+FFE2 × 81CA

まとめると、Shift_JISと Windows-31Jは、以下の点が異なります。

  • Windows-31Jは、IBM独自拡張とNEC独自拡張を扱える
  • 一部の記号をUnicodeに変換したときのコードポイントが異なる

つまり、通常はより文字集合の広い Windows-31Jを使っておけば、問題ないでしょう。

(7) OracleのJDBCドライバのマッピング

Oracleのデータベースを読み書きするときには、OracleのJDBCドライバが独自のマッピングコンバータを利用しているので注意が必要です。詳しくは以下のサイトをご覧ください。

(8) 参考サイト

3.2.2 CSVファイルを読み込む

ここでは、CSVファイルを読み込んで表示するフローを作成します。

CSVファイルを読み込む方法は、テキストファイルを読み込む場合とほとんど変わりません。 基本的には同じコンポーネントを利用するのですが、ストリーム形式を CSVにするなどのいくつかの設定が異なります。

それでは、フローを作っていきましょう。

Component Tab Description
(1) FileSystem(Get) Storage ファイルを読み込む
(2) EndResponse Control 終了(レスポンス)
コンポーネントに対して、プロパティを設定してください。

(1) FileSystem(Get)
FilePath input_data/music.csv
OutputStreamFormat CSV
FieldCount 5
Encoding Windows-31J

これでCSVファイルを読み込むフローが完成しました。

OutputStreamFormat を CSV、FieldCount を 5と指定することで、FilePathで指定されたファイルを 5フィールドからなる CSV形式のデータとして読み込むことができます。

では、実行してみましょう。

この実行結果から、music.csvをCSV形式のデータとして読み込めていることがわかります。

3.2.3 RDBからデータを読み込む (1テーブル)

ここでは、RDBからレコード形式のデータを読み込むフローを作成します。

RDBからレコードを読み出すためには、RDB(Get)コンポーネントを利用します。 RDB(Get)コンポーネントは、SQL Builderで自動生成した SQL文を実行することで、RDBからデータを読み込む機能を持ったコンポーネントです。

それでは、フローを作っていきましょう。 以下のようにコンポーネントを順に配置してください。

Component Tab Description
(1) RDB(Get) Storage RDBからの読み込み
(2) Converter Control ストリーム型の変換
(3) EndResponse Control 終了(レスポンス)
コンポーネントのプロパティを順に設定していきましょう。

(1) RDB(Get)
Connection asbook

ここから、SQL Builderを使って、RDBから読み込むテーブルとカラム(データ項目)を設定する手順に入っていきます。

では、「品目マスタ」を全件取得する設定をしていきましょう。

まず、Fieldタブを選択してください。

この画面の上半分の白いキャンバスが SQL Builderです。 このキャンバスを使って、読み込むテーブルと結合条件の設定を行います。 その定義内容を元にして、ASTERIAが SQLプロパティに SQL文を自動生成します。

キャンバスの上で、右クリックするとメニューが表示されます。

メニューから「テーブルの追加」を実行すると、Connectionプロパティで設定したRDBから取得できるテーブルの一覧が表示されます。

ここでは「品目マスタ」を選択しましょう。 そうすると、キャンバスに「品目マスタ」テーブルが表示されます。

次にどのカラムを読み込むかを設定します。 「品目マスタ」テーブルを選択して、右クリックメニューから「テーブル全体をフィールド定義に追加」を実行します。

この操作で、テーブルのすべてのカラムがフィールドとして定義されました。

これで、「品目マスタ」のすべてのカラムを読み込む設定が完了しました。 ここでは特に where条件を指定していないので、データを全件取得するようになっています。

次に、以下の設定を行ってください。

(2) Converter
OutputStreamFormat CSV

この設定は、RDB(Get)コンポーネントから出力されてきたレコード形式のデータを、CSV形式に変換して見やすくするためのものです。

これで、RDBのデータを読み込むフローは完成しました。

実行してみると、RDBの「品目マスタ」を全件取得した結果が CSV形式で表示されます。

ここまでの内容が RDBからデータを読み出すときの基本形なので、しっかり押さえておいてください。

(1) ソートの指定(ORDER BY句)

フィールド定義にソート条件を指定することで、RDBから読み出したレコードをソートすることができます。ソートキーになるフィールドのSort列を「ASC」にすると昇順、「DESC」にすると降順でソートされます。

ここでは、「品目番号」のSort列を「DESC」に設定してみましょう。

フローを実行すると、以下の結果が出力されます。 さきほどの実行結果と比べてみると、「品目番号」をキーとして降順にソートされた結果が出力されていることがわかります。

(2) 条件の指定(WHERE句)

フィールドのCondition列を設定することで、条件に一致するレコードだけを読み込むことができます。

例えば、単価が10万円以上のレコードのみを取り出したいとしましょう。

その場合、「単価」のCondition列に「>=100000」を指定します。

この状態でフローを実行すると、以下の結果が得られます。

単価が 100000以上のレコードだけを取得できていることがわかります。

(3) 条件の結合(AND、OR)

複数のフィールドに条件設定をする場合、それらすべてを満たすレコードだけ読み込む場合(AND)と、いずれかを満たせば良い場合(OR)とがあります。 その設定はModeプロパティでおこなうことができます。

たとえば、「単位」フィールドに「='セット'」、「単価」フィールドに「>=100000」と設定します。既定値ではModeは「AND」ですので、これら2つの条件をともに満たすレコードだけが読み込まれます。

実行すると、以下の結果が得られます。

Modeを「OR」にすると、2つの条件のうち少なくとも一方を満たすレコードを読み込むことができます。

実行すると、先ほどと違った結果が得られます。

なお、ここで作成したフローは「3.3.3 RDBへデータを書き出す」で利用するので、保存しておいてください。

3.2.4 RDBからデータを読み込む (動的なSQLの生成)

ASTERIAでは、SQL文に動的に検索条件を指定することが可能になっています。

ここでは、先ほどの「品目マスタ」の全件取得フローを拡張して、「単価」の下限を動的に検索条件として指定するフローを作成していきます。

それでは、フローを作っていきましょう。 以下のようにコンポーネントを順に配置してください。

Component Tab Description
(1) Mapper Control データのマッピング
(2) RDB(Get) Storage RDBからの読み込み
(3) Converter Control ストリーム型の変換
(4) EndResponse Control 終了(レスポンス)
各コンポーネントのプロパティを、以下のように設定してください。

(1) RDB(Get)
Connection asbook

(2) Converter
OutputStreamFormat CSV

RDB(Get)コンポーネントのFieldタブで、先ほどと同じように「品目マスタ」を全件取得する設定を行います。 そして「単価」のCondition列に「>=?下限?」と設定してください。ここで設定した「?下限?」の部分は、次に設定するSQL Parameterで置き換えられます。

RDB(Get)コンポーネントのSQL Parameterタブを選択して、「下限」というパラメータを追加してください。 直前のマッパーで、この「下限」パラメータに値を差し込んでやることで、先ほどConditionに設定した「?下限?」の部分に値を差し込むことができます。

次にMapperをダブルクリックして開き、以下のようにマッピングしてください。

CONST関数のDataプロパティを設定します。

CONST
Data 80000

CONST関数の出力は、SQL Parameterの「下限」に接続します。 これで、SQL Parameterの「下限」に「80000」が設定され、Conditionの「?下限?」にこの値が差し込まれます。

以上でフローは完成しました。

それでは、実行してみましょう。

実行結果から、「単価」が「80000」以上のレコードが取得されていることがわかります。

SQLパラメータとSQL置換文字列

この節では、「?フィールド名?」の形式を使って、動的にSQLにフィールド値を差し込む方法を扱いました。 この方法をSQLパラメータ方式と呼んでいます。

実は、SQLパラメータ方式でSQLに差し込めるのはSQLの式の値の場合だけという制限があります。 式の値でないテーブル名、カラム名などを値を差し込むことはできません。 例えば、ORDER BY句にカラム名を指定してソート条件を変えたいという要求には、この方法を適用することはできないということです。

そのような場合には、「$文字列$」の形式を使うことで、動的にSQLを組み立てる方法が利用できます。この方法をSQL置換文字列方式と呼んでいます。

SQLパラメータ方式と、SQL置換文字列方式の違いを、以下の表にまとめました。

SQLパラメータ SQL置換文字列
指定形式 ?フィールド名? $文字列$
利用できる場所 SQLの式の値 どこでも可能
パフォーマンス SQL文をキャッシュするので高速 SQL文をキャッシュできないので少し遅い

まとめると、機能的にはSQL置換文字列方式のほうが制限が少なく、パフォーマンスはSQLパラメータ方式のほうが良好です。

パフォーマンスがSQLパラメータ方式のほうがよいのは、SQL置換文字列方式を使っていないSQL文の場合、JDBCの PreparedStatementを再利用でき、RDBサーバが毎回SQL文を解釈する必要がなくなるからです。 一方、SQL置換文字列方式を使った場合、PreparedStatementを再利用できなくなるので、その分だけ遅くなります。

従って、SQLパラメータ方式とSQL置換文字列方式を、以下の指針で使い分けることを推奨します。

  • 検索条件式の値など、SQLパラメータ方式が使えるところは、SQLパラメータ方式を使う
  • テーブル名やカラム名など、SQLパラメータ方式がカバーできないところは、SQL置換文字列方式を使う

さて、ここまでSQLパラメータ方式とSQL置換文字列方式の違いを説明してきましたが、SQL置換文字列方式の具体例として、ORDER BY句を動的に組み立ててソート条件を指定する方法を紹介しておきます。

まず、RDB(Get)コンポーネントのSQL Parameterタブに「ソートキー」を登録します。

そして、SQLプロパティを直接変更して、以下のように ORDER BY句に「$ソートキー$」を指定した SQL文に書き換えます。

※一度でも直接書き換えてしまうと、以後 SQL Builderを使うことができなくなるので注意が必要です。

最後に、RDB(Get)コンポーネントの直前のマッパーで、SQL Parameterの「ソートキー」にRDBのカラム名(例えば「品目番号」など)を差し込んでください。

これで、ORDER BY句にフロー変数を差し込み、ソート条件を動的に指定することができるようになりました。

3.2.5 RDBからデータを読み込む (複数テーブルの結合)

複数テーブルの結合(JOIN)も、ASTERIAではSQL文を手書きすることなく実現することができます。

ここでは通常の結合(JOIN句を使わないWHERE句による等価結合)を例としていますが、JOIN句を用いるインナージョイン(INNER JOIN)やアウタージョイン(OUTER JOIN)も簡単に実現できます。詳しい方法については、ASTERIA Users Guideの『第10章ASTERIA Designer』のRDB_Getコンポーネントの項を参照してください。

それでは、フローを作っていきましょう。 以下のようにコンポーネントを順に配置してください。

Component Tab Description
(1) RDB(Get) Storage RDBからの読み込み
(2) Converter Control ストリーム型の変換
(3) EndResponse Control 終了(レスポンス)
では、プロパティを設定していきましょう。

(1) RDB(Get)
Connection asbook

ここで、SQL Builderを使って、読み込むテーブルとフィールドの選択、検索条件を設定します。 今回は、見積書、見積書明細、品目マスタの3つのテーブルを結合し、必要なフィールドを全件読み込む設定をしてみましょう。

Fieldタブを選び、上半分のキャンバスで右クリックして「テーブルの追加」を実行します。 そしてテーブルの一覧から「見積書」を選択してください。

続いて、同じ操作を行って「見積書明細」テーブルも追加してください。

さらに、「品目マスタ」テーブルも追加します。

これで、読み込む3つのテーブルを指定することができました。

次に、各テーブルを結合(Join)をします。

ここでは、「見積書」テーブルと「見積書明細」テーブルを「見積番号」フィールドで、「見積書明細」テーブルと「品目マスタ」テーブルを「品目番号」で結合していきます。

「見積書」テーブルの「見積書番号」からドラッグを開始してください。

そのまま右にドラッグを続けます。

そして、「見積書明細」テーブルの「見積書番号」でドロップしてください。

今度は、「見積書明細」テーブルの「品目番号」でドラッグを開始してください。

そのまま右にマウスを移動してドラッグを続けます。

「品目マスタ」テーブルの「品目番号」でドロップしてください。

これで、3つのテーブルが結合する設定ができました。

最後に読み込むフィールドを選択します。 「見積書」テーブルから「見積書番号」、「見積日」を、「見積書明細」テーブルから「見積書明細番号」、「品目番号」、「数量」を、「品目マスタ」テーブルから「品名」、「単位」、「単価」を読み込む場合には、次のように操作します。

「見積書」テーブルをクリックして選択してください。

「見積書番号」フィールドをクリックして選択してください。

Ctrlキーを押しながら「見積日」フィールドをクリックして選択してください。

選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。

「見積書明細」テーブルをクリックして選択し、「見積書明細番号」フィールドをクリックして選択します。

Ctrlキーを押しながら「品目番号」フィールドをクリックして選択してください。

さらに、Ctrlキーを押しながら「数量」フィールドをクリックして選択してください。

選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。

品目マスタテーブルをクリックして選択、「品名」フィールドをクリックして選択してください。

Ctrlキーを押しながら「単位」フィールドと「単価」フィールドをクリックして選択してください。

選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。

これで、読み込むフィールドをすべてフィールド定義に追加することができました。

次に、Converterコンポーネントのプロパティを設定してください。

(2) Converter
OutputStreamFormat CSV

この設定により、RDB(Get)コンポーネントから出力されたレコード形式のストリームが CSV形式に変換されます。

これで、RDBから複数テーブルを結合してデータを読み出すフローが完成しました。

それでは、実行してみましょう。

RDBから読み込まれたレコードが CSV形式で表示されました。

3.2.6 メールを受信する

この節では、メールサーバからメールを受信し、そのメールの本文を読むフローを作ってみましょう。 (接続するメールサーバの種類は、POP3サーバです。)

POP3サーバとは、メールボックスにメールをためておき、メーラー(メールクライアント)で受信するためのプロトコル「POP3(Post Office Protocol version 3)」をサポートしているサーバのことです。 ASTERIAは、POP3とIMAP4に対応しています。

それでは、以下のようにコンポーネントを配置して、フローを作り始めましょう。

Component Tab Description
(1) POP3 Network POP3によるメール受信
(2) EndResponse Control 終了(レスポンス)
コンポーネントのプロパティを、以下のように設定していってください。

(1) POP3
Connection asbook_pop3
DeleteMessages True
OutputStreamFormat Text

これでメールサーバからメールを受信し、本文を読むフローが完成しました。

POP3コンポーネントのストリーム種類表示がこのようになっているのは、ループ処理の開始を意味します。 この例では複数件のメールを受信したときに1通ずつ処理されるという意味になります。 ループについての詳細は「4.3.3 ループ 」をご覧ください。

POP3コンポーネントのDeleteMessagesプロパティにTrueをセットすると、実行時にサーバー上のメールメッセージをすべて削除しますので注意してください。デフォルトでは、メールを読み込んでもサーバ上のメールを削除せずに残す設定となっています。

それでは、フローを実行してメールを受信してみましょう。

はじめに、BlackJumboDogが立ち上がっていることを確認してください。 立ち上がっていなければ、立ち上げておきましょう。

その次に、受信するメールがなければフローを実行してもメールを読み込めないので、メーラーから1通のメールを自分(user@example.net)宛てに送信しておきます。

そして、メーラーで受信する前にフローを実行すると、次のように実行結果が表示されます。

これで、メール本文を読み込むことができました。

ここではメール本文のみを読み込みましたが、もちろん送信元、送信先のメールアドレスや、メールの題名も、簡単に読み込むことが可能です。 詳しくは、POP3コンポーネントのヘルプをご覧ください。

メールサーバ上に複数件のメールが溜まっている状態でこのフローを実行すると、最後の一通の内容が画面表示されます。 これは後述するループ処理の関係で、複数件のメールはすべて一旦読み込まれますが、最後の1件以外のデータはレスポンスとしては出力しない設定となっているためです。 (EndResponseコンポーネントのPackRecordsプロパティをTrueにすることで、全件出力することができます。)

3.2.7 メールを受信し、添付ファイルを読み込む

この節では、添付ファイルつきのメールを受信するフローを作っていきます。

メールの仕組み上、添付ファイルつきのメールは、MIME形式というフォーマットで実現されています。 そのため、いったん本文と添付ファイルを含むMIME形式でメールを受信しておき、そのあとで本文と添付ファイルに分解するという手順を踏むことで、メールの添付ファイルを取り出すことができます。

MIME形式とは、RFC2822で定義されたメールメッセージのフォーマット仕様です。 以下のウェブサイトで詳しく説明されています。

http://www.hitachi-to.co.jp/prod/prod_2/inter/emk/help/TecInfo/message/

それでは、以下のようにコンポーネントを順に配置していってください。

Component Tab Description
(1) POP3 Network POP3によるメール受信
(2) MIMEDecode Format MIME形式からのデコード
(3) EndResponse Control 終了(レスポンス)
各コンポーネントのプロパティの設定をしていきましょう。

(1) POP3
Connection asbook_pop3
DeleteMessages True

Sourceプロパティでは、MQL形式で取り出すメールを指定します。 MQL形式については、この節の最後で説明します。

(2) MIMEDecode
Source part[2]
OutputStreamFormat Text
Encoding Windows-31J

これでメールサーバからメールを受信し、添付ファイルを読み込む処理が完成しました。

このフローは、必ず添付ファイルがついたメールが届くことを前提にしているので、エラー処理をしていません。 もし添付のないメールを受信すると、MIMEDecodeコンポーネントでエラーになります。

そのため、このフローを実行する前にあらかじめメーラーで受信処理をしておくことで、メールサーバを空にしておきましょう。

さて、それでは1通のメールを自分(user@example.net)宛てに、テキストファイルを1つ添付して送信してみましょう。 今回は、添付ファイルとして「[HOME]/input_data/soseki.txt」を添付します。

メールを送信したあとに、フローを実行してください。

そうすると、以下のような実行結果が得られます。

これで、メールの添付ファイルが表示されることを確認できました。

今回作ったフローでは、POP3コンポーネントに加えてMIMEDecodeコンポーネントにも、ループ開始の表示が出ています。 これは、メールに複数件の添付ファイルが含まれていた場合に、それを1件ずつ処理するという意味になります。 ただし、今回は Sourceプロパティを「part[2]」と設定したので、複数のファイルが添付されていても1件目だけが読み込まれます。(なお、part[1]はメール本文です。)

MIMEDecodeコンポーネントのSourceプロパティには、MIME形式のデータのどの部分を読み込むかを指定する条件式を設定します。 ここで指定する条件式には、「MQL」と呼ばれるASTERIAの独自の条件式を使います。

MQLについての詳細は、ブランチ開始(BranchStart)コンポーネントのヘルプをご覧ください。

複数件の添付に対応するために、

part[*].header[content-disposition].attribute[filename] = *

のように指定して、ループで取り出すことができます。

3.2.8 Excelファイルから読み込む

この節では、Excelファイルからセルの値を読み出し、CSVに変換するフローを作っていきます。

ASTERIAでは、Excel上で読み込むセル領域を指定できる Excel Builderという機能を提供しています。 この機能を利用することで、実際に利用されるExcel帳票を見ながら、直感的に読み込む領域を指定することができます。

Excel形式のデータは、Microsoft Excel独自の形式で保存されているため、データを取り出すことが困難です。ASTERIAのExcelInput/ExcelOutputコンポーネントは、Excelに依存せずにデータを読み書きすることができるため、非常に使い勝手のよいコンポーネントです。

それでは、以下のようにコンポーネントを配置してフローを作ってください。

Component Tab Description
(1) FileSystem(Get) Storage ファイルを読み込む
(2) ExcelInput Format Excelデータからの入力
(3) Mapper Control データのマッピング
(4) FileSystem(Put) Storage ファイルへ書き込む
(5) End Control 終了
各コンポーネントのプロパティを指定していきましょう。

(1) FileSystem(Get)
FilePath input_data/ExcelInput.xls

ここで、Excel Builderを使って、読み込むデータ項目を設定します。

(2) ExcelInput

まず、ExcelInputコンポーネントをダブルクリックしてください。 以下のダイアログが表示されたら、「マクロを有効にする」をクリックします。

マクロのセキュリティ設定が「高」の場合、Excel Builderを実行することができません。 設定を「中」に変更してからいったんExcelを終了し、再度ExcelInputコンポーネントをダブルクリックしてExcelを起動して下さい。

Excelが立ち上がったら、まず読み込むセル領域を指定するためのテンプレートになる Excel帳票を読み込みます。 ここでは、「[HOME]/input_data/ItemTemplateExcel.xls」を読み込みましょう。

テンプレートのExcelファイルは、フローの実行時に読み込むExcelファイルと「ワークシート名」「ワークシート内のデータレイアウト(セルの配置等)」が一致している必要があります。 ワークシート名が一致していない場合には、実行時にデータを読み取ることができずに例外になる可能性があります。 また、データレイアウトが一致していない場合には、読み取り対象のセルがずれてしまい、正しいデータを読み取ることができない可能性があります。

ツールバーの左下にある、Excel Builderのアイコンをクリックして、Excel Builderを立ち上げます。

Excel Builderの画面が表示されました。 これからこのダイアログで、読み込むデータ項目を指定していきます。

まず「単一セル」のタブを選択し、「追加」ボタンをクリックしてください。 範囲指定ダイアログが表示されるので、Excelシート上の「更新日」の1つ右のセル(E6)を選択して、「$E$6」と表示されたことを確認してから、「OK」ボタンを押して次に進みます。

次に「項目入力」ダイアログが表示されます。ここには、読み込むデータ項目名「更新日」と入力して、「OK」ボタンを押します。

このように、読み込む単一セル項目をすべて入力していきます。 今回の例では、読み込む単一セルは「更新日」のみですので、1つだけで結構です。

次に、明細を読み込む設定を行いましょう。

まず、「レコード」タブを選択して、「追加」ボタンをクリックしてください。そうすると、「範囲指定」ダイアログが開くので、Excelシート上で明細の範囲(B9〜E50)を選択します。

「$B$9:$E$50」と表示されていることを確認してから、「OK」ボタンをクリックすると、「レコード名入力」ダイアログが表示されるので、「明細」と入力してください。

明細の件数をあらかじめ予測できない場合には、ここでの領域選択を多めに設定しておくことをおすすめします。 例えば、最大50000件程度に設定しておけば、ほとんどの場合には設定よりレコードの件数が多くなるという事を防ぐことができるでしょう。

そうすると、レコードリストに「明細」という行が追加されますので、その上でクリックして選択します。

「明細」レコードの定義がレコードフィールドリストに表示されました。

この設定のままだと、フィールド名がExcelの列名になってしまっています。 これでは、後ほどマッパーでマッピングを行う際に、どのフィールドがどのような意味かわかりづらいでしょう。手間はかかりますが、あとで見ても意味がわかるようにしっかりした名前をつけておくことにしましょう。

レコードフィールドリストの一番上の行を選択して、「変更」ボタンをクリックすると、「名前入力」ダイアログが表示されます。

Excelシートの明細ヘッダの1カラム目は「品目番号」なので、ここでも「品目番号」と入力して、「OK」ボタンを押してください。

そうすると、以下のダイアログが表示されます。 今回の実習では、終了条件を使用しませんので「いいえ」をクリックします。

この操作で、フィールドBのフィールド名を変更することができました。同様の操作を繰り返し、CからEのフィールドについても、以下のようにフィールド名を変更してください。

以上で、Excelファイルから読み込むセルの定義が完了しました。 「登録」ボタンをクリックして登録が完了したら、Excelのウィンドウを閉じて終了してください。

Excelを終了させることでExcel Builderも終了し、ASTERIAデザイナに制御が戻ります。

次に、ExcelInputコンポーネントのCellタブを選択して、以下のように型定義を変更してください。

これでExcelInputコンポーネントの設定は完了しました。

次に、以下のようにマッパーのプロパティを設定します。

(3) Mapper
OutputStreamFormat CSV
FieldCount 5
Encoding Windows-31J

さらに、マッパーをダブルクリックして開き、以下のようにマッピングします。

以下のように、マッパー関数を設定してください。

FORMATDATE
Format yyyy/MM/dd

マッピングが終了したら、マッパーを保存してから閉じます。

最後に、FileSystem(Put)コンポーネントのプロパティを設定します。

(4) FileSystem(Put)
FilePath output_data/readExcel.csv

これで、Excelファイルから読み出したデータを、CSVファイルに書き込むフローが完成しました。

このフローを実行すると、指定したファイルパスにCSVファイルが出力されます。

ExcelInputコンポーネントで設定しておいた単一セル、レコードの領域を読み込み、CSVファイルに書き込めていることを確認してください。