【パブリッシャー】Sharperlightクエリーを利用したKENDO DataSource - UI:Grid

Sharperlightの公開クエリを利用したKENDO Datasourceへのデータの提供を紹介しようと思います。
Sharperlightの公開クエリは、Sharperlight RESTfulサービスを介して、通常はWEBレポートを提供しますが、そのURLパラメータを使い分けることでJSON形式でデータを返してくれます。
今回はそのJSON形式でのデータを利用します。

# データソース用公開クエリ(Published Report)の作成 #
JSON形式でKENDO Datasourceへデータを供給する公開クエリとなります。
Sharperlightアプリケーションメニューから**パブリッシャー**を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/9ac76dec-8930-f92b-ab00-5f08598e4d1a.png)
## 一般項目 ##
**パブリッシャー**が起動したら、`新規`ボタンで新しい公開クエリの作成を始めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6be31f66-f7c3-7bb7-c458-7b86e837ac0c.png)
最初に`コード`と`グループ`を記入します。この二つの組み合わせが一意のIDとなります。
`タイトル`および`レポートのタイトル`も記入します。
`著者`や`バージョン`も何人かのグループで公開クエリの作成を行う場合は使用したほうがいいですね。
ここまで来たら`適用`ボタンを押してみてください。以下のメッセージが表示されますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/59fc90bb-46a9-5fe5-642b-890d312253d1.png)
これは、**一公開クエリに一クエリ**という決まりがあるためです。
ということで、`クエリーを編集`ボタンでクエリーの作成を開始します。
## クエリの作成 ##
Sharperlightアプリケーション群で共通の`クエリビルダ`が起動します。これはSharperlight Excelアドインでも同じユーザーインターフェースを使用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/df48264d-4f16-5a44-405a-d549b80f326d.png)
**フィルター**、**選択**および**出力**という三つの領域で構成されたユーザーインターフェースとなります。
クエリビルダの目的はSQL文の設計なので、つまり**フィルター**領域ではFROM句とWHERE句、**出力**領域ではSELECT句の設計を行うということになります。**選択**領域は、指定したFROM句、つまり指定したテーブルに属するフィールドやJOIN情報を表示する領域となります。この領域からフィルターや出力に使用するフィールドを選択することができます。
ではクエリの作成を始めます。
`製品`(データモデル)を選びます。今回は**SAP Business One**を利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f96ab805-44ec-8844-7200-b9e3d42a5a4d.png)
`Company`には、**OEC Computers AU**を指定します。
次に`テーブル`を選択します。同じように検索ウインドウから**A/R Sales Invoice**を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ffce395f-045f-7d0a-128b-230e807cd5b0.png)
選択領域に**A/R Sales Invoice**テーブルのフィールドとJOIN一覧が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/41994198-fc4a-453b-9049-a6686d6c966b.png)
また四つの必須フィルターが自動的に表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3bcfc91b-34c5-0497-2490-379eb6cc8644.png)
これは**A/R Sales Invoice**テーブルが選択された場合、これら四つのフィールドを必須フィルターにしなさいという指定が、**SAP Business One**データモデルに定義されているからです。
今回は必須フィルター**Canceled**に**Ｎ**(No)を指定します。その他の三つの必須フィルターは\<ALL>のままにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/413000ba-587c-f3ac-3ea5-b0153146bbbc.png)
<cr>
次に出力の定義を行います。
選択領域のフィールド一覧より、以下のものをダブルクリックもしくはドラッグ＆ドロップで出力領域に設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/56429dec-5c1e-01fc-6682-d296ccf59ebf.png)
最後に出力アイテムとして設定した七つのフィールドの出力名(内部的に使用される一意の名)を編集します。
右クリックメニューから**名前の変更**を選択し編集します。
編集後はこのようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bc069d94-d0f8-ecdf-f60a-f682f6e41bce.png)
今回はこれで完成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f31d32dd-b44d-4285-1583-8a412b3c2313.png)
`プレビュー`ボタンでクエリの試行ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/76654b92-776f-d426-478e-23e7a37b61da.png)
`OK`ボタンでクエリを保存し公開クエリのダイアログに戻ります。さらに`OK`ボタンで公開クエリも保存します。
クエリの準備完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/19c44ace-28f9-d8d1-c816-d9039e0ba0ac.png)
# KENDO GRID および Datasourceを使用したHTMLの作成 #
今回作成するHTMLコードは、後で別のSharperlight公開クエリを作成し、その公開クエリに埋め込むといった手法でSharperlight RESTfulサービスを介して公開できるようにするというのが前提で記述されています。
よってSharperlight専用タグ等が記述されているので、その辺りを含めて要所を説明していきます。
完成したHTMLおよびJavaScriptコードはこのようになっています。
```
<!DOCTYPE html>
<html>
    <head>
        <title>Order</title>
        <meta charset="utf-8"/>
        <base href="{*Url.Root}"/>
        <link rel="shortcut icon" type="image/x-ico" href="favicon.ico"/>
        <link rel="icon" type="image/x-ico" href="favicon.ico"/>
        
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.default.min.css" />
	    <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.common.min.css" />
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.default.mobile.min.css" />
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.silver.min.css"/>
        <link rel="stylesheet" type="text/css" href="{*Url.Root}Resources/kendo/styles/kendo.silver.mobile.min.css" />
        
        <script type="text/javascript" src="{*Url.Root}Resources/jquery/jquery.min.js"></script>
                
        <script type="text/javascript" src="{*Url.Root}Resources/kendo/js/kendo.all.min.js"></script>
        <script type="text/javascript" src="{*Url.Root}Resources/kendo/js/kendo.timezones.min.js"></script>
    
    </head>
    <body>
        <style type="text/css">
            body {
                height: 1500px;
                font-family: Tahoma;
                font-size: 11px;
            }          
 </style>
        
        <div id="grid" style="width: 1500px"></div>
        
        
        <script type="text/javascript">
            var gURL_Read = "{*Row.DatasourceURL.text}";
            var gKGrid = null;
            
            function _Feed_Data_To_Grid(dsURL){
                try{
                    var dsItems = _Datasource_Create(dsURL);
                    if (dsItems != null){				
                        dsItems.read().then(function (){
                            gKGrid.setDataSource(dsItems);
                            gKGrid.refresh();      
                        });
                    }else{
                        console.log("_Feed_Data_To_Grid(): " + "No Dataset populated");
                    }
                }catch (err){
                    console.log("_Feed_Data_To_Grid(): " + err.message);
                }
            };

            

            function _Datasource_Create(dsURL){
                try{
                    var ds = new kendo.data.DataSource({
                        serverFiltering: false,
                        transport: {
                            read: {
                                datatype: "jsonp",
                                url: dsURL
                            }
                        },
                        schema: {
                            model: {
                                id: "DocId",
                                fields: {
                                    DocId: { type: "number" },
                                    DocDate: { type: "datetime" },
                                    DocNumber: { type: "string" },
                                    CusCode: { type: "string" },
                                    CusName: { type: "string" },
                                    Quantity: { type: "number" },
                                    RowTotal: { type: "number" }
                                }
                            }
                        }
                    });
                    return ds;
                }catch (err){
                    console.log("_Datasource_Create(): " + err.message);
                    return null;
                }
            };
            
            
            // Start from here ==================================================
            $(document).ready(function() {
            
                gKGrid = $("#grid").kendoGrid({
                    columnMenu: {
                        filterable: false
                    },
                    height: 580,
                    editable: "incell",
                    pageable: false,
                    sortable: true,
                    navigatable: true,
                    resizable: true,
                    reorderable: true,
                    groupable: false,
                    filterable: false,
                    columns: [
                        {
                            field: "DocDate",
                            title: "Document Date",
                            width: 80
                        },{
                            field: "DocNumber",
                            title: "Document Number",
                            width: 100
                        },{
                            field: "CusCode",
                            title: "Customer Code",
                            width: 80
                        },{
                            field: "CusName",
                            title: "Customer Name",
                            width: 80
                        },{
                            field: "Quantity",
                            title: "Quantity",
                            width: 80
                        },{
                            field: "RowTotal",
                            title: "Row Total",
                            width: 80
                        }]
                }).data("kendoGrid");
            
                console.log(gURL_Read);
                _Feed_Data_To_Grid(gURL_Read);

            });
        
        </script>
    </body>
</html>
```
要所を説明していきます。
## head部 ##
1. `{*Url.Root}`タグ: 実行時にSharperlight RESTfulサービスの基礎URLに置き換わる
2. Sharperlightに梱包されているJavaScriptファイルおよびCSSファイルへのリンク

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/7999af5a-637e-d336-df1c-f5e659cc70ac.png)
## body部 ##
最初のHTMLコードの部分では、KENDO Grid コントロールを作成するためのdivを準備。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/41d545db-21e8-c379-fa52-cb6a9d6334dd.png)
script部では、以下の三つの構成になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/12857f4d-7bb3-9bd8-1dde-25db70d2f205.png)
1. Sharperlight RESTfulサービスを介してデータソースを取得するためのURLとKENDO Gridコントロールの変数を準備。URLはこのHTMLコードを埋め込む予定の公開クエリのクエリ定義の中に定義しました。`{*Row.DatasourceURL.text}`がそれを参照するためのタグです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/00f54302-fac1-d56d-0fd8-263302491152.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/89d2f78e-aaf9-7592-e33b-07ded1053d23.png)
2. 二つの関数があります。_Feed_Data_To_Grid( )はKENDO Gridにデータを供給する関数、そして_Datasource_Create( )関数は、KENDO Datasourceを作成する関数で、_Feed_Data_To_Grid( )関数からコールされます
3. お馴染みの$(document).ready関数です。ここから全てが始まります。よってKENDO Gridコントールの定義と_Feed_Data_To_Grid( )関数のコールを行います。
### _Feed_Data_To_Grid関数 ###
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/68863858-c5ae-5154-806b-35ae9f623428.png)
### _Datasource_Create関数 ###
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bf188be1-9636-ae94-a696-5fec729ed57a.png)
### $(document).ready関数 ###
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/0057f825-ca05-2f55-b811-c74f87cfc2e4.png)
以上です。このHTMLコードをxxxxxxxxx.htmlとして保存しておきます。
# HTMLコードをホストする公開クエリの作成 #
Sharperlightアップリケーションメニューからパブリッシャーを起動します。
"新規"ボタンで作成開始。
## 一般項目 ##
**コード**と**グループ**は最低限記入が必要です。**タイトル**等はお好みでいいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/90f06f05-8ae6-178d-248f-c96544975db9.png)
## HTMLコードの埋め込み ##
`オプション`タブのこれら三つのオプションを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a79d1104-edeb-5984-63b9-958ca86bc09f.png)
1. `リソース`オプションでは、先に作成したHTMLコード（ファイル）をリソースとして埋め込みます
編集ボタンをクリックして、リソース設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5c4717c1-1000-cb25-bc52-a5afcd522b5b.png)
`新規`アイコンで埋め込みを開始します。上部グリッドに新規アイテムが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b6602bbe-3111-2e8d-3d3e-535d9dd187de.png)
`パス`に先のHTMLファイルを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6f9b08fb-a053-f288-0b7c-8767307e6ef0.png)
最後に`参照`属性の**リソースコードタグ**をクリップボードにコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f26d5a2f-4da7-b122-0548-fc8407f6bb51.png)
`同期`ボタンで同期を再確認してから、`閉じる`ボタンで保存します。
2. `カスタムHTML`オプションでリソースを実際に使用します。
有効をオンにし、編集ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/06d460f7-99ef-169f-2366-ceeec145ad91.png)
カスタムHTMLエディターが開きます。サンプルコードが既に記されているので全て削除しましょう。
先ほどのクリップボードにコピーした**リソースコードタグ**を貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/8febb3b9-0ae2-609d-fba8-d91a40ee1ca7.png)
以上で埋め込み完了です。`OK`ボタンで保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c27120f3-cb53-e263-bb34-e5dd83169581.png)
3. ブラウザ上でのプロンプトの表示は必要ないので、プロンプトをオフにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/bd6db634-5ab5-3fb4-97cc-9a5b6fb086a7.png)


