3.2 データの読み込み
|
|
ここでは、テキストファイルを読み込んでそのまま表示するフローを作ります。 すでに「Hello ASTERIA world!」で作ったフローとほぼ同じフローですが、確認の意味も込めてもう一度フローを作ってみましょう。 以下のようにコンポーネントを配置して、フローを作ってください。
ここで使用するコンポーネントは、以下の通りです。
これでテキストファイルを読み込むフローが完成しました。 それでは、さっそく実行してみましょう。
実行結果を見ると、ryoma.txtの内容が表示されていることがわかります。 FileGetコンポーネントに設定したプロパティの、それぞれの意味を見ていきましょう。
いわゆる「文字コード」とは、文字集合とエンコーディング方式の組み合わせのことです。 このうち、文字集合とは「含まれる文字を明示した集まり」のことです。文字集合に入っていない文字は、コンピュータ上で使用することができません。もう一方の、エンコーディング方法とは、文字集合に含まれるすべての文字を「どのように数値に対応づけるか」という対応表のことです。 つまり、文字集合とエンコーディング方法の組み合わせが決まれば、それぞれの文字に対応する数値が決まります。 日本では、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ビット目を使わないという特徴があります。 その反面、エスケープシーケンスによって扱う文字集合を切り替えるため、プログラムでの文字列処理には不向きで、主にネットワーク上でのデータ交換に利用されています。 まず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で大幅に増やすことができるようになったわけです。 EBCDICについては、「レガシーシステムと固定長フォーマット」の項に詳しい解説をしていますので、そちらを参照してください。 ASTERIAは、以下の文字コードに対応しています。
また、FileSystem(Get)コンポーネントの場合には、読み込むファイルがどのようなエンコーディングで保存されているのかを FileEncodingプロパティで指定することができます。
このように、ASTERIA上でデータの処理をするときには、かならず文字コードの問題に触れることになりますので、頭の片隅に入れておいてください。 すでに述べたように、Shift_JISとWindows-31Jでは、扱える文字集合とエンコーディング方法が異なります。そのため、Unicodeとの間の相互のマッピングコンバータについても、別のマッピングを利用することになります。 以下に、Shift_JISとWindows-31Jが異なるところをまとめてみました。
ユーザ定義文字は、Unicodeの私用領域にマップされます。 そのときの表は、以下のようになります。
まとめると、Shift_JISと Windows-31Jは、以下の点が異なります。
Oracleのデータベースを読み書きするときには、OracleのJDBCドライバが独自のマッピングコンバータを利用しているので注意が必要です。詳しくは以下のサイトをご覧ください。
|
|
ここでは、CSVファイルを読み込んで表示するフローを作成します。 CSVファイルを読み込む方法は、テキストファイルを読み込む場合とほとんど変わりません。 基本的には同じコンポーネントを利用するのですが、ストリーム形式を CSVにするなどのいくつかの設定が異なります。 それでは、フローを作っていきましょう。
これでCSVファイルを読み込むフローが完成しました。 OutputStreamFormat を CSV、FieldCount を 5と指定することで、FilePathで指定されたファイルを 5フィールドからなる CSV形式のデータとして読み込むことができます。 では、実行してみましょう。
この実行結果から、music.csvをCSV形式のデータとして読み込めていることがわかります。
|
|
ここでは、RDBからレコード形式のデータを読み込むフローを作成します。 RDBからレコードを読み出すためには、RDB(Get)コンポーネントを利用します。 RDB(Get)コンポーネントは、SQL Builderで自動生成した SQL文を実行することで、RDBからデータを読み込む機能を持ったコンポーネントです。 それでは、フローを作っていきましょう。 以下のようにコンポーネントを順に配置してください。
ここから、SQL Builderを使って、RDBから読み込むテーブルとカラム(データ項目)を設定する手順に入っていきます。 では、「品目マスタ」を全件取得する設定をしていきましょう。 まず、Fieldタブを選択してください。
この画面の上半分の白いキャンバスが SQL Builderです。 このキャンバスを使って、読み込むテーブルと結合条件の設定を行います。 その定義内容を元にして、ASTERIAが SQLプロパティに SQL文を自動生成します。 キャンバスの上で、右クリックするとメニューが表示されます。
メニューから「テーブルの追加」を実行すると、Connectionプロパティで設定したRDBから取得できるテーブルの一覧が表示されます。
ここでは「品目マスタ」を選択しましょう。 そうすると、キャンバスに「品目マスタ」テーブルが表示されます。
次にどのカラムを読み込むかを設定します。 「品目マスタ」テーブルを選択して、右クリックメニューから「テーブル全体をフィールド定義に追加」を実行します。
この操作で、テーブルのすべてのカラムがフィールドとして定義されました。
これで、「品目マスタ」のすべてのカラムを読み込む設定が完了しました。 ここでは特に where条件を指定していないので、データを全件取得するようになっています。 次に、以下の設定を行ってください。
この設定は、RDB(Get)コンポーネントから出力されてきたレコード形式のデータを、CSV形式に変換して見やすくするためのものです。 これで、RDBのデータを読み込むフローは完成しました。 実行してみると、RDBの「品目マスタ」を全件取得した結果が CSV形式で表示されます。
ここまでの内容が RDBからデータを読み出すときの基本形なので、しっかり押さえておいてください。
|
|
フィールド定義にソート条件を指定することで、RDBから読み出したレコードをソートすることができます。ソートキーになるフィールドのSort列を「ASC」にすると昇順、「DESC」にすると降順でソートされます。 ここでは、「品目番号」のSort列を「DESC」に設定してみましょう。
フローを実行すると、以下の結果が出力されます。 さきほどの実行結果と比べてみると、「品目番号」をキーとして降順にソートされた結果が出力されていることがわかります。
|
|
フィールドのCondition列を設定することで、条件に一致するレコードだけを読み込むことができます。 例えば、単価が10万円以上のレコードのみを取り出したいとしましょう。 その場合、「単価」のCondition列に「>=100000」を指定します。
この状態でフローを実行すると、以下の結果が得られます。
単価が 100000以上のレコードだけを取得できていることがわかります。
|
|
複数のフィールドに条件設定をする場合、それらすべてを満たすレコードだけ読み込む場合(AND)と、いずれかを満たせば良い場合(OR)とがあります。 その設定はModeプロパティでおこなうことができます。 たとえば、「単位」フィールドに「='セット'」、「単価」フィールドに「>=100000」と設定します。既定値ではModeは「AND」ですので、これら2つの条件をともに満たすレコードだけが読み込まれます。
実行すると、以下の結果が得られます。
Modeを「OR」にすると、2つの条件のうち少なくとも一方を満たすレコードを読み込むことができます。
実行すると、先ほどと違った結果が得られます。
なお、ここで作成したフローは「3.3.3 RDBへデータを書き出す」で利用するので、保存しておいてください。
|
|
複数テーブルの結合(JOIN)も、ASTERIAではSQL文を手書きすることなく実現することができます。
|
ここでは通常の結合(JOIN句を使わないWHERE句による等価結合)を例としていますが、JOIN句を用いるインナージョイン(INNER JOIN)やアウタージョイン(OUTER JOIN)も簡単に実現できます。詳しい方法については、ASTERIA Users Guideの『第10章ASTERIA Designer』のRDB_Getコンポーネントの項を参照してください。 |
それでは、フローを作っていきましょう。 以下のようにコンポーネントを順に配置してください。
ここで、SQL Builderを使って、読み込むテーブルとフィールドの選択、検索条件を設定します。 今回は、見積書、見積書明細、品目マスタの3つのテーブルを結合し、必要なフィールドを全件読み込む設定をしてみましょう。 Fieldタブを選び、上半分のキャンバスで右クリックして「テーブルの追加」を実行します。 そしてテーブルの一覧から「見積書」を選択してください。
続いて、同じ操作を行って「見積書明細」テーブルも追加してください。
さらに、「品目マスタ」テーブルも追加します。
これで、読み込む3つのテーブルを指定することができました。 次に、各テーブルを結合(Join)をします。 ここでは、「見積書」テーブルと「見積書明細」テーブルを「見積番号」フィールドで、「見積書明細」テーブルと「品目マスタ」テーブルを「品目番号」で結合していきます。 「見積書」テーブルの「見積書番号」からドラッグを開始してください。
そのまま右にドラッグを続けます。
そして、「見積書明細」テーブルの「見積書番号」でドロップしてください。
今度は、「見積書明細」テーブルの「品目番号」でドラッグを開始してください。
そのまま右にマウスを移動してドラッグを続けます。
「品目マスタ」テーブルの「品目番号」でドロップしてください。
これで、3つのテーブルが結合する設定ができました。 最後に読み込むフィールドを選択します。 「見積書」テーブルから「見積書番号」、「見積日」を、「見積書明細」テーブルから「見積書明細番号」、「品目番号」、「数量」を、「品目マスタ」テーブルから「品名」、「単位」、「単価」を読み込む場合には、次のように操作します。 「見積書」テーブルをクリックして選択してください。
「見積書番号」フィールドをクリックして選択してください。
Ctrlキーを押しながら「見積日」フィールドをクリックして選択してください。
選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。
「見積書明細」テーブルをクリックして選択し、「見積書明細番号」フィールドをクリックして選択します。
Ctrlキーを押しながら「品目番号」フィールドをクリックして選択してください。
さらに、Ctrlキーを押しながら「数量」フィールドをクリックして選択してください。
選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。
品目マスタテーブルをクリックして選択、「品名」フィールドをクリックして選択してください。
Ctrlキーを押しながら「単位」フィールドと「単価」フィールドをクリックして選択してください。
選択したフィールドの上で右クリックし、メニューから「フィールド定義に追加」を実行してください。
これで、読み込むフィールドをすべてフィールド定義に追加することができました。
次に、Converterコンポーネントのプロパティを設定してください。
この設定により、RDB(Get)コンポーネントから出力されたレコード形式のストリームが CSV形式に変換されます。 これで、RDBから複数テーブルを結合してデータを読み出すフローが完成しました。 それでは、実行してみましょう。
RDBから読み込まれたレコードが CSV形式で表示されました。
|
|
この節では、メールサーバからメールを受信し、そのメールの本文を読むフローを作ってみましょう。 (接続するメールサーバの種類は、POP3サーバです。)
|
POP3サーバとは、メールボックスにメールをためておき、メーラー(メールクライアント)で受信するためのプロトコル「POP3(Post Office Protocol version 3)」をサポートしているサーバのことです。 ASTERIAは、POP3とIMAP4に対応しています。 |
それでは、以下のようにコンポーネントを配置して、フローを作り始めましょう。
これでメールサーバからメールを受信し、本文を読むフローが完成しました。
POP3コンポーネントのストリーム種類表示がこのようになっているのは、ループ処理の開始を意味します。 この例では複数件のメールを受信したときに1通ずつ処理されるという意味になります。 ループについての詳細は「4.3.3 ループ 」をご覧ください。
POP3コンポーネントのDeleteMessagesプロパティにTrueをセットすると、実行時にサーバー上のメールメッセージをすべて削除しますので注意してください。デフォルトでは、メールを読み込んでもサーバ上のメールを削除せずに残す設定となっています。 それでは、フローを実行してメールを受信してみましょう。 はじめに、BlackJumboDogが立ち上がっていることを確認してください。 立ち上がっていなければ、立ち上げておきましょう。 その次に、受信するメールがなければフローを実行してもメールを読み込めないので、メーラーから1通のメールを自分(user@example.net)宛てに送信しておきます。
そして、メーラーで受信する前にフローを実行すると、次のように実行結果が表示されます。
これで、メール本文を読み込むことができました。 ここではメール本文のみを読み込みましたが、もちろん送信元、送信先のメールアドレスや、メールの題名も、簡単に読み込むことが可能です。 詳しくは、POP3コンポーネントのヘルプをご覧ください。
メールサーバ上に複数件のメールが溜まっている状態でこのフローを実行すると、最後の一通の内容が画面表示されます。 これは後述するループ処理の関係で、複数件のメールはすべて一旦読み込まれますが、最後の1件以外のデータはレスポンスとしては出力しない設定となっているためです。 (EndResponseコンポーネントのPackRecordsプロパティをTrueにすることで、全件出力することができます。)
|
|
この節では、添付ファイルつきのメールを受信するフローを作っていきます。 メールの仕組み上、添付ファイルつきのメールは、MIME形式というフォーマットで実現されています。 そのため、いったん本文と添付ファイルを含むMIME形式でメールを受信しておき、そのあとで本文と添付ファイルに分解するという手順を踏むことで、メールの添付ファイルを取り出すことができます。
MIME形式とは、RFC2822で定義されたメールメッセージのフォーマット仕様です。 以下のウェブサイトで詳しく説明されています。 http://www.hitachi-to.co.jp/prod/prod_2/inter/emk/help/TecInfo/message/ それでは、以下のようにコンポーネントを順に配置していってください。
|
Sourceプロパティでは、MQL形式で取り出すメールを指定します。 MQL形式については、この節の最後で説明します。 |
これでメールサーバからメールを受信し、添付ファイルを読み込む処理が完成しました。
このフローは、必ず添付ファイルがついたメールが届くことを前提にしているので、エラー処理をしていません。 もし添付のないメールを受信すると、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] = * のように指定して、ループで取り出すことができます。
|
|
この節では、Excelファイルからセルの値を読み出し、CSVに変換するフローを作っていきます。 ASTERIAでは、Excel上で読み込むセル領域を指定できる Excel Builderという機能を提供しています。 この機能を利用することで、実際に利用されるExcel帳票を見ながら、直感的に読み込む領域を指定することができます。
|
Excel形式のデータは、Microsoft Excel独自の形式で保存されているため、データを取り出すことが困難です。ASTERIAのExcelInput/ExcelOutputコンポーネントは、Excelに依存せずにデータを読み書きすることができるため、非常に使い勝手のよいコンポーネントです。 |
それでは、以下のようにコンポーネントを配置してフローを作ってください。
ここで、Excel Builderを使って、読み込むデータ項目を設定します。
まず、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コンポーネントの設定は完了しました。 次に、以下のようにマッパーのプロパティを設定します。
さらに、マッパーをダブルクリックして開き、以下のようにマッピングします。
以下のように、マッパー関数を設定してください。
マッピングが終了したら、マッパーを保存してから閉じます。 最後に、FileSystem(Put)コンポーネントのプロパティを設定します。
これで、Excelファイルから読み出したデータを、CSVファイルに書き込むフローが完成しました。
このフローを実行すると、指定したファイルパスにCSVファイルが出力されます。
ExcelInputコンポーネントで設定しておいた単一セル、レコードの領域を読み込み、CSVファイルに書き込めていることを確認してください。 |