GCP/Apps Script

Apps Script로 Google Sheets의 선택된 항목을 sidebar에서 수정하도록 구현 (셀 클릭 이벤트 대체)

whistory 2023. 4. 21. 10:51
반응형

Google Sheets에서 버튼을 생성해 클릭하여 이벤트를 실행 할 수는 있으나

셀 클릭 event는 없는 것 같다.

 

셀 클릭 이벤트가 안되니,

셀에 checkbox를 생성하고 checkbox를 클릭 했을 때 sidebar를 열어주는 이벤트를 추가해본다.

 

아래와 같은 sheet가 있다.

일단 checkbox가 여러 개 선택 되지 않고 하나만 선택되도록 해본다.

 

 

/**
 * edit event
 * @param {object} e = event
 */
function onEdit(e) {
    const getValue    = e.value;
    const spreadSheet = e.source;
    const sheetName   = spreadSheet.getActiveSheet().getName();
    const column      = e.range.getColumn();
    const row         = e.range.getRow();
    const activeCell  = spreadSheet.getActiveCell();
	
    if ( sheetName == "checkbox_test2" ) {
        if ( column == 1 && row >= 2 ) {
            // 모든 체크박스 해제
            unckeckAll();

            if ( getValue == 'FALSE' ) { return; }

            // 선택된 체크박스 재선택
            activeCell.setValue(true);
        }
    }
}

/**
 * 전체 선택 해제
 */
function unckeckAll(){
    const range = "A2:A10";
    const value = false;

    allCheckbox(range, value);
}

/**
 * 전체 선택 공통
 */
function allCheckbox(range, value) {
    const checkRange = SpreadsheetApp.getActiveSpreadsheet().getRange(range);
    checkRange.setValue(value);
}

 

 

 

onEdit 트리거를 통해

전체를 unselect 처리 한 뒤, 자기 자신만 select 처리해준다.

 

 

 

이제 선택된 checkbox의 값들을 가지고 sidebar를 열어줘 본다. 근데 onEdit 에서는 sidebar를 열어주지 못했다.

Installable Triggers 로 새로운 trigger를 생성하여 sidebar를 열어준다.

 

event trigger

/**
 * edit event
 * @param {object} e = event
 */
function onEdit(e) {
	const getValue    = e.value;
	const spreadSheet = e.source;
	const sheetName   = spreadSheet.getActiveSheet().getName();
	const column      = e.range.getColumn();
	const row         = e.range.getRow();
	const activeCell  = spreadSheet.getActiveCell();
	
    if ( sheetName == "checkbox_test2" ) {
        if ( column == 1 && row >= 2 ) {
            // 모든 체크박스 해제
            unckeckAll();

            if ( getValue == 'FALSE' ) { return; }

            // 선택된 체크박스 재선택
            activeCell.setValue(true);
        }
    }
}


/**
 * custom edit event
 * @param {object} e = event
 */
function onEditCustom(e) {
    const getValue    = e.value;
    const spreadSheet = e.source;
    const sheetName   = spreadSheet.getActiveSheet().getName();
    const column      = e.range.getColumn();
    const row         = e.range.getRow();
    const sheet       = e.source.getActiveSheet();

    if ( sheetName == "checkbox_test2" ) {
        if ( column == 1 && row >= 2 ) {
            if ( getValue == 'FALSE' ) { return; }
            const thisRowValue = sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues();
            openHtmlSideBar(thisRowValue[0], row);
    }
}

 

  • 선택된 데이터만 가져오는지 확인

  • sidebar가 열리는 것을 확인

 

 

 

sidebar 호출

/**
 * Side bar 열기
 */
function openHtmlSideBar(data, row) {
  var html = HtmlService.createHtmlOutput(
        '<html> '
      + ' <body> '
      + '   <div> '
      + '     이름 : '
      + '     <input type="text" id="name" value="'+data[1]+'" /> '
      + '   </div> '
      + '   <div style="padding-top: 10px;"> '
      + '     직업 : '
      + '     <input type="text" id="job" value="'+data[2]+'" /> '
      + '   </div> '
      + '   <div style="padding-top: 10px;padding-bottom: 10px;"> '
      + '     메모 : '
      + '     <input type="text" id="job" value="'+data[3]+'" /> '
      + '   </div> '
      + '   <div style=position:fixed;background-color:white;width:100%;line-height:2rem;> '
      + '     <input type="button" value="저장" onclick="saveData()" /> '
      + '     <input type="button" value="삭제" onclick="deleteData()" /> '
      + '     <input type="button" value="닫기" onclick="closeModal()" /> '
      + '   </div> '
      + ' </body> '
      + ' <script type="text/javascript"> '
      + '     function closeModal() { google.script.host.close(); } '
      + '     function saveData() { '
      + '          const query = "input[type=\\'text\\']"; '
      + '          const selected = document.querySelectorAll(query); '
      + '          let arr = new Array(); '
      + '          for ( var i=0; i<selected.length; i++){ '
      + '              arr.push(selected[i].value); '
      + '          } '
      + '       google.script.run.setSelectedValues(arr, '+row+'); '
      + '     }'
      + '     function deleteData() { '
      + '		    if (confirm("삭제하시겠습니까?")) { '
      + '         google.script.run.deleteRowData('+row+'); '
      + '       } '
      + '     } '
      + ' </script> '
      + '</html> ').setTitle("SideBar");

  SpreadsheetApp.getUi().showSidebar(html);
}

html 이벤트 처리

/**
 * sidebar 저장 이벤트 처리
 */
function setSelectedValues ( arr, row ) {
    closeSidebar();
    const sheet = SpreadsheetApp.getActive().getSheetByName("checkbox_test2");
    for ( i in arr ) {
    	sheet.getRange(row, (parseInt(i)+2)).setValue(arr[i]);
    }
}
/**
 * sidebar 삭제 이벤트 처리
 */
function deleteRowData( row ) {
    closeSidebar();
    const sheet = SpreadsheetApp.getActive().getSheetByName("checkbox_test2");
    sheet.deleteRow(row);
    alertMessage("완료", "선택하신 데이터가 삭제되었습니다.");
}
/**
 * modal 창 닫기
 */
function closeSidebar() {
    var html = HtmlService.createHtmlOutput("<script>google.script.host.close();</script>");
    SpreadsheetApp.getUi().showSidebar(html);
}

 

 

 

 

수정 기능 테스트

 

 

삭제 기능 테스트

 

 

 

 

 

 

작성하면서 느낀점

이럴거면 Google Sheets를 왜 쓰는걸까

웹개발로 가는게 맞는거같다.

 

소규모 사업장에서 서버유지비용을 절감하고 간단하게 운영하기에는 적합 할것 같다.

 

 

 

 

 

 

반응형