自動採番フォーマットを正確に追加したい。

次のカスタマイズを参考にソースコードを作成して、自動採番フォーマットの最初の追加を2016-P1-S1と設定しましたが、2016-P1-S1の次を追加したら、2016-P2-S2となります。

年次ごとの自動採番を行うワザ 

年次ごとの自動採番フォーマットにアルファベットを導入したい

下2桁の年を4桁に変更したい。

2016-P1-S1の次が2016-P2-S2ではなく、2016-P1-S2に。また2016-P1-S9の次が2016-P1-S0ではなく、2016-P2-S1に自動採番追加できるようにすることは可能でしょうか?

(追記)

自分が作成した自動採番フォーマットのソースコードも紹介しておきます。

/*
* Copyright (c) 2016 Cybozu
* Licensed under the MIT License
*/

(function() {
“use strict”;

function autoNum(event) {
var record = event.record;

// 日付を取得し、2桁の年を取得する
var dt = record[‘日付’].value;
var dtyy = dt.substring(0, 4);
var dtmin = dtyy + ‘-01-01’;
var dtmax = (parseInt(dtyy, 10) + 1) + ‘-01-01’;

// クエリ文の設定
var query = {
“app”: kintone.app.getId(),
“query”: ‘日付 >= "’ + dtmin + ‘" and 日付 < "’ + dtmax + ‘" order by 自動採番 desc limit 1’
};

// 設定された日付から最新の番号を取得する
return kintone.api(kintone.api.url(‘/k/v1/records’, true), ‘GET’, query).then(function(resp) {
var records = resp.records;

// 対象レコードがあった場合
if (records.length > 0) {
var rec = records[0];
var autono = rec[‘自動採番’].value;
autono = parseInt(autono.substring(6), 10) + 1;
autono = ‘’ + autono;
autono = dt.substring(0, 5) + ‘P’+ autono.substring(autono.length - 1) + ‘-S’ + autono.substring(autono.length - 1);
event.record[‘自動採番’].value = autono;

// 対象レコードがなかった場合
} else {
event.record[‘自動採番’].value = dt.substring(0, 5) + ‘P1’ + ‘-S1’;
}

return event;
}).catch(function(e) {
alert("レコードの取得でエラーが発生しました - error: " + e.message);
return false;
});
}

//新規作成画面の保存
kintone.events.on(‘app.record.create.submit’, autoNum);

// 新規作成画面表示
kintone.events.on(‘app.record.create.show’, function(event) {
var record = event.record;
//フィールドを非活性にする
record[‘自動採番’].disabled = true;
return event;
});

// 編集画面表示
kintone.events.on([‘app.record.edit.show’, ‘app.record.index.edit.show’], function(event) {
var record = event.record;
//フィールドを非活性にする
record[‘自動採番’].disabled = true;
record[‘日付’].disabled = true;
return event;
});

})();

ao1962さん

ソースを眺める限り、P側の連番とS側の連番がどちらも、autono+1 で取得されているので、

自ずとP,S両方の数字がカウントアップしてしまうのかなと思います。

まずは、P側連番とS側連番を別の変数でカウントする様にすると、一歩前に進むかと。

P側S側の双方が個別に加算できるようになれば、

>2016-P1-S9の次が2016-P1-S0ではなく、2016-P2-S1に自動採番追加

の実装も、楽かと思います。

P側の連番とS側の連番がどちらも、autono+1 で取得されていることについて、1つの共通のautono+1 として取得されているために、P側連番とS側連番を別の変数でカウントすることについても、個別に変えることができないと思いますが、どうでしょうか?

もしautonoで取得された連番が共通カウントではなく、個別にカウントを変えることができれば、楽勝だと思いますが、問題なのはautono をP側連番向けとS側連番向けにそれぞれ個別に取得できればと思いますが、次の共通コードをどのように個別に変えていったらいいのかが不明です。

