APEX超入門チュートリアル Part 2 - Excelファイルをクラウドアプリ化する


![スクリーンショット 2016-07-19 14.30.58.png](https://qiita-image-store.s3.amazonaws.com/0/26079/639aba50-b6b7-6ded-c213-891a819d7f97.png "スクリーンショット 2016-07-19 14.30.58.png")


Excelファイルはデータをインポートすることで簡単にクラウドアプリ化することができます。
クラウドアプリ化すればExcelファイルをメールに添付して情報共有するスタイルから脱却し、Excelで管理しているいろんなマイクロ・レガシー業務をモダナイズすることができるでしょう。

本チュートリアルではこんな利用シーンでのAPEXにおけるアプリ開発方法をゼロから学んでいきます。

## 前提条件

- APEX環境はバージョン5.1を利用します。2016年7月19日現在、APEX 5.1のワークスペースは https://apexea.oracle.com から無償で作成可能です。[本チュートリアルのPart 1](http://qiita.com/nkjm/items/40af991e27fd3b71f403)でワークスペース作成方法を解説しています。

## データベース（表）の作成

通常、データベースの表はフィールドや型を指定することで手作業で作成しますが、APEXではスプレッドシート形式のデータをインポートすることで表の作成とデータのインポートを一気におこなうことができます。今回はこのやり方で素早くデータをロードしていましましょう。

#### ファイルをインポートする

APEXにインポートできるファイル形式はCSVです。Excelファイルはまず下図のようにヘッダー部分（フィールド名になります）およびデータ部分という形に整え、CSV形式で保存しておく必要があります。＊ヘッダー部分はあってもなくても構いません。

| フィールド名 | フィールド名 | フィールド名 |
|--:|--:|--:|
| データ | データ | データ |
| データ | データ | データ |

今回はビジネスシーンでよくExcelでやりとりされる商談情報をクラウドアプリで管理できるようにします。
下記に商談情報を保存したサンプルのCSVファイルを用意しましたので本チュートリアルではこのデータを使って作業していきましょう。

https://dl.dropboxusercontent.com/u/149862/APEX_Bootcamp/Pipeline.csv

このファイルをアップロードします。
SQL Workshop > Utilities > Data Workshopを選択します。

![スクリーンショット_2016-07-19_12_34_23.png](https://qiita-image-store.s3.amazonaws.com/0/26079/47404ef1-d530-1747-13ea-7a55ef1885aa.png "スクリーンショット_2016-07-19_12_34_23.png")


Spreadsheet Dataを選択します。するとインポートウィザードがはじまりますので、各ステップを下記の通り入力してデータをインポートします。

![スクリーンショット_2016-07-19_12_34_34.png](https://qiita-image-store.s3.amazonaws.com/0/26079/9daae1af-e22c-0c75-77c4-d1aefbb66140.png "スクリーンショット_2016-07-19_12_34_34.png")


**Target and Method**

- Load to: New table
- Load from: Upload file (comma seperated or tab delimited)
- Nextボタンをクリック

**File Details**

- Text File: CSVファイルを選択
- Seperator: (¥t for tab): ,
- First Row contains column names: チェック
- File Charactor Set: Japanese Shift JIS
- Nextボタンをクリック

**Table Properties**

- Schema: あなたのスキーマ
- Table Name: opportunity
- Preserve Case: チェックなし
- Nextボタンをクリック

**Primary key**

デフォルトのままLoad Dataボタンをクリック。

これでデータがインポートされたはずです。5件のレコードが問題なくインポートされたことを確認してください。

![スクリーンショット_2016-07-19_12_44_37.png](https://qiita-image-store.s3.amazonaws.com/0/26079/6a8ef9e4-8fd2-f353-2052-6b2d6b03f1c8.png "スクリーンショット_2016-07-19_12_44_37.png")


## アプリケーションの開発

次にアプリケーションを新規作成します。いくつかのアプリケーション・タイプがありますが、APEXで新規アプリを開発するときはデスクトップアプリケーションというタイプが一般的です。今回もこのタイプのアプリを作成していきます。

#### デスクトップアプリケーションの作成

App Builder > Createを選択します。

![スクリーンショット_2016-07-19_12_48_35.png](https://qiita-image-store.s3.amazonaws.com/0/26079/e038e7b7-9566-fa1b-92a4-bfbf68edafd3.png "スクリーンショット_2016-07-19_12_48_35.png")

Desktopを選択します。

![スクリーンショット_2016-07-19_14_47_12.png](https://qiita-image-store.s3.amazonaws.com/0/26079/c4231073-cf3d-842a-dd1e-bc1eafe06c60.png "スクリーンショット_2016-07-19_14_47_12.png")


アプリケーション作成のウィザードがはじまりますので下記のように入力していきます。指定がない項目はデフォルトのままでOKです。



**Name**

- Schema: あなたのスキーマ
- Name: 商談管理アプリ
- Nextボタンをクリック

**Pages**

- デフォルトのままNextボタンをクリック。

**Shared Components**

- デフォルトのままNextボタンをクリック。

**Attributes**

- Authentication Scheme: No Authentication
- Language: Japenese (ja)
- Nextボタンをクリック

**Confirm**

- Create Applicationボタンをクリック

これで「商談管理アプリ」が作成されます。
この時点でアプリがどのような仕上がりになっているのかプレビューしておきましょう。

Run Applicationボタンをクリックしてください。

![スクリーンショット_2016-07-19_12_55_40.png](https://qiita-image-store.s3.amazonaws.com/0/26079/496dce22-0020-97ff-ba2f-9b248faf9deb.png "スクリーンショット_2016-07-19_12_55_40.png")


下図のような画面が表示されるはずです。
![スクリーンショット 2016-07-19 12.57.21.png](https://qiita-image-store.s3.amazonaws.com/0/26079/05b7dc4d-dc53-be41-3b92-6650f0a7a5a0.png "スクリーンショット 2016-07-19 12.57.21.png")



## ページのカスタマイズ

#### 商談一覧リージョンの追加

この画面をカスタマイズしてまずは商談情報を一覧できるようにしましょう。
画面したのEdit Pageボタンをクリックしてこのページの編集ツールを起動します。
![スクリーンショット_2016-07-19_13_05_47.png](https://qiita-image-store.s3.amazonaws.com/0/26079/fa50d378-09d5-0944-8d90-ae84ac750f5b.png "スクリーンショット_2016-07-19_13_05_47.png")



この画面はページ・デザイナーと呼ばれ、ページを開発するときのメインとなる画面です。
![スクリーンショット 2016-07-19 13.08.43.png](https://qiita-image-store.s3.amazonaws.com/0/26079/dc5c8ca2-f0df-78e4-3680-598a49333d5c.png "スクリーンショット 2016-07-19 13.08.43.png")



左サイドバーに階層構造でページの構成要素が表示されています。

中央のエリアは簡易プレビュー画面となっており、ここでページのレイアウトなどを確認することができます。

右サイドバーには左サイドバーまたは中央のエリアで現在選択中の構成要素のプロパティが表示され、ここで多くの設定・開発作業をおこなうことになります。

APEXではページの構成要素となる表示領域を「リージョン」と呼んでいます。主なリージョンは左サイドバーの階層構造ではContent Body以下に表示されます。現時点ではContent Body以下には何もリージョンがない状態です。ここに商談一覧を表示するリージョンを作成しましょう。

Content Bodyを右クリックし、Create Regionを選択します。するとNewという新しいリージョンが作成されたことがわかります。
![スクリーンショット_2016-07-19_13_14_39.png](https://qiita-image-store.s3.amazonaws.com/0/26079/ed098bca-7440-4def-33ae-e7eca51c4854.png "スクリーンショット_2016-07-19_13_14_39.png")


同時に、現在そのリージョンが選択された状態なので、右サイドバーにそのプロパティが表示されています。まずこのリージョンの名前を変更しておきましょう。現在Newという名前になっていますが、これを商談一覧に変更します。右サイドバーのTitle属性を商談一覧にします。

- Title: 商談一覧

そして全てのリージョンには「タイプ」があります。現在の商談一覧リージョンのタイプであり、数あるリージョンタイプの中でもっとも原始的なのがStatic Contentです。

これは単にHTMLコードを自由に書けますよ、というリージョンになります。これはこれで柔軟性があるのでときとして有用ですが、今回はもっと簡単に多機能な画面を作っていきます。

今回利用するリージョンタイプはInteractive Gridです。これはAPEX 5.1からの新しいリージョンタイプで、まるでExcelのようにデータを閲覧・編集できるリージョンです。

右サイドバーのTypeをInteractive Gridに変更します。

Type: Interactive Grid


すると左サイドバーおよび画面中央、そして右サイドバーにそれぞれ赤い警告がでます。これは何かの設定が足りていないか間違っていることを意味しています。
![スクリーンショット_2016-07-19_13_23_13.png](https://qiita-image-store.s3.amazonaws.com/0/26079/d9b0a554-d1ac-d9b3-6aa0-0bdc0b19ea57.png "スクリーンショット_2016-07-19_13_23_13.png")


結論から言えば今回はSQL Queryが入力されていないことが原因です。
Interactive Gridはデータベースからデータを取得し、その情報をExcel形式で表示するリージョンです。そのため、このリージョンにはデータソースを必ずSQLで指定する必要があるのです。

というわけで、まず下記の通り非常にシンプルなSQL文を入力します。先ほどデータ・インポートで作成したopportunityテーブルから全件取得するSQLですね。

```sql
select * from opportunity
```

![スクリーンショット_2016-07-19_13_28_50.png](https://qiita-image-store.s3.amazonaws.com/0/26079/d58d6f51-a341-fa0e-927e-094341fa3dee.png "スクリーンショット_2016-07-19_13_28_50.png")



そしてフォーカスをこのテキストフィールドから外すと、自動的に構文チェックが実行されます。エラーがなければ赤い警告がすべて消えるはずです。

この状態で最低限必要なInteractive Gridの設定は以上です。画面右上の青い再生ボタンをクリックすると現状で設定を保存し、同時に出来あがりをプレビューできます。
![スクリーンショット_2016-07-19_13_31_42.png](https://qiita-image-store.s3.amazonaws.com/0/26079/6d19bcd7-5cd3-916c-9f1b-8ec6ed90f4c9.png "スクリーンショット_2016-07-19_13_31_42.png")



下図のような画面が表示されればOKです。インポートしたデータがちゃんと表示されていますね。
![スクリーンショット 2016-07-19 13.32.22.png](https://qiita-image-store.s3.amazonaws.com/0/26079/0f32a8d8-86cb-e9ea-6271-c3cf9db39c21.png "スクリーンショット 2016-07-19 13.32.22.png")


ただしこの状態で「Excelのように編集する」ことはまだできません。

この設定は将来変わる可能性はありますが、現時点ではInteractive Gridのデフォルト設定で、編集機能が無効化されているからです。編集機能を有効化するにはもう一度このページのページ・デザイナーに戻ります。

画面下部のEdit Pageボタンをクリックします。

左のサイドバーで、商談一覧の配下にあるAttributesを選択してください。すると右サイドバーに商談一覧リージョンのさらなる属性情報が表示されます。この一番上にあるEditセクションのEnabledフラグが、編集の有効化をコントロールしています。
![スクリーンショット_2016-07-19_13_35_47.png](https://qiita-image-store.s3.amazonaws.com/0/26079/172f1a04-e9a3-05b2-621d-11ea17f66215.png "スクリーンショット_2016-07-19_13_35_47.png")


これをYesにしてもう一度画面右上のプレビューボタンをクリックしてください。
すると今度はセルをダブルクリックするとデータが編集できるはずです。
![スクリーンショット_2016-07-19_13_38_58.png](https://qiita-image-store.s3.amazonaws.com/0/26079/394f0a7b-b143-6f97-b14d-16107ea564c9.png "スクリーンショット_2016-07-19_13_38_58.png")


データをいくつか編集したあと、Saveボタンをクリックすれば変更内容がすべてデータベースに保存されます。


#### グラフを追加

データが大量に保存されるようになればそれらをいくつかのグラフによって可視化したくなるでしょう。そのようなダッシュボードも簡単に作成できます。

例えば商談のフェーズごとに金額をまとめてグラフで表示したいとします。これを実現するにはグラフを表示する新しいリージョンを現在のページに追加するというやり方が考えられます。

画面下部のEdit Pageボタンをクリックしてまたページ・デザイナーに戻ります。

Content Bodyを右クリックしてCreate Regionを選択します。

リージョンの名前はフェーズ別金額としておきましょう。

- Title: フェーズ別金額

そして肝心のリージョンタイプですが、今回はグラフを表示するリージョンなのでChartを選択します。

- Type: Chart


すると左サイドバーでなにやら警告が表示されました。
![スクリーンショット_2016-07-19_13_53_44.png](https://qiita-image-store.s3.amazonaws.com/0/26079/e5235a93-0160-c7c0-de08-3e7530fff4b6.png "スクリーンショット_2016-07-19_13_53_44.png")



この警告となっている構成要素を左サイドバーで選択してみます。

するとSourceセクションのSQL Queryと、Column MappingセクションのLabelおよびValueの設定が必要なことがわかります。

![スクリーンショット_2016-07-19_13_55_03.png](https://qiita-image-store.s3.amazonaws.com/0/26079/b315ee67-ca76-ae69-20df-2b6c8d727c96.png "スクリーンショット_2016-07-19_13_55_03.png")


グラフを表示するには元になるデータが必要です。まずこのデータを取得するSQLが必要なのと、SQLで取得したデータの内、どのフィールドをラベルに使用し、どのデータを値にするのかという指定が必要です。

まずSQLは下記のようにフェーズごとにgroup byでデータをグルーピングし、sum()関数にてそれぞれのフェーズでの金額を合算しています。

```sql
select "フェーズ", sum("金額") total_amount from opportunity group by "フェーズ"
```

そしてLabelにフェーズ、Valueにフェーズ別の合算金額であるtotal_amountを指定します。

- Label: フェーズ
- Value: TOTAL_AMOUNT

![スクリーンショット_2016-07-19_14_01_13.png](https://qiita-image-store.s3.amazonaws.com/0/26079/3be761df-0256-75a7-7010-a08c367c3e44.png "スクリーンショット_2016-07-19_14_01_13.png")


これでChartリージョンに必要な設定が揃いました。
画面右上のプレビューボタンをクリックして表示を確認してみましょう。
![スクリーンショット 2016-07-19 14.02.46.png](https://qiita-image-store.s3.amazonaws.com/0/26079/c551f7bf-a923-45f5-422a-7defa106d663.png "スクリーンショット 2016-07-19 14.02.46.png")


デフォルトだと上図のように棒グラフで表示されますが、様々なタイプのグラフが用意されており、パラメータ一つで変更できます。例えば、ドーナツ・グラフに変更してみましょう。

画面下部のEdit Pageボタンをクリックしてページ・デザイナーに戻ります。

左サイドバーでフェーズ別金額の配下のAttributesを選択します。すると右サイドバーのChartセクションでTypeがBarになっているのがわかります。
![スクリーンショット_2016-07-19_15_06_57.png](https://qiita-image-store.s3.amazonaws.com/0/26079/6d8c89c4-b072-3387-c9f7-8503614cd8d0.png "スクリーンショット_2016-07-19_15_06_57.png")

これをDonutに変更します。

Type: Donut


画面右上のプレビューボタンをクリックして表示を確認してみましょう。下図のようにグラフがドーナツ型に変更されているはずです。
![スクリーンショット 2016-07-19 14.07.34.png](https://qiita-image-store.s3.amazonaws.com/0/26079/b8d7c230-416d-11c5-2f9b-58e14912bd81.png "スクリーンショット 2016-07-19 14.07.34.png")



#### レイアウトの変更


次に、画面のレイアウトを少し変更しましょう。グラフは最も目を引くページのトップに移動して一目で現在の商談状況を確認できるようにしましょう。

画面下部のEdit Pageボタンをクリックしてページ・デザイナーに戻ります。

左サイドバーのフェーズ別金額をドラッグ&ドロップで商談一覧の上に移動します。
![スクリーンショット_2016-07-19_15_08_06.png](https://qiita-image-store.s3.amazonaws.com/0/26079/3c0072a8-4cda-e132-132c-ba4f4d865818.png "スクリーンショット_2016-07-19_15_08_06.png")


下図のようになればOKです。
![スクリーンショット 2016-07-19 14.12.22.png](https://qiita-image-store.s3.amazonaws.com/0/26079/1bbb2e57-48a0-9b89-09f6-25c74149ff4f.png "スクリーンショット 2016-07-19 14.12.22.png")

画面右上のプレビューボタンをクリックして表示を確認してみましょう。グラフがページのトップに移動しているはずです。
![スクリーンショット 2016-07-19 14.13.09.png](https://qiita-image-store.s3.amazonaws.com/0/26079/757547fe-113a-dbd9-f32a-102bd1b17de6.png "スクリーンショット 2016-07-19 14.13.09.png")


ちなみに、リージョンはこのように縦に追加していくだけでなく、横方向に並べることも可能です。せっかくなのでもう一つ、担当営業別の金額を表示するグラフを作成してフェーズ別金額の横に並べるようにしてみましょう。

画面下部のEdit Pageボタンをクリックしてページ・デザイナーに戻ります。

Content Bodyを右クリックしてCreate Regionを選択します。例によって新しいリージョンが作成されますので下記のようにまず名前とタイプを設定します。

- Title: 担当営業別金額
- Type: Chart


![スクリーンショット_2016-07-19_14_23_32.png](https://qiita-image-store.s3.amazonaws.com/0/26079/0a3ba2da-981f-f441-6ede-4337ca0d8760.png "スクリーンショット_2016-07-19_14_23_32.png")



次に左サイドバーで警告が出ている構成要素を選択します。すると前回と同じくSQL QueryとLabel, Valueを指定する必要があるということで下記の通り入力します。

```sql
select "担当営業", sum("金額") total_amount from opportunity group by "担当営業"
```

- Label: 担当営業
- Value: TOTAL_AMOUNT

![スクリーンショット_2016-07-19_14_23_46.png](https://qiita-image-store.s3.amazonaws.com/0/26079/d9504f8e-abed-5501-752a-91c692bfcd62.png "スクリーンショット_2016-07-19_14_23_46.png")


これでリージョンとしては完成ですが、レイアウトを少し変更してフェーズ別金額グラフの右隣に担当営業別金額が表示されるようにしましょう。

左サイドバーで担当営業別金額をドラッグ&ドロップでフェーズ別金額の次の位置に移動します。このとき、担当営業別金額がフェーズ別金額の配下に入らないように注意してください。あくまでも次に入るように。

![スクリーンショット_2016-07-19_14_25_54.png](https://qiita-image-store.s3.amazonaws.com/0/26079/225f87ab-5c75-7ca6-4c2a-9638db9e7397.png "スクリーンショット_2016-07-19_14_25_54.png")


そして左サイドバーで担当営業別金額を選択し、右サイドバーのLayoutセクションを見てみてください。
![スクリーンショット_2016-07-19_14_27_31.png](https://qiita-image-store.s3.amazonaws.com/0/26079/0a2943e1-5368-5244-f217-6954cb35c5cb.png "スクリーンショット_2016-07-19_14_27_31.png")


ここのStart New RowがYesになっていると、このリージョンは改行して前段のリージョンの下に表示されます。これをNoにすると前段のリージョンの右隣に配置されます。中央のプレビューでも確認できると思います。
![スクリーンショット 2016-07-19 15.27.01.png](https://qiita-image-store.s3.amazonaws.com/0/26079/ab41b7ed-7b1f-c94e-4ac5-ab65a766c786.png "スクリーンショット 2016-07-19 15.27.01.png")

これで画面右上のプレビューボタンをクリックして表示を確認してみましょう。新しい担当営業別金額グラフがフェーズ別金額の隣に表示されるはずです。

![スクリーンショット 2016-07-19 14.30.58.png](https://qiita-image-store.s3.amazonaws.com/0/26079/4947476b-e76e-e0c9-7ff2-f6c5b198e384.png "スクリーンショット 2016-07-19 14.30.58.png")


## まとめ

Excelをクラウドアプリ化することで、まず複数人がいつでも更新できるようになります。そしてWebアプリであってもExcelと同じような操作性で、データを可視化するグラフも簡単に追加できます。

しかしメリットはそれだけにとどまりません。他のシステムからAPIでデータにアクセスできるようになり、さらにはOracle Database Cloudではデータをそのまま機械学習で分析することが可能です。

## 次のステップ

- [APEX超入門チュートリアル Part 3 - センサーデバイスからデータを受け取るIoTバックエンドを構築する](http://qiita.com/nkjm/items/49ba467ac9da306d53f7)