
๐ก Google Sheets ๊ธฐ๋ฐ์ ์ํ ๊ด๋ฆฌ ์์คํ ์ ๋ง๋ค์ด๋ณธ๋ค.
์ผ๋ง์ ์ ๊ฐ๋จํ ์ํ๋ฑ๋ก ํ๋ฉด์ ๊ตฌํํด๋ณด์๋ค.
์ํ ๋ฑ๋ก, ์์ , ์ญ์ ๊ฐ ๊ฐ๋ฅํ ์์คํ ์ผ๋ก ๊ณ ๋ํ ํด๋ณธ๋ค.
Apps Script๋ก Google Sheets์์ ์ํ ๊ด๋ฆฌ sheet ๋ง๋ค๊ธฐ
๐ก Google Sheets์์ ์ํ์ ๋ฑ๋กํ๊ณ ๋ฆฌ์คํธ๋ก ๊ด๋ฆฌํ๋ ํ๋ฉด์ ๊ตฌ์ฑํด๋ณธ๋ค ์ ๋ ฅํผ์์ ์ํ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๋ฉด, ๋ฆฌ์คํธ ํ๋ฉด์ ์ ๋ ฅํ ์ํ์ ๋ฆฌ์คํธ๊ฐ ์ถ๊ฐ๋๋ ํ๋ฉด์ ๊ตฌ์ฑํด๋ณธ๋ค. ์ ๋ ฅ ํ๋ฉด์
whiseung.tistory.com
์ฌ์ฉ์๋ค์ด ์์ ์ Google Sheets์์ ์ํ ์ ๋ณด๋ค์ ์ ๋ ฅํ๊ณ , ๋ฆฌ์คํธ๋ฅผ ํ์ธ๋ง ํ ์ ์๋ค.
๊ด๋ฆฌ์์ฉ Google Sheets ์์ ์ํ ์ ๋ณด ๋ฆฌ์คํธ๋ฅผ ํ์ธํ๊ณ ์ด๋ ฅ ๊ด๋ฆฌ๊น์ง ํ ์ ์๋ ๊ฐ๋จํ ์์คํ ์ ๊ตฌํํด๋ณธ๋ค.

