Kintone width Appscript (ok)
Last updated
Was this helpful?
Last updated
Was this helpful?
ShowForm.gs
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Kintone Menu')
.addItem('Kintoneから データー集計','showForm')
.addToUi();
}
function showForm() {
const form = HtmlService.createTemplateFromFile('Form').evaluate().setHeight(180);
SpreadsheetApp.getUi().showModalDialog(form, 'Request Data Window');
}
Form.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script type="text/javascript" src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
</head>
<body>
<form>
<label for="dueDate">Due Date</label>
<input id="dueDate" class="datepicker">
<button id="btn"> Submit </button>
</form>
<script type="text/javascript">
function getAllDaysInMonth(year, month) {
const date = new Date(year, month, 1);
const dates = [];
while (date.getMonth() === month) {
dates.push(new Date(date));
date.setDate(date.getDate() + 1);
}
return dates;
}
function writeResponse() {
google.script.host.close();
}
document.getElementById('btn').addEventListener('click', getData);
async function getData() {
var data = document.forms[0]
var id = data[0].value;
var mydate = id.split('/');
if(mydate.length == 1) {
var mydate = id.split('-');
}
var arrform = [];
var arrDay = [];
var arrdats = getAllDaysInMonth(parseInt(mydate[0]),(parseInt(mydate[1]) - 1));
arrdats.forEach(function(element, index) {
arrform.push(moment(element).format('MM/DD'));
arrDay.push(moment(element).day())
});
google.script.run.saveData(id,arrform, arrDay);
await writeResponse();
}
$( function() {
$( "#dueDate" ).datepicker({ dateFormat: 'yy/mm' }).val();
} );
</script>
</body>
</html>
SaveData.gs
var KintoneManager = (function() {
/**
* @param {string} subdomain your subdomain (For kintone.com domains, you must state the FQDN such as "subdomain.kintone.com" )
* @param {object} apps application information.
* @param {string} user (optional) user name or encoded authentication information: base64("USER:PASS")
* @param {string} pass (optional) password
* @constructor
*/
function KintoneManager(subdomain, apps, user, pass) {
this.subdomain = subdomain;
this.authorization = null;
this.apps = apps;
if (arguments.length > 3) {
this.authorization = Utilities.base64Encode(user + ":" + pass);
} else if (arguments.length > 2) {
// 引数が3つの場合はエンコード済みの認証情報として処理
this.authorization = user;
}
}
/**
* Constructor
* @param {string} app_name Application name
* @param {Array} records Kintone record objects ref) https://developer.cybozu.io/hc/ja/articles/201941784
* @returns {HTTPResponse} ref) https://developers.google.com/apps-script/reference/url-fetch/http-response
*/
KintoneManager.prototype.create = function(app_name, records) {
var app = this.apps[app_name];
var payload = {
app: app.appid,
records: records
};
var response = UrlFetchApp.fetch("@1/records.json".replace(/@1/g, this._getEndpoint(app.guestid)), this._postOption(app, payload));
return response;
};
/**
* Search records
* @param {string} app_name Application name
* @param {string} query kintone API query ref) https://developer.cybozu.io/hc/ja/articles/202331474-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%8F%96%E5%BE%97-GET-#step2
* @returns {Array} search results
*/
KintoneManager.prototype.search = function(app_name, query) {
var q = encodeURIComponent(query);
var app = this.apps[app_name];
var response = UrlFetchApp.fetch("@1/records.json?app=@2&query=@3&totalCount=true".replace(/@1/g, this._getEndpoint(app.guestid)).replace(/@2/g, app.appid).replace(/@3/g, q), this._getOption(app));
return response;
};
/**
* Updates records
* @param {string} app_name Application name
* @param {Array} records Array of records that will be updated.
* @returns {HTTPResponse} ref) https://developers.google.com/apps-script/reference/url-fetch/http-response
*/
KintoneManager.prototype.update = function(app_name, records) {
var app = this.apps[app_name];
var payload = {
app: app.appid,
records: records
};
var response = UrlFetchApp.fetch("@1/records.json".replace(/@1/g, this._getEndpoint(app.guestid)), this._putOption(app, payload));
return response;
};
/**
* Deletes Records
* @param {string} app_name Application name
* @param {Array} record_ids Array of record IDs that will be deleted.
* @returns {HTTPResponse} ref) https://developers.google.com/apps-script/reference/url-fetch/http-response
*/
KintoneManager.prototype.destroy = function(app_name, record_ids) {
var app = this.apps[app_name];
var query = "app=" + app.appid;
for (var i = 0; i < record_ids.length; i++) {
query += "&ids[@1]=@2".replace(/@1/g, i).replace(/@2/g, record_ids[i]);
}
var response = UrlFetchApp.fetch("@1/records.json?@2".replace(/@1/g, this._getEndpoint(app.guestid)).replace(/@2/g, query), this._deleteOption(app));
return response;
};
/**
* option for GET Method
* @param {object} app Application object
* @returns {object} Option for UrlFetchApp
* @private
*/
KintoneManager.prototype._getOption = function(app) {
var option = {
method: "get",
headers: this._authorizationHeader(app),
muteHttpExceptions: true
};
return option;
};
/**
* option for POST Method
* @param {object} app Application object
* @param {object} payload Request payload
* @returns {object} Option for UrlFetchApp
* @private
*/
KintoneManager.prototype._postOption = function(app, payload) {
var option = {
method: "post",
contentType: "application/json",
headers: this._authorizationHeader(app),
muteHttpExceptions: true,
payload: JSON.stringify(payload)
};
return option;
};
/**
* option for PUT Method
* @param {object} app Application object
* @param {object} payload Request payload
* @returns {object} Option for UrlFetchApp
* @private
*/
KintoneManager.prototype._putOption = function(app, payload) {
var option = {
method: "put",
contentType: "application/json",
headers: this._authorizationHeader(app),
muteHttpExceptions: true,
payload: JSON.stringify(payload)
};
return option;
};
/**
* option for DELETE Method
* @param {object} app Application Object
* @returns {object} option Option for UrlFetchApp
* @private
*/
KintoneManager.prototype._deleteOption = function(app) {
var option = {
method: "delete",
headers: this._authorizationHeader(app),
muteHttpExceptions: true
};
return option;
};
/**
* Gets Endpoint
* @param {string} guest_id (optional) Guest id if you are a guest account.
* @returns {string} Endpoint url
* @private
*/
KintoneManager.prototype._getEndpoint = function(guest_id) {
if (this.subdomain.slice(-4) == '.com') {
var endpoint = "https://@1".replace(/@1/g, this.subdomain);
} else {
var endpoint = "https://@1.cybozu.com".replace(/@1/g, this.subdomain);
}
if (guest_id == null) {
return endpoint + "/k/v1";
} else {
return endpoint + "/k/guest/@1/v1".replace(/@1/g, guest_id);
}
};
/**
* Header Authentication Information
* @param {object} app Application object
* @param {string} app.token Application's API token
* @returns {object}
* @private
*/
KintoneManager.prototype._authorizationHeader = function(app) {
if (this.authorization) {
// Password authentication
return { "X-Cybozu-Authorization": this.authorization };
} else if (app.token) {
// API token authentication
return { "X-Cybozu-API-Token": app.token };
} else {
throw new Error("Authentication Failed");
}
};
return KintoneManager;
})();
function uniqByKeepFirst(a, key) {
let seen = new Set();
return a.filter(item => {
let k = key(item);
return seen.has(k) ? false : seen.add(k);
});
}
function dateFormat(inputDate, format) {
const date = new Date(inputDate);
const day = date.getDate();
const month = date.getMonth() + 1;
const year = date.getFullYear();
format = format.replace("MM", month.toString().padStart(2, "0"));
if (format.indexOf("yyyy") > -1) {
format = format.replace("yyyy", year.toString());
} else if (format.indexOf("yy") > -1) {
format = format.replace("yy", year.toString().substr(2, 2));
}
format = format.replace("dd", day.toString().padStart(2, "0"));
return format;
}
function thayDoi(data, pi2) {
// var ui = SpreadsheetApp.getUi();
// ui.alert(JSON.stringify(data));
return data.reduce((acc, item) => {
acc[item.name] = [item];
acc[item.name] = [];
pi2.forEach(function(element2, index2) {
if (item.name == element2.name) {
data.forEach(function(element, index) {
if (item.name == element.name) {
acc[item.name].push(element);
}
});
}
});
return acc;
}, {});
}
const getAllDaysInMonth = (month, year) => Array.from({
length: new Date(year, month, 0).getDate()
},
(_, i) => new Date(year, month - 1, i + 1));
function docGhiMang1(datas, lenkey, days, boole = false) {
var i = 3;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi();
var sheet = ss.getActiveSheet();
var lastRow = sheet.getLastRow();
if (boole) {
if(lastRow) {
sheet.deleteRows(1, lastRow);
}
for (var k = 1; k < 30; k++) {
for (j = 0; j < days.length; j++) {
sheet.getRange(k, j + 2).setBackground("white");
if (days[j] == 0 && k == 2) {
sheet.getRange(k, j + 2).setBackground("#FF1493");
}
if (days[j] == 6 && k == 2) {
sheet.getRange(k, j + 2).setBackground("#63B8FF");
}
}
}
} else {
for (key in datas) {
var valus = [];
var len = datas[key].length + 2;
var lenkeya = lenkey + 2;
var cell = sheet.getRange(1, 1, lenkeya, len);
cell.setHorizontalAlignment("center");
cell.setBorder(true, true, true, true, true, true, "#000000", SpreadsheetApp.BorderStyle.SOLID);
var dates = ["民名"];
valus.push(key);
var total = 0;
var string = '';
datas[key].forEach(function(element, index) {
string = element.month;
dates.push(element.date);
valus.push(element.number);
if (!isNaN(Number(element.number))) {
total += Number(element.number);
}
});
string += "月度";
dates.push("Total");
valus.push(total);
var dich0 = sheet.getRange(1, 1);
dich0.setValue(string);
var dich1 = sheet.getRange(2, 1, 1, len);
dich1.setValues([dates]);
var dich2 = sheet.getRange(i, 1, 1, len);
dich2.setValues([valus]);
i++;
}
}
}
function saveData(id, arrform, arrDay) {
var ui = SpreadsheetApp.getUi();
var subdomain = "genkaitec1.cybozu.com";
var apps = {
YOUR_APPLICATION1: { appid: 20, token: "NXvOuhG5WPpexePRTs1OGdDOHcxYtQpE9TKbDYSS" }
};
var user = "kaori_aikawa@namura.co.jp";
var pass = "a00d0pd0kinton12";
var kintone_manager = new KintoneManager(subdomain, apps, user, pass);
var query = 'レコード番号 > 0'
var response = kintone_manager.search('YOUR_APPLICATION1', query);
var code = response.getResponseCode();
var content = JSON.parse(response.getContentText());
var records = content.records;
var datas = [];
var dates = [];
var valus = [];
var datest = [];
var valuss = [];
var number = 0;
var id = id.replace(/\//g, "-");
var datein = dateFormat(JSON.stringify(id), 'yyyy-MM');
var ardatm = datein.split("-");
var newyear = ardatm[0];
var newmon = ardatm[1];
var iddat = id.split("-");
records.forEach(function(element, index) {
var idnam = element.日付.value.split("-");
if (iddat[0] == idnam[0] && iddat[1] == idnam[1]) {
datas.push({ date: dateFormat(element.日付.value, 'MM/dd'), number: element.集計用.value, name: element.作成者.value.name });
}
});
var dataGetKey = uniqByKeepFirst(datas, it => it.name);
var lenKey = dataGetKey.length;
var dataLast = [];
var piar;
var pi = thayDoi(datas, dataGetKey);
var arrformd = {};
var number = '';
dataGetKey.forEach(function(element, index3) {
function userExists(username) {
return pi[element.name].some(function(el) {
return el.date == username;
});
}
if (pi.hasOwnProperty(element.name)) {
var j = 0;
arrformd[element.name] = [];
arrform.findIndex(function(currentValue, index) {
pi[element.name].sort(function(a, b) {
var c = new Date(a.date);
var d = new Date(b.date);
return c - d;
});
if (userExists(currentValue)) {
number = pi[element.name][j].number;
j++;
} else {
number = '';
}
arrformd[element.name].push({ month: newmon, date: currentValue.toString(), number: number });
});
}
});
docGhiMang1(arrformd, lenKey, arrDay, true);
docGhiMang1(arrformd, lenKey, arrDay);
}