ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [구글 앱스 스크립트 기본 6] 두개 이상의 셀과 상호작용할 때 주의해야 할 2차원 배열
    구글 시트&앱스스크립트&루커스튜디오/구글 앱스 스크립트 2023. 8. 6. 19:16

     

     

     

     

    글의 순서

    더보기
    • getValue(s)의 리턴 자료형 & setValue(s)의 매개변수 자료형
    • 배열이란?
    • 두 개 이상의 셀과 상호작용할 때 사용하는 자료형, 2차원 배열
    • 한 개의 셀과 상호작용할 때 사용하는 자료형
    • 상황에 맞는 자료형을 정확히 선택하지 않았을 때
    • 배열에서 원하는 값 선택하기

     

    getValue(s)의 리턴 자료형 & setValue(s)의 매개변수 자료형

    지난 '[구글 앱스 스크립트 기본 5] 로그를 사용해 스크립트의 진행상황 파악하기' 글에서 다룬 example3 코드의 예를 다시 가져와보겠습니다.  우리는 "A1:B3" 범위에 있는 값을 가져오는 getValue 메서드를 활용한 코드를 val이라는 변수에 넣었고, log 메서드를 통해 val이라는 변수의 값을 문자열로 실행 로그에 표시했었습니다. 

    function example3() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A1:B3");
      var val = range1.getValues();
    
      Logger.log(val);
    }

     

    이 코드를 설명하면서 "A1:B3" 범위에 있는 셀의 값을 잘 받아와서 실행 로그에 잘 표시했으므로 코드가 잘 동작한다는 것을 알 수 있다 정도로 넘어갔었습니다. 눈치가 빠르신 분들은 실제로 해당 셀에는 없던 대괄호들이 실행 로그에 표시되었었다는 사실을 인지하셨을 수도 있습니다. 위의 코드를 실행시켜 보면 실행 로그에 표시되는 변수 val은 [[Row1 Column A, Row1 Column B], [Row2 Column A, Row2 Column B], [Row3 Column A, Row3 Column B]] 로 표시됩니다. 오늘은 바로 이 대괄호에 대해서 살펴보려고 합니다.

     

     

    구글 앱스 스크립트 레퍼런스에서 getValue 메서드를 찾아보면 반환 값으로 Object 라는 표시와 함께 The value in this cell (이 셀의 값입니다)라는 설명을 볼 수 있습니다. 여기서 Object라는 말은 문자열/숫자 등 어떠한 객체가 있다는 말입니다. 따라서 셀의 값이 숫자면 숫자를, 문자열이면 문자열을 반환한다는 사실을 알 수 있습니다. 그런데 getValues 메서드에 대한 반환 값은 약간 다릅니다. getValues의 반환 값은 Object [][]라는 표시와 함께 A two-dimensional array of values(값의 2차원 배열입니다)라는 설명이 있습니다. 마찬가지로 구글 앱스 스크립트 레퍼런스에서 setValue(s)에 대한 설명을 찾아보겠습니다. 하나의 값을 입력하는 setValue 메서드의 경우 매개변수로 getValue의 반환 값과 같은 Object를 이용한다는 것을 알 수 있습니다. 여러 값을 입력하는 setValues 메서드의 경우 getValues의 반환값과 같은 two-dimensional array(2차원 배열)를 매개변수로 이용한다는 것을 알 수 있습니다.  

     

     

    다시 위의 example3 예제를 살펴보면 구글 앱스 스크립트 레퍼런스에서 말한 것과 같이 getValues 메서드로 여러 값을 가져올 때 [대괄호]를 이용해 가져왔다는 사실을 알 수 있습니다. 그럼 설명에서 말하는, getValues의 반환값이자 setValues의 매개변수로 사용되는 two-dimensional array 2차원 배열)는 무엇을 뜻하는 것일까요?

     

     

    배열이란?

    자바스크립트에서 사용하는 배열(Array)을 쉽게 설명해보자면, 한 개의 박스(변수)에 여러 개의 물건(요소)들을 순서대로 저장하는 형태의 객체(Object)입니다. 즉 물건들을 한 박스에 넣는데 순서가 있기 때문에 몇 번째로 넣었는지를 안다면 그 물건을 쉽게 찾을 수 있습니다. 이러한 객체를 자바스크립트에서는 대괄호 []를 이용해 표시합니다. 

     

     

    박스에 물건을 넣을 때는 한 단에 하나의 물건을 넣는 방식을 활용해 여러단으로 넣을 수 있습니다. 이 경우 각 단은 물건을 넣은 순서에 따라 번호가 붙여지게 되고, 번호가 붙여진 각각의 단에는 하나의 물건만 존재할 겁니다. 이런 형태를 배열에 그대로 적용시켜 보겠습니다. 대괄호 []라는 박스 안에 한 단에 하나의 물건(Element/요소)을 넣는다면 이런 형태를 띠게 됩니다. [물건 1, 물건 2, 물건 3, 물건 4,...] 이러한 형태를 띠는 배열이 1차원 배열입니다. 만약 문자열인 요소 개, 고양이, 닭이 순서대로 들어간 1차원 배열을 만든다면 그 배열은 ["개", "고양이", "닭"]과 같은 형태를 띠게 됩니다. 만약 숫자 형태의 요소 1, 10, 100을 순서대로 넣은 1차원 배열을 만든다면 그 배열은 [1, 10, 100]과 같은 형태를 띠게 됩니다. 

     

     

    만약 한 단에 물건을 하나가 아닌 여러개를 쌓는다면 어떻게 될까요? 각각의 단에 물건을 1X2형태로 박스에 담아, 그 박스를 다시 하나의 커다란 박스에 담는 상황을 상상해 봅시다. 각각의 단에 들어가는 박스는 물건을 넣은 순서에 따라 [물건 1, 물건 2] 형태로 존재하게 됩니다. 첫 번째 박스도 [물건 1, 물건 2], 두 번째 박스도 [물건 1, 물건 2], 마지막 박스인 네 번째 박스도 [물건 1, 물건 2] 형태로 적재되어 있습니다. 이제 이 박스들을 커다란 박스에 다시 넣습니다. 그러면 이 작은 박스들은 커다란 박스에 들어가는 순서에 따라 [[물건 1, 물건 2], [물건 1, 물건 2], [물건 1, 물건 2], [물건 1, 물건 2]] 형태를 띠게 됩니다. 이와 같이 배열 안에 다른 배열이 들어가 있는 배열이 2차원 배열입니다. 만약 각기 다른 문자열인 과일이름이 들어간 2차원 배열을 만든다면 [["배", "사과"], ["감", "귤", "딸기"],...]와 같은 형태가 됩니다. 1차원 배열에서 배열 안에 들어가 있는 요소들 수에 제한이 없는 것처럼, 2차원 배열에서도 배열 안의 배열에 들어가는 요소들의 수와 더불어, 배열 안에 들어가는 배열의 수도 제한이 없고 수를 일치시킬 필요도 없습니다. 

     

     

    다시 가장 처음에 소개한 코드의 log 메서드가 반환한 값을 살펴보겠습니다. 그 값은 [[Row1 Column A, Row1 Column B], [Row2 Column A, Row2 Column B], [Row3 Column A, Row3 Column B]] 입니다. 이제 이 값이 어떠한 구조로 되어있는지 보이시나요? 2개의 요소가 들어가 있는 배열 3개가 한 배열에 들어가 있는 2차원 배열의 형태를 띠고 있습니다. 구글 앱스 스크립트 내에서 데이터를 계산하고 가공할 때는 어떤 형태의 배열을 사용해도 상관없습니다. 구글 앱스 스크립트 자체는 자바스크립트의 문법을 따르고 있으니까요. 하지만 구글 앱스 스크립트로 Spreadsheet Service를 활용해 구글 시트와 상호작용을 할 때는, Spreadsheet Service의 각각의 클래스와 메서드에서 지정하고 있는 매개변수와 리턴 형태를 알아야 정확한 값을 가져오고 넣을 수 있습니다. 

     

     

    두 개 이상의 셀과 상호작용할 때 사용하는 2차원 배열

    우리가 getValues 메서드를 통해 구글 시트의 두 개 이상의 셀에서 정보를 가져올 때 위에서 살펴본 것처럼 구글 앱스 스크립트는 이를 2차원 배열 형태로 반환합니다. 그렇다면, 과연 2차원 배열에서 우리는 어떤 정보가 어떤 위치에 있는 셀에서 가져왔는지 알 수 있을까요? 예제를 통해서 살펴보겠습니다. 이 예제에서 사용할 구글 시트 정보와 구글 앱스 스크립트 코드는 아래와 같습니다. 

    function example1() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A1:B3");
      var val = range1.getValues();
    
      Logger.log(val);
    }

     

     

    우리는 "A1:B3" 범위에 있는 정보를 구글 앱스 스크립트로 불러올겁니다. 각각의 셀에는 행 번호와 열 이름이 들어가 있습니다. 위의 example1 코드를 실행하면 실행 로그를 통해 확인되는 로그는 아래와 같습니다. 

     

     

    2차원 배열이기에 가장 바깥에 있는 배열은 자신의 요소로 다른 행렬을 받고 있습니다. 우리는 열이 3개, 행이 2개인 3X2 배열의 범위에 존재하는 값을 불러왔고, 그 결과로 배열 3개를 요소로 받고 있는 2차원 배열을 결과로 얻었습니다. 2차원 배열 내부에 위치하는 요소인 배열은 각각 2개의 문자열 타입의 데이터를 요소로 가지고 있습니다. 이를 정리해 보면 getValues 메서드는 한 행에 존재하는 데이터들을 하나의 배열로 가져오고 이 배열들을 배열로 다시 한번 만들어 2차원 배열로 가져오고 있다는 사실을 알 수 있습니다. 이를 그림으로 정리해 보면 아래와 같습니다. 

     

     

    한 개의 행만 존재하는 1X2 범위("A1:B1")의 데이터를 가져오는 경우 배열의 구조는 어떨까요? 한 개의 열만 존재하는 2X1범위("A1:A2")의 데이터를 가져오는 경우 배열의 구조는 어떨까요? 각각의 상황에 맞는 스크립트와 실행 결과는 아래와 같습니다. 

    function example1() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A1:B3");
      var range2 = sheet.getRange("A1:B1");
      var range3 = sheet.getRange("A1:A2");
      var val1 = range1.getValues();
      var val2 = range2.getValues();
      var val3 = range3.getValues();
    
      Logger.log(val1);
      Logger.log(val2);
      Logger.log(val3);
    }

     

     

    하나의 행 또는 하나의 열의 데이터만 가져온다고 하더라도 구글 앱스 스크립트의 클래스 Range의 메서드 getValues는 1차원 배열을 반환하지 않습니다. 만약 행이 하나인 범위에서 데이터를 가져온다면 getValues 메서드는 배열 하나를 요소로 가지고 있는 2차원 배열을 반환하고(val2의 경우), 만약 열이 하나인 범위에서 데이터를 가져온다면 getValues 메서드는 요소가 하나인 배열들을 요소로 가지는 2차원 배열을 반환하게 됩니다(val3의 경우).

     

    이번에는 setValues 메서드를 이용해 두 개 이상의 셀에 값을 입력하는 예제를 살펴보겠습니다. 가장 먼저 두 개의 행을 가지고 세 개의 열을 가지는 "D1:F2" 범위에 값을 입력해 보겠습니다. 각각의 셀에는 이전 예제와 마찬가지로 행 번호와 열 이름을 넣도록 하겠습니다. 새로운 함수 example2를 만들어 해당 기능을 실행시키는 코드를 입력해 보겠습니다. 가장 먼저 값으로 넣을 2차원 배열을 array1이라는 변수에 지정하겠습니다. 값을 넣을 범위의 행이 2개, 열이 3개이기 때문에 우리가 만들어야 할 2차원 배열은 배열 2개를 요소로 받는 2차원 배열의 형태를 띠게 됩니다. 그리고 요소인 배열은 각각 3개의 문자열 타입의 데이터를 요소로 가지게 됩니다. 이를 코드로 작성해 보면 아래와 같습니다. 

    function example2() {
      var array1 = [["Row1 ColumnD", "Row1 ColumnE", "Row1 ColumnF"],["Row2 ColumnD", "Row2 ColumnE", "Row2 ColumnF"]];
    }

     

    이 array1을 구글 시트의 "D1:F2" 범위에 입력하는 스크립트를 완성하면 아래와 같습니다. 

    function example2() {
      var array1 = [["Row1 ColumnD", "Row1 ColumnE", "Row1 ColumnF"],["Row2 ColumnD", "Row2 ColumnE", "Row2 ColumnF"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("D1:F2");
      range1.setValues(array1);
    }

     

    위의 코드를 실행해보면 아래와 같이 우리가 작성한 배열이 원하는 범위에 정확히 들어간 것을 알 수 있습니다. 

     

    그렇다면 열이 하나고 행이 3개인 범위 "H1:H3"에 setValues 메서드로 값을 입력하는 경우 setValues의 매개변수로 들어가야 할 2차원 배열은 어떤 형태일까요? 또한 열이 3개고 행이 하나인 범위 "J1:L1"에 setValues 메서드로 값을 입력하는 경우 setValues의 매개변수로 들어가야 할 2차원 형해의 배열은 어떤 형태일까요? 이 두 문제에 대한 해답을 먼저 스스로 써보시길 바랍니다. 이 문제에 대한 답은 아래를 펼쳐 확인하실 수 있습니다.

     

    더보기
    function example3() {
      var array1 = [["Row1 ColumnH"], ["Row2 ColumnH"], ["Row3 ColumnH"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("H1:H3");
      range1.setValues(array1);
    }
    
    function example4() {
      var array1 = [["Row1 ColumnJ", "Row1 ColumnK", "Row1 ColumnL"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("J1:L1");
      range1.setValues(array1);
    }

     

     

     

    한 개의 셀과 상호작용할 때 사용하는 자료형

    두 개 이상의 셀과 상호작용을 하기 위한 자료형인 2차원 배열에 대해서도 알아봤으니, 한 개의 셀과 상호작용을 할 때 사용하는 자료형에 대해서도 간단하게 짚고 넘어가겠습니다. 한 개의 셀과 상호작용을 하는 메서드인 getValue메서드와 setValue메서드는 각각 반환값과 매개변수로 모두 Object(객체)를 이용합니다. 객체(Object)에 대해 자세히 설명하려면 글 하나로 부족할 수도 있으니 간단하게 구글 앱스 스크립트를 사용하는 우리에게 객체는 하나의 값 정도로 생각하면 좋을 듯합니다. 그리고 이 하나의 값은 문자열이 될 수도 있고, 숫자가 될 수도 있고, 배열이 될 수도 있고, 참과 거짓 두 값만 가지는 불리언(Boolean) 일 수도 있습니다. 즉 우리에게 객체는 다양한 형태의 데이터 타입을 가지는 하나의 값으로 이해하면 됩니다. 

     

    예제 세 개를 살펴보겠습니다. 첫 번째는 A6셀에 "Row6 ColumnA"라는 문자열 타입의 데이터를 입력하는 예제입니다. 두 번째는 B6셀에 6이라는 숫자 타입의 데이터를 입력하는 예제입니다. 세 번째는 C6셀에 true라는 불리언 타입의 데이터를 입력하는 예제입니다. 각각의 예제를 실행하는 함수 example5, example6, example7는 아래와 같습니다. 아래의 답을 보시기 전에 먼저 스스로 스크립트를 작성해 보시는 것을 추천합니다. (참고로 불리언 타입의 데이터는 참(true)이나 거짓(false)만 값으로 가지는 형태의 데이터입니다.)

    function example5() {
      var val1 = "Row6 ColumnA";
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A6");
      range1.setValue(val1);
    }
    
    function example6() {
      var val1 = 6;
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("B6");
      range1.setValue(val1);
    }
    
    function example7() {
      var val1 = true;
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("C6");
      range1.setValue(val1);
    }

     

     

    불리언 타입의 데이터를 입력하는 example7 함수에 대해 간략한 설명을 덧붙이겠습니다. 구글 앱스 스크립트에서 참/거짓을 표현하기 위해서는 따옴표 없이 true/false를 소문자로 입력해야 합니다. 만약 대문자가 하나라도 포함되어 있을 경우 구글 앱스 스크립트는 이를 참/거짓이라는 불리언 타입의 데이터가 아닌 변수로 이해합니다. 구글 시트에서는 불리언 타입의 데이터를 모두 대문자인 TRUE/FALSE로 표시합니다. 이 때문에 구글 앱스 스크립트에서 true라는 불리언 타입의 데이터를 입력했을 때, 구글 시트에는 대문자 TRUE가 나타나게 됩니다. 참고로 구글 앱스 스크립트에서 true에 대문자를 섞어 쓰면 아래와 같은 오류가 실행 로그에 나타납니다. 

     

     

    마지막으로 두 개의 예제를 더 살펴보겠습니다. 위에서 setValue는 매개변수로 Object(객체)를 받고, Object에는 위에서 언급한 배열도 포함되었다고 설명했습니다. 만약 setValue의 매개변수로 배열을 사용한다면 어떻게 될까요? 아래의 두 예제는 setValue 메서드를 이용해 각각 "A8", "B8"에 1차원 배열과 2차원 배열을 매개변수로 사용해보는 예제입니다. 먼저 A8셀에는 example8 함수를 만들어 setValue 메서드의 매개변수로 1차원 배열 [ "Row8 ColumnA", "Row8 ColumnB"]를 사용해 보도록 하겠습니다. 그다음에 B8 셀에 example9 함수를 만들어 setValue 메서드의 매개변수로 2차원 배열 [[ "Row8 ColumnB", "Row8 ColumnC"], [ "Row9 ColumnB", "Row7 ColumnC"]] 를 사용해 보도록 하겠습니다.  스크립트는 아래와 같습니다. 

    function example8() {
      var val1 = [ "Row8 ColumnA", "Row8 ColumnB"];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A8");
      range1.setValue(val1);
    }
    
    function example9() {
      var val1 = [[ "Row8 ColumnB", "Row8 ColumnC"], [ "Row9 ColumnB", "Row7 ColumnC"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("ㅠ8");
      range1.setValue(val1);
    }

     

    위의 스크립트를 실행해보면 오류 없이 함수가 실행되는 것을 볼 수 있습니다. 또한 setValue 메서드는 배열의 구조와 상관없이 가장 앞에 오는 요소를 선택된 범위에 입력한다는 사실을 알 수 있습니다. 

     

     

    상황에 맞는 자료형을 정확히 선택하지 않았을 때

    위의 setValue 메서드에서 매개변수로 배열을 사용하는 경우는 setValue 메서드가 받을 수 있는 매개변수 타입인 Object(객체)에 배열이 포함되기 때문입니다. 따라서 상황에 맞는 자료형을 사용했다고 볼 수 있습니다. 하지만 setValues 메서드의 경우 매개변수로 2차원 배열만 받을 수 있다는 사실을 구글 앱스 스크립트 레퍼런스에서 명시하고 있습니다. 따라서 2차원 배열이 아닌 다른 타입의 데이터는 상황에 맞지 않는 자료형이라고 볼 수 있습니다. 그렇다면 setValues 메서드의 매개변수로 각각 문자열, 숫자, 1차원 배열을 사용하는 경우는 어떻게 될지 각각 example10, example11, example12 함수를 만들어 살펴보겠습니다. 이번 예제에서 사용할 코드는 아래와 같습니다. 

    function example10() {
      var val1 = "Row10 ColumnA";
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A10:B10");
      range1.setValues(val1);
    }
    
    function example11() {
      var val1 = 10;
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A11:B11");
      range1.setValues(val1);
    }
    
    function example12() {
      var val1 = ["Row12 ColumnA", "Row12 ColumnA"];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A12:B13");
      range1.setValues(val1);
    }

     

    가장 먼저 문자열 하나를 매개변수로 사용하는 예제인 함수 example10의 실행결과입니다. 이 함수를 실행하면 아래와 같이 매개변수로 String(문자열) 타입의 데이터가 들어갔고, 이는 SpreadsheetApp.Range.setValues. 메서드에 맞지 않는다는 사실을 실행 로그에서 확인할 수 있습니다.

     

     

    두 번째는 숫자열 타입의 데이터를 매개변수로 사용하는 예제인 함수 example11의 실행결과입니다. 이번에도 마찬가지로 매개변수로 number(숫자) 타입의 데이터가 들어갔다는 사실과 함께 아까와 같은 오류를 반환합니다.

     

     

    마지막으로 1차원 행렬을 매개변수로 사용하는 예제인 함수 example12의 실행결과입니다. 여전히 마찬가지로 매개변수의 데이터 타입이 잘못되었다는 오류를 반환합니다. 우리가 레퍼런스에서 본 2차원 배열은 number [][]인데, 실행 로그에서 보여주는 우리가 입력한 매개변수는 number []로 1차원 배열이라는 사실을 알 수 있습니다. 

     

     

    위의 예제들을 통해 하나의 값을 입력하는 메서드 setValue의 경우 배열이 들어가도 맨 앞의 요소를 범위에 입력하는 반면, 여러 값을 입력하는 메서드 setValues의 경우 꼭 2차원 배열을 사용해야 한다는 사실을 알 수 있습니다. 다음으로 살펴볼 예제는 setValues 메서드를 사용할 때 우리가 지정한 범위와 2차원 배열의 구조가 매칭되지 않을 때입니다. 이번 예제에서 우리는 2X2 범위의 범위를 선택하는 반면, 매개변수로 사용할 배열은 1X2 범위에 대응하는 배열입니다. 이번 예제에서 사용할 코드는 아래와 같습니다. 

    function example13() {
      var val1 = [["Row14 ColumnA", "Row14 ColumnB"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A14:B15");
      range1.setValues(val1);
    }

     

    위의 코드를 실행시켜보면, 아까 setValues 메서드가 받지 않는 타입의 매개변수를 사용했을 때와는 다른 오류를 반환합니다. 바로 데이터의 행 개수와 선택한 범위의 행 개수가 일치하지 않는다는 오류와 함께 매개변수에 넣은 데이터의 행 개수는 1개, 선택한 범위의 행 개수는 2개라는 사실까지 친절하게 알려줍니다. 

     

     

    마지막으로 위에서 사용한 example13 함수를 변형해 조금 기형적인 구조의 2차원 배열을 사용해 보겠습니다. 바로 2차원 배열의 첫 번째 요소 배열은 2개의 요소를 가지지만, 두 번째 요소 배열은 1개의 요소를 가지는 배열입니다. 우리가 2X2 범위에 값을 넣는데 가장 오른쪽 아래의 셀에는 넣을 데이터가 없는 경우를 가정한 상황입니다. 이번에 사용할 코드는 아래와 같습니다. 

    function example14() {
      var val1 = [["Row14 ColumnA", "Row14 ColumnB"], ["Row15 ColumnA"]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A14:B15");
      range1.setValues(val1);
    }

     

    이 스크립트를 실행해보면 아까와 비슷하지만 약간은 다른 오류를 반환합니다. 아까는 행 개수가 일치하지 않는다고 했지만, 이번에는 열 개수가 일치하지 않는다는 오류를 반환합니다.

     

     

    그렇다면 만약 선택한 범위에서 넣을 값이 없는 경우에는 어떻게 해야 할까요? 이 때는 배열의 구조는 선택한 범위와 같게 만들되, 값을 넣지 않을 셀에 대응하는 요소의 위치에는 아무 값도 없는 문자열 타입의 데이터인 따옴표 두 개("")를 넣으면 됩니다. example14 함수를 약간 수정해 작동하도록 만든 example15 함수는 아래와 같습니다. 

    function example15() {
      var val1 = [["Row14 ColumnA", "Row14 ColumnB"], ["Row15 ColumnA", ""]];
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getActiveSheet();
      var range1 = sheet.getRange("A14:B15");
      range1.setValues(val1);
    }

     

    위의 코드를 실행해보면 example14 함수와는 달리 오류 없이 작동하고, 아래의 스크린숏처럼 원하는 값이 원하는 위치에 들어갔다는 사실을 확인할 수 있습니다.

     

     

     

    배열에서 원하는 값 선택하기

    마지막으로 배열에서 원하는 값을 선택하고자 할 때는 어떻게 해야 하는지 살펴보겠습니다. 구글 앱스 스크립트를 구글 시트와 연동해서 사용하다 보면 넓은 범위의 데이터를 가져와서 그중에 한두 개의 데이터만 이용하는 경우가 많습니다. 이 경우 우리는 배열에서 원하는 데이터만 추출해야 합니다. 이때 사용하는 것이 바로 인덱스입니다. 가장 먼저 1차원 배열에서 원하는 값을 가져오는 경우를 살펴보겠습니다. 이를 위해 데이터 타입이 문자열인 요소1, 요소2, 요소3, 요소4를 요소로 가지고 있는 배열 하나를 만들어 arr1이라는 변수에 할당하겠습니다. 

      var arr1 = ["요소1", "요소2", "요소3", "요소4"];

     

    1차원 배열의 요소에 접근하려면 인덱스를 사용해야 하고, 인덱스는 배열 뒤에 대괄호 []를 통해 사용할 수 있습니다. 대괄호 안에 요소의 순서를 넣어주면 해당 순서에 있는 요소에 접근할 수 있습니다. 여기서, 요소의 순서는 1이 아닌 0부터 시작한다는 사실에 주의하셔야 합니다. 즉, 가장 첫 요소인 요소1에 접근하기 위해서는 [1]이 아닌 [0]을 사용해야 합니다. 이를 구글 스크립트에서 log 메서드를 활용해 확인해 보겠습니다. 

    function example16() {
      var arr1 = ["요소1", "요소2", "요소3", "요소4"];
      Logger.log(arr1[0]);
      Logger.log(arr1[1]);
      Logger.log(arr1[2]);
      Logger.log(arr1[3]);
    }

     

     

    위의 스크립트를 실행해보면 arr1[1]에 대응하는 요소는 요소 1이 아닌 요소 2라는 사실을 알 수 있습니다. 요소 1에 접근하기 위해서는 arr1[0]처럼 인덱스 0을 이용해야 합니다. 만약 2차원 배열의 경우는 어떨까요? 2차원 배열의 경우는 대괄호[]를 두 번 사용해서 각각 열 인덱스와 행 인덱스에 접근할 수 있습니다. 

    function example17() {
      var arr1 = [["요소1-1", "요소1-2"], ["요소2-1", "요소2-2"]];
      Logger.log(arr1[0][0]);
      Logger.log(arr1[0][1]);
      Logger.log(arr1[1][0]);
      Logger.log(arr1[1][1]);
    }

     

     

    2차원 배열 요소에 접근하기 위해 사용하는 첫 번째 대괄호는 바깥 배열 안에 있는 요소인 배열에 접근하기 위해 사용됩니다. 두 번째 사용하는 대괄호는 안에 위치한 배열의 요소에 접근하기 위해 사용됩니다. 처음에는 인덱스가 0에서 시작된다는 점과 2차원 배열에서 사용되는 인덱스가 낯설게 느껴지실 수 있습니다만, 몇 번 log 메서드를 이용해 구글 앱스 스크립트에서 연습을 해보면 크게 어렵지 않다는 사실을 알 수 있습니다.

     

    배열에 관련된 사항만 따로 빼서 글을 작성한 건, 구글 앱스 스크립트와 구글 시트를 연동해 사용할 경우, 우리가 선택된 범위와 그 범위에 입력할 배열의 구조가 달라서 오류가 나는 경우가 많기 때문입니다. 또한 구글 시트에서 구글 앱스 스크립트를 사용하는 이유는 구글 시트에서 데이터를 가져와 스크립트로 그 데이터를 가공한 후 다시 구글 시트에 입력하기 위한 경우가 많은데, 이때 값을 가져오고 입력하기 위한 메서드의 반환값과 매개변수의 구조를 정확히 알지 않으면 꽤 많은 오류를 경험하기 때문입니다. 처음 구글 앱스 스크립트를 접하시는 경우, 이 '배열'이라는 개념이 어렵게 다가올 수 있겠지만, 어려운 만큼 꼭 알아야 할 중요한 개념이기에, 긴 공간을 이용해 이를 설명하는 시간을 가졌습니다. 

    댓글

ⓒ 2018. Haedie's all rights reserved.