OutSystemsをじっくり触ってみる
※過去の記事が version 10.0 での記事だったため、version 11.0 の記事に更新しました!
こんにちは、ソリューション技術部の藤山と山崎です。
ポルトガル発のローコードプラットフォーム、OutSystems で「QA管理システム」を作ってみます。
画面キャプチャや説明が多いため、前編、中編、後編の3つの記事に分けて紹介します。
この記事は後編です。
説明を抜かせばサクッと開発できるのでぜひ試してみてください。
この記事について
前編、中編に続き、「QA管理システム」完成を目指します。
今回はOutSystemsの細かい設定も行います。前回ほど高速での開発ではありませんが、ここまで出来れば自身で開発できる知識がある状態になります。
是非チャレンジしてみてください!
この記事は、続きの記事です。 前編、中編からの「Entity」、質問一覧画面、質問登録画面を作成していない人は以下の記事からをどうぞ
OutSystemsって何のこと?って方は以下の記事をどうぞ
「QA管理システム」作成
以下の画面構成の「QA管理システム」作成を目指して作成して行きます。
質問詳細画面(Answers)作成
質問詳細画面(Answers)にあたる画面を追加しましょう。 今回は以下の手順にて簡単に、作成済み「Answer」Entityから簡単に一覧画面を作成します。
1、 「MainFlow」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[MainFlow]をダブルクリックします。
2、質問詳細画面(Answers)の一覧画面を作成します。
2.1、画面右上の[Data]をクリックします。
2.2、「Answer」をドラック&ドロップし、「Answers」を作成します。
権限変更
1、質問詳細画面(Answers)にログイン不要でアクセスできるように設定します。
1.1、「Answers」をクリックします。
1.2、画面右下から[Anonymous]のボックスをクリックします。
回答一覧への直接遷移を削除
ドラック&ドロップにて自動作成された一覧画面は、作成時に自動的にメニューに追加されていますが、今回は質問一覧画面(Questions)から特定の質問を選択し遷移するようにしたい為、メニューからの直接遷移を削除します。
1、画面構成を変更するために、「Widget Tree」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[Common]の[Menu]をダブルクリックします。
1.3、[Widget Tree]をクリックします。
2、「DropDownMenu」で「Answers」側のメニューを削除します。
2.1、「RichWidgets\DoropDownMenu」をクリックし、画面中央の「Answers」のほうであることを確認します。
2.2、「RichWidgets\DoropDownMenu」を右クリックします。
2.3、表示されたメニューから[Delete]をクリックします。
3、 「Common」に存在する「Menu」から「Answers」へのリンクを削除します。
3.1、画面右上の[Interface]をクリックします。
3.2、[Common]をダブルクリックします。
3.3、画面中央の[Answers]を右クリックします。
3.4、表示されたメニューから[Delete]をクリックします。
4、[Answers]が削除されていることを確認します。
4.1、以下の図のように表示されていることを確認します。
TIPS 画面処理について
作業は一旦置いておいて、操作について簡単に説明します。 そのまま「QA管理システム」を作成したい人は読み飛ばして問題ありません。
「Interface」タブ内で作成した「Web Screen」は「Screen Action」という処理、「Preparation」という画面表示時の処理を持たせることが出来ます。
また、「Input Parameter」という画面遷移時に渡されるパラメータ、「Local Variable」という対象画面の処理で利用する事の出来る変数を持たせる事も出来ます。
上記は「Answers」の画面に解りやすいように適当に「Input Parameter」「Local Variable」を追加してみました。 また、自動生成された「Answers」には、「Preparation」と「RefreshAnswerTable」という「Screen Action」が既に自動追加されていることが見て解ると思います。
自動追加されている「Answers」の「Preparation」をダブルクリック選択して見てみましょう。
「GetAnswers」というデータベースからデータを取得する処理が追加されています。「Answers」画面のテーブル一覧「Table Recods」は、ここで取得した結果「GetAnswers.List」を参照し一覧画面を表示させています。
自動追加されている「Answers」の「Screen Action」の「RefreshAnwserTable」は、「Answers」画面の「Reset」ボタンに押下時に呼び出される「Screen Action」です。
RefreshAnswerTable」をダブルクリック選択して見てみましょう。
「RefreshAnswerTable」は「Input Parameter」として「ResetFilters」「ResetPageination」を持っていることに気づいたでしょうか?
「Screen Action」は独自の引数「Input Parameter」、独自の内部変数「Local Variable」を持つことが出来ます。
この「RefreshAnwserTable」は、「Answers」画面の「Reset」ボタンに押下時に呼び出されるようになっています。
パラメータ追加してみよう
質問詳細画面(Answers)は、質問一覧画面(Questions)で選択された特定の質問についての回答を一覧表示させます。
その為に質問詳細画面(Answers)は、質問一覧画面(Questions)から特定の質問ID「QuestionId」を受け渡しを行う必要があります。
まずは、質問詳細画面(Answers)に入力パラメータ「QuestionId」を追加しましょう。
1、 質問詳細画面(Answers)を選択し「Add Input Parameter」をクリックします。
1.1、[MainFlow]の[Answers]を右クリックします。
1.2、表示されたメニューから[Add Input Parameter]をクリックします。
2、 「Name」に「QuestionId」を作成します。
2.1、作成した[Add Input Parameter]をクリックします。
2.2、画面右下の[Name]に「QuestionId」と記入します。
2.3、[Data Type]に「Question Identifier」が自動変換されていることを確認します。
質問詳細画面(Answers)の検索条件追加
質問詳細画面(Answers)に追加した「Input Parameter」「QuestionId」を利用して、特定の質問の回答一覧を表示するよう修正を行いましょう。
特定の質問に対しての回答を一覧表示する為に、検索条件に質問ID(QuestionId)を以下の手順にて追加します。
1、 回答一覧の取得をしている「Aggregate」の「GetAnswers」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[MainFlow]で[Answer]の[Preparation]をダブルクリックします。
1.3、[GetAnswers]をダブルクリックします。
2、 「Aggregate」に条件追加を行うため、「Filters」をクリックします。
2.1、①の[Filters]をクリックします。
3、 条件追加を行うため、「Add Filter」をクリックします。
3.1、表示されたフィルター画面の「Add Filter」をクリックします。
4、 「Question」の「Id」と「QuestionId」がイコールとなる条件を追加するため、フィルター条件「Question.Id = QuestionId」を設定します。
4.1、左下のツリー図から[Attributes]で[Question]の[Id]をクリックします。
4.2、「= QuestionId」と記入します。
4.3、[DONE]をクリックします。
Link作成
質問一覧画面(Questions)にて表示されている質問から、質問詳細画面(Answers)へ遷移出来るように「Link」を作成します。
1、 質問一覧画面(Questions)の「Widget Tree」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[Questions]をダブルクリックします。
1.3、[Widget Tree]をクリックします。
2、 リンクを「Title」に追加します。
2.1、画面右部から[MainContent]で[Row]の[Title]を右クリックします。
2.2、表示されたメニューから[Link to]をクリックします。
2.3、メニューの隣にサブメニューが出ますので[(Another Destination...)]をクリックします。
3、 遷移先に「Answers」を設定します。
3.1、[Select On Click Destination]の画面が出てきますので[UI Flows]の[Main Flow]の[Answers]をクリックします。
3.2、[OK]をクリックします。
4、 「Answers」に追加済みの「Input Parameter」「QuestionId」に対象Rowの「QuestionTable.List.Current.Question.Id」を渡すように設定します。
4.1、[Link]が作成されたことを確認します。
4.2、作成した[Link]をクリックします。
4.3、画面右下の詳細から[QuestionId]に[QuestionTable.List.Current.Question.Id]をクリックします。
これで一通りの画面遷移が完成です!
質問一覧画面のカスタマイズ
ここからは個別の画面の表示部分をカスタマイズしながら「OutSystems」を楽しんでいきましょう。
まずは質問一覧画面(Questions)です。
質問一覧の「Message」の「Length」は最大2000文字となっており、さすがに「Message」を全て表示するとなると長すぎます。 そこで以下の仕様を実現してみましょう。
- 「Message」が50文字以上の場合に49文字+「…」を表示する
1、 回答一覧(Questions)を選択し「Widget Tree」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[QuestionDetail]をダブルクリックします。
1.3、[Widget Tree]をクリックします。
2、 「Message」を含む「Cell」の「True」に「Message」を置くため、「If」を追加します。
2.1、[MainContent]で[Question Table]の[Cell]に[if]をドラック&ドロップします。
3、「True」にその「Message」を追加します。
3.1、[Message]を[True]にドラック&ドロップします。
ここで利用している。「Length」関数はあらかじめ定義されている「Built-in Function」という関数です。 以下の11カテゴリがあり、今回利用したのは「Text」にある「Length」関数で文字列の長さを返す関数です。
- Math
- Numeric
- Text
- Date and Time
- Date Conversion
- Format
- Environment
- URL
- Miscellaneous
- Roles
4、 「if」に条件「Length(QuestionTable.List.Current.Question.Message) <=50」と設定します。
4.1、[if]をダブルクリックします。
4.5、[DONE]をクリックします。
5、 「If」の「False」に新規「Expression」を作成します。
5.1、[False]に[Expression]をドラック&ドロップします。
6、 新規「Expression」のValueに「Concat(Substr(QuestionTable.List.Current.Question.Message,0,49),""…"")」と設定します。
6.1、[False]の[Expression]をダブルクリックします。
6.5、[DONE]をクリックします。
「Built-in Function」を利用し「Substr」関数で前方49文字で切り、「Concat」関数で切り出し済み文字列と文字列「…」とを結合します。
ここでは「Expression」を利用し変数を文字列表示したり、「if」を利用し表示を切り替えたりする方法を理解して頂けましたでしょうか。
また、「Built-in Function」という便利に使える関数すでに用意されており、これらを利用する事でさまざまなことが簡単に実現できるのではないでしょうか?
質問登録画面(QuestionDetail)のカスタマイズ
質問登録画面(QuestionDetail)をカスタマイズしてみましょう。 自動作成されている質問登録画面(QuestionDetail)は、テーブルの全てのフィールドが入力出来るようになっています。 そこで以下の仕様を実現してみましょう。
- 登録時の質問ステータスは「オープン」とする。
- 登録日時は入力せず、現在日時を自動的に登録する。
まずは、質問ステータスの仕様を実現しましょう。
1、質問登録画面(QuestionDetail)を選択し「Widget Tree」を表示します。
1.1、[Interface]をクリックします。
1.2、[QuestionDetail]をダブルクリックします。
1.3、[Widget Tree]をクリックします。
2、「Question Status」の表示を「オープン」のみに設定します。
2.1、[MainContent]で [Container]の[Question_QuestionStatusId]をクリックします。
2.2、画面右下の[Fnabled]で[False]をクリックします。
3、「Update Date Time」を非表示に設定します。
3.1、一番下の[Container]をクリックします。
3.2、[Display]で[False]をクリックします。
4、「Save」ボタンクリック時に実行される「Screen Action」「Save」をの設定画面を表示します。
4.1、[Interface]をクリックします。
4.2、[QuestionDetail]をクリックします。
4.3、[Save]をダブルクリックします。
5、「Valid」True下に「Assign」を追加します。
5.1、[Assign]を[Valid]と[CreateOrUpdateQuestion]の間にドラック&ドロップします。
5.2、[Assign]をクリックします。
6、追加した[Assign]を設定します。
6.1、画面右下に[Variable]と[Value]のテキストボックスがあることを確認します。
6.4、表示されたメニューから「Record1」をクリックします。
6.7、表示されたメニューから「CurrDateTime()」をクリックします。
ここでは「Screen Action」で「Assign」を利用し変数の値変更することを見ることが出来たと思います。
左辺は代入先「変数」ですが、右辺は「Expression」となっており「Built-in Function」を利用することも出来ます。
問詳細画面(Answers)のカスタマイズ
最後に質問詳細画面(Answers)をカスタマイズしてみましょう。 以下の仕様を実現してみましょう。
- 自動作成された検索機能を不要とし非表示とする。
- 一覧はMessageだけ表示に変更し、ヘッダ表示は無しにする。
- 質問詳細画面(Answers)のタイトル下に質問の「Title」、「Message」を表示する。
- 質問詳細画面(Answers)から回答「Answer」の登録が出来るように変更する。
まずは、検索機能を非表示を行ってみます。
1、質問詳細画面(Answers)を「Widget Tree」で表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[Answers]をダブルクリックします。
1.3、[Widget Tree]をクリックします。
2、検索機能を実現している「Filters_Wrapper」の「Display」をFalseに設定します。
2.1、[MainContent]の[AnswerTable_Wrapper]をクリックします。
2.2、[Display]で[False]をクリックします。
テーブル表示をヘッダ無し、「Message」だけの表示に変更します。
1、「Row」下の「Message」以外のCellを削除します。
1.1、[AnserTable]の[Row]をクリックします。
1.2、セル名が[Message]ではないものを右クリックします。
1.3、表示されたメニューから[Table]をクリックします。
1.4、[Table]のサブメニューから[Delete Column]をクリックします。
2、ヘッダ表示を無しに設定します。
2.1、[AnswerTable]をクリックします。
2.2、画面右下の[Show Header]で[No]をクリックします。
質問詳細画面(Answers)に質問の「Title」、「Message」を追加表示します。
1、質問詳細画面(Answers)の「Preparation」を表示します。
1.1、画面右上の[Interface]をクリックします。
1.2、[Answers]の[Preparation]をダブルクリックします。
2、質問を取得するため、「GetQuestion」を追加します。
2.1、画面右上の[Data]をクリックします。
2.2、[Entities]の[GetQuestion]をクリックします。
2.3、画面右下の[Id]で[QuestionId]をクリックします。
2.4、 [GetQuestion]を[Start]と[GetAnswers]の間にドラック&ドロップします。
「OutSystems」では定義済みEntityについては、以下の6個のロジックが自動的に作成され「Screen Action」「Server Action」から簡単に利用することが出来ます。
- Create[Entity名]
- CreateOrUpdate[Entity名]
- Update[Entity名]
- Get[Entity名]
- Get[Entity名]ForUpdate
- Delete[Entity名]
3、質問詳細画面(Answers)を「Widget Tree」で表示します。
3.1、画面右上の[Interface]をクリックします。
3.2、[Answers]をダブルクリックします。
3.3、[Widget Tree]をクリックします。
4、「Expression」を利用し「Title」「Message」の表示を追加します。
4.1、[Maincontenter]の[AnswerTable_Wapper]の上に[Contanier]を二つドラック&ドロップします。
4.2、ドラッグ&ドロップした[Contanier]に[Expression]をドラック&ドロップします。
4.3、ドラッグ&ドロップした上の[Expression]をクリックします。
4.4、画面右下の[Value]で「GetQUestion.Record.Question.Title」とクリックします。
4.6、画面右下の[Value]で「GetQUestion.Record.Question.Message」とクリックします。
最後に、回答「Answer」の登録が出来るように変更してみましょう。
1、質問詳細画面(Answers)に「Answer」の「Local Varriable」を登録用に追加します。
1.1、画面右上の[Interface]をクリックします。
1.2、[Answers]を右クリックします。
1.3、表示されたメニューから[Add Local Variable]をクリックします。
2、「Local Varriable」の名称を「Answer」に設定します。
2.1、[Answer]をクリックします。
2.2、画面右下の[Name]に「Answer」と記入します。
2.3、[Data Type]に[Answer]と自動変換されていることを確認します。
3、質問詳細画面(Answers)を「Widget Tree」で表示します。
3.1、画面右上の[Interface]をクリックします。
3.2、[Answers]をダブルクリックします。
3.3、[Widget Tree]をクリックします。
4、データ投入先として作成済み「Local Varriable」の「Answer」を設定するため、登録用の「Form」を作成します。
4.1、[Maincontenter]の[Container]と[AnswerTable_Wapper]の間に[Form]をドラック&ドロップします。
4.2、[Form]をクリックします。
4.3、画面右下の[Source Record]で[Answer]をクリックします。
5、登録用の「Form」に「Message」入力用の「Input」を追加します。
5.1、作成した[Form]に[Container]をドラック&ドロップします。
5.2、[5.1]で作成した[Container]に[Input]をドラック&ドロップします。
5.3、[Input]をクリックします。
5.4、画面右下の[Variable]で[Answer.Message]をクリックします。
5.5、[Max, Length]に「2000」と記入します。
5.6、[Text Lines]に「5」と記入します。
6、登録用の「Form」に登録ボタンを追加し、新規「Screen Action」をボタンクリック時のアクションとして設定ます。
6.1、[Container]と[AnswerTable_Wapper]の間に[Container]をドラック&ドロップします。
6.2、[6.1]で作成した[Container]に[Button]をドラック&ドロップします。
6.3、[Button]をクリックします。
6.4、画面右下の[Label]に「"登録"」と記入します。
6.5、[Destination]は[Save]をクリックします。
7、新規「Screen Action」の名称を「Save」に設定します。
7.1、画面右上の[Interface]をクリックします。
7.2、[Save]をクリックします。
7.3、画面右下の[Name]に「Save」と記入します。
8、「Save」で「Answer」を新規登録出来るように、「CreateAnswer」を追加します。
8.1、画面右上の[Data]をクリックします。
8.2、[Start]と[End]の間に[CreateAnswer]をドラック&ドロップします。
8.3、ドラッグ&ドロップした[CreateAnswer]をクリックします。
8.4、画面右下の[Source]に「Answer」をクリックします。
9、「Save」で「Question」を更新出来るように、「UpdateQuestion」を追加します。
9.1、[CreateAnswer]と[End]の間に[UpdateQuestion]をドラック&ドロップします。
9.2、ドラッグ&ドロップした[UpdateQuestion]をクリックします。
9.3、画面右下の[Source]に「GetQuestion.record.Question」をクリックします。
10、「Answer」の「QuestionId」、「Question」の「UpdateDateTime」に「CurrDateTime()」を設定します。
10.1、[Start]と[CreateAnswer]の間に[Assign]をドラック&ドロップします。
10.2、ドラッグ&ドロップした[Assign]をクリックします。
10.3、画面右下の[Assignments]に「GetQuestion.Record.Question.UpdateDateTime」と記入します。
10.4、[10.3]の下に「CurrDateTime()」と記入します。
10.5、もう一つのテキストボックスに「Answer.QuestionId」と記入します。
10.6、[10.5]の下に「QuestionId」と記入します。
11、「1-Click Publish」をクリックします。
11.1、画面上部の①アイコンをクリックします。
12、「Open in Browser」をクリックします。
12.1、画面上部の矢印アイコンをクリックします。
13、ブラウザが表示されたら完成です!
13.1、期待通りの画面が表示されることを確認します。
後編まとめ
これで、簡単な「QA管理システム」がOutSystemsで作れたと思います。いかがだったでしょうか。 ここで、まだ追加しなくてはいけない機能がいくつかあります。ステータス更新や、バリデーション処理についてです。 バリデーション検証についてはまた別途記事にする予定ですが、ステータス更新については皆さんへの宿題としてとっておきます。是非試してみてください。
ここまでで、画面での表示条件の追加、「Form」等を利用したデータの登録、「Screen Action」の作成がある程度出来るようになったと思います。 ちょっとしたQA管理としては使える物が出来たと思いますが、まだバリデートなどより詳細な箇所には触れてません。これもまた別の記事で詳細を記載したいと思います。
全3編のまとめ
以上で全3編でお送りした「QA管理システム」はひとまず完成しました。いかがだったでしょうか。
新しい開発手法なのでやりにくいと感じることもあったと思います。しかし、変更などについての強さ、GUIによる理解の早さを考えれば他の開発よりもより少ない学習コストで開発に参画できるんじゃないかなぁと思っています。
また、OutSystemsは入力方法は色々なやり方があります。右クリックからの入力、プルダウンからの入力、メニューからの入力など、そのユーザの使いやすい方法で作業を行うことができます。
別の資料では別の方法を使っている場合がありますが、ゴール地点は一緒なので安心してください。
いろいろ説明をしたいところですが、どんどん記事が膨らんでしまうので、また小出しにして説明します。
まだまだOutSystemsには便利な機能があります。
今後ともどんどん紹介していくので、引き続き記事を読んでいただき、試してみてください!