GCP/Apps Script

Apps Script로 Google Sheets 셀 병합하기

whistory 2023. 8. 24. 14:33
반응형

 

데이터를 뿌려준 후,

동일한 값들이 연속 될 경우 셀 병합을 진행하고 싶다.

 

아래와 같은 데이터가있다.

지역(B) 행의 연속되는 셀들을 병합하고 싶다.

 

 

 

 

 

/**
 * 셀 병합
 * @param {Object}  sheet   = google sheet object
 * @param {Object}  values  = 셀 병합을 위해 비교할 데이터
 * @param {Array}   columns = 셀 병합할 컬럼 순번
 */
function mergeCell(sheet, values, columns) {
  columns = [2];
  sheet   = SpreadsheetApp.getActive().getSheetByName("셀병합테스트");
  values  = sheet.getRange(`A2:D${sheet.getLastRow()}`).getValues();
 
  // 열의 갯수만큼 반복
  for (var i = 0; i < values[0].length; i++) {
    // 각 열별 데이터 추출
    const col = values.map(e => e[i]);
    
    // 셀병합정보(columns)에 없으면 pass
    if (!columns.includes(i + 1)) continue;
    
    let temp = {};
    // 열의 데이터 수 만큼 반복
    for (var j = 0; j < col.length; j++) {
      // 현재 열의 값을 row 변수에 할당
      const row = col[j];
      // 다음 열의 값을 nextRow 변수에 할당
      const nextRow = col[j + 1];
      
      // 현재 값과 다음 값이 같고, 현재 값이 temp 객체에 없는 경우
      if (row === nextRow && !(row in temp)) {
				// temp 에 현재 행의 인덱스를 값으로 저장
        temp[row] = j;
      
      // 현재 값과 다음 값이 다르고, 현재 값이 temp 객체에 있는 경우
      // temp 객체에 저장된 위치부터 현재 위치까지의 범위를 선택하여 셀 병합
      } else if (row !== nextRow && row in temp) {
        sheet.getRange(temp[row] + 2, i + 1, (j - temp[row]) + 1, 1).merge().setVerticalAlignment("middle").setHorizontalAlignment("center");
        temp = {};
      }
    }
  }
}

 

 

 

 

 

그럼 2개 이상의 행을 병합 할 순 없을까?

파라미터인 columns 배열에 순번을 추가해본다.

/**
 * 셀 병합
 * @param {Object}  sheet   = google sheet object
 * @param {Object}  values  = 셀 병합을 위해 비교할 데이터
 * @param {Array}   columns = 셀 병합할 컬럼 순번
 */
function mergeCell(sheet, values, columns) {
  columns = [2, 4];
  sheet   = SpreadsheetApp.getActive().getSheetByName("셀병합테스트");
  values  = sheet.getRange(`A2:D${sheet.getLastRow()}`).getValues();
 
  // 열의 갯수만큼 반복
  for (var i = 0; i < values[0].length; i++) {
    // 각 열별 데이터 추출
    const col = values.map(e => e[i]);
    
    // 셀병합정보(columns)에 없으면 pass
    if (!columns.includes(i + 1)) continue;
    
    let temp = {};
    // 열의 데이터 수 만큼 반복
    for (var j = 0; j < col.length; j++) {
      // 현재 열의 값을 row 변수에 할당
      const row = col[j];
      // 다음 열의 값을 nextRow 변수에 할당
      const nextRow = col[j + 1];
      
      // 현재 값과 다음 값이 같고, 현재 값이 temp 객체에 없는 경우
      if (row === nextRow && !(row in temp)) {
				// temp 에 현재 행의 인덱스를 값으로 저장
        temp[row] = j;
      
      // 현재 값과 다음 값이 다르고, 현재 값이 temp 객체에 있는 경우
      // temp 객체에 저장된 위치부터 현재 위치까지의 범위를 선택하여 셀 병합
      } else if (row !== nextRow && row in temp) {
        sheet.getRange(temp[row] + 2, i + 1, (j - temp[row]) + 1, 1).merge().setVerticalAlignment("middle").setHorizontalAlignment("center");
        temp = {};
      }
    }
  }
}

 

 

실제로 구현했던 셀 병합 코드

function mergeCell(sheet, values, columns) {
  try {
    values[0].map((_, i) => values.map(e => e[i]))
            .forEach((col, i) => {
              if (!columns.includes(i + 1)) return;
              let temp = {};
              col.forEach((row, j) => {
                if (row === col[j + 1] && !(row in temp)) {
                  temp[row] = j;
                } else if (row != col[j + 1] && row in temp) {
                  sheet.getRange(temp[row] + 2, i + 1, (j - temp[row]) + 1, 1).merge()
																									.setHorizontalAlignment("center")
																									.setVerticalAlignment("middle");
                  temp = {};
                }
              });
    });
  } catch (error) {
    const msg01 = error.message;
    alertMessage("❌ Error", "(mergeCell) Error Message : " + msg01);
    Logger.log(msg01);
  }
}
반응형