GCP/Apps Script

Apps Script๋กœ Google Sheets ๊ธฐ๋ฐ˜์˜ ์ƒํ’ˆ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ๋งŒ๋“ค๊ธฐ

whistory 2023. 5. 17. 14:26
๋ฐ˜์‘ํ˜•

 

๐Ÿ’ก 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 ๋กœ๊ทธ๋“ค๋„ ํ•œ๋ˆˆ์— ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

 

 

๋ฐ˜์‘ํ˜•