// 対象レコードがあった場合
if (records.length > 0) {
var rec = records[0];
var autono = rec[‘自動採番’].value;
autono = parseInt(autono.substring(6), 10) + 1;
autono = ‘’ + autono;
autono = dt.substring(0, 5) + ‘P’+ autono.substring(autono.length - 1) + ‘-S’ + autono.substring(autono.length - 1);
event.record[‘自動採番’].value = autono;

 

ao1962さん

JavaScriptのコーディングの話になってきますので、コード自体は書きませんが、ロジック的には。

目的は

2016-P1-S1

2016-P1-S2

(省略)

2016-P1-S9

2016-P2-S1

この様にカウントアップすることですので、

2016-P*-S* を取得後に、Pの右側の数字,Sの右側の数字を個別に取得。

その後、S側数字が9ならば、P側数字をカウントアップ。。というようなロジックになるかと。

なお、このロジックの場合、2016-P9-S9 の次をどのようにカウントアップするかは、事前に考えられた方がよいかなと覆います。

別の方法として、"自動採番して、レコード登録する"を参考に次のソースコードを作成してみました。

2016-P1-S1の次を追加しても、相変わらず2016-P2-S2となります。

/*
* 自動採番のサンプルプログラム
* Copyright (c) 2015 Cybozu
*
* Licensed under the MIT License
*/

(function() {

“use strict”;

// レコード追加、編集画面の表示前処理
var eventsShow = [‘app.record.create.show’, ‘app.record.edit.show’, ‘app.record.index.edit.show’];
kintone.events.on(eventsShow, function(event) {

var record = event.record;

if ((‘app.record.create.show’).indexOf(event.type) >= 0) {
record[‘No’][‘value’] = “”;
}
record[‘No’][‘disabled’] = true;

return event;

});

// レコード追加画面の保存前処理
kintone.events.on(‘app.record.create.submit’, function(event) {

var recNo = 1;
var record = event.record;
var m = moment();

// URLを設定する
var appUrl = kintone.api.url(‘/k/v1/records’, true) +
‘?app=’ + kintone.app.getId() + ‘&query=’ + encodeURI(‘limit 1&fields[0]=$id’);

var xmlHttp = new XMLHttpRequest();
// 同期リクエストを行う
xmlHttp.open(“GET”, appUrl, false);
xmlHttp.setRequestHeader(‘X-Requested-With’, ‘XMLHttpRequest’);
xmlHttp.send(null);

if (xmlHttp.status === 200) {
if (window.JSON) {
var obj = JSON.parse(xmlHttp.responseText);
if (obj.records.length > 0) {
try {
recNo = parseInt(obj.records[0][‘$id’].value, 10) + 1;
} catch(e) {
event.error = ‘見積番号が取得できません。’;
}
}
//自動採番を見積番号に設定する
var autoEstNo = m.format(‘YYYY’) + ‘-P’ + (‘’ + recNo).slice(-1) + ‘-S’ + (‘’ + recNo).slice(-1);
alert(“見積番号 " + autoEstNo + " を登録します”);
record[‘No’][‘value’] = autoEstNo;
} else {
event.error = xmlHttp.statusText;
}
} else {
record[‘No’].error = ‘見積番号が取得できません。’;
}
return event;
});
})();

ついでに"ドロップダウンの値を変更して別フィールドの値を変更したり、無効に設定する"も参考にして、次のソースコードを作成してみましたが、相変わらず2016-P1-S1の次が2016-P2-S2となります。

その原因として、P側のrecNoをP1が次のS1が来るまでP2に進まないようにしたいのですが、可能でしょうか?

/*
* 旅費精算申請のプログラム
* Copyright (c) 2015 Cybozu
*
* Licensed under the MIT License
*/

(function () {

“use strict”;

// 地域の条件に応じて日当を変更する。
function ChangeArea(event){
var record = event.record;

switch (record[‘地域’][‘value’]){
case “首都圏”:
record[‘日当’][‘value’] = “0”;
record[‘日当’][‘disabled’] = true;
break;
case “海外”:
record[‘日当’][‘value’] = “3000”;
record[‘日当’][‘disabled’] = true;
break;
case “その他”:
record[‘日当’][‘disabled’] = false;
break;
default:
record[‘日当’][‘value’] = “1000”;
record[‘日当’][‘disabled’] = true;
break;
}
return event;
}

// レコード追加、編集前、地域変更で処理を実行する
var events = [‘app.record.create.show’,‘app.record.edit.show’,‘app.record.index.edit.show’,
‘app.record.edit.change.地域’,‘app.record.create.change.地域’,‘app.record.index.edit.change.地域’];
kintone.events.on(events, function(event) {

event.record[‘No’][‘disabled’] = true;
if ((‘app.record.create.show’).indexOf(event.type) >= 0){
event.record[‘No’][‘value’] = “”;
}

// 地域変更による他のフィールド値変更
ChangeArea(event);

//路線検索リンク表示
var el = kintone.app.record.getSpaceElement(‘TravelSearch’);
// すでに設定されている子ノードがあったら削除する
for (var i = el.childNodes.length-1; i>=0; i–){
el.removeChild(el.childNodes[i]);
}

var elTravel = document.createElement(‘a’);
elTravel.appendChild(document.createTextNode(‘路線検索サイト(外部サイト)’));
elTravel.addEventListener(‘click’, function() {
// 路線検索サイトのリンクを指定します。
window.showModalDialog(“http://~~”,window,“center;”);
},false);
el.appendChild(elTravel);

return event;
});

// 出発、帰着の値変更時のエラーチェックをする
var eventCheck = [‘app.record.create.change.出発’,‘app.record.create.change.帰着’,
‘app.record.edit.change.出発’,‘app.record.edit.change.帰着’,
‘app.record.index.create.change.出発’,‘app.record.index.create.change.帰着’,
‘app.record.index.edit.change.出発’,‘app.record.index.edit.change.帰着’];
kintone.events.on(eventCheck, function(event) {

var record = event.record;
var vlFrom = record[‘出発’][‘value’];
var vlTo = record[‘帰着’][‘value’];

// 出発が空白で、帰着が空白でない場合
if ( !(vlFrom) && (vlTo)){
record[‘出発’][‘error’] = “出発日を入力してください。”;

} else if ( (vlFrom) && (vlTo)){
// 帰着が出発より前に設定されている場合
if (vlFrom > vlTo){
record[‘帰着’][‘error’] = “出発日よりあとに変更してください。”;
}
}
return event;

});

// レコード追加、編集の保存前に自動採番を作成する
var eventSubmit =[‘app.record.create.submit’, ‘app.record.edit.submit’, ‘app.record.index.edit.submit’];
kintone.events.on(eventSubmit, function (event) {

// 保存前の画面上のレコード
var record = event.record;
var m = moment();

// 旅費、経費が出発や帰着の範囲内でない場合はエラーを表示する
var vlFrom = record[‘出発’][‘value’];
var vlTo = record[‘帰着’][‘value’];

// 旅費
for (var i = 0; i < record[‘旅費’][‘value’].length; i++) {
var vlDate = record[‘旅費’][‘value’][i][‘value’][‘旅費日付’][‘value’];

if (!vlDate){
continue;
}

if ((vlDate < vlFrom) || (vlDate > vlTo)){
event.error = “旅費日付が申請期間の範囲外です。”;
record[‘旅費’][‘value’][i][‘value’][‘旅費日付’][‘error’] = “旅費日付が申請期間の範囲外です。”;
return event;
}
}

// 経費
for (var i = 0; i < record[‘経費’][‘value’].length; i++) {
var vlDate = record[‘経費’][‘value’][i][‘value’][‘経費日付’][‘value’];

if (!vlDate){
continue;
}

if ((vlDate < vlFrom) || (vlDate > vlTo)){
event.error = “経費日付が申請期間の範囲外です。”;
record[‘経費’][‘value’][i][‘value’][‘経費日付’][‘error’] = “経費日付が申請期間の範囲外です。”;
return event;
}
}

// No が空白の場合に処理する。
if (!record[‘No’][‘value’]){

var appUrl = kintone.api.url(‘/k/v1/records’,true) + ‘?app=’+ kintone.app.getId() + ‘&query=’ + encodeURI(‘limit 1&fields[0]=$id’);
var xmlHttp = new XMLHttpRequest();
var recNo = 1;

// 同期リクエストを行う
xmlHttp.open(“GET”, appUrl, false);
xmlHttp.setRequestHeader(‘X-Requested-With’,‘XMLHttpRequest’);
xmlHttp.send(null);

if (xmlHttp.status == 200){
if(window.JSON){
var obj = JSON.parse(xmlHttp.responseText);
if (obj.records[0] != null){
try{
recNo = parseInt(obj.records[0][‘$id’][‘value’],10) +1;
} catch(e){
event.error = ‘番号が取得できません。’;
return event;
}
}
//自動採番を見積番号に設定する
var autoEstNo = m.format(‘YYYY’) + “-P” + recNo + “-S” + recNo;
alert(“番号 " + autoEstNo + " を登録します”);
event.record[‘No’][‘value’] = autoEstNo;
} else{
event.error = xmlHttp.statusText;
}
} else{
record[‘No’].error = ‘番号が取得できません。’;
}
return event;
}

});

// レコード表示時の処理
var eventShow = [‘app.record.detail.show’];
kintone.events.on(eventShow, function(event) {

// 精算金額のスタイルを変更する
var elTotal= kintone.app.record.getFieldElement(‘精算金額’);
elTotal.style.fontWeight = “bold”; //太字
elTotal.style.fontSize = document.body.style.fontSize + “large”;

// 印刷ボタンの表示
var elPrint = document.createElement(‘button’);
elPrint.style.height = “30px”;
elPrint.style.width = “50px”;
elPrint.style.borderRadius = ‘0.5em’;
elPrint.appendChild(document.createTextNode(’ 印刷 '));
elPrint.addEventListener(‘click’, function() {
alert(“印刷するボタンの例です。実際には印刷されません。”);
},false);

kintone.app.record.getHeaderMenuSpaceElement().appendChild(elPrint);
});

})();