(著者:kintone エバンジェリスト 村濱 一樹)
はじめに
kintoneはブラウザーからレコードの一覧の表示や編集ができますが、Excelのような画面で閲覧・編集がしたいという要望を度々聞きます。
今回はCybozu CDNで公開されている、Handsontableを使ってExcelライクな入力を実現してみました。 やり方を以下にまとめますので、興味のある方は是非試してみてください。
Handsontableとは
ホームページ: https://handsontable.com/
HandsontableはExcelのようなスプレッドシートライクな入力を可能にしてくれるJavaScriptライブラリです。
サンプルページで試すとわかりますが、Excelのようにデータ入力ができるだけでなく、セルの書式の指定やチャートが作れたりと、機能が多いのも魅力です。
kintoneカスタマイズでの導入方法
実際に、Handsontable(無償版)をkintoneのカスタマイズに利用してみましょう。
デモ環境
先に完成イメージのデモを示します。こちらのデモ環境から実際に動作を確認をしてみてください。
https://dev-demo.cybozu.com/k/37/
デモ環境アカウントとパスワードは、サインイン後にこちらのページでご確認ください。
サンプルアプリの準備
まずはアプリの準備をします。
フィールドの設定
サンプルアプリのフィールドは以下です。フィールド名とフィールドコードは同一にしました。
フィールド名(フィールドコード) | フィールドタイプ |
レコード番号 | レコード番号 |
会社名 | 文字列(1行) |
先方担当者名 | 文字列(1行) |
見込み時期 | 日付 |
確度 | ラジオボタン |
製品名 | ドロップダウン |
単価 | 数値 |
ユーザー数 | 数値 |
小計 | 計算 |
一覧の設定
アプリの一覧は、カスタマイズビューを用います。
スプレッドシート表示のための要素をHTMLで記述します。
<div id="sheet"></div>
カスタマイズビューについての詳細は下記を参照ください。
JavaScript/CSSの設定
今回はCybozu CDNに登録されているものを利用します。Cybozu CDNにはJavaScriptだけでなくCSSファイルも提供されている上、キャッシュも有効になっているので高速化が図れるという利点があります。
今回はversion 6.2.2を利用します※。アプリのJavaScript/CSS設定画面には、下記URLを指定します。
- JavaScript URL
https://js.cybozu.com/handsontable/6.2.2/handsontable.full.min.js - CSS URL
https://js.cybozu.com/handsontable/6.2.2/handsontable.full.min.css
このカスタマイズでは、MIT ライセンスである v6.2.2 を利用しています(ライセンス表記)。
v7.0.0 以降を利用する際は Handsontable の HP で有償ライセンスを購入し、ライセンス条件に従ってご利用ください。
詳細は、Cybozu CDN ライセンス対応ガイド をご参照ください。
データの入力
確認のために、サンプルデータを先に数件入力しておきましょう。
JavaScriptプログラミング
実際にJavaScriptでプログラミングしていきます。
Handsontableの仕様や使い方はHandsontableの公式ドキュメント(v6.2.2)を参照ください。
Handsontableの使い方
下記のように指定するだけでスプレッドシートの表示が可能です。 Handsontableのdataオプションにkintoneのレコードデータを指定すればバインドできそうです。
スプレッドシートにレコードを一覧表示する
まずは単純にkintoneのレコードをスプレッドシートに表示してみます。
Handsontableのdataオプションには、kintoneのレコードデータを指定し、columnsには"フィールド名.value"と指定することで、kintoneのレコードデータをそのまま反映することができます。
必要に応じて、colHeadersオプションに配列を指定することで、ヘッダ行も指定できます。
※viewIdはカスタマイズビュー設定時のviewIdを入力してください。
これでkintoneに登録したデータをExcelのように表示できるようになるはずです。
スプレッドシートに表示したレコードを更新する
表示することはできたので、その表示されたデータを更新できるようにします。
データの更新時、afterChangeオプションに指定したメソッドが呼び出されるので、そのメソッドを利用してkintoneのアップデート処理を行います。
また、columnsオプションを指定するときは、編集されたくないデータはreadOnlyの指定をすることができます。
afterChangeメソッドの引数Changeは下記の配列が格納されます。上記の例では、"変更があったセルの行数"を参照しどのレコード番号のデータを変更するかを指定しています。
ちなみに、データのバインディングは自動で行われますので、スプレッドシート上で変更したデータは、kintoneのevent.records変数にすでに反映されています。便利ですね。
おわりに
今回はHandsontableを用いて、Excelライクな見た目で、レコードの表示と編集が行えるようにkintoneをカスタマイズしました。
次回はレコードの追加やプルダウンによる選択などを試してみます。
Handsontableを使ってkintoneをExcelライクに入力しよう その2 - 基本編>>
このTipsは、2022年7月版 kintone で確認したものになります。
質問させてください。
提示された方法でアプリに組み込んでみたところ、ほぼ想定通りに動いてくれたのですが、
プロセス管理を有効にすると編集したものに更新されなくなります。
(画面上、編集はいったんされますが、画面切り替え等、更新のタイミングで
編集前の内容に戻ってしまいます)
おそらくは非同期処理に絡むと思われるのですが(ちがっていたらすみません)、
一覧表示イベントだとpromise関数は現状使えないようなので
何か別の方法で解消できないかと考えています。
例えば「更新」ボタンを設置し、手動で上書きタスクを強制的に走らせられれば解決できそうなのですが
現状でプロセス管理と同居できる方法はありますでしょうか?
当方でも現象を再現できました。確認したところ、プロセスを有効にした際に、「ステータス」「作業者」のフィールドも有効になるのですが、それが更新できなくてエラーになってしまっているようです。
なので、フィールドコードを除外するためのメソッドに「ステータス」「作業者」を追加してあげてください。
ご回答ありがとうございます。
さっそく修正内容を追記しましたところ、プロセス管理を有効の状態でも編集が可能になりました。
新年早々、課題が一つ解消できて一安心です。
複数レコードを一括できるとても便利な機能なので、標準での実装を期待してます!
回答が遅れてすいません。
> ルックアップを使用しているとまた別の処理も必要になるなど、制限があるのでしょうか。
ルックアップなら問題なさそうです。ただ、ルックアップはAPIからデータをいれる場合、コピー元がユニークである必要があります。 その設定を見なおしていただいてもよろしいでしょうか。
参考:REST APIを使ってルックアップフィールドの一括更新を行う
https://www.joyzo.co.jp/blog/293
掲示されているサンプルはJavaですが、kintoneの注意については同じなので確認をしてみてください。
村濱様
ご返答頂きありがとうございます。私も返信が遅れ、失礼いたしました。
> ルックアップなら問題なさそうです。ただ、ルックアップはAPIからデータをいれる場合、コピー元がユニークである必要があります。 その設定を見なおしていただいてもよろしいでしょうか。
ご指摘いただいた通り、コピー元がユニークでないルックアップがあるのが原因でした。
なので、API発行時に更新したいフィールドのみを指定したら、思い通りの更新をすることができました。
大変助かりました。ありがとうございます。
質問させてください。
「アプリコード(レコード番号に前に付与する文字列)」を設定していないアプリでは、
本ページのサンプルのセル編集が正しく動作したのですが、
「アプリコード(student)」を設定したアプリでセルの編集を行うと、
{"code":"CB_VA01","id":"1505999166-246192175","message":"入力内容が正しくありません。","errors":{"records[0].id":{"messages":["整数で指定してください。"]}}}
というエラーが発生します。
Request Payloadを見ると、
{app: 7, records: [{id: "student-5970",…}], __REQUEST_TOKEN__: "~~~~"} とあり、
idにアプリコードが付与されているため、「整数で指定してください」というエラーが出たのだと思うのですが、
どう回避すればよいでしょうか?
Hiroshi Yoshioka さん
編集、ということですので下記の記事(その2)を参考にされているということですよね。
https://cybozudev.zendesk.com/hc/ja/articles/207331836
今回のサンプルではアプリコードに対応してないので、アプリコードに対応させるようにする必要があります。
上記は、レコード番号をそのまま使用してしまっているので、下記のように直すと動くかと思います。
(未検証ですが)
※アプリコードとは別に$idというフィールドがあり、そこには整数のIDがはいっています。
回答になってますでしょうか。不明点があればまたご連絡ください。
村濱様
ご返信、ありがとうございます。
>編集、ということですので下記の記事(その2)を参考にされているということですよね。
記事(その1)の「スプレッドシートに表示したレコードを更新する」を参考にしたコードで、
試しておりました。
アドバイス通り、
["レコード番号"]部分を.$idに置き換えることで、
無事、アプリコード付きアプリでも編集(PUT成功)することができました。
迅速なご対応、ありがとうございました!
いえいえ、
https://github.com/mura-/kintone-spreadsheet
プラグイン化したのもあるので、必要に応じて試してみてください。
(少なくともコードは参考になるかもしれません)
村濱様
>https://github.com/mura-/kintone-spreadsheet
>
>プラグイン化したのもあるので、必要に応じて試してみてください。
ありがとうございます。
Handsontableを直接利用すると、カラムのtypeやカラム名などをjsファイルに入力するのが手間でしたが、
設定画面でフィールドを選ぶだけで適切なtypeを自動で指定してくれて、非常に便利です!
現在、アプリのレコード数が1000以上あるため、
絞り込みができないのは苦しいのですが、
これが解決できれば、すぐに業務で利用したいと思います。(^^
下記コードを入れないと、ページ送りでおかしくなります。
サンプルのアプリでもページ送りが可能な場合はおかしくなっていました。
本文も修正していただいた方が、今後のためにも良いと思います。
ページ送りを考慮してませんでした。ご連絡ありがとうございます。
社内抵抗が強く、浸透するまでということで旧版で運用しております。本件を新版でテストすると反映されるのですが、旧版では動きません。新・旧で使用に違いはあるのでしょうか?
連絡おくれました。
特に問題なく動くはずなのですが、、具体的にどう「動かない」のか教えてもらってもいいですか?(表示されない、データの表示がおかしい、など)
また、何かしらエラーがでている可能性がありますので、是非下記の通り確認してみてください。
https://cybozudev.zendesk.com/hc/ja/articles/207613916-%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%84-%E3%81%9D%E3%82%93%E3%81%AA%E6%99%82%E3%81%AF%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%82%92%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86-%E5%85%A5%E9%96%80%E7%B7%A8
村瀬様
お世話になります。
Tips第7回カスタマイズビューを利用してみようを参考に一覧をカスタマイズ設定しました。その後本件を参考にjsとCSSをコピーし相対するフィールド名のみ変更して作成してみました。
新版ではデータ7件のみですが、ご教示の通り一覧表示されております。旧版はデータが3000件あり、右上で1-100と表記されるので100件は並んでほしいのですが表にならない状況です。
エラー表示も出ているのですが、新・旧とも同じjsとCSSを貼り付けているため、;がありません、構文エラーです、の意味もわからないままです。
12/6大阪で行われた【kintone devCamp初級編】kintone をカスタマイズしてルーチンワークをお手軽に!にも参加させていただき何とか理解を深めようと勉強中です。
初心者のため投稿も十分に内容を伝えることがままならない状況ですがよろしくお願いいたします。
工藤
これだけではやはり原因を特定するのは難しいですが....、
1つ気づいたのが、旧デザインの場合cssのスタイルがなぜか当たっていない気がします。
CSSがなにかおかしいのかもしれませんね、もしかすると、そのアプリに別のCSS、あるいはkintone全体にCSSやJSが当たっていて競合している、ということは有りえませんかね?
(設定確認はこちら https://help.cybozu.com/ja/k/admin/javascript_fullcustomize.html )
それを確認してみて、問題なければ、そのエラーが表示されているという画像を高解像度で送ってもらってもいいですか?
上記貼り付けられている画像が、小さくてよく見えなくて...。
お世話になります。さっそくご回答いただき、恐縮です。
実寸で添付いたしました。アドバイスいただけますか。
工藤
ちょっと試している最中なのですが、 IE8モードで動いてるのが原因の1つな気がします。
問題の切り分けのためにChromeで試してもらうことって可能ですか?
再三で恐れ入ります。
エラー表示が違う形で表示されましたので添付いたしました。どうぞよろしくお願いいたします。
工藤
こちらこそ再三のお願いになってしまいますが。。
右画像のdownload.do~の部分、クリックできるハズですので(クリック後はエラー該当箇所が表示されるはず)、クリックしたあとの画像もいただけますでしょうか。
お世話になります。
こちらでよろしいでしょうか。
工藤
まさにその赤線の部分、タイプミスをしていませんでしょうか?
掲載されているコードとくらべて確認してみてください。
【表示されるjs】
(function() {
"use strict";
kintone.events.on(['app.record.index.show'], function(event) {
// ビューIDを指定する(指定したビューID以外は処理しない)
if (event.viewId !== 5287827) return;
var records = event.records;
// カスタマイズビュー設定時に登録したHTMLの要素を指定します。
var container = document.getElementById('sheet');
// Handsontableをインスタンス化
var hot = new Handsontable(container, {
// kintoneのレコードデータを指定
data: records,
minSpareRows: 0,
// カラムのヘッダーを指定
colHeaders: ["レコード番号", "部屋コード", "所有者", "利用者名", "利用人数", "来館予定日", "退館予定日", "来館日", "退館日", "車両数"],
contextMenu: false,
// dataオプションのどの列を表示するか指定する。
columns: [
{data: "レコード番号.value"},
{data: "部屋コード.value"},
{data: "所有者.value"},
{data: "利用者名.value"},
{data: "利用人数.value"},
{data: "来館予定日.value"},
{data: "退館予定日.value"},
{data: "来館日.value"},
{data: "退館日.value"},
{data: "車両数.value"}
],
});
});
})();
【表示されなかったjs】
(function() {
"use strict";
kintone.events.on(['app.record.index.show'], function(event) {
// ビューIDを指定する(指定したビューID以外は処理しない)
if (event.viewId !== 5287827) return;
var records = event.records;
// カスタマイズビュー設定時に登録したHTMLの要素を指定します。
var container = document.getElementById('sheet');
// Handsontableをインスタンス化
var hot = new Handsontable(container, {
// kintoneのレコードデータを指定
data: records,
minSpareRows: 0,
// カラムのヘッダーを指定
colHeaders: ["レコード番号", "部屋コード", "所有者", "利用者名", "利用人数", "来館予定日", "退館予定日", "来館日", "退館日", "車両数"],
contextMenu: false,
// dataオプションのどの列を表示するか指定する。
columns: [
{data: "レコード番号.value"},
{data: "部屋コード.value"},
{data: "所有者.value"},
{data: "利用者名.value"},
{data: "利用人数.value"},
{data: "来館予定日.value"},
{data: "退館予定日.value"},
{data: "来館日.value"},
{data: "退館日.value"},
{data: "車両数.value"}
],
});
});
})();
村濱様
お世話になります。
修正を行いましたが、結果は同じでした。ただし、クロームで行うと本件このサイト通りの表示ができました。
残念ながらグループ内ルールではクローム×、IE8○のためこのままでは社内システムとして使えないこともわかりました。
いろいろご指導いただいたことで知識が増えました。今回はありがとうございました。今後もアドバイスいただけますようお願いいたします。
工藤
> 残念ながらグループ内ルールではクローム×、IE8○のためこのままでは社内システムとして使えないこともわかりました。
そうでしたか。。実はkintone自体もIE9以上しかサポートしておりませんし、他のクラウドサービスもそういう傾向にありますので
ルールが更改されることを願っております。
済みませんが、エクセルのように*、+、-などの計算は出来るものなのでしょうか?
原島様
HandsontableはExcelライクにできるだけですので、計算処理はkintone側でする必要があります。
計算処理にはkintoneの標準機能を利用できます。利用できる演算子は、ヘルプ をご確認ください。
デモ環境内のアプリでは、kintoneの自動計算を利用して小計を自動で出していますので、よろしければ実際にご確認ください。
(デモ環境の利用には、当サイトのメンバー登録が必要です。)
デモ環境
https://dev-demo.cybozu.com/k/37/
※デモ環境についての説明はこちら
できました!ありがとうございます!!
こちらの記事の通りに入力したのですが、
罫線などがなく表示が崩れた状態になってしまいます。
試しに、
カスタマイズビューには
https://js.cybozu.com/handsontable/0.20.0/handsontable.full.min.js
https://js.cybozu.com/handsontable/0.20.0/handsontable.full.min.css
を読み込ませてから、jsファイルに