0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

kintone × カスタマインで、プロセス管理で「Excel出力~kintone書き戻し」まで自動化する方法

Last updated at Posted at 2026-02-03

はじめに

kintoneのプロセス管理で「計算実行」や「請求書作成」などのアクションを起点に、

  • ExcelテンプレートからExcel/PDFを出力し
  • 添付としてレコードに反映し
  • 添付Excelを解析して計算結果をkintoneへ書き戻し
  • 最後にステータスを更新して完了通知

までを一連で自動化したいケースがあります。

この記事では、実運用で採用したフロー(①〜⑩)を、チーム共有/再現可能な形で整理します。

カスタマイン請求書.gif

対象:サービス請求書(例)

  • 数量・単価などはkintoneの入力値
  • 金額・税額・合計などの計算はExcel側
  • 顧客提示はPDF
  • kintoneは計算結果と成果物(Excel/PDF)を保持する

kintoneフィールド構成

image.png

請求書テンプレート(Excel)

image.png


実運用フロー(①〜⑩)

① プロセス管理のアクションを実行

ユーザーはkintone上でプロセス管理アクション(例:計算実行)を押す。
ここが自動処理の起点。


② Excelテンプレートを取得

レコードの「テンプレート」ファイル(FILE)を参照し、出力の元となるExcelテンプレートを取得する。

image.png


③ プロセス管理での保存をキャンセル

プロセス管理アクションは通常「レコード保存」を伴うが、
このフローでは いったん保存をキャンセルし、以降はカスタマイン側で更新を制御する。

狙い:

  • “中途半端な状態”でレコードが保存されるのを避ける
  • 後続の添付・計算結果反映・ステータス更新を 順序通りに確実に実行する

image.png


④ Excel・PDF出力

取得したテンプレートを使って、

  • 請求書Excelを出力(計算ロジック込み)
  • 顧客提出用PDFを出力(表示シートのみ)

を生成する。

image.png


⑤ Excel・PDF添付でレコードを更新(競合チェックしない)

生成した Excel / PDF を添付してレコードを更新する。
ここでは 競合チェックなしで更新する(上書き運用を前提)。

狙い:

  • 出力物の添付は「常に最新を正」とするため、履歴管理は別設計
  • 更新競合で止まるよりも、確実に最新成果物で上書きする

image.png


⑥ JavaScriptを実行して添付Excel解析

  • 添付済みExcelを対象に、カスタマインの「JavaScriptを実行」を使って解析する。
  • 事前にExcel解析用のライブラリをJSに登録しておく
  • REST APIでレコードを取得し fileKey を取得
  • /k/v1/file.json でExcelをDL
  • SheetJSなどでExcelを解析し、計算結果を抽出
  • 値を return

image.png

サンプルコード
var EXCEL_FILE_FIELD = 'Excel添付';
var TARGET_SHEET = '請求書';
var TARGET_CELL = 'H34';

if (typeof XLSX === 'undefined') {
  throw new Error('XLSX is not defined');
}

