---
# System prepended metadata

title: OutSystems

---

# OutSystems

## Component and tools of OutSystems
OutSystemsのコンポーネントとツール
![image](https://hackmd.io/_uploads/ryoVa8M1Jg.png)

其中整個架構可以分成幾個部分:

### Platform Server
Platform Server的功能有:
1. Complier(コンパイル）
2. Deploy（デプロイ）
3. 管理
4. 實行
5. 監視

### Service Studio
Platform Server會接收來自Service Studio的開發內容。

Service Studio是OutSystems的web/mobile app的ビジュアル(visual)開發環境，開發完成後，會透過パブリッシュ(publish)推送到Platform Server中。

每個開發バージョン(version)會被儲存在Platform Database中。

Platform Server會編譯並生成標準程式碼。

### Integration Studio
Integration Studio與Service Studio式相同的開發環境，而Integration Studio可以藉由平台擴充(プラットフォームにエクステンション)生成。

例如: C#/.net/database等外部資源擴充

### Service Center

Service Center是用來建構app的工具，透過檢查インフラ（基礎），掌握可利用的app以及環境。

### LifeTime

Service Center的擴充性能web app，確認アプリケーションのライフサイクル(lifecycle)以及改變配置。
追蹤インフラ內各環境デプロイされたアプリ以及バージョン。
管理各ユーザーやチーム的權限。
收集パフォーマンス(performance)的結果以及ボトルネック(Bottleneck)的修正。

### OutSystems Forge
OutSystems Forgeは、アプリの開発やデリバリーの加速を支援する、ダウンロード可能なコンポーネントのソースです。 


## OutSystems的機能
1. 既存のほぼあらゆるシステムと連携できるという点です。
2. Service Studioで使用できで、データモデルの一部となるエンティティ（Entity)の設計や作成、ビジネスロジックやプロセスの作成です。
3. パブリッシュ中、アプリケーションのコードから標準の最適化されたHTML、CSSやJavaScript、.NETコードが生成されます。
4. 開発環境からQA環境、本番環境へとデプロイしていきます。 デプロイ中には整合性チェックが行われます(開發->測試->部屬->整合性測試)。
5. アプリケーションの依存関係やコードのバージョンに問題がないことを確認するためです。このプロセスではガバナンス(Governance)も行います。
6. インフラはクラウドでもオンプレミス(On-Premise)でも実行できます。

![image](https://hackmd.io/_uploads/HJavS_zJ1g.png)

## Service Studio介紹
OutSystemsのローコードビジュアル(Low-Code Visual)開発環境です。 
Service Studioを使用すると、サーバー(Server)上にアプリやモジュール(module)を作成することができます。
Web/モバイルアプリ向けのUIを仮想的に作成・定義することもできます。
アプリを作成して編集し、更新・パブリッシュしてサーバー上でデバッグ(debug)することもできます。
Service Studioはサーバーのクライアントであり、ローカルではアプリを実行しません。OutSystemsサーバー自体がコードの生成とコンパイルを行い、IISなどのアプリケーションサーバーにアプリをデプロイします。 

![image](https://hackmd.io/_uploads/rJMZkiXyyg.png)

### レイヤー
分為 Processes、Interface、Logic、Data，點選開啟其中的プロパティ(屬性)列表。

![image](https://hackmd.io/_uploads/HydP4jXy1e.png)
![image](https://hackmd.io/_uploads/BymO4jQ1kg.png)

#### プロセスレイヤー(Process Layer)
プロセスには、ビジネスプロセスと手動/自動タスクがありますこれには判断、イベント、待機時間が含まれます。
![image](https://hackmd.io/_uploads/rkJNC6Xy1e.png)

タイマーには、優先順位をつけることもできます。 
複数を同時に実行する場合は、より重要なものを優先させられます。 ある時点で実行を止められるよう、タイムアウト機能も設けられています。 プロセスレイヤーには、最上位で実行されるロジックやタスクに関する情報が多く含まれています。
![image](https://hackmd.io/_uploads/ryd0Camkke.png)

#### インターフェイスレイヤー(Interface Layer)
UIフロー:画面やブロックのグループと呼ばれます。 
画像:UIフローのほかにもグラフィックやアイコンなど様々な画像があります。 
テーマ:アプリのルックアンドフィールを決める。 
スクリプト: 要素で必要になるJavaScriptリソースがあたります。
![image](https://hackmd.io/_uploads/ByQOe07y1x.png)

#### ロジックレイヤー(Logic Layer)
サーバー側やクライアント側で実行される個々のロジックが表示されています。

クライアントアクション(Client actions) <=> サーバーアクション(Server actions)

これにはSOAP Webサービス、RESTサービスやSAPなどの企業システムへのコネクタなどが含まれます。 
![image](https://hackmd.io/_uploads/S1mjgCmyyl.png)

ロジックやコンポーネントへのアクセス(Accessed)権限を制限し、セキュアにする必要があります。ユーザーがどのリソースにアクセスできるかを明確にするには、ロール(roles)を定義し、ユーザーに割り当てます。
**例外のスローや処理についてもこのレイヤーで定義します。**

#### データレイヤー(Data Layer)
様々なエンティティを定義する
![image](https://hackmd.io/_uploads/SyG6gR71Je.png)

### Publish
將模組內容組裝完成後，透過Publish將組建推上Platform Server，Platform Server會自動生成相對應的程式碼並執行在browser。
如果有錯誤則會顯示為紅色，並顯示錯誤訊息在下方狀態列中。
![image](https://hackmd.io/_uploads/ryFZHsmkJg.png)

バージョンをサーバーにパブリッシュした後に以前のバージョンに戻す。Moduleメニューに移動してOpen Other Versionを選択すると、いつでもモジュールのバージョンを切り替えられます。
![image](https://hackmd.io/_uploads/ry6QLRmkke.png)

バージョンをマージ(merge)してパブリッシュすることも、自分の変更で上書くも、手動で比較。
![image](https://hackmd.io/_uploads/HJzXDAmkkg.png)

### キャンバス
キャンバス(canvas)中央には画面のライブプレビュー(life preview)があります。
![image](https://hackmd.io/_uploads/r1BzUimkJg.png)

プロセスやビジネスロジックの場合は、ロジックのビジュアル表現が表示されます。
![image](https://hackmd.io/_uploads/SymPcTX1yg.png)

ツールボックスにはウィジェットではなく、ロジックフローで使用する要素が表示されています。 
![image](https://hackmd.io/_uploads/S1hs5pm11l.png)
割り当てやループ、データベースクエリなどがその一例です。 

### ツールボックス
左にはツールボックス(tool box)が見えます。これはUI要素なので、画面の構築要素となるウィジェットが表示されています。
![image](https://hackmd.io/_uploads/S1tiIj7kkl.png)

### ウィジェットツリー
ウィジェットツリー(widget tree)の切り替えボタンはUI画面での作業中に役立ちます。画面が複雑になるにつれ、ウィジェットツリーを切り替えると、画面内の全ウィジェットの階層を表示できます。
![image](https://hackmd.io/_uploads/BJblFiXykg.png)

### ブレッドクラム
画面下部にはウィジェットのブレッドクラム(breadcrumb)があります。 これが特に役立つのは、作業中の特定のウィジェットの階層を移動する場合です。
![image](https://hackmd.io/_uploads/rk7KF6mJ1e.png)

### データレイヤー
データモデルやエンティティ(Entity)のビジュアル表現をデータベーステーブルとして確認することができます。
![image](https://hackmd.io/_uploads/rkDMsTQyJe.png)

## OutSystems application
OutSystemsには主に2種類のアプリがあります。

* **モバイルアプリ(Mobile app)**
ネイティブモバイルアプリとPWAはオフラインデータストレージに対応しています。

* **リアクティブWebアプリ(Reactive app)**
Reactを基に構築されたSPAは、データを非同期で取得しながら動作しますが、オフライン機能はありません。
リアクティブWebアプリはブラウザでアクセスし、モバイルアプリはデバイス上でネイティブ(natively)に実行され、内部ストレージ(storage)を持つ点が主な違いです。


## Create New Scratch

建立一個新的開發專案，目前OutSystems提供六種開發模式

1.Reactive web app:響應式網頁程序
2.Tablet app:平板介面的應用程序
3.Phone app:手機的應用程序
4.External web portal:入口登入網站
5.Traditional web:基於web的應用程式，可以在桌面運行
6.Service:訪問外部系統的web服務，可使用service/SOAP/REST API等

## データモデル

データモデリングについて、こうしたコンセプト（concept）をモデル化したものを「エンティティ(entity)」と呼んでいます。
![image](https://hackmd.io/_uploads/rJHTOXE1Jg.png)
エンティティはデータベーステーブルとなります。

![image](https://hackmd.io/_uploads/SkxQFQEk1x.png)
**エンティティとテーブルの対応**

* エンティティ - テーブル
* アトリビュート - 列
* エンティティ識別子　-　主キー
* 参照アトリビュート　-　外部キー
* インデックス - インデックス
* レコード　や　インスタンス - タプル

### エンティティ

エンティティによってデータの保持とアクセスが可能になります。
エンティティに新たなレコードが挿入または作成されると、データベーステーブルの行として維持されます。
エンティティはデータセットを保存し、データはアトリビュートで分類されます。
![image](https://hackmd.io/_uploads/r1aPT7Vy1l.png)

### Idアトリビュート(ID Attributes)

Idは各エンティティのレコードを一意に識別するもので、適宜変更できます。
データベーステーブルの主キーとなり、エンティティ間のリレーション作成に役立ちます。
![image](https://hackmd.io/_uploads/ry0aa7E11g.png)


### アトリビュート(Attributes)

![image](https://hackmd.io/_uploads/r1vfCm4yyx.png)

アトリビュートにも基本データ型が設定する。
![image](https://hackmd.io/_uploads/H16s0Q41yg.png)

新しいアトリビュートや変数の名前を定義する際に、OutSystemsはそのデータ型を名前に基づいて推測します。
![image](https://hackmd.io/_uploads/HkYjl44Jkx.png)

レコードの作成、取得、更新、削除を行うCRUD操作が含まれます。
![image](https://hackmd.io/_uploads/BJKAkEN1Jg.png)

### Excelからエンティティ
データをブートストラップするには エンティティを右クリックし Advancedにポインタを重ねます。 
Create Action to Bootstrap Data from Excelを選択し Excelファイルを選択します。 
![image](https://hackmd.io/_uploads/SyVv_ELkkx.png)

Service StudioがExcelファイルを解析し、Excelの列と、エンティティの既存アトリビュートを対応させます。
![image](https://hackmd.io/_uploads/rkjVt4LJ1e.png)

エンティティにデータがあるかどうかを確かめるためのロジックです。
データが存在しなければ、Excelファイルを読み込み、各行に対応する顧客をデータベースに作成します。 
![image](https://hackmd.io/_uploads/ry3N5E8Jyg.png)

建立多張エンティティ、使用Entity Diagrams建立EmployeeDirectoryDataModel。
![image](https://hackmd.io/_uploads/HkQkSBLkkg.png)

### **静的エンティティ(Static Entity)**

静的エンティティは、事前定義された値のリストを作成し、**実行時に変更できない特殊なエンティティです。**
これを「レコード」と呼び、エンティティアクションは**GetEntitiesのみ使用可能です。**

![image](https://hackmd.io/_uploads/SJ2tiBLkJe.png)

静的エンティティには デフォルトで4つのアトリビュートがあります。Id、Label、Order、Is_Activeです。
![image](https://hackmd.io/_uploads/HkYGTHIJJx.png)

静的エンティティにはレコードがあります。これはRecordフォルダを開くと確認できます。Low、Medium、Highというレコードがあります。各レコードにはIdがあります。

---
#### 静的エンティティのレコードに関する説明
* 必要な数のレコードを含めることができますが、開発中に定義する必要があります。
* レコードの追加や削除は、開発中にのみ行うことができる。
* 静的エンティティの識別子はレコード識別子である。
* 識別子アトリビュートは、すべての静的エンティティで必要である。
* 静的エンティティのアトリビュートは必須または任意に設定することができます。値を設定する必要があるのは、アトリビュートが必須の場合のみです。

---

### データリレーション(Data Relations)
データリレーションのタイプは、**1対多、1対1、多対多**の3つです。
* **エンティティに**は、リレーションを実現するための識別子が必要である。
* **リレーション**は、Entity Identifierデータ型のアトリビュートを設定すると作成されます。

![image](https://hackmd.io/_uploads/rk1uBUL11x.png)

#### 1 to Many
リレーションを作成するために、Entity Bにはデータ型がEntity A Identifierのアトリビュートを用意します。

We can set a attribute name of relationship entity A, OutSystems can set data type(*entity A* Identifier) autolly.
e.t.c: XXXXXXXId => XXXXXXX is order entity A.

![image](https://hackmd.io/_uploads/HyhRO8U1Je.png)

---
Q: マスターエンティティA と 詳細エンティティB の間に1対多のリレーションを作成するために必要な手順はどれです。

A:エンティティBには、Entity A Identifier型の参照アトリビュートが必要である。

---

#### 1 to 1 
Entity Aの識別子はデータ型がEntity A Identifierであり、Entity Aと同じです。データベースに同じ識別子を2つ保持することはできないため、こうすることで注文には1つのレシートのみが関連付けられることになります。
Entity Bの識別子のデータ型をEntity A Identifier に設定することで、1対1のリレーションを定義できるのです。

![image](https://hackmd.io/_uploads/SJmTCLLyye.png)

We need to change the Entity A Identifier, which entity A get 1-to-1 link and setting "*entity A* Identifier".

![image](https://hackmd.io/_uploads/HJ4kbvL11x.png)

---
Q:エンティティAとエンティティBの間に1対1のリレーションを作成するために必要な手順はどれですか。

A:エンティティBの識別子アトリビュートのデータ型をEntity A Identifierに設定する。

---

#### Many to Many

Entity AとEntity Bの間に多対多のリレーションを作成するには新しいエンティティが必要です。
これがEntity AとEntity Bとのリレーションを定義することになります。

![image](https://hackmd.io/_uploads/r1Ji8DI1Jl.png)

We set a many to many relationship between two entities(参照アトリビュート), *entity A* Id and *entity B* Id, and OutSystems can relation two sheet autolly.

![image](https://hackmd.io/_uploads/r1KXPwLJ1l.png)

---
Q:エンティティAとエンティティBの間に多対多のリレーションを作成するために必要な手順はどれですか。

A:Entity A Identifier型およびEntity B Identifier型の2つの参照アトリビュートを持つ新しいエンティティCを追加する。

---

### データモデルの整合性
インデックスは、データベースのテーブルからデータを高速に取得するためのデータ構造です。アトリビュートにインデックスを定義すると、データ選択時の取得速度が向上します。

###### インデックスを増やしすぎるとパフォーマンスが悪くなりますが、適切な数であればパフォーマンスが向上します。

![image](https://hackmd.io/_uploads/BJbQd2Uy1l.png)

![image](https://hackmd.io/_uploads/S1gBdnUJ1l.png)


一方、削除規則というものもあります。
削除規則には3つの選択肢があります。

* Protect : レコードの削除を許可しないです。
* Delete : レコードを削除します。
* Ignore : 参照整合性は保証されなくなります。

![image](https://hackmd.io/_uploads/ryqLO2I1yl.png)

---
Q:インデックスに関する説明として正しいものはどれですか。
A:一連のアトリビュートに一意のインデックスを定義すると、それらのアトリビュートに保存されるデータは一意になります。

---

## UI開発
画面の作成方法やコンテンツ、要素、変数、入力などを取り上げます。 

画面は主要なUI構築要素であり、リンク、ボタン、画像、テーブルなどの複数の要素で構成されています。これらの要素を組み合わせることで、リッチなインターフェイスを作成できます。
![image](https://hackmd.io/_uploads/B1Hdah8kyg.png)

ウィジェットの大きな特徴はレスポンシブであり、使用するデバイスに応じて画面の動作が変わることです。これにより、さまざまなデバイスで最適なユーザー体験を提供できます。
![image](https://hackmd.io/_uploads/S1nyCn8J1l.png)

製品の詳細を表示するためには、一意に製品を特定する必要があります。この情報は入力パラメータ(Parameters)を通じて渡され、ローカル(Local)変数を使って一時的に保管できますが、ローカル変数は各画面のスコープ(Scope)内でのみ有効です。別の画面に移動すると、前の画面の変数にはアクセスできません。
![image](https://hackmd.io/_uploads/ByxFRnUy1l.png)

ボタンやリンクを使うことで、ロジックフロー(Logic Flow)の実行をトリガーできます。たとえば、Saveボタンを押すとデータベースが更新され、画面アクションとして定義されたフローが実行されます。UIはロジックフロー内の変数の変更に自動で反応し、即座に更新を反映します。
![image](https://hackmd.io/_uploads/By3syp8yye.png)

LinkはButtonと似ており、両方ともOn Clickプロパティでさまざまな動作をトリガーできます。具体的には、アプリケーションや外部URLへの移動、アクションフローの実行、イベントのトリガーが可能です。**主な違いは、インターフェイスの表示方法とフォーム内のインタラクションにあります。**
![image](https://hackmd.io/_uploads/SkQFeaLJ1l.png)

---
Q:画面内で作成できるのは、どの型の変数ですか。
A:**入力パラメータ**と**ローカル変数**のみ。画面に出力パラメータはありません。

画面のローカル(Local)変数は他の画面から直接アクセスできません。入力パラメータとローカル変数のスコープは、それぞれが定義された画面内に限定されています。

---

### ウィジェット(Widget)

#### Expression
Expressionエディタで計算式を入力することで、実行時にエンドユーザーにテキストを表示します。数値の計算や文字列の連結、関数の使用も可能で、プレビュー機能を利用しながら表示内容を調整できます。

![image](https://hackmd.io/_uploads/SJOZKpLJyg.png)

#### Link　& Button
ボタンはクリック時にアクションを設定し、入力パラメータを操作できます。入力パラメータを画面に表示し、ボタンを押すと値を増やし、別画面に渡して結果を表示する流れを確認できます。リンクもボタンと同様に使用でき、画面遷移の設定が可能です。

#### If
Ifウィジェットを使って条件に応じたコンテンツの表示方法を紹介しています。ローカル変数を増減させ、Ifウィジェットで数値がゼロかどうかを確認し、ゼロなら「number is zero」と表示します。さらに、Falseブランチに別のIfを追加し、数値が正か負かを判定して適切なメッセージを表示します。

![image](https://hackmd.io/_uploads/rJiPjpU1Jl.png)

#### Container
Containerウィジェットを使って画面のレイアウトやスタイルを調整する方法を紹介しています。3つのコンテナを作成し、SNSアイコンを横並びに配置します。コンテナにCSSのcardスタイルクラスを適用し、アイコンを中央揃えにします。コンテナを使うことで、簡単にスタイルを適用し、コンテンツを整理できます。

![image](https://hackmd.io/_uploads/SyLL268Jkx.png)

#### <實作>
設定畫面文字內容
1.新增Button以及設定on click事件
![image](https://hackmd.io/_uploads/ryEFeWKkJg.png)

(1)將Button移動至Click to add Actions，設定好Button text。
(2)設定On Click事件(切換畫面)。

---

2.設定Link切換畫面
![image](https://hackmd.io/_uploads/HknYQbKkJx.png)

(1)在首頁(Menu)將要切換的畫面拖曳至Top Bar。
(2)選擇Link並設定On Click事件。


---
Q1:Expressionウィジェットに関する説明として正しいものはどれですか。
A1:実行時に**計算された**テキストを表示する。

Q2:LinkとButtonの動作として正しいものはどれですか。
A2:LinkとButtonでできるのは、画面への移動や画面アクションのトリガーである。

Q3:Ifウィジェットに関する説明として正しいものはどれですか。
A3:
* Ifの条件内で関数を使用できる。
* 各Ifウィジェットのブランチは、**TrueとFalseの2つのみ**です。
* いずれかのブランチのみが表示される。
* 各ブランチには複数のウィジェットを追加できる。

Q4:Containerウィジェットに関する説明として正しいものはどれですか。
A4:
* Containerを使用すると複数のウィジェットをグループ化できる。
* デフォルトでは、Containerは1～12列にすることができる。
* Containerは、他のContainer内に配置することができる。
* Container内にはウィジェットが1つ以上必要がない、空でも問題ありません。

---

## Aggregate

1. Aggregateの概要：AggregateはOutSystemsの視覚的ツールで、開発者がSQLを深く理解せずにデータのクエリ、フィルタリング、ソートを可能にします。
2. 機能紹介：Aggregateエディタには、**データソースの追加、フィルタの作成、ソート(sort)の定義、クエリ(query)のテストを行う**ための4つの主要タブがあり、Excelに似た操作性があります。
3. フィルタリング(Filters)とソート：フィルタを使用することで特定の条件に基づいてデータを絞り込むことができ、ソート機能では昇順や降順の指定が可能で、設定順序が結果に影響します。
4. テスト機能：テストタブ(Test tab)では変数値を入力してクエリを評価し、即座にデータのプレビューを更新できるため、出力結果を確認しやすくなります。

### Aggregateの出力とプロパティ(Property)

1. 出力概要：Aggregateはクエリに一致するレコードをリスト形式で返し、重要なプロパティとして反復子関連のプロパティやLength、Emptyなどがあります。
2. プロパティの詳細：Current RowNumberは0から始まり、Lengthは返されたレコードの数を示します。Emptyは一致するレコードがない場合にTrueとなります。また、Count出力パラメータは基準に一致するレコードの総数を示します。
3. 最大レコード数とSQL確認：Max Recordプロパティにより返されるレコード数を制限可能ですが、Countには影響しません。ExecutedSQLプロパティでは生成されたSQLを確認できます。
4. SQLへの変換：Aggregateの内容はコンパイル時にSELECT SQLクエリに変換され、SourcesタブはFROM句、FiltersはWHERE句に適用されます。OutSystemsコンパイラが必要なアトリビュートを自動的に検出し、アプリケーションコードに基づいてSELECT句を再計算します。

![image](https://hackmd.io/_uploads/ryNAuztkJl.png)

![image](https://hackmd.io/_uploads/BkDZYMK11e.png)

<實作>
1. Fetch Data(獲取資料)

可以在要加入資料的page點右鍵，選擇Fetch Data from Database。
![image](https://hackmd.io/_uploads/HJSKkZhy1g.png)

或是在左側輸入要fetch的data entity名稱，選擇需要的Database。
![image](https://hackmd.io/_uploads/r1L5kZh11x.png)

2. Filter Data(過濾資料)

點選filter，新增過濾條件。
![image](https://hackmd.io/_uploads/H1nkGb2Jyx.png)

3. Sort Data

點選sort，選擇排序的欄位。
![image](https://hackmd.io/_uploads/rJBqHZ31kg.png)

條件中可以選擇升冪排列或是降冪排列。
![image](https://hackmd.io/_uploads/H1BILbnkkl.png)


---

Q1:Sourcesセクションは、何のために使用しますか。
A1:リレーション(relation)が定義されている1つ以上のソースエンティティをサポートします。

Q2:複数のフィルタを追加できます。次のうち、正しくないものはどれですか。
A2:レコードが出力結果に含まれるには、定義されたすべてのフィルタに対してTrueである必要があります。

(正しいもの)
フィルタは、AND演算子で連結される。
すべてのフィルタはSQLに変換され、WHERE句に含まれる。
論理演算子と一部のビルトイン関数をフィルタ内で使用できる。

Q3:ソートに関する説明として正しいものはどれですか。
A3:ソート基準の方向は、昇順または降順のいずれかにする必要があります。

Q4:Test Valuesセクションは、何のために使用しますか。
A4:テストして出力レコードをプレビューするために使用します。

---

### データを含む画面の構築

從左側工具列點選Table，並將其拉至欲放置的畫面。
![image](https://hackmd.io/_uploads/SJHyyPT1yg.png)

選擇目標Table(需有先加入到該畫面的table)
![image](https://hackmd.io/_uploads/SJnu1wpJyl.png)

將該Table拖曳至該Table工具內。
![image](https://hackmd.io/_uploads/rkfkbvpkJe.png)

可以選擇資料的顯示狀態(Expression)。
![image](https://hackmd.io/_uploads/r1bRlP6yyg.png)

點選text，並輸入該text的字元。
![image](https://hackmd.io/_uploads/SymFZP6JJe.png)

有欲刪除的列，點選Header Cell，右鍵選擇Delete。
![image](https://hackmd.io/_uploads/B1uJzwT1ye.png)

如果想新增預設顯示的欄位，可直接將該欄位拖曳至Table內。
![image](https://hackmd.io/_uploads/r1gHfPaJ1e.png)

可選擇位置調整資料位置。
![image](https://hackmd.io/_uploads/By0sfPaJ1x.png)

### List データを表現する画面の構築

將List工具列拖曳至畫面中。
![image](https://hackmd.io/_uploads/Hk14q6ygJe.png)

選擇該List的Source。
![image](https://hackmd.io/_uploads/HJtjqT1lkx.png)

將List Item拖曳至先前已設定的List中。
![image](https://hackmd.io/_uploads/S18ksaJxke.png)
ListItem會在原本的List右側建立action button。

將原本設定在該畫面的Project table放入該List Item中。
![image](https://hackmd.io/_uploads/S1SGhTyx1g.png)


設定List Item的On-click事件(Left action)，可用於手機的向左滑。
![image](https://hackmd.io/_uploads/BJ7z41egkg.png)


設定スワイプするとアクション/オプション以及フルスワイプアクション兩種滑動操作模式。
1.在List中選擇ListItem，選擇是否開啟滑動功能。
![image](https://hackmd.io/_uploads/B1ZUJ7Gx1g.png)

下方的Properties中，設定Swipe Left/Swipe Right。

**スワイプするとアクション/オプション:Swipe後，會顯示按鈕。
フルスワイプアクション:Swipe後，直接執行按鈕預設動作。**

![image](https://hackmd.io/_uploads/rJFOk7zlJx.png)
如果要設定Swipe Right，點選上面的Swipe Right Action新增on click行為。

---
Q1:画面のAggregateに関する説明として正しいものはどれですか。
A1:
非同期的に並行して実行される。
定義されている画面のスコープ内にのみ存在する。
データベースからのみデータを取得できる。

Q2:AggregateのデータをTableウィジェットやListウィジェットにバインドするには、どのようにしますか。
A2:ウィジェットのSourceプロパティをAggregateの出力に設定する。

Q3:List ItemとList Actionに関する説明として正しいものはどれですか。
A3:
List ActionはList Item内のみで使用できる。
List ItemはList外で使用できる。
List Actionは、スワイプ(Swipe)時に実行されるロジックを備えた画面アクションをトリガーする。
List Actionは、List Itemで定義されたロジックを使用するだけです。

Q4:データアクションの出力を使用して、一連のプロジェクトをすべて画面に表示したいと思います。
A4:
ListウィジェットのSourceプロパティをAggregateの出力に設定する。
ExpressionウィジェットのValueプロパティを、Aggregateの結果に対応する特定のアトリビュートに設定する。

Expressionウィジェットには、Aggregateの出力を取得するListウィジェットのコンポーネントであるSourceプロパティがありません。
Listウィジェットには、Expressionウィジェットの必須コンポーネントであるValueプロパティがありません。

Q5:スワイプアクションを実行するためのリストアクションを定義するには、どのようにすればよいですか。
A5:On-ClickのDestinationプロパティで、必要なロジックを含むクライアントアクションを指定する。

Q6:左にスワイプするとアクション/オプション(Options)を、右にスワイプするとフルスワイプアクション(Full Swipe action)を表示するには、どのようなスワイプアクションを定義すればよいでしょうか。
A6:Full Swipe Leftプロパティを「No」に設定し、Full Swipe Rightプロパティを「Yes」に設定する。

---

## Aggregateの高度な機能

* 複数のソースエンティティに対応し、異なるデータソース間で「Only With」「With or Without」「With」などの結合が可能。

* 結合の種類によって、SQLではINNER JOIN、LEFT JOIN、FULL OUTER JOINに変換される。
![image](https://hackmd.io/_uploads/HyKro2oxyg.png)

* 計算アトリビュート（Calculated Attributes）の使用
計算アトリビュートを用いて、データベースに直接保存されていない値を生成できる。
ExpressionやOutSystemsのビルトイン関数を利用し、カスタム計算結果を追加できる。
![image](https://hackmd.io/_uploads/SyKoonjgJg.png)

* データの集約と集計関数
AggregateでSum、Average、Min、Max、Countなどの集計関数が使え、複数行のデータをまとめて分析が可能。
集計された列は青く表示され、視覚的に識別しやすくなる。

<實作1>
我們要調整資料內容，透過Aggregate的方式合併多個來源資料並呈現在畫面上。

1.將之前建立好的ProjectMember新增一個Entity，將ProjectId資料匯入。
![image](https://hackmd.io/_uploads/H1HHkkhg1x.png)

2.在ProjectDetails內新增一個Aggregate，將ProjectMember Entity匯入。
![image](https://hackmd.io/_uploads/rkMN00ix1g.png)

3.開啟GetProjectMembers，點選Add source，選擇Employee。
![image](https://hackmd.io/_uploads/HkXnyJhgye.png)

4.在Join的區域選擇`With or Without`，確認下方join的Attribute；再新增另一張Entity Project。
![image](https://hackmd.io/_uploads/S19KlJ3gJe.png)

5.開啟ProjectDetails，選取List工具，將GetProjectMembers內的資料匯入該List中，並調整資料(First+Last)。
![image](https://hackmd.io/_uploads/H1O8M1hxke.png)

6.將剛才整理好的資料Entity匯入到List項目中，並整理source。
![image](https://hackmd.io/_uploads/Bk2pLyhekl.png)

---

<實作2>
使用Expression計算資料後呈現在畫面中。

1.點選Logic，在サーバーアクション(Server Actions)中新增一個Server Action，開啟Action匯入Aggregate工具。
![image](https://hackmd.io/_uploads/B1AC5_hl1e.png)

2.開啟Aggregate並匯入兩張Entity:Employee以及Department，並設定Joins是`Only With`。
![image](https://hackmd.io/_uploads/rJARi_hlkg.png)

3.選擇New Attribute，選擇Value輸入計算式計算結果。
![image](https://hackmd.io/_uploads/ByIt6u2g1x.png)

---
<實作3>
1.開啟前一個實作的Aggregate，將另一張Entity(Project)拉入フロー。
![image](https://hackmd.io/_uploads/BkKgOY3xkx.png)

2.對NAME這個Attribute點右鍵，選擇Group By Name，OutSystems會自動分群。
![image](https://hackmd.io/_uploads/rJpF2Yhe1x.png)

3.對FirstName這個Attribute點右鍵，選擇Count，OutSystems會執行計算。
![image](https://hackmd.io/_uploads/HkelpK2gyx.png)

4.進入Sort，使用Count作為排序依據，並選擇`Desc`。
![image](https://hackmd.io/_uploads/HkRwAF2xkg.png)

5.確認本次排序結果，應該會以Count作為排序依據。
![image](https://hackmd.io/_uploads/rywWk52gkl.png)

---
Q1:「With or Without」結合を使用するAggregateがあるとします。 どのようなAggregateの出力が想定されますか。
A1:右のエンティティに対応するレコードがない場合でも、左のエンティティのレコードをすべて返す（LEFT JOIN）。

Q2:Aggregateでは列を非表示(隱藏列)にすることができます。
A2:Aggregateの列を非表示にした場合、出力のプレビューにのみ影響する。

Q3:Aggregateで計算アトリビュートを作成するときに使用できる要素はどれですか。
A3:
ソースエンティティのアトリビュートの値
SQLに変換できるビルトイン関数（Length()、Power()など）
変数

（使用できない）
エンティティ アトリビュートを使用したサーバーアクション。
=>サーバーアクション(Server Action)をすべてSQLに変換することができるでしょう。

Q4:集約関数を適用する必要があるとします。 次のうち、正しいものはどれですか。
A4:
Aggregate内で複数の集約関数を適用できる。
Integerデータ型のアトリビュートには、sum、max、min、count、averageの各関数を適用できる。
Aggregateの出力にグレーの列は含まれない。

（正しくない）
Aggregateの出力にはソースエンティティのすべてのアトリビュートのほか、集約列が含まれる。
=>集約列のみが返されます。

---

## Webフォームの作成
1.ユーザーとアプリケーションのインタラクションの重要性
データの編集と送信に焦点を当てています。

2.単一レコードの表示と編集
フォームや入力ウィジェットを使用してデータを編集します。

![image](https://hackmd.io/_uploads/Hy9RNqzlkx.png)


3.入力ウィジェットの種類
テキストボックス、数値ボックス、日付ピッカー、ドロップダウンなど、多様な入力オプションを提供します。

----
![image](https://hackmd.io/_uploads/rJSpNqGgkx.png)

----
![image](https://hackmd.io/_uploads/r1cer9Mxkx.png)

----
![image](https://hackmd.io/_uploads/HkLUHqMe1l.png)

----
![image](https://hackmd.io/_uploads/HkLdHqGlke.png)

----
![image](https://hackmd.io/_uploads/ByfYrqMeye.png)

----
![image](https://hackmd.io/_uploads/HyU9B5zlkl.png)

----
![image](https://hackmd.io/_uploads/By6jBcfxkl.png)

----
![image](https://hackmd.io/_uploads/By61LcGxkg.png)

----

4.詳細画面の構築
インタラクションのための入力ウィジェットが含まれるフォーム。
Aggregateを使用してデータベースからデータを取得します。

5.変数の管理
すべての入力ウィジェットには、ユーザー入力データを保存するための変数プロパティがあります。

6.データの送信
リンクやボタンを使用してロジック操作をトリガーし、データをデータベースに保存します。
![image](https://hackmd.io/_uploads/ry1b8cMgke.png)

---

### Input & Text Area

1.Product Detail画面の設計
商品名を入力するためのInputウィジェットとデータを保存するためのSaveボタンが含まれています。

2.Variableプロパティの設定
InputのVariableプロパティを画面のスコープ内の変数に設定し、入力値を保持します。
![image](https://hackmd.io/_uploads/Hk6OVSQgyx.png)

3.Price入力フィールドの追加
Price属性をフォームにドラッグし、自動的に対応するInputとLabelが作成されます。

4.Text Areaウィジェットの使用
DescriptionにText Areaウィジェットを使用し、Variableプロパティを設定します。
![image](https://hackmd.io/_uploads/SkJCEHXgkx.png)

5.インターフェースのテスト
モジュールをパブリッシュし、ブラウザでテストして、入力フィールドが正しく表示され、データが保存されるかを確認します。

### Checkobx & Switch
1.フォームの構成
複数のInputウィジェットを含むフォーム。
Aggregateを使ってデータベースから注文を取得。

2.Has Stockの設定
フォームにはID以外に「Has Stock」アトリビュートのみ。
Has Stockをフォームにドラッグしてチェックボックスを作成。
チェックボックスはHas StockのVariableプロパティにバインド。

3.動作確認
モジュールをパブリッシュし、ブラウザでテスト。
商品の詳細情報がフォームに表示される。

4.スイッチへの変更
チェックボックスを削除し、スイッチをドラッグして配置。
VariableプロパティをHas Stockに設定。
LabelをInputウィジェットにバインド。

5.再テスト
モジュールを再パブリッシュし、ブラウザで確認。
スイッチを操作して「在庫あり」に設定。

6.相違点
SwitchとCheckboxは動作や定義方法が似ているが、アプリケーションでのインタラクションが異なる。

### Drop down(下拉式清單)
1.Dropdownの定義
ユーザーがリストからオプションを選択できるようにするデモ。

2.フォームの構成
Service StudioのOrder Detail画面に複数のInputウィジェットを含むフォーム。
注文を取得するためのAggregateがあり、注文ステータス用のAggregateも用意。
![image](https://hackmd.io/_uploads/HJIh7_me1e.png)

3.参照アトリビュート
Orderエンティティを展開すると、他のエンティティを参照するアトリビュートが表示。
参照アトリビュートには選択肢が表示される。
![image](https://hackmd.io/_uploads/H1XCX_XeJg.png)

4.RequestedByアトリビュート
RequestedByアトリビュートをフォームにドラッグすると自動的にドロップダウンが生成。
Variableプロパティは注文のRequestedByアトリビュートに設定され、選択した内容が保存される。

5.リストプロパティ
ウィジェットのListプロパティには顧客のリストが含まれ、ドロップダウンに表示される。
このリストは自動作成されたAggregateに基づく。

6.オプションのプロパティ
Textプロパティには顧客の名前が設定。
Options Valueプロパティは顧客のIDを設定。

7.注文の全ステータス表示
手動で全ステータスを表示するDropdownを追加。
Variableプロパティを注文のStatusアトリビュートに設定。
ListプロパティにGetOrderStatuses Aggregateの出力を設定。

8.ラベルの設定
Inputウィジェットを識別するLabelを追加し、「Status」と設定。

### Radio Group
1.Radio Groupの定義
ユーザーが少数の選択肢から値を選択できるようにするデモ。

2.フォームの構成
Service StudioのOrder Detail画面に複数のInputウィジェットを含むフォーム。
注文を取得するためのAggregateがあり、注文ステータス用のAggregateも用意。
![image](https://hackmd.io/_uploads/rJQpvY7gJg.png)

3.参照アトリビュート
Orderエンティティを展開すると、他のエンティティを参照するアトリビュートが表示。
参照アトリビュートには選択肢が表示される。
![image](https://hackmd.io/_uploads/ByOQutme1g.png)


4.RequestedByアトリビュート
RequestedByアトリビュートをフォームにドラッグすると自動的にドロップダウンが生成。
Variableプロパティは注文のRequestedByアトリビュートに設定され、選択した内容が保存される。

5.リストプロパティ
ウィジェットのListプロパティには顧客のリストが含まれ、ドロップダウンに表示される。
このリストは自動作成されたAggregateに基づく。

6.オプションのプロパティ
Textプロパティには顧客の名前が設定。
Options Valueプロパティは顧客のIDを設定。

7.注文の全ステータス表示
手動で全ステータスを表示するDropdownを追加。
Variableプロパティを注文のStatusアトリビュートに設定。
ListプロパティにGetOrderStatuses Aggregateの出力を設定。

8.ラベルの設定
Inputウィジェットを識別するLabelを追加し、「Status」と設定。


### Button Group

1.Button Groupの定義
ユーザーが複数の選択肢から値を選択できるようにするデモ。

2.フォームの構成
Service StudioのOrder Detail画面には、複数のInputウィジェットを含むフォーム。
注文を取得するためのAggregateがあり、OrderエンティティにはPriorityアトリビュートが表示。
![image](https://hackmd.io/_uploads/S1YSttQlkg.png)

3.Priorityアトリビュート
優先度にはLow、Medium、Highの3つがある。
これはButton Groupの典型的なユースケース。

4.Button Groupの作成
Button Groupをフォームにドラッグすると、自動で3つの選択肢が作成される。
選択肢の数は自由に変更可能。

5.プロパティの設定
Button Groupを選択し、Aggregateから取得したOrderのPriorityアトリビュートをVariableプロパティに設定。
エンドユーザー(End users)が選択した選択肢の保存先を定義。

6.選択肢の値設定
優先度Lowの項目名を変更し、その値を「Low」に設定。
Valueプロパティで、選択したときにButton GroupのVariableプロパティに保存する内容を定義。
![image](https://hackmd.io/_uploads/r11qFY7g1g.png)

7.他の選択肢の設定
2つ目の優先度を「Medium」、3つ目を「High」に設定。

8.ラベルの追加
Button Groupの上にLabelをドラッグし、「Priority」と名付け、Input WidgetプロパティをButton Groupに設定。

9.機能の特性
Button Groupは少数の選択肢から値を選ぶ際に役立ちますが、小数の選択肢向きの機能です。

---
<實作>
製作畫面讓使用者輸入資料，並從資料庫中抽取對應的資料顯示於畫面。

1.畫面右鍵點選Fetch Data from Database，並將要使用的Table拉入。
![image](https://hackmd.io/_uploads/HJCTi67l1e.png)

2.將工具列的Form項目拉進container中。
![image](https://hackmd.io/_uploads/r1nmaT7lyg.png)

3.將第一步綁訂好的Table拉進該Form中。
![image](https://hackmd.io/_uploads/SJy9pa7gye.png)

4.Form工具會自動依據匯入的資料檢視其Data Type，例如本次資料中Department為Dropdown、IsAction為CheckBox。
![image](https://hackmd.io/_uploads/BybceRmgyx.png)

![image](https://hackmd.io/_uploads/H1Xwe07xkx.png)
因之前有設定過reference，因此會自動建立GetDepartments。

5.設定底下Botton的On-click事件，此處設定為"目前畫面"。
![image](https://hackmd.io/_uploads/BkMzjC7gyl.png)

6.表格客製化:新增一個欄位"辦公地點"
將原本的Email欄位刪除，並引入另一個Expression工具重新定義該欄位資料。
![image](https://hackmd.io/_uploads/BJ30XAmlJe.png)

7.由於清空原本的Input Data Source，因此要將Input Widget設為None。
![image](https://hackmd.io/_uploads/HJXsVC7x1e.png)

8.由於我們在此處新增一個Dropdown，因此我們要新增一個attribute給該Dropdown。
因此我們需要:
    (1)新增一個static entity
    (2)在原本的Employee entity中新增一個attribute並跟新增的static entity串聯。

9.先在Data中新增一個Static Entity。
![image](https://hackmd.io/_uploads/HyBtwC7g1g.png)

10.在原本的Entity中新增一個attribute，並將其設定跟新增的Static Entity。(Data Type: XXXXXX Identifier；Is Mandatory:True)
![image](https://hackmd.io/_uploads/rkXQdRmx1l.png)

11.回到剛才的頁面，再新增一個Fetch Data，並將剛才新增的Static Entity匯入。
![image](https://hackmd.io/_uploads/rkkMY0Xeyl.png)

---

### Upload

1.Uploadウィジェットの使用
アプリにファイルをアップロードするデモ。

2.シナリオの説明
商品が一覧表示され、商品をクリックすると情報を編集可能。
Uploadウィジェットを追加して商品の画像を変更できるようにする。

3.フォームの構成
注文詳細画面にはフォームがあり、Uploadウィジェットを任意の場所に配置。

4.必要なプロパティ
1つ目のプロパティ: アップロードしたファイルの内容を保存するためのBinary Data変数。
2つ目のプロパティ: ファイル名を保持するための変数（デモでは使用しないが必要）。

5.保存ロジックの確認
サーバーアクションが呼び出され、アップロードが実行される。

6.テスト手順
商品を選択し、Uploadウィジェットをクリック。
ファイル選択ダイアログが表示され、画像を選択してSaveボタンをクリック。
Products画面の商品の画像が更新される。

---
<實作>
增加新增資料的功能更新資料庫的資料(範例中要新增資料圖片)。

1.在預設定的畫面中右鍵新增Aggregate，並設定Data Source。
![image](https://hackmd.io/_uploads/BkQP0Y4lke.png)

2.先放入Container，再匯入Image，設定Type以及Image Content。
![image](https://hackmd.io/_uploads/HklVycNlyx.png)

3.設定Image Content的資料路徑。
![image](https://hackmd.io/_uploads/SkCCyqNg1x.png)

4.匯入Upload工具，設定File Content以及File Name。
![image](https://hackmd.io/_uploads/ryyml5Elyl.png)

5.File Content為檔案內容內容；File Name為檔案名稱。
![image](https://hackmd.io/_uploads/rkbXZ94eJe.png)

![image](https://hackmd.io/_uploads/SkAHZ5Ng1e.png)

---

### Label

1.Labelウィジェットの重要性
Inputウィジェットだけでは、ユーザーは何を入力すべきかわからない。
Labelを使用して、入力フィールドの目的を明確にする。

2.Labelの設定
Labelのテキストを「Name」に設定し、ユーザーに指示を与える。
LabelのInput Widgetプロパティをフォームの入力に設定して、関連付けを行う。

3.アクセラレータの使用
Priceなどの属性をドラッグしてフォームにドロップすると、InputとLabelが自動的に作成され、バインディングも行われる。

4.フォーカスの利点
Labelをクリックすると、入力フィールドにフォーカスが移動する。
ユーザーが入力内容を確認しやすくなる。


### Form

1.Formの機能と作成方法
Service StudioでProduct Detail画面にフォームをドラッグする。
空のフォームに入力フィールドを追加。

2.データのドラッグと自動生成
Aggregateを展開してProductエンティティをドラッグし、入力フィールドを作成。
各入力フィールドとLabelが自動的に追加される。

3.Inputウィジェットの自動設定
Inputウィジェットのデータ型は追加されたアトリビュートに基づく。
ドロップダウンやCheckboxなどが生成される。

4.Saveボタンの追加
Formにエンティティをドラッグすると、Saveボタンが自動で追加。
このボタンはデータベース関連のアクションをトリガー。

5.アクションとデータ検証
ボタンをダブルクリックして画面アクションを定義。
フォームの有効性を確認するロジックが自動設定。

6.データベース操作の定義
定義済みのアクションを使用して、商品の作成や更新ロジックを設定。

---

<實作>
設計一組功能可輸入、顯示和修改項目詳細資料的使用者介面。透過特定的小部件合併到表單中，使每個小部件與項目實體的屬性對齊來實現。

1.先從Data端設定一個新的Static Entity，命名為Priority。
![image](https://hackmd.io/_uploads/Sk02nGrlyl.png)

2.將該Static Entity中的Records設定好三個權重。
![image](https://hackmd.io/_uploads/HyZx0GSekx.png)

3.在Project這個Entity內新增一個Attribute命名為GetPriorities，將上面設定好的Static Entity匯入。
![image](https://hackmd.io/_uploads/SJTXCzrlJx.png)

在頁面下新增一個Aggregate，
![image](https://hackmd.io/_uploads/Syxy7XSgJx.png)

4.匯入Form工具，並將資料匯入該Form當中。
![image](https://hackmd.io/_uploads/SJDU7mHlyg.png)

5.依序建立TextArea、Label以及Input。並將其資料Source依序連接。
![image](https://hackmd.io/_uploads/ry108Qreyx.png)

6.設定上述要顯示的Priority，並依據其值設定優先型態。
![image](https://hackmd.io/_uploads/ryoEY7rgJx.png)

---

Q1:Formの説明として正しいものはどれですか。
A1:
Formを使用すると、入力ウィジェットをグループ化し、データを表示したり編集したりすることができる。
Formには入力ウィジェットのほか、LinkウィジェットやButtonウィジェットなどを含めることができる。
Formは、ユーザーから送信されたデータを検証するときに便利である。

（正しくない)
Formには、ユーザーから送信された値を保持するSourceプロパティがある。
＝＞各入力の値を保持するのはForm内のInputにあるVariableプロパティです。

Q2:DropdownおよびButton Groupに関する説明として正しいものはどれですか。
A2:
Button Groupには、ユーザーが選択できる各オプションを示すButton Group Itemが必要である。
DropdownのListプロパティは、ユーザーに対しオプションとして画面に表示されるデータを定義する。
DropdownのVariableプロパティには、ユーザーが選択した値が保存される。 その値は、Options Valueプロパティで定義する。

（正しくない)
Button Group内の各Button Group Itemには、ユーザーが選択したオプションを保存するVariableプロパティがある。
＝＞選択された項目の値を保存するVariableは、Button Groupにあります

Q3:CheckboxウィジェットやSwitchウィジェットがバインドされるのは、どの型の変数ですか。
A3:Boolean

Q4:InputとLabelに関する説明として正しいものはどれですか。
A4:必須フィールドに関連付けられたLabelにより、画面に視覚的なマークが表示される。
![image](https://hackmd.io/_uploads/rJdUZSSlJl.png)

---
## ロジック(Logic)

### アクションとフロー

1. アクション(Action)はOutSystemsでロジックを定義する場所であり、サーバーまたはクライアント側で実行される。
2. ロジックフローには開始の「Start」ノードと終了の「End」ノードが含まれる。
3. フローにツール（If、Switch、Assignなど）を使用してロジックを構築できる。
4. アクションには3種類あり、画面アクション、クライアントアクション、サーバーアクションがある。
5. 画面アクションは特定の画面にバインド(Binding)され、主にボタンが押されたときなどに実行される。
6. クライアントアクションは画面にバインドされないため、モジュール全体で使用される。
7. サーバーアクションはサーバー側で実行されるロジックを定義する。
![image](https://hackmd.io/_uploads/SJAz-yUl1x.png)

<!-- 這段看不懂 -->
8. コードの再利用は、複数の画面やアクション間で使用できるロジックを作成することにより、コードベースの保守を容易にする。
9. 画面アクションは特定の画面に限定されるが、クライアントアクションやサーバーアクションはより広範囲で再利用できる。
![image](https://hackmd.io/_uploads/SkqqZJLxke.png)

10. クライアントアクションは他のクライアントアクションを、サーバーアクションは他のサーバーアクションを呼び出すことができる。
11. 画面アクションは他の画面アクションを呼び出せないが、クライアントアクションを呼び出すことは可能。
<!-- 這段看不懂 什麼是クライアントアクション  サーバーアクション  画面アクション -->

### 変数

1. 変数はメモリ内でデータを保持する場所であり、OutSystemsでは入出力パラメータとローカル変数が存在する。
2. **変数はスコープ内でのみ存在し、スコープを離れると破棄される。**

![image](https://hackmd.io/_uploads/BkDev-Ieyx.png)

3. **入力パラメータはスコープ外から値を受け取るために使用される。**
4. パラメータが必須かどうか設定可能で、**実行がスコープを離れると破棄される。**
![image](https://hackmd.io/_uploads/rkV7vbLx1g.png)


5. 出力パラメータはスコープ外に値を返すために使用され、スコープ外でも値が保持される。
![image](https://hackmd.io/_uploads/HyRBPbIxJg.png)

6. **ローカル変数はスコープ内でのみ存在し、スコープ外に出ると破棄される。**
![image](https://hackmd.io/_uploads/ByOYvbLxJg.png)


7. OutSystemsの変数は**強く型付けされており**、データ型は実行中に変化しない。
8. 基本型（Integer、Text、Dateなど）、複合型（ストラクチャ、リスト）、リスト型がある。
9. ストラクチャはエンティティに似た複合データ型で、メモリにデータを保存する。

<!-- ストラクチャ是什麼? 類似excel的table? -->

![image](https://hackmd.io/_uploads/Hkxk_-Ug1x.png)

![image](https://hackmd.io/_uploads/SJuf_ZUxye.png)

![image](https://hackmd.io/_uploads/BJdNdbUl1x.png)

---

Q1:正しいものはどれですか。
A1:クライアントアクションと画面アクションは、サーバーアクションを呼び出すことができる。

Q2:クライアントアクションとサーバーアクションで使用できる変数はどれですか。
A2:入力パラメータ、出力パラメータ、ローカル変数を使用できる。

Q3:アクションのフローに含めることができるものはどれですか。
A3:Startノードは1つに限定されるが、Endノードは複数含めることができる。

---
### クライアントアクションの作成

1. Saveボタンにロジックを関連付けるために、OnClickプロパティを「New Client Action」に設定。
2. Saveボタンがクリックされると、クライアントアクションが実行される。

3. クライアントアクションはフォーム検証ロジックを持ち、後でボタンに関連付けることが可能。
4. ただし、現在アクションは空であり、Saveボタンとの関連付けは自動ではない。
![image](https://hackmd.io/_uploads/ByH5OuUg1x.png)

5. サーバーアクションはドラッグ＆ドロップで簡単に使用可能。
6. サーバーアクションが実行された後、ユーザーを前の画面にリダイレクトする。

7. Assignノードを使って、Created OnやCreated Byなどの値を設定する。
8. これにより、現在の日付とログイン中のユーザー情報が保存される。

![image](https://hackmd.io/_uploads/B1dodd8xJl.png)

9. Logicタブでアクションフォルダを右クリックし、「Add Action」を選択してサーバーアクションやクライアントアクションを追加。
10. Saveボタンを押して注文を保存し、Orders画面に戻ることを確認。

### IfとSwitchの条件分岐の使用

1. 初期セットアップ
画面にアクションを呼び出すボタンを追加。
ボタンがクリックされると、数値が奇数か偶数かを判定する画面アクションが実行される。
入力パラメータとして数値（100）を設定。

2. If条件分岐で奇数・偶数を判定
Ifノードを使用し、数値を2で割った余りがゼロでなければ奇数と判定するロジックを作成。
奇数の場合、Trueブランチでフィードバックメッセージを表示（「奇数です」）。
偶数の場合、Falseブランチで別のフィードバックメッセージを表示（「偶数です」）。

![image](https://hackmd.io/_uploads/SyrkZtUlyx.png)

![image](https://hackmd.io/_uploads/rkSMWF8g1g.png)

3. ゼロのケースの追加
新しいIfノードを追加し、数値がゼロかどうかを確認。
ゼロの場合は「ゼロです」と伝えるメッセージを表示。

![image](https://hackmd.io/_uploads/HJ6wbY8xkx.png)

4. Switchノードを使用した条件分岐
IfノードをSwitchノードに置き換え、同じロジックを作成。
最初のSwitchブランチでは、数値がゼロかどうかを確認。
Trueの場合に対応するメッセージを表示し、ブランチをEndで終了。
Otherwiseブランチを追加して偶数を処理。

![image](https://hackmd.io/_uploads/B1-ZMFUeyl.png)

### ループ(Loop)

1. 初期セットアップ

画面に「Power Of Two」アクションを呼び出すボタンを追加。
ボタンのNumber入力パラメータに「3」を設定（2を3回掛ける計算を行うため）。


2. ループの構成

Assignノードを使用して、計算結果を保存するローカル変数を作成（データ型はInteger、初期値は1）。
Ifノードを使い、Number > 0 を条件にループを設定。
ループ内で2を掛け、Numberを1減らすことで、累乗の計算を行う。

![image](https://hackmd.io/_uploads/r1iq7tIx1e.png)

![image](https://hackmd.io/_uploads/SkjCmF8eJg.png)

3. ループの完了条件

ループはNumberがゼロになると終了する。
これにより、無限ループを防ぐことができる。

![image](https://hackmd.io/_uploads/rkkdNtUxyx.png)

4. 複数の数値に対して実行

画面にもう1つのボタンを追加し、異なる数値に対する2の累乗の計算を実行できるようにする。

<實作>
透過調整Dropdown的國家改變該員工的信箱網址。

1.選擇EmployeeDetails畫面，並開啟OfficeLocation Dropdown工具。點選On Change中的New Client Action。

2.開啟フロー，新增Switch以及Assign工具，並將Assign內的Data Source以及函數設定完成。

![image](https://hackmd.io/_uploads/SkzZvY8gkx.png)

![image](https://hackmd.io/_uploads/SJOJuYUxJg.png)

3.將Switch以及Assign連接，並設定此連接內容。

![image](https://hackmd.io/_uploads/S1n0_YIlJx.png)

4.依序新增三個Assign，同樣設定好該Data Source以及函數值，最後將該連接過濾設定完成(pt、in、sg)。

5.在原本的End中間再新增一個Assign，並命名為Other_location。

6.將剩下的Assign通通指向一個End，完成該邏輯設定。

![image](https://hackmd.io/_uploads/Hy0N3FIlyl.png)

7.完成該業務邏輯設定後，要將On Change設定為該設定完的業務邏輯選項，否則Email不會發生變化。

### JavaScriptエディタ

1. ボタンの追加
まず、画面にボタンを追加します。このボタンをクリックすると、JavaScriptコードを実行するためのアクションが開始されます。

2. JavaScriptノードの作成
ボタンのクライアントアクションを開き、JavaScriptノードを追加します。ノードをダブルクリックしてJavaScriptエディタを開きます。

3. JavaScriptコードの記述
OutSystemsのJavaScript APIに基づき、Feedback Message APIを使用します。次のコードを貼り付けます：

`$public.FeedbackMessage.showFeedbackMessage("This is a custom feedback message", 1);`

これにより、ボタンを押したときに「This is a custom feedback message」というメッセージが表示されます。

<!-- 這邊指的JavaScript API 是依定要使用Outsystems的javascript API的內容嗎? -->

4. JavaScriptノードに入力パラメータを追加
次に、入力パラメータをJavaScriptノードに追加して、メッセージをカスタマイズできるようにします。これにより、パラメータで受け取った値に基づいてフィードバックメッセージが表示されるようになります。


5. JavaScript内でパラメータの使用
パラメータをJavaScriptで使用するために、パラメータをダブルクリックし、次のようにして、パラメータ値を表示します：

`$public.FeedbackMessage.showFeedbackMessage($parameters.MessageText, 1);`

![image](https://hackmd.io/_uploads/rkBo79Lxyx.png)

<實作>

1.在Server Actions中新增一個Server Action。
![image](https://hackmd.io/_uploads/rkqL49UxJx.png)

2.在該Server Actions底下新增一個Input Parameter。
(這些資料將在之後被存入Employee這張table中。)

3.切換至Data，並將Employee這張table的CreateOrUpdateEmployee拉至該Input Paameter中。
![image](https://hackmd.io/_uploads/HkHEHcUeJx.png)

4.設定CreateOrUpdateEmployee的Source。

5.新增另兩個Input Patameter，並將另一張table的CreateOrUpdateEmployeePicture拉入剛才的フロー中。
![image](https://hackmd.io/_uploads/H1bwLcLxyx.png)

6.設定該CreateOrUpdateEmployeePicture的Source。
![image](https://hackmd.io/_uploads/SJgzu5Uxyg.png)

7.再新增兩個SErver Actions以及其底下的input parameter:
Project & ProjectMember。
![image](https://hackmd.io/_uploads/HkcQF9Llyg.png)

8.將table的CreateOrUpdateXXX拉入該フロー中。
![image](https://hackmd.io/_uploads/Hy-LtcIxyl.png)

9.進入EmployeeDetails，對save按鈕調整on-Click事件的觸發結果。

10.將Server Action工具拉入該フロー，並選擇Employee_CreateOrUpdate這個Action。
![image](https://hackmd.io/_uploads/S1k6iqIxJx.png)

11.依序將每個Action對應到的參數設定完成(參數為上述設計出的三個input parameter)。
![image](https://hackmd.io/_uploads/Hy-F35Lg1l.png)

12.新增一個Message工具，並設定Message的內容。
![image](https://hackmd.io/_uploads/rkkQaqIxye.png)

13.為了顯示空白的資料，因此使用filter篩選器調整資料排序。

14.開啟EmployeeDashboard畫面並選擇Button，在EmployeeId這個選項中選擇`NullIdentifier()`。
![image](https://hackmd.io/_uploads/SJ5uCqIgyx.png)

15.進入畫面，嘗試輸入資料並儲存。

16.開啟前面設定好的SaveOnClick Action，使用Destionation取代End。並調整EmployeeId為`NullIdentifier()`。
![image](https://hackmd.io/_uploads/SkKhJoUxyg.png)

17.調整EmployeeDashboard的畫面，將Name的資料Link到EmployeeDetails。
![image](https://hackmd.io/_uploads/HJ4AmMve1l.png)

18.在EmployeeDetails新增資料，並到EmployeeDashboard確認新增資料是否出現。

在ProjectDetails設定Server parameter以及傳遞變數。

19.新增input parameter，並設定GetProjects的filter篩選條件。
![image](https://hackmd.io/_uploads/B1ZrUzDlke.png)

20.在button中設定On-click事件(New Client Action)，並設定Server Action(Project_CreateOrUpdate)。
![image](https://hackmd.io/_uploads/ryQ0UMDgkx.png)

21.新增Message，並設定Message內容。
![image](https://hackmd.io/_uploads/SkkuwMvgkx.png)

22.新增Destination，並將其導向ProjectDetails，然後到ProjectDashboard，將button以及left action重新設定(ProjectId)。
![image](https://hackmd.io/_uploads/rkP0aGvxyl.png)

---
Q1:If文に関する説明として正しくないものはどれですか。
A1:必要に応じてさらにブランチを追加することができる。Switch文では追加することができます。

Q2:Switch文に関する説明として正しくないものはどれですか。
A2:評価がTrueになるすべてのブランチが実行される。評価がTrueになる最初のブランチです。Trueになるブランチがない場合は、Otherwiseが実行されます。

---
### 例外処理とハンドリング

1. 例外の発生
実行時に操作が失敗した場合、自動的に例外が発生し、フローが中断されます。たとえば、データベース操作中に制約違反があった場合などです。また、開発者が明示的に例外を発生させることも可能です。

2. 例外ハンドラの動作
例外が発生すると、実行は最適な例外ハンドラに移り、そのハンドラフローが実行されます。元のフローに戻ることはありません。
例外の種類に応じて適切なハンドラが呼ばれ、たとえば、Database Exceptionが発生した場合、DatabaseExceptionハンドラが実行されます。

![image](https://hackmd.io/_uploads/ryIPkXPgyg.png)


3. 複数の例外ハンドラ
1つのアクションフローに複数の例外ハンドラ（Database、Security、Communication、Custom User など）を設定できます。すべてのフローにハンドラを設定する必要はありませんが、ハンドラがない場合、例外はバブルアップして上位のコンテキストへと伝わります。

4. グローバル例外ハンドラ
例外が上位のコンテキストにバブルアップしても適切なハンドラが見つからない場合、最終的にグローバル例外ハンドラに渡されます。グローバル例外ハンドラは、アプリケーション全体のあらゆる例外をキャッチするため、設定が重要です。

---

Q1:アクションフローに関する説明として正しいものはどれですか。
A1:各フローはそれぞれ独立している必要があります。例外ハンドラのフローが他のフローと交わることはできない。


Q2:複数の例外ハンドラがあるアクションフローで例外が発生した場合の説明として正しいものはどれですか。
A2:実行は、例外に最も適した例外ハンドラに移動される。

---

## フォーム検証

ユーザーが入力したデータの正確性を確認するための重要なプロセスが含まれています。OutSystemsでは、ビルトインバリデーションとカスタムバリデーションの2つの方法で検証を実施することができます。

1. ビルトインバリデーション
* 自動検証：
OutSystemsは入力フィールドに対して自動的に基本的な検証を行います。これには、必須フィールドの入力確認や、データ型が正しいかどうかのチェックが含まれます。
例えば、Due Dateフィールドには「必須」や「日付型」の検証が自動で適用されます。
* プロパティ設定：
Input Type：入力フィールドのデータ型を指定します。
Mandatory：必須フィールドかどうかを定義します。
* ボタンやリンクにビルトインバリデーションを適用：
送信ボタンに設定されたBuilt-in Validationsプロパティを「Yes」にすることで、自動検証が実行されます。

2. カスタムバリデーション
* カスタムバリデーション
ビジネスルールや特定の検証を定義するために使用されます。たとえば、2つの入力値が依存関係にある場合や、特定の条件でのみ有効な値を設定する場合です。
(1) Validプロパティ：入力フィールドが有効かどうかを判断します。
(2) ValidationMessageプロパティ：入力が無効だった際に表示するエラーメッセージを定義します。
![image](https://hackmd.io/_uploads/Bk6sZXwlyg.png)

* 実装方法：
(1) If条件を使用して、入力が有効かどうかを確認します。
(2) 無効であれば、AssignでValidプロパティを`False`に設定し、エラーメッセージを表示します。

3. フォーム全体のValidプロパティ
フォームにもValidプロパティがあります。これにより、すべての入力フィールドが有効かどうかを一括して確認できます。1つでも無効なフィールドがあれば、フォーム全体のValidは`False`に設定され、データ保存が中断されます。

![image](https://hackmd.io/_uploads/r1aGzQwgJg.png)

4. 検証メッセージの表示
ユーザーが無効な入力を行った場合、フィールドが赤枠で囲まれ、フォーカス時に検証メッセージが表示されます。例えば、「Due date cannot be in the past」というメッセージが表示される場合があります。

### ビルトインフォーム検証を使用する方法
1. 入力フィールドの設定：
「OrderDetail」画面には注文に関連する入力フィールドがあります。

2. ビルトインバリデーション(Built-in Validations)の動作：
ビルトインバリデーションでは、**必須フィールドの入力有無とデータ型の整合性を確認します。**
Priorityフィールドを除き、フォームのすべての入力フィールドが必須項目に設定されています。
![image](https://hackmd.io/_uploads/HJ4lwujl1x.png)

3. Save ボタンの設定：
Save ボタンには、**ビルトインバリデーションを自動で実行するための Built-in Validations プロパティがあり、デフォルトで「Yes」に設定されています。**
ボタンがクリックされると、**SaveOnClick**アクションが呼び出され、入力データの保存が実行されます。
CreateOrUpdateの前にある If 条件では、フォームが有効かどうかを確認し、すべての必須項目が入力されているかとデータ型に相違がないかをチェックします。
![image](https://hackmd.io/_uploads/r1PY2dogyl.png)

4. ビルトインバリデーション(Built-in Validations)のテスト：
Save ボタンを押すと、必須項目が入力されていない場合にエラーメッセージが表示されます。例えば、リクエスト者を未選択のまま保存しようとすると、「必須」というメッセージが表示されます。
リクエスト者を選択して再度 Save ボタンを押すと、処理が正常に完了します。
![image](https://hackmd.io/_uploads/HJlfPOixJe.png)

5. ビルトインバリデーション プロパティの変更：
Saveボタンの Built-in Validationsプロパティを「No」に変更し、再度保存操作を行うと、必須チェックが行われず、入力が不完全でも操作が完了します。
最後に、**SaveOnClickアクション**でフォームの有効性を確認する If 条件と False ブランチを削除し、検証なしのフローをテストします。

<實作>
1.開啟ProjectDetails，選擇SaveOnClick(Client Action)，開啟フロー，加入If判斷。
![image](https://hackmd.io/_uploads/BykWLtilyl.png)

2.在If條件式中設定篩選條件 `GetProjectById.List.Current.Project.DueDate > CurrDate()`。
![image](https://hackmd.io/_uploads/HkywUKjekl.png)

3.新增Assign，連接If跟Assign，同時右鍵選擇Swap Connectors，將true跟false判斷對調。
![image](https://hackmd.io/_uploads/HyuaYKixyg.png)

![image](https://hackmd.io/_uploads/B12Bjtslyg.png)

4.在Assign內設定兩個變量屬性(assignments)，最後將Assign拉回Form1.Valid。
![image](https://hackmd.io/_uploads/rkx9HpYixJx.png)

![image](https://hackmd.io/_uploads/BJ6qTKjx1x.png)


---
Q1:ウィジェットが有効になっていない場合（ValidプロパティがFalseに設定されている場合）、画面の動作はどのようになりますか。
A1:通常のウィジェットが表示され、特定のスタイル（赤枠など）が適用され、検証エラーメッセージが表示される。

Q2:OutSystemsのビルトイン検証の対象ではないものはどれですか。
A2:テキストフィールドの最大長。必須フィールドとデータ型は、プラットフォームにより自動的に実行される検証です。

Q3:FormのValidプロパティに関する説明として正しいものはどれですか。
A3:最後のカスタム検証が終わった後に、FormのValidプロパティが確認される。

---
## ロールベースのアクセス
* アクセス制御の概要
アクセス制御は、ユーザー（「誰」）に対して、画面へのアクセスやデータの追加（「何」）といったリソースやアクションの使用を許可する仕組みです。
![image](https://hackmd.io/_uploads/ryV2_Z6eJl.png)
アクセス制御は通常、認証（ユーザーの識別）と認可（行動の許可）に分けられます。
![image](https://hackmd.io/_uploads/HJe0pdZpgyx.png)

* ユーザー管理とロールの作成
OutSystemsの「Users」アプリケーションで、ユーザーを作成・管理できます。ユーザー識別情報としてはユーザー名とパスワードが使用され、プログラム的に作成することも可能です。

* ロールの種類と操作
「Service Studio」には「Anonymous」と「Registered」の2つのビルトインロールがあり、さらにアプリ固有のロールを任意に作成できます。Check、Grant、Revokeアクションを用いて、ユーザーに特定のロールがあるかの確認やロールの割り当て、削除ができます。
![image](https://hackmd.io/_uploads/rJZEKZpe1e.png)

* 権限の付与と確認方法
ロールを割り当てると、そのロールに基づいて特定のタスクの実行権限が付与されます。
CheckRoleアクションを利用して、サーバーアクション内で特定のロールを持つユーザーにのみタスクを許可するように設定可能です。
![image](https://hackmd.io/_uploads/HJlkq-plke.png)

* スクリーンロールの設定
各画面にはScreen Rolesプロパティがあり、ここで設定されたロールを持つユーザーのみアクセスが許可されます。

* まとめ
アクセス制御は以下の3つで構成されます。
**ユーザー作成・管理（Usersアプリで）**
**ロール割り当て**
**特定タスクの権限確認**
![image](https://hackmd.io/_uploads/Hyx4cb6x1l.png)

### ユーザーにロール
* ロールの作成方法
Service StudioのLogicにあるRolesフォルダには、AnonymousとRegisteredの2つのビルトインロール（built-in roles；內建）が含まれています。
新しいロールを作成するには、Rolesフォルダを右クリックして「Add Role」を選択し、ロール名を「Manager」とします。
作成したロールには、 **確認、付与、取り消し** に対応する3つのビルトインアクションが用意されています。

* ユーザーにロールを割り当てる手順
Usersアプリでエンドユーザーのリストを確認できます。新しいユーザーを作成するには、氏名、ユーザー名、パスワードを入力し、詳細ページのRolesセクションで「Manager」ロールを割り当てます。複数のManagerロールがある場合は、モジュール名で識別されます。

* 権限の付与
「Manager」ロールが割り当てられると、そのロールで定義された権限がユーザーに付与されます。

<實作1>
新增一個HR Manager以及設定其帳戶的權限。

1.Logic中的Roles點右鍵`Add Roles`，新增一個`HR Manager`。
![image](https://hackmd.io/_uploads/B1AjCzpe1e.png)

2.開啟OutSystems的User Page，新增兩名使用者資料。並分別幫兩位使用者新增Roles。
![image](https://hackmd.io/_uploads/SJAgQmpgke.png)

設定用戶權限
3.開啟網頁的六個畫面，下方有`Anonymous`以及`Registered`(預設為勾選)，將兩個選項取消。
![image](https://hackmd.io/_uploads/BJErJN6eyl.png)

4.分別使用兩個權限的帳號登入，確認權限是否設置成功。

<實作2>
在編輯資料時，確認使用者權限是否符合條件，新增IF判斷式檢核使用者權限。

1.開啟Employee_CreateOrUpdate(Server Action)，將IF工具加入到フロー中，並輸入Condition:`CheckHRManagerRole()`。
![image](https://hackmd.io/_uploads/rkLuNEae1g.png)

2.右鍵點選Swap Connectors，調整判斷結果為`TRUE`。
![image](https://hackmd.io/_uploads/Bk0CNV6gyx.png)

3.新增兩個Assign工具，分別為`EmployeeAdded=True` and `EmployeeAdded=False`
![image](https://hackmd.io/_uploads/rkvbcEaeyg.png)

4.分別使用兩種不同的帳號登入，確認是否有根據帳號提供不同的操作權限。

5.調整另一個畫面的權限判斷，開啟EmployeeDetails的SaveOnClick(Client Action)。
![image](https://hackmd.io/_uploads/rJHV6ZCxkg.png)

6.使用Message工具，設定匯入成功的訊息提示。
![image](https://hackmd.io/_uploads/S1yVWMAlJe.png)

7.另一邊則設定輸入錯誤時的Error訊息。
![image](https://hackmd.io/_uploads/ryyyfMRgye.png)

8.分別使用兩組不同權限的帳戶登入，確認各自的權限差異。

---
Q1:ユーザーとロールに関する説明として正しいものはどれですか。
A1:デフォルトでは、ビルトインのUsersアプリケーションでエンドユーザーを管理する。

Q2:画面へのアクセスを制限するには、どのようにすればよいですか。
A2:画面のプロパティで、ロールのチェックを外してアクセスを制限する。

Q3:ビルトインのロールアクションに関する説明として正しいものはどれですか。
A3:
CheckRoleアクションは、ユーザーに特定のロールがあるかどうかを確認する。
GrantRoleアクションでは、プログラムによってロールをユーザーに付与することができる。
RevokeRoleアクションでは、ユーザーのロールをプログラムによって削除することができる。

(正しくない）
CreateUserWithRoleアクションは、エンドユーザーを作成してそのユーザーにロールを付与する。
＝＞実際には、　ユーザーの作成　と　ユーザーへのロールの割り当て　の2つの手順による操作になります。

---
## デバッグ（Debug）

### アプリのデバッグ
* トラブルシューティング(Trouble Shooting)とデバッグの定義
トラブルシューティングは実行時エラーを素早く発見し修正することで、デバッグはその一部で、エラーを特定して解決する技術です。

* デバッグ手順
デバッグには、**ブレークポイント設定、デバッガ起動、アプリ実行、コードデバッグ**の4ステップがあります。
![image](https://hackmd.io/_uploads/rkU2jfRxJl.png)

ブレークポイントで停止し、Service Studioでステップオーバーやステップイン操作を行い、変数やウィジェットの値を確認して動作を確認します。
![image](https://hackmd.io/_uploads/rJQ_2fCx1g.png)

* 複数モジュール間のデバッグ
通常、デバッガは現在のモジュールのみを対象としますが、複数モジュールが関わる場合はエントリモジュールを設定して、プロデューサとコンシューマ間のブレークポイントを停止させるようにします。


プロデューサ モジュール(Producer Module):實作出來成為Function供其他Module使用。

コンシューマ モジュール(Consumer Module):取用他人已開發好Function的Module。

---
Q1:ブレークポイント(BreakPoint)を配置できる場所はどこですか。
A1:アクションのみ（クライアント側とサーバー側）

Q2:デバッグ中に変数の値を検査することができます。
A2:コードのデバッグ中、スコープに基づいて変数の値を検査することができます。

Q3:OutSystemsのデバッガで利用できないコマンドはどれですか。
A3:Restart Debugging

Q4:コンシューマ モジュール(Consumer Module)をデバッグする際に、プロデューサ モジュール(Producer Module)に定義されたブレークポイントで確実に実行を停止するには、どのようにすればよいですか。
A4:プロデューサで、Entry Moduleプロパティをコンシューマ モジュールに設定する。

![image](https://hackmd.io/_uploads/Sy99yF0lke.png)

> hint: https://success.outsystems.com/ja-jp/documentation/11/debugging_apps/debugging_producer_modules/

---
## ページネーション
1. ページネーションの追加
従業員のテーブル表示にOutSystems UIの`Pagination`パターンを追加し、開始インデックスと1ページの最大レコード数を設定するため、ローカル変数を用意します。
![image](https://hackmd.io/_uploads/H1s2St0eye.png)

2. 設定の手順
* `StartIndex`と`MaxRecords`はローカル変数に直接設定。
![image](https://hackmd.io/_uploads/ry5gUYAlke.png)
* `Total Count`はAggregateで取得した総レコード数を設定。
![image](https://hackmd.io/_uploads/BJobIFCeJe.png)

3. ページ切り替えロジック
ページ切り替え時に`Refresh`アクションを実行し、`NewStartIndex`入力を`StartIndex`変数に設定。Aggregateを再実行し、新しいページデータを表示します。

4. 変数の初期値
`StartIndex`のデフォルトを0、`MaxRecords`を5に設定。これにより1ページ5レコードが表示され、ページ変更で開始インデックスが更新されます。

5. パブリッシュと検証
モジュールをパブリッシュ後、ページ間の移動が可能。さらに新規画面の作成では`スキャフォールディングアクセラレータ`で簡単にページネーションをカスタマイズできます。

<實作>
替表格新增分頁

1.在欲設定分頁的頁面中新增一個區域變數(Add Local Variable)，確認其資料格式為Integer，Default Value設為0。
![image](https://hackmd.io/_uploads/HyTHOKRlye.png)

2.新增另一個區域變數，並將此變數命名為`MaxRecords`，其Default Value設為10。

3.在工具列中選擇`Pagination`，並將其拖曳至表格正下方。
![image](https://hackmd.io/_uploads/S1tktYAgye.png)

4.將其內容的三個變數(StartIndex、MaxRecords、TotalCount)依據輸入。
![image](https://hackmd.io/_uploads/HJkSFYClyl.png)

5.將該`Pagination`下方的`Handler`點選`New Client Action`。

6.開啟該Client Action，新增一個`Assign`工具，並調整其內容，新增StartIndex。
![image](https://hackmd.io/_uploads/Sk2P9t0ekx.png)

7.將欲設定分頁的Entity拉入該Flow中，並將其Aggregate內的Start Index以及Max. Index設定為前述的兩個Local Variable。
![image](https://hackmd.io/_uploads/H1ao9F0x1e.png)

![image](https://hackmd.io/_uploads/Hk1BitAx1x.png)

8.確認畫面是否出現表格分頁。
![image](https://hackmd.io/_uploads/SJimnKAl1x.png)

### ソート

1. ソート機能の追加
従業員テーブルにエンドユーザーがヘッダークリックでソートできる機能を追加。GetEmployees Aggregateでテーブルのデータが表示されます。

2. Sort Attributeの設定
各列のヘッダーセルにSort Attributeを設定。Employee Name列やCity列にソート基準を追加します。

3. On Sortイベントの設定
* On Sortイベントのハンドラを定義し、列をクリックするとソートされるように設定。
* ソートの基準を保持するローカル変数を作成し、これをAggregateで使用。
* ソートの順序を変更するロジックを追加し、クリックされた列の属性によって昇順・降順が切り替わるようにします。

4. Aggregateの更新
AggregateにTableSort変数を設定し、動的にソートできるようにします。これにより、ユーザーがクリックした列に従ってデータがソートされます。

5. ブラウザでの確認
実装後、ブラウザでソート機能を確認。列のヘッダーをクリックすると昇順・降順に切り替わることを確認。

<實作>
幫網頁表格新增排序功能

1.選擇欲設定排序的表單，點選`Header Cell`，在`Sort Attribute`輸入欲參考的值。
![image](https://hackmd.io/_uploads/Hk9H6G1Wkg.png)

2.選擇Entity下方的breadcrumb，在`OnSort`中新增一個Client Action。
![image](https://hackmd.io/_uploads/Hy7kG7yW1g.png)

![image](https://hackmd.io/_uploads/S17QMQ1-yg.png)

3.在On Sort的事件下方的New Argument選擇新參數`ClickedColumn`，同時在該畫面內新增一個`Local Variable`。

4.開啟OnSort這個Clint Action，新增兩個Assign工具(True and False)，其中皆新增兩個參數:

`SortColumn = ClickedColumn + " DESC"`
`StartIndex = 0`

並在False的Assign下方加入一個`Refresh Data`，並選擇`GetEmployees`。
![image](https://hackmd.io/_uploads/B1uVU71b1e.png)

5.開啟`Refresh Data`，新增Sort條件，開啟`Add Dynamic Sort`，
![image](https://hackmd.io/_uploads/rJu78XJ-Jl.png)

設置表單顯示行數
6.將一個Input工具拉入畫面，要設定顯示表格行數(MaxRecords)。將該Input的Variable設定為`MaxRecords`，將On Change設定為`Refresh`，並設定初始值為0。
![image](https://hackmd.io/_uploads/BJnmcmybkx.png)

---
Q1:テーブルまたはリストでページネーションを実装する際の説明として正しいものはどれですか。
A1:ページネーションのMax Recordsプロパティは、1ページに表示するレコード数を保持する。

Q2:テーブルのソートに関する説明として正しいものはどれですか。
A2:On Sortイベントの入力パラメータには、クリックされた列が含まれている。
![image](https://hackmd.io/_uploads/S1nDpQJbJg.png)

Q3:リストのソートに関する説明として正しいものはどれですか。
A3:エンドユーザーがソート基準を定義できるようにするには、他のウィジェットを使用する必要がある。新しいソート基準によるデータの更新をトリガーします。

---
## ブロック(Block)

1. ブロックの概念
ブロックは再利用可能なUIコンポーネントで、他のウィジェット、パターンも組み込め、複雑なUIを構築可能。インスタンスとして画面や他のブロックに配置し、「親」となる画面やブロック内で複数回使用できます。

2. スコープと通信
* ブロックは独立したスコープを持ち、親から直接アクセス不可。
* 入力パラメータとイベントを使用して、親から情報を受け取ることや、ブロックと親の通信を行えます。

3. プレースホルダの活用
プレースホルダは未定義のスペースを確保し、インスタンスごとに異なる内容を設定できるため、柔軟なカスタム化をサポートします。

4. ブロックの利点
再利用可能で保守性が高く、改良や修正が全インスタンスに反映されるため、開発効率と保守の手間を大幅に軽減できます。

<實作>
新增一個Block，並讓其顯示其他分頁的資訊

1.在MainFlow中點選右鍵，選擇`Add Block`，新增一個畫面。
![image](https://hackmd.io/_uploads/HyQ2bT1-yl.png)

2.右鍵選擇`Add Input Parameter`以及`Fetch Data from Database`，新增顯示資料內容。
![image](https://hackmd.io/_uploads/SykHQT1W1g.png)

3.依序建構畫面內容。
![image](https://hackmd.io/_uploads/Sk2Pmaybkl.png)

4.將畫面資料與該ブロック連接，在ウィジェット中新增Container，並右鍵點選`Encolse If`，新增是否顯示資料的條件。
![image](https://hackmd.io/_uploads/SJtvHay-Je.png)

5.設定資料顯示的條件，使用`Encolse If`設計判斷式，檢查該輸入的資料是否正確。
![image](https://hackmd.io/_uploads/H1GoLTJWyg.png)


>https://learn.outsystems.com/ja-jp/training/journeys/web-developer-662/using-block-exercise/o11/6243


---
Q1:ブロックは再利用可能なUIコンポーネントです。 次のうち、正しいものはどれですか。
A1:
一度開発すれば何度も再利用できるため、再利用性が向上する。
独自のロジックをカプセル化する。
デザインや機能を変更するとすべての利用箇所に反映されるため、保守性が向上する。

Q2:ブロックはどこで使用できますか。
A2:ブロックを他の画面内とブロック内で使用することはできますが、そのブロック内で再帰的に使用することはできません。


Q3:プレースホルダ(Placeholders)に関する説明として正しいものはどれですか。
A3:プレースホルダはインターフェイス内にスペースを確保し、インスタンス化されたブロックに場所を割り当てられるようにする。

---

## ブロックイベント

1. ブロックイベントの役割
イベントはブロックが親とやりとりするための要素で、特定のアクションをトリガーして親に通知。
ブロック内でイベントを定義し、親側(父元件)がイベントを処理することで、異なるスコープ間でのデータ共有が可能。

2. イベントのトリガー(Trigger)と処理方法
イベントに入力パラメータ（Parameters）を設定し、トリガー時にブロック内データを親へ渡す。
親はハンドラ（handler）で画面アクションを定義し、イベントがトリガーされると実行フローが親のハンドラへ移る。

3. 実行例 - WeekDayブロック
エンドユーザーが曜日を選択すると、関連クライアントアクションがブロック内でトリガーされる。
親のハンドラが実行され、処理後に元のフローに戻る。

### On Parameters Changed

1. On Parameters Changed イベントの役割
このビルトインイベントはブロック内でのみ使用可能で、**親がブロックの入力パラメータを変更した際に、自動でトリガーされます。**
これにより、ブロックが親の変更に応答できるようになります。
ブロック内で入力パラメータを変更しても、イベントはトリガーされません。
（父元件變數改變影響子元件；子元件變數改變不影響父元件)

2. 動作の流れ
親画面に選択中の製品IDがあり、このIDがブロックの入力パラメータとして渡されます。選択IDが変わるたびに、On Parameters Changedイベントがトリガーされ、製品詳細情報が更新されます。
新しい製品が選択されるたびに、イベントがトリガーされ、処理フローが実行され、表示情報が更新されます。
![image](https://hackmd.io/_uploads/r1Kb5ay-1g.png)

3. イベントのライフサイクル
入力パラメータが変更されると、On Parameters Changedイベントがトリガーされ、データ更新処理が始まります。
その後、ブロックのRender、画面のRenderが順に実行され、AggregateのAfter Fetchイベントがトリガーされ、再描画が完了します。

<實作>
在子層建立一個下拉式選單，並透過事件傳遞通知父層進行資料顯示

1.新增一個Server Action，並在該Action中新增一個變數Employee。
![image](https://hackmd.io/_uploads/rJ2BxCybyl.png)

2.將該Entity的`UpdateEmployee`拉入該變數的Flow中。
![image](https://hackmd.io/_uploads/BkqGERJbye.png)

3.觸發以及處理該事件，新增一個`Dropdown`，變數輸入Employee Entity的Department。(注意不要選擇錯誤，可能導致資料不會響應改變)
![image](https://hackmd.io/_uploads/S1ITVRkZyg.png)

4.選擇On Change中選擇New Client Action命名為`UpdateEmployee`，在流程中新增一個Server Action，選擇`UpdateEmployee` Server Action。
![image](https://hackmd.io/_uploads/BJFtHAybkl.png)

5.在子層(EmployeeInfo)中右鍵選擇`Add Event`，並將名稱訂為`EmployeeUpdated`。
![image](https://hackmd.io/_uploads/H1_1L0ybyx.png)

6.在前述的Client Action`UpdateEmployee`中增加觸發事件(Trigger)，並將該事件選擇`EmployeeUpdated`。
![image](https://hackmd.io/_uploads/S1fuIRybkg.png)

因觸發事件，因此必須要有處理，要定義處理流程。

7.在父層(EmployeeDashboard )新增Client Action，命名為`Refresh`，在其流程中引入Refresh Data`GetEmployees aggregate`。
![image](https://hackmd.io/_uploads/SyPMDCybke.png)

8.最後進入子層中在Handler中選擇該事件`Refresh`。
![image](https://hackmd.io/_uploads/SJAHPRy-Jl.png)

結果:在子層中調整下拉式選單，會將該值賦值給父層並修改其表格資料。

---

Q1:ブロックイベントに関する説明として正しいものはどれですか。
A1:
イベントを使用してブロックのスコープから親のスコープに情報を渡すことができる。
イベントはブロックによってトリガーされ、その親によって処理される。
ブロックの2つのインスタンスが同じイベントで同じハンドラを使用する場合がある。

(正しくない)
イベントは、ブロックレベルまたは画面レベルで定義できる。
＝＞親要素との通信を可能にするためのものです。**画面は親を持ちません。**

Q2:ブロックイベントのハンドラを定義する必要があるのはどの場合ですか。
A2:イベントが**必須に設定されている**場合。

Q3:On Parameters Changedイベントがトリガーされるのはどの場合ですか。
A3:ブロックの親が、ブロックの入力パラメータの値を1つ以上変更した場合。

---

## リアクティブ　プログラミング　モデル（Reactive Programming Model）

### 画面イベント

1.　画面イベントの概要
画面イベントにより、特定のタイミングでアクションを実行し、アプリケーションの変化に対応できる。

2.　画面のライフサイクルイベント
![image](https://hackmd.io/_uploads/HJfNgvlZJg.png)
* On Initialize: 画面の初期化時にトリガー。Aggregateとデータアクションがバックグラウンドで実行される。
* Ready: DOMの読み込み完了後、**画面描画前にトリガーのみ**。
* Render: 画面がユーザーに表示される際にトリガー。再描画時もトリガーされ、**データ変更に対応**。
* After Fetch: Aggregate取得後にトリガーされ、**画面が更新される**。
* On Destroy: 画面移動時に古い画面が破棄される際にトリガー。

3.　画面遷移時のイベントフロー
移動先の画面で On Initialize → Ready → Render → On Destroy が実行され、最終的に新しい画面がユーザーに表示される。

4.　各イベントのユースケース
* On Initialize: デフォルト設定やリダイレクト処理に利用。
* Ready: JavaScriptリスナー追加や特定ウィジェットへの焦点設定。
* Render: データ変更時の対応。
* On Destroy: JavaScriptリスナーの解除など。
* After Fetch: Aggregate間の依存関係処理に便利。

---
Q1:画面やブロックで利用できないイベントはどれですか。
A1:After Fetch，画面のAggregateとデータアクションでのみ利用可能です。データベースやサーバーからのデータ取得を受けて作動します。

Q2:画面のInitializeイベントに最適なユースケースはどれですか。
A2:ローカル変数のデフォルト値を設定する。

Q3:画面でイベントが発生する順序として正しいものはどれですか。
A3:Initialize、Ready、Render、Destroy

---

### オンデマンド(On Demand)

1. 画面のAggregateデフォルト設定
Aggregateは初期化時に非同期で実行され、データ取得後に画面が再描画される(At Start)。

2. Fetchプロパティのオプション
* At Start: 画面初期化時に自動でAggregateをトリガーし、効率的にデータを表示する。
* Only On Demand: 特定のアクションでのみトリガーされ、画面初期化時にはAggregateが実行されない。

3. 実行シナリオ例
従業員リストの画面で、リスト表示のAggregateはAt Startで実行し、選択後に詳細情報のAggregateがOnly On Demandでトリガーされる。

4. オンデマンド実行方法
Refresh Dataを使用し、画面アクションフローからAggregateをトリガーして非同期にデータを取得する。

**PS:On Demand => 當選擇載入資料時網頁才會將資料取出生成並呈現在畫面上，可以減少初始載入網頁的時間以及資源。**

<實作>
建立員工的國家、州別、城市，並讓資料在畫面切換時顯示

1.建立國家、州、城市的Static Entity，並將其串接到主表(Employee)上。
![image](https://hackmd.io/_uploads/Sy6xWdeZyg.png)

(太多寫不完)
>https://learn.outsystems.com/ja-jp/training/journeys/web-developer-662/fetching-data-on-demand-exercise/o11/6225

---

Q1:画面のAggregateに関する説明として正しいものはどれですか。
A1:

Fetchプロパティが「only on demand」に設定されているAggregateの実行が完了した時点で、画面のRenderイベントがトリガーされる。
画面のAggregateは、画面の初期化中またはOn Demandでのみトリガーできる。
On After Fetchイベントは、Fetchプロパティに関係なくあらゆるAggregateでトリガーされる。

(正しくない)
デフォルトでは、どのAggregateのFetchプロパティもOn Demandに設定されている。
=>Aggregate作成時のデフォルトは、At Startです。

Q2:FetchプロパティがOnly On Demandに設定されているAggregateがあるとします。このAggregateはいつ実行されますか。
A2:画面アクションのRefresh Dataノードを使用して、プログラムによって実行される。

At Startでデータを取得するように設定されているAggregateにRefresh Dataノードを使用することもできます。

---
## クライアント変数(Client variable)

1. クライアント
ユーザー固有の設定を保存し、クライアントブラウザに保持するためのもの。
基本データ型やエンティティ識別子の保存が可能。
ログイン後、変数の値は保持されるが、ログアウトやログイン期限切れで初期値にリセットされる。
ブラウザを閉じても値は保持され、再度開いた際に読み込み直される。

2. ユースケース
よく使用する情報のキャッシュ：サーバーやデータベースへのリクエストを減らし、パフォーマンスを向上。
ユーザー設定の保存：検索キーワード、ページ表示アイテム数、レイアウト形式などを記憶する。

3. 注意点
機密情報の保存は避ける：クライアント変数はブラウザに保存されるため。

---

Q1:クライアント変数に関する説明として正しいものはどれですか。
A1:頻繁にアクセスされる情報をキャッシュするうえで便利である。


Q2:クライアント変数に適したユースケースはどれですか。
A2:ユーザー名やデータベースへのリクエストを減らす。

---
## サイトプロパティ (Site property)

1. サイトプロパティの定義
アプリケーション全体で共有するグローバルな構成変数として利用。
サーバー側でのみ存在し、環境内の全ユーザーと情報を共有可能。

2. サポートされるデータ型
保存できるのは、`Integer`、テキスト(text)、エンティティ識別子などの**基本的なデータ型に限定**。

3. Service Centerでの実行時変更
サイトプロパティの値は、開発や再デプロイを行わずにService Centerから変更可能。
ただし**頻繁な変更はパフォーマンスに悪影響を与える可能性があるため**、推奨されない。

4. 環境ごとの独立性
各環境（開発、テスト、本番）で異なる値を設定でき、環境固有の構成が可能。

5. 代表的なユースケース
APIキー(API Key)の保存：環境ごとに異なるAPIキーを設定可能。
機能の有効化/無効化(控制功能啟用與否)：新機能のリリース時に有効化/無効化を管理。
頻繁に変わる値には使用せず、アプリケーションの定数として使用することが推奨される。

---

Q1:Service Centerでサイトプロパティの値を変更し、実行時のアプリケーションの動作を変更することができます。
A1:正しい、設計時にデフォルト値を設定し、環境に応じてService Centerで変更することができます。

Q2:サイトプロパティに適したユースケースはどれですか。
A2:REST WebサービスのAPIキー。

---
## SQLクエリ(SQL Query)
1. SQLツールの機能
SQL文の作成・テストが可能（UPDATE、INSERT、DELETEなどのSELECT以外も含む）。
複雑なデータ取得やサブクエリが必要な場合に活用。

2. SQLツールの利用方法
サーバーアクションや画面のデータアクションで利用。
ビジュアルエディタ上で入出力設定し、SQLクエリを下部タブで手動記述。
SQLツールが自動で構文チェックし、キーワードや変数は色分け。

3. データアクセスのスコープとパラメータ
スコープ外のデータには、入力パラメータ（@parameter_name）を使用してアクセス。
ターゲットDBごとに記述が異なり、例：SQL ServerではTOPを、MySQLではLIMITを使用。

4. エンティティとアトリビュートの扱い
エンティティ名は波括弧 {}、アトリビュートは角括弧[]で囲む。
OutSystemsが自動で物理DBの名前に変換するため、特別な構文が必要。
ex: select {entity}.[attribute_1], {entity}.[attribute_2] from {entity} 

5. ストラクチャ(Structures)と出力設定
ストラクチャは複合データ型（エンティティに似るが値を保持しない）で、変数のデータ型として設定可能。
SQLクエリ出力には**エンティティやストラクチャが必要**で、SELECTのカラム(columns)とデータ型を一致させる。
![image](https://hackmd.io/_uploads/HkIvR2eZkl.png)

![image](https://hackmd.io/_uploads/S1QPJagbkg.png)

6. クエリテスト
Test Inputsタブでパラメータ設定し、クエリ実行後、Test Outputタブで結果を確認。
テストはSQLクエリが期待通りに動作するか確認するための重要な手順。

7. 複雑なSQL文
SELECT以外の文（INSERT、UPDATE、DELETE）も記述可能。
出力が不要な場合でも、エンティティやストラクチャを定義する（便宜上、対象エンティティを使用）。

<實作>
使用新的練習專案，練習基本SQL語法

--select

1.開啟GetEmployees這個Action，並將原本的GetAggregate更換為SQL。
![image](https://hackmd.io/_uploads/H1WDt6lZJl.png)

2.在Parameters中新增一個`Query Parameters`，設定名稱以及資料型態。

3.在下方的SQL欄位中撰寫SQL語法({表格名稱} & [欄位名稱])。
![image](https://hackmd.io/_uploads/SkznK6xWyg.png)

4.在Output Entities/Strutures中選擇輸出資料的Structure。
![image](https://hackmd.io/_uploads/BJTd9axbkl.png)

5.點選`TEST SQL`並開啟Test Output查看執行結果。
![image](https://hackmd.io/_uploads/BkSYs6xbJl.png)

6.確認執行結果後回到SQL工具，並將QuerySearch項目設定為SearchFilter。
![image](https://hackmd.io/_uploads/HyfAnaeW1e.png)

--delete

7.開啟Server Actions的DelteALLEmployees，在流程中加入SQL工具。
![image](https://hackmd.io/_uploads/rkDo6pxWkg.png)

--update

8.在Server Actions中找到`IncreaseSalary`，開啟後新增SQL工具，並設定SQL工具。

9.新增查詢參數並確認資料格式，新增輸出Entity以及SQL。
![image](https://hackmd.io/_uploads/Sk3GlCx-yx.png)

10.注意開SQL語法中有一個變數(@Percentage)，輸入變數的地方在`Test Input`。
![image](https://hackmd.io/_uploads/Hyhul0eb1g.png)

11.回到該SQL工具，調整其Percentage。
![image](https://hackmd.io/_uploads/BkxplAgbJg.png)



---

Q1:エンティティとアトリビュートの構文として正しいものはどれですか。
A1:{エンティティ}.[アトリビュート]

Q2:AggregateとSQLツールに関する説明として正しいものはどれですか。
A2:SQLツールでは、サブクエリ(Subqueries)を含むクエリを作成できる。

Subqueries:子查詢

Q3:SELECT SQLクエリの出力にはエンティティよりもストラクチャを優先する必要がありますか。
A3:正しい。クエリで取得するアトリビュートとデータの量が少なくなるため。

Q4:SELECT以外のクエリに関する説明として正しいものはどれですか。
A4:出力のエンティティまたはストラクチャを設定する必要がある。

---

## 考試重點:

①Aggregateは動的にsortingも可能（DynamicSort）
=> Aggregate 支援在運行時動態指定排序條件，這對於使用者介面上的資料列表，根據使用者選擇進行不同排序需求很有幫助。

②Functionが「Yes」の場合、Output　Parameterが一つしか作成できない。且つOutput　Parameter作成は必須です
=> 當 Function 的屬性為「Yes」時，僅能有一個 Output Parameter，且必須要有 Output Parameter，這是為了確保 Function 的結果有唯一回傳值。

③FunctionのParamterにはBasicTypeと複合型両方使えます、SitePropertyはBasicTypeのみが使えます。
=>Function 的 Parameter 支援基本型別（BasicType）和複合型（ComplexType），但 Site Property 僅支持 BasicType，例如整數、字串等簡單資料型態。

④ExpressionにはFunction()を呼ぶことできます
=>Expression 中可以嵌入 Function 調用，這樣可以在顯示資料或處理資料時進行運算和邏輯判斷。

⑤Linkは他のWidgetを含めることができますが、Buttonはできません
=>Link 可以包含其他 Widget，例如 Icon 或圖片等；但 Button 則無法包含其他 Widget，Button 主要是提供簡單的按鈕操作。

⑥Input Widgetを使うとき、Variableに指定するのが必要です。
=>使用 Input Widget 時，必須指定一個變數來儲存輸入值，以便在應用程式中使用該數據進行邏輯處理。

⑦SQLのOutPutEntitiesにEntititesかStructuresかどれか一つのみ指定できます
=>SQL 查詢的 OutPutEntities 只能指定一個資料來源類型，可以是 Entities 或 Structures，但不能同時指定多個來源。

⑧SQL とAggregateの違いはAggregate機能のすべてがSQLで代替できます、SQL機能のすべてがAggregateで代替できません
=>Aggregate 提供的功能能夠在 SQL 中實現，但 SQL 的靈活性和自定義性超出 Aggregate 能力範疇，特別是在複雜查詢中。

⑨WebBlockのEventが必須に指定される場合のみ親がHandlingしなければなりません
=>當 WebBlock 的 Event 標記為「必須」，父元件必須進行該 Event 的處理，否則可能會出現錯誤。

⑩StaticEntityはGet()のみ実行でき、更新、新規、削除できません
=>StaticEntity 只能通過 Get() 方法檢索，無法進行更新、新增或刪除操作，通常用於靜態數據。

⑪SitePropertyにパスワードの最小桁数などが保存すべき
=>SiteProperty 可用來保存應用程式的設置，例如密碼的最小長度等安全設定，讓管理更靈活。

⑫StyleSheetの優先順はScreens＞Theme＞Webblocks（同じ定義の場合、Screensは正とする）
=>在相同定義下，優先順序為 Screens > Theme > WebBlocks，這決定了樣式的最終顯示效果。

⑬セッション変数はログインと関係なく有効期限が切れると、データが廃棄される
=>不論是否登錄，Session 變數都會依設定的時間到期並被自動清除，影響短期狀態管理。

⑭多対多のリレーションシップには中間Entityが必要
=>多對多關係中，需要透過中間 Entity 來存儲兩個實體之間的關聯，以便於查詢與管理。

⑮Debugって、Step-by-Step見ることができる
=>調試過程中支援 Step-by-Step 逐步檢查程式邏輯，方便追蹤變數狀態和排錯。

⑯UserGroupの作用複数のユーザーを一気にロール付与または外す
=>UserGroup 可用於管理多個用戶的角色分配，能批量進行角色添加或移除操作，方便管理。

⑰ソースコードでもユーザーロールを付与することができる
=>可以透過程式碼直接對用戶進行角色分配，實現靈活的權限控制。

----------------------------
名詞解釋

* リダイレクト Redirect 重定向
* レンダリング Rendering 渲染
* プロンプト Prompt 迅速的
* パラメータ Parameters 參數
* ローカル Local 區域
* ロール Role 角色
* オプション Options 選項
* レコード Records 紀錄
* フィルター Filter 篩選
* ハンドラー Handlers 處理程序
* パラメーター Parameters 參數
* イベント Events 事件
* コンポーネント Components 成分
* マッピング Mapping 對應
* インデックス Index 索引
* アトリビュート Attribute 屬性
* フェッチ Fetch 取得
* バインド Bindings 綁定
* プロパティ Property 特性
* スタイル Style 樣式
* ヘッダーセル Head Cell 表頭
* ステップオーバー Step Over 步驟停止
* デフォルト Default 預設
* オンデマンド On Demand 
* スコア Score 分數
* フォーム Form 表單
* カスタム検証 Custom check 自訂驗證
* アクセス Access 使用權
* クリック Click 點選
* メソッド Method 方法
* クライアント Client 客戶端
* ステートメント Statement 描述
* シナリオ Scenario 設想
* ラベル Label 標籤
* フィールド Field 場地
* フルスワイプ Full Swipe
* セッション Session 會議
* テーマ Theme 主題
* レイアウト Layout 布局
* プレースホルダー Placeholder 佔位符號
* コンテンツ Content 內容
* インスタンス Instance 實例
* ブートストラップ Bootstrap 引導
* 






















