GCP/Apps Script

Apps Script로 Google Sheets의 Sidebar를 이용한 데이터 선택

whistory 2022. 9. 6. 10:44
반응형

 

반응형

 

💡Apps Script로 Google Sheets에서 Sidebar에 데이터를 선택하는
     HTML 페이지를 불러오는 방법을 알아본다.

 

데이터를 조회하는 화면에서

조회조건인 G/L 계정 값들을 다중 선택 하여 조회하고 싶다는 요구 사항이 들어왔다.

 

 

 

 

처음엔 sheet edit trigger를 이용해 개발하였는데,

외부 trigger라 속도가 느렸다.

https://whiseung.tistory.com/entry/Apps-Script%EB%A1%9C-Google-Sheets%EC%97%90%EC%84%9C-Dropdown-multi-select%EB%8B%A4%EC%A4%91%EC%84%A0%ED%83%9D-%EA%B5%AC%ED%98%84

 

Apps Script로 Google Sheets에서 Dropdown의 multi select(다중선택) 구현

현재 ‘code’ 라는 시트의 데이터를 Dropdown(선택상자, SelectBox) 을 조회 조건으로 사용 중이다. ‘testSheet’ 라는 시트에서, G/L 계정의 조회 조건을 다중 선택을 하고 싶다는 요구 사항을 받았다. Go

whiseung.tistory.com

 

성능개선의 요구를 받았고,

Sidebar와 Modal 로 개발을 진행하였다.

 

 

 

 

 

 

 

일단 버튼을 만들었다.

 

버튼에 실행할 script도 할당하였다.

다른 시트에 있는 해당 데이터들을 가져올 것이다.

 

 

 

 

SpreadsheetApp 을 이용해 sheet의 데이터들을 가져오고,

가져온 데이터들을 html 을 이용하여 sidebar에 그려준다.

/**
 * sidebar 열기
 * @param {string}  gubun = 구분값
 */
function open_GlSideBar(gubun){
  // 소스
  const sheetUrl        = SpreadsheetApp.getActiveSpreadsheet().getUrl();
  const masterSheetName = "가져올시트";
  const sheetName       = "할당할시트";
  const title           = "G/L계정 선택";
  
  // sidebar에 뿌려줄 데이터 가져오기
  const sheet = SpreadsheetApp.openByUrl(sheetUrl).getSheetByName(masterSheetName);
  const data  = sheet.getRange("A2:B"+sheet.getLastRow()).getValues();

  // 할당할 시트
  const workSheet      = SpreadsheetApp.openByUrl(sheetUrl).getSheetByName(sheetName);
  const selectedValues = workSheet.getRange("B5").getValue();

  // 선택된 값들에 checked 
  const arrayValues = selectedValues.toString().split(", ");
  var loopHtml      = "";

  for (i in data) {
    var status = "";
    for ( j in arrayValues ) {
      if ( data[i][0] == arrayValues[j] ) {
        status = 'checked="checked"';
      }
    }
    loopHtml += '<div class="itemKeys"><li style=list-style:none; >';
    loopHtml += '<input type="checkbox" class="check" onchange="selectVal()" name="' + data[i][1] + '" id="items" value="' + data[i][0] + '"'+status+'><font class="itemName" size="1">' + data[i][0] + " (" + data[i][1] + ')</font></li></div>';
  }

  var html = HtmlService.createHtmlOutput('<html> '
                                        + ' <body> '
                                        + '   <div style=position:fixed;background-color:white;width:100%;top:0;line-height:2rem;>'
                                        + '     <input onkeyup="filter()" type="text" id="value" placeholder="검색어 입력" style="width: 220px;"> '
                                        + '   </div> '
                                        + '   <br />'
                                        + '   <div>'
                                        +       loopHtml 
                                        + '   </div>'
                                        + '   <div style=position:fixed;background-color:white;width:100%;bottom:0;line-height:2rem;>'
                                        + '     <input type="button" value="초기화" onclick="resetChecked()" /> '
                                        + '     <input type="button" value="닫기" onclick="closeModal()" /> '
                                        + '   </div> '
                                        + '   <script type="text/javascript"> '
                                        + '     function closeModal() { google.script.host.close(); }'
                                        + '     function setSelectedValues(resultVal, resultName) { google.script.run.setSelectedValues(resultVal, resultName, "'+gubun+'"); }'
                                        + '     function resetValues() { google.script.run.setSelectedValues("", "", "'+gubun+'"); }'
                                        + '     function selectVal() {  '
                                        + '       const query = "input[id=\\'items\\']:checked"; '
                                        + '       const selectedEls = document.querySelectorAll(query); '
                                        + '	      var resultVal = ""; '
                                        + '	      var resultName = ""; '
                                        + '	      for ( var i=0; i<selectedEls.length; i++ ) { '
                                        + '		      if ( i == 0 ) { '
                                        + '			      resultVal += selectedEls[i].value; '
                                        + '			      resultName += selectedEls[i].name; '
                                        + '		      } else { '
                                        + '			      resultVal += ", " + selectedEls[i].value; '
                                        + '			      resultName += ", " + selectedEls[i].name; '
                                        + '		      } '
                                        + '	      } '
                                        + '       setSelectedValues(resultVal, resultName); '
                                        + '     } '
                                        + '     function filter() { '
                                        + '     	var value, name, item, i; '
                                        + '     	value = document.getElementById("value").value.toUpperCase().trim(); '
                                        + '     	item = document.getElementsByClassName("itemKeys"); '
                                        + '     	for( i=0; i<item.length; i++ ) { '
                                        + '     		name = item[i].getElementsByClassName("itemName"); '
                                        + '     		if ( name[0].innerHTML.toUpperCase().indexOf(value) > -1 ) { '
                                        + '     			item[i].style.display = "flex"; '
                                        + '     		} else { '
                                        + '     			item[i].style.display = "none"; '
                                        + '     		} '
                                        + '     	} '
                                        + '     } '
                                        + '     function resetChecked() { '
                                        + '     	var item = document.getElementsByClassName("check"); '
                                        + '     	for ( i=0; i<item.length; i++ ) { '
                                        + '     		item[i].checked = false; '
                                        + '     	} '
                                        + '       resetValues(); '
                                        + '     } '
                                        + '   </script> '
                                        + ' </body> '
                                        + ' </html> ')
                      .setTitle(title);

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

 

HTML 과 Google Sheets의 연결을 위해,

HTML 에서 아래와 같이 Google Sheets에서 생성한 함수를 호출해야한다.

google.script.run.anyFunction
/**
 * sidebar에서 선택된 값 sheet에 할당
 * @param {string} val     = 코드
 * @param {string} name    = 명칭
 * @param {string} gubun   = 구분자
 */
function setSelectedValues ( val, name, gubun ) {
  const sheetUrl  = SpreadsheetApp.getActiveSpreadsheet().getUrl();
  const sheetName = "할당할시트";
  const sheet = SpreadsheetApp.openByUrl(sheetUrl).getSheetByName(sheetName);
  sheet.getRange("B5").setValue(val);
  sheet.getRange("C5").setValue(name);
}

 

 

 

 

 

 

 

모달로 호출하려면, showModalDialog() 를 사용하면 된다.

var htmlString = "";
var html = HtmlService.createHtmlOutput(htmlString)
                      .setTitle(title)
                      .setWidth(600).setHeight(350);

SpreadsheetApp.getUi().showModalDialog(html, title);

 

 

 

 

 

검색 기능도 들어가 있다.

 

 

 

 

 

 

 

 

 

 

 

 

반응형