์ผ๋ฐ ์ฌ์ฉ์๋ค์ ์ ๋ ฅ ํ๋ฉด
์ ๋ ฅํผ๊ณผ, ์ํ๋ฆฌ์คํธ ํ๋ฉด์ด ์๋ค.
์ํ๋ฆฌ์คํธ ํ๋ฉด์ IMPORTRANGE๋ฅผ ์ด์ฉํด ๋ณด๊ธฐ๋ง ๊ฐ๋ฅํ๋ค.
Apps Script๋ก Google Sheets์ ๋ง์คํฐ์ฑ ๋ฐ์ดํฐ ๊ด๋ฆฌํ๊ธฐ
Google Sheets ๋ ๊ณต๋ ์์ ํด์ด๋ค. ์๋ก ๋ค๋ฅธ ๋ถ์(ํ)์ ํ์ผ์๋ ์์ ๊ถํ์ด ์์ด์ผ ํ๋ค. ํ์ง๋ง ๋ถ์(ํ) ๋ด์์ ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ ๋ง์คํฐ์ฑ์ ๋ฐ์ดํฐ๋ค์ ์กด์ฌํ ๊ฒ์ด๋ค. (์๋ค ๋ค๋ฉด ๋๋กญ๋ค
whiseung.tistory.com

๊ด๋ฆฌ์ ์ฉ Google Sheets
์ํ๋ฆฌ์คํธ, ์์ history, ์ญ์ history๋ก ๊ตฌ์ฑํ์๋ค.

1. ์ ์ฅ ๊ธฐ๋ฅ ๊ตฌํ
1.1 ์ ๊ท ๋ฑ๋ก
key ๊ฐ์ธ ์ํ ID๊ฐ ๋ฆฌ์คํธ์ ์กด์ฌํ์ง ์์ผ๋ฉด, ์ ๊ท row๋ฅผ ์๋๋ค.


function saveProduct() {
// ๋ฐ์ดํฐ ์
๋ ฅ ์ํธ
const inputSheetName = "์ง์ฌ_์
๋ ฅํผ";
const sheet = SpreadsheetApp.getActive().getSheetByName(inputSheetName);
const dataRange = sheet.getRange("D4:D14");
const values = dataRange.getValues();
// ์
๋ ฅํผ ์์น์ ๋ณด
let inputArr = [
{"row":0, "value":"์ํ ID"}
, {"row":2, "value":"์ํ๋ช
"}
, {"row":4, "value":"์ํ๊ตฌ๋ถ"}
, {"row":6, "value":"๋ธ๋๋"}
, {"row":8, "value":"์ํ๊ธ์ก"}
, {"row":10, "value":"์ํ์ค๋ช
"}
];
var cnt = 0;
let dataRow = new Array(1);
dataRow[0] = new Array(inputArr.length);
// ์
๋ ฅ ๋ฐ์ดํฐ ํ์ธ ๋ฐ ๊ฐ๊ณต
for( i in values ) {
for ( j in inputArr ) {
if ( i == inputArr[j].row) {
const inputValue = values[i][0];
if ( inputValue == '' || inputValue.length < 1 ) {
alertMessage("์ค๋ฅ", inputArr[j].value + "์(๋) ํ์์
๋ ฅ ๊ฐ์
๋๋ค.");
return;
}
dataRow[0][cnt] = values[i];
cnt++;
}
}
}
// ๋ฐ์ดํฐ ์ ์ฅ ์ํธ ์ ๋ณด
const dataSheetId = "GOOGLE_SHEET_ID";
const dataSheetName = "์ํ๋ฆฌ์คํธ";
const dataSheetSs = SpreadsheetApp.openById(dataSheetId);
const dataSheet = dataSheetSs.getSheetByName(dataSheetName);
const dataListLastRow = dataSheet.getLastRow() + 1;
var dataListRange = dataSheet.getRange(`A${dataListLastRow}:I${dataListLastRow}`);
const dataListValues = dataSheet.getRange(`A2:I${dataListLastRow}`).getValues();
var executeGubun = "์ ์ฅ";
var createdDttm, updatedDttm;
for ( k in dataListValues ) {
// ์์ ์ ๋ก์ง ์์ฑ
if ( dataRow[0][0] == dataListValues[k][0] ) {
createdDttm = getDateTime(dataListValues[k][6]); // ๋ฑ๋ก์ผ์
updatedDttm = getDateTime(); // ์์ ์ผ์
dataListRange = dataSheet.getRange(`A${parseInt(k)+2}:I${parseInt(k)+2}`);
const modifyValues = dataListRange.getValues();
modifyValues[0][6] = getDateTime(modifyValues[0][6]); // ๋ฑ๋ก์ผ์
modifyValues[0][7] = getDateTime(modifyValues[0][7]); // ์์ ์ผ์
modifyValues[0].push(Session.getActiveUser().getEmail()); // ์์ ์
// ์์ history ์ํธ ์ ๋ณด
const modifySheetName = "์์ history";
const modifySheet = dataSheetSs.getSheetByName(modifySheetName);
const modifyLastRow = modifySheet.getLastRow() + 1;
// ์์ history ์ ์ฅ
modifySheet.getRange(`A${modifyLastRow}:J${modifyLastRow}`).setValues(modifyValues).setBorder(true, true, true, true, true, true);
executeGubun = "์์ ";
break;
}
createdDttm = getDateTime(); // ๋ฑ๋ก์ผ์
updatedDttm = ''; // ์์ ์ผ์
}
dataRow[0][cnt++] = [createdDttm]; // ๋ฑ๋ก์ผ์
dataRow[0][cnt++] = [updatedDttm]; // ์์ ์ผ์
dataRow[0][cnt++] = [Session.getActiveUser().getEmail()]; // ์์ฑ์
// ๋ฐ์ดํฐ ์ํธ์ ์ ์ฅ
dataListRange.setValues(dataRow).setBorder(true, true, true, true, true, true);
// ์
๋ ฅํผ ์ด๊ธฐํ
dataRange.clearContent();
// ์ฑ๊ณต ๋ฉ์ธ์ง
alertMessage("์ฑ๊ณต", `๋ฐ์ดํฐ ${executeGubun}์ ์ฑ๊ณตํ์์ต๋๋ค.`);
}
/**
* KST ์๊ฐ ๋ฐํ
*/
function getDateTime(curr) {
if ( curr == null ) {
curr = new Date();
}
const utc = curr.getTime() + (curr.getTimezoneOffset() * 60 * 1000);
const KR_TIME_DIFF = 9 * 60 * 60 * 1000;
const today = new Date(utc + (KR_TIME_DIFF));
var dateConcat = "-";
var timeConcat = ":";
var allConcat = "T";
const date = today.getFullYear() + dateConcat + lpad((today.getMonth()+1), 2, '0') + dateConcat + lpad(today.getDate(), 2, '0');
const time = lpad(today.getHours(), 2, '0') + timeConcat + lpad(today.getMinutes(), 2, '0') + timeConcat + lpad(today.getSeconds(), 2, '0');
const result = date + allConcat + time;
return result;
}
/**
* Alert message
*/
function alertMessage(tit, msg) {
var ui = SpreadsheetApp.getUi();
ui.alert(tit, msg, ui.ButtonSet.OK);
}
/**
* lpad
*/
function lpad(str, padLen, padStr) {
if ( padStr.length > padLen ) {
console.log("์ค๋ฅ : ์ฑ์ฐ๊ณ ์ ํ๋ ๋ฌธ์์ด์ด ์์ฒญ ๊ธธ์ด๋ณด๋ค ํฝ๋๋ค");
return str;
}
str += "";
padStr += "";
while (str.length < padLen) {
str = padStr + str;
}
str = str.length >= padLen ? str.substring(0, padLen) : str;
return str;
}
ํ ์คํธ๋ฅผ ์ํด ๋ฐ์ดํฐ๋ฅผ ๋ ์ ๋ ฅํด ๋ณด์๋ค.

1.2 ์์ ๊ธฐ๋ฅ
์ค๋ณต๋ key ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๋ฉด,
๋ฆฌ์คํธ์์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ค.
์์ history sheet์ ์ด๋ ฅ์ ๋จ๊ธฐ๋ ๊ธฐ๋ฅ๋ ์ถ๊ฐํ๋ค.


2. ์กฐํ ๊ธฐ๋ฅ ๊ตฌํ
key ๊ฐ์ธ ์ํID๋ฅผ ์ ๋ ฅํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ ํผ์ ๋ฟ๋ ค์ค๋ค.
๋ฐ์ดํฐ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฉด alert ๋ฉ์ธ์ง๋ฅผ ๋ฟ๋ ค์ค๋ค.

function getProduct() {
// ๋ฐ์ดํฐ ์
๋ ฅ ์ํธ
const inputSheetName = "์ง์ฌ_์
๋ ฅํผ";
const sheet = SpreadsheetApp.getActive().getSheetByName(inputSheetName);
const dataRange = sheet.getRange("D4");
const searchValue = dataRange.getValue();
if ( searchValue == null || searchValue == "" ) {
alertMessage("์๋ฆผ", "์กฐํ์กฐ๊ฑด์ ์
๋ ฅํด์ฃผ์ธ์.");
resertForm();
return;
}
// ๋ฐ์ดํฐ ์ํธ
const dataSheetId = "GOOGLE_SHEET_ID";
const dataSheetName = "์ํ๋ฆฌ์คํธ";
const dataSheetSs = SpreadsheetApp.openById(dataSheetId);
const dataSheet = dataSheetSs.getSheetByName(dataSheetName);
const dataListLastRow = dataSheet.getLastRow() + 1;
const dataListValues = dataSheet.getRange(`A2:I${dataListLastRow}`).getValues();
var resultFlag = false;
for ( k in dataListValues ) {
if ( searchValue == dataListValues[k][0] ) {
sheet.getRange("D6").setValue(dataListValues[k][1]);
sheet.getRange("D8").setValue(dataListValues[k][2]);
sheet.getRange("D10").setValue(dataListValues[k][3]);
sheet.getRange("D12").setValue(dataListValues[k][4]);
sheet.getRange("D14").setValue(dataListValues[k][5]);
resultFlag = true;
break;
}
}
if ( !resultFlag ) {
alertMessage("์๋ฆผ", `"${searchValue}" ์กด์ฌํ๋ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.`);
resertForm();
}
}
/**
* ์
๋ ฅ ํผ ์ด๊ธฐํ
*/
function resertForm() {
const inputSheetName = "์ง์ฌ_์
๋ ฅํผ";
const sheet = SpreadsheetApp.getActive().getSheetByName(inputSheetName);
const dataRange = sheet.getRange("D4:D14");
dataRange.clearContent();
}
3. ์ญ์ ๊ธฐ๋ฅ ๊ตฌํ
๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ณ ์ญ์ ๋ฅผ ์งํํ๋ค.
์ญ์ ์ฒ๋ฆฌ ์ ์ญ์ history sheet์ log๋ฅผ ๋จ๊ฒจ์ค๋ค.

์ํ๋ฆฌ์คํธ์์ ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋๊ณ , ์ญ์ ๋ ๋ฐ์ดํฐ๊ฐ ์ญ์ history ์ํธ์ ์ ์ฅ๋๋ค.

function deleteProduct() {
// ๋ฐ์ดํฐ ์
๋ ฅ ์ํธ
const inputSheetName = "์ง์ฌ_์
๋ ฅํผ";
const sheet = SpreadsheetApp.getActive().getSheetByName(inputSheetName);
const dataRange = sheet.getRange("D4");
const searchValue = dataRange.getValue();
if ( searchValue == null || searchValue == "" ) {
alertMessage("์๋ฆผ", "์ญ์ ํ ์ํ ID๊ฐ ์์ต๋๋ค.");
return;
}
// ๋ฐ์ดํฐ ์ ์ฅ ์ํธ ์ ๋ณด
const dataSheetId = "GOOGLE_SHEET_ID";
const dataSheetName = "์ํ๋ฆฌ์คํธ";
const dataSheetSs = SpreadsheetApp.openById(dataSheetId);
const dataSheet = dataSheetSs.getSheetByName(dataSheetName);
const dataListLastRow = dataSheet.getLastRow() + 1;
const dataListValues = dataSheet.getRange(`A2:I${dataListLastRow}`).getValues();
var resultFlag = false;
for ( k in dataListValues ) {
if ( searchValue == dataListValues[k][0] ) {
const thisRow = parseInt(k)+2;
const dataListRange = dataSheet.getRange(`A${thisRow}:I${thisRow}`);
const deleteValues = dataListRange.getValues();
deleteValues[0][6] = getDateTime(deleteValues[0][6]); // ๋ฑ๋ก์ผ์
deleteValues[0][7] = getDateTime(deleteValues[0][7]); // ์์ ์ผ์
deleteValues[0].push(getDateTime()); // ์ญ์ ์ผ์
deleteValues[0].push(Session.getActiveUser().getEmail()); // ์ญ์ ์
// ์ญ์ history ์ํธ ์ ๋ณด
const deleteSheetName = "์ญ์ history";
const deleteSheet = dataSheetSs.getSheetByName(deleteSheetName);
const deleteLastRow = deleteSheet.getLastRow() + 1;
// ์ญ์ history ์ ์ฅ
deleteSheet.getRange(`A${deleteLastRow}:K${deleteLastRow}`).setValues(deleteValues).setBorder(true, true, true, true, true, true);
// ๋ฐ์ดํฐ ๋ฆฌ์คํธ์์ ํด๋น row ์ญ์
dataSheet.deleteRow(thisRow);
resultFlag = true;
break;
}
}
if ( resultFlag ) {
// ์ฑ๊ณต ๋ฉ์ธ์ง
alertMessage("์ฑ๊ณต", `๋ฐ์ดํฐ ์ญ์ ๋ฅผ ์ฑ๊ณตํ์์ต๋๋ค.`);
// ์
๋ ฅํผ ์ด๊ธฐํ
resertForm();
}
}
์ฌ๊ธฐ๊น์ง๊ฐ ๊ฐ๋จํ ์ํ๊ด๋ฆฌ ๊ธฐ๋ฅ์ด๊ณ ,
์์ฉํ๋ฉด ๋ฐ์ฃผ ๊ธฐ๋ฅ๋ฑ์ ์ถ๊ฐํ์ฌ ์์คํ ์ ๊ตฌ์์ ๊ฐ์ถ ์ ์์๊ฒ์ด๋ค.
๋ชจ๋ ์์ ์ ์ฌ์ฉ์์ฉ Google Sheets์์ ์ด๋ฃจ์ด์ง๊ณ ,
๊ด๋ฆฌ์์ฉ Google Sheets๋ DB ์ญํ ๋ง ํ๊ฒ ๋๋ค.
update / delete ๋ก๊ทธ๋ค๋ ํ๋์ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.