## クエリの定義 ##
この公開クエリは、先のHTMLコードのコンテナというだけなのでクエリは必要ないのですが、先にも述べたように**一公開クエリに一クエリ**のルールがありますので、クエリの定義を行います。
先ずクエリによって返されるレコードは少ないほど良いので、一レコードのみ返すクエリを定義します。
以下の`製品`にシステムを使用し、ユーザーアカウントテーブルを指定するこのクエリがいいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/fee7795f-cbd2-1649-22b8-d15380aa13aa.png)
出力領域では、埋め込んだHTMLコードに渡したい定数等を指定します。ここでは拡張表現を利用してデータソース用のURLを指定します。これが**body部**の説明の最初に説明した部分です。
右クリックメニューから`拡張表現を追加`を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/01280f12-3b53-16aa-9322-70c7878a8689.png)
キーワード**REST**で構文を検索し、見つかったService URL構文を上部テキストエディタに転送します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c88c2a5b-6673-9f71-7ceb-6fdceea00f18.png)
構文を以下のように編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e076fc8b-60f4-7f16-731b-4735741a8823.png)
`OK`ボタンで保存します。
説明と名前を以下のように編集します。とりわけ名前は大事です。
HTMLコード内ではこの名前を参照しています。これ`{*Row.DatasourceURL.text}`です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/4d6d5ee1-9966-5db9-79b1-e5b0c457cf19.png)
以上です。OKボタンで保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e2eaf867-fcd1-1bc4-76c6-3ea3a7b9c362.png)
公開クエリもOKボタンで保存します。
今保存した公開クエリを選択し、右クリックメニューからレポートの表示を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f7258012-75f6-b830-767a-9462c9e45d48.png)
Sharperlightサービスが起動していればお手持ちのブラウザにこの公開クエリが表示されます。Sharperlightサービスの起動は、Sharperlightアプリケーションメニューから、あるいはWindowsサービスダイアログから行えます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/299db6de-a046-e165-1d15-f6fec25f9b96.png)