function getAppId() {
  try {
    var id = kintone.app.getId && kintone.app.getId();
    if (id) return id;
  } catch (e) {}
  var m = String(location.pathname).match(/\/k\/(\d+)\//);
  if (m) return Number(m[1]);
  throw new Error('appId not found');
}

function getRecordId() {
  var url = String(location.href);
  var m1 = url.match(/[?&]record=(\d+)/);
  if (m1) return Number(m1[1]);
  var m2 = url.match(/#.*record=(\d+)/);
  if (m2) return Number(m2[1]);
  var m3 = url.match(/\/show#record=(\d+)/);
  if (m3) return Number(m3[1]);
  throw new Error('recordId not found');
}

function fetchJson(url) {
  return fetch(url, {
    method: 'GET',
    headers: { 'X-Requested-With': 'XMLHttpRequest' }
  }).then(function (r) {
    if (!r.ok) throw new Error('GET failed: ' + r.status);
    return r.json();
  });
}

function fetchArrayBuffer(url) {
  return fetch(url, {
    method: 'GET',
    headers: { 'X-Requested-With': 'XMLHttpRequest' }
  }).then(function (r) {
    if (!r.ok) throw new Error('GET failed: ' + r.status);
    return r.arrayBuffer();
  });
}

function toNumber(v) {
  if (typeof v === 'number') return v;
  var n = Number(String(v).replace(/,/g, '').trim());
  if (Number.isNaN(n)) throw new Error('NaN');
  return n;
}

var appId = getAppId();
var recordId = getRecordId();

return fetchJson('/k/v1/record.json?app=' + encodeURIComponent(appId) + '&id=' + encodeURIComponent(recordId))
  .then(function (res) {
    var files = res.record && res.record[EXCEL_FILE_FIELD] && res.record[EXCEL_FILE_FIELD].value;
    if (!files || files.length === 0) throw new Error('no file');
    var fileKey = files[files.length - 1].fileKey;
    return fetchArrayBuffer('/k/v1/file.json?fileKey=' + encodeURIComponent(fileKey));
  })
  .then(function (buf) {
    var wb = XLSX.read(buf, { type: 'array' });
    var ws = wb.Sheets[TARGET_SHEET];
    if (!ws) throw new Error('sheet not found');
    var cell = ws[TARGET_CELL];
    if (!cell) throw new Error('cell not found');
    var raw = (cell.v !== undefined) ? cell.v : cell.w;
    return toNumber(raw);
  });

⑦ JavaScriptでreturnした結果でレコードを更新(競合チェックしない)

⑥で取得した計算結果を、kintoneの 計算結果 フィールドへ書き戻す。
ここも 競合チェックなしで上書き更新する。

image.png


⑧ 現在のレコードを取得する

最新状態(添付・計算結果を含む)を再取得する。
この後のステータス更新に備えて、状態を正しく揃える。

image.png


⑨ 取得したレコードのステータスを更新する

最後に、プロセス管理のステータスを更新する(例:計算完了 へ遷移)。

狙い:

  • 成果物添付・計算結果反映が完了してから、状態遷移を確定させる
  • “計算完了ステータスなのに成果物が無い”という矛盾を防ぐ

image.png


⑩ 計算完了ダイアログ・リロード

ユーザーに完了を通知し、画面をリロードして最新状態を表示する。

image.png


このフローの設計意図まとめ

  • 保存キャンセル(③):中途半端保存を避け、カスタマイン側で順序制御する
  • 競合チェックなし更新(⑤⑦):上書き運用に寄せて処理停止リスクを減らす
  • 最後にステータス更新(⑨):成果物と状態遷移の整合性を担保する
  • JSのreturn設計(⑥):値の取得と保存を分離し、処理を再利用しやすくする

応用:複数の計算結果を扱いたい場合(JSON解析)

本記事では、
添付されたExcelから 1つの計算結果を取得する例を紹介しました。

ただし実務では、

  • 小計
  • 消費税
  • 合計金額
  • 数量・単価の再計算結果

など、複数の値を同時に扱いたいケースも多いと思います。

JavaScriptの return を JSON にする

カスタマインの「JavaScriptを実行」は、
オブジェクト(JSON)をそのまま return できます。

return {
  subtotal: 50000,
  tax: 5000,
  total: 55000
};

このようにしておくと、
後続の処理で複数値をまとめて扱えます。

「JSONを解析して」アクションを使う

カスタマインには
「JSONを解析して」 という標準アクションがあります。

これを使うことで、

  • JavaScriptで return したJSONを分解し
  • 各キーをカスタマイン変数として取得
  • 複数フィールドへ一括反映

といった処理が可能になります。

JavaScript側は「値を取得して返すだけ」、
フィールド更新はカスタマイン設定側で行う、
という役割分担ができるのがメリットです。

本記事のフローに当てはめると

⑥ JavaScriptを実行
   └ Excel解析 → JSONを return

⑦(応用)JSONを解析して
   └ 複数の値を変数に展開

⑧ レコードを更新
   └ 各フィールドに反映

今回は詳細な設定までは触れませんが、
複数項目を扱う場合の拡張方法として有効です。

おわりに

本記事では、

  • プロセス管理アクションを起点に
  • Excel / PDF 出力
  • 添付Excelの解析
  • 計算結果の反映
  • ステータス更新

までを、実運用フローとして整理しました。

「Excelで計算し、kintoneで管理する」構成は、
請求書・見積書・申請書など多くの業務に応用できます。

同じような構成で悩んでいる方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?