Google Sheets와 Slides를 사용하여 빅데이터에서 유용한 정보 도출

데이터 과학자가 빅데이터 분석을 수행하는 데 사용할 수 있는 도구는 많지만, 최종적으로 그러한 결과를 타당하게 관리해야 하지는 않나요? 종이나 데이터베이스에서 다수의 수치를 만들어 주요 이해관계자에게 파악하기는 어렵습니다. Google Apps Script인 Google Apps Script Codelab에서는 Google의 개발자 플랫폼인 G SuiteGoogle Cloud Platform (GCP)을 활용해 최종 목표를 달성하는 데 도움을 받을 수 있습니다.

Google Cloud의 개발자 도구를 사용하면 딥 데이터 분석을 실시한 후 결과를 스프레드시트에 입력한 후 해당 데이터를 사용하여 슬라이드 프레젠테이션을 생성하여 결과에 따라 보다 적절한 결과를 제공할 수 있습니다. 이 Codelab은 GCP&#39의 BigQuery API (Apps Script 고급 서비스)와 Google SheetsGoogle Slides내장 Apps Script 서비스에 관해 다룹니다.

동기 부여/사전 예술

이 Codelab의 샘플 앱은 다른 코드 샘플에서 영감을 받았습니다.

Slides API Codelab 샘플 앱에는 BigQuery 및 Slides도 포함되어 있지만 이 Codelab 샘플 앱은 여러 가지 차이점이 있습니다.

  • Node.js 앱과 Apps Script 앱의 비교
  • Apps Script 서비스를 사용하는 동안 REST API 사용
  • Google Drive를 사용하지만 Google Sheets는 사용하지 않지만 이 앱에서는 스프레드시트를 사용하지만 Drive는 사용하지 않습니다.

이 Codelab에서는 실제 사용 사례와 더 유사한 방식으로 Google Cloud의 기능과 API를 보여 주는 동시에 최대한 많은 기술을 단일 앱에 통합하려고 했습니다. 이 가이드는 여러분이 상상력을 발휘하고 조직 또는 고객의 어려운 문제를 해결하기 위해 GCP와 G Suite를 모두 활용하는 것을 목표로 합니다.

학습할 내용

  • 여러 GCP (Google Cloud & G Suite) 서비스에서 Google Apps Script를 사용하는 방법
  • Google BigQuery를 사용하여 빅데이터를 분석하는 방법
  • Google 시트를 만들고 데이터를 채우는 방법
  • Sheets에서 새 차트를 만드는 방법
  • Sheets에서 Google Slides로 차트 및 데이터를 전달하는 방법

필요한 항목

  • 인터넷 및 웹브라우저에 대한 액세스
  • Google 계정(G Suite 계정의 경우 관리자 승인이 필요할 수 있음)
  • 기본 자바스크립트 기술
  • Apps Script 개발에 관한 지식이 있다면 유용할 수 있지만 필수는 아닙니다.

본 Codelab/튜토리얼은 어떻게 사용하실 계획인가요?

정보를 참고하여 기술 동료에게 전달합니다. 최대한 많은 방법을 살펴보고 최대한 많은 운동을 시도합니다. 지옥 같은 물에 빠졌거나 전체 Codelab을 완료하려고 합니다.

G Suite 개발자 도구 및 AMP API 사용 경험은 어땠나요?

초급 중급 고급

Apps Script 사용 경험이 어떠셨나요?

초급 중급 고급

GCP 개발자 도구 및 AMP API 사용 경험을 평가해 주세요.

초급 중급 고급

이 Codelab에 관한 내용을 알았으니 이제 정확히 무엇을 할 건가요?

  1. 기존 Apps Script-BigQuery 샘플을 가져와 작동
  2. 이 샘플에서 BigQuery로 쿼리를 전송하고 결과를 가져오는 방법을 알아봅니다.
  3. Google 시트를 만들고 BigQuery의 결과를 여기에 채웁니다.
  4. 반환되는 코드를 약간 변경하여 코드를 약간 수정하여 스프레드시트에 추가합니다.
  5. Apps Script에서 Sheets 서비스를 사용하여 BigQuery 데이터 차트 만들기
  6. Slides 서비스를 사용하여 새 슬라이드 프레젠테이션 만들기
  7. 모든 새 슬라이드 자료에서 자동으로 생성된 기본 제목 슬라이드에 제목과 부제목 추가
  8. 데이터 표로 새 슬라이드를 만든 다음 해당 시트의 데이터 셀을 가져옵니다.
  9. 새 슬라이드 추가 및 스프레드시트 차트를 추가합니다.

Apps Script, BigQuery, Sheets, Slides에 관한 배경 정보를 알아보겠습니다.

Google Apps Script 및 BigQuery

Google Apps Script는 Google REST API를 사용할 때보다 더 높은 수준에서 작동하는 G Suite 개발 플랫폼입니다. 광범위한 개발자 기술 수준에 액세스할 수 있는 서버리스 개발 및 애플리케이션 호스팅 환경입니다. Apps Script는 한마디로 G Suite 자동화, 확장, 통합을 위한 서버리스 자바스크립트 런타임입니다.

Node.js와 유사하게 서버 측 자바스크립트이지만 빠른 비동기 이벤트 기반 애플리케이션 호스팅이 아닌 G Suite 및 기타 Google 서비스와의 통합에 중점을 둡니다. 또한 익숙한 환경과 완전히 다른 개발 환경도 포함되어 있습니다. Apps Script를 사용하면 다음을 수행할 수 있습니다.

  • 브라우저 기반 코드 편집기에서 개발하지만 Apps Script용 명령줄 배포 도구인 clasp를 사용하는 경우 로컬에서 개발 가능
  • G Suite 및 기타 Google 또는 외부 서비스 (Apps ScriptURLfetch 또는 Jdbc 서비스 사용)에 맞춤설정된 맞춤 버전의 자바스크립트
  • Apps Script가 알아서 처리하므로 승인 코드 작성을 할 수 없음
  • 앱을 호스팅할 필요 없이 클라우드의 Google 서버에서 실행 및 실행됩니다.

참고: 대부분의 경우 이 Codelab에서는 Apps Script를 학습합니다. 작업에 도움이 되는 온라인 리소스가 많이 있습니다. 공식 문서에는 빠른 시작이 포함된 개요, 튜토리얼, 동영상도 포함되어 있습니다. 마지막으로, Apps Script 소개 Codelab을 꼭 기억하시기 바랍니다. 이 Codelab을 시작하기 전에 완료해야 합니다.

Apps Script는 다음 두 가지 방식으로 다른 Google 기술과 상호작용합니다.

  • 기본 서비스/네이티브 서비스
  • 고급 서비스

내장 서비스는 G Suite 또는 Google 제품 데이터나 기타 유용한 유틸리티 메서드에 액세스하는 데 사용할 수 있는 대략적인 방법을 제공합니다. 고급 서비스는 G Suite 또는 Google REST API 주변의 얇은 래퍼입니다. 고급 서비스는 REST API의 전체 기능을 제공하며 기본 제공 서비스보다 더 많은 작업을 수행할 수 있지만 REST API 자체보다 훨씬 사용하기 쉬운데 더 많은 코드 복잡성이 필요합니다. 고급 서비스를 사용하기 전에 스크립트 프로젝트에서도 사용 설정해야 합니다.

가능한 경우 개발자는 고급 서비스보다 사용하기가 더 쉽고 복잡하지 않은 작업도 하기 때문에 기본 제공 서비스를 선호합니다. 그러나 일부 Google API에는 기본 제공 서비스가 없으므로 고급 서비스만 선택할 수 있습니다. Google BigQuery를 예로 들 수 있습니다. 기본 제공 서비스를 사용할 수 없지만 BigQuery 고급 서비스있음합니다. (서비스가 없는 경우보다는 낫습니다.) BigQuery를 처음 사용하는 경우라면 매우 큰 데이터 코퍼스에 대해 단순 (또는 복잡한) 쿼리를 수행할 수 있는 GCP 서비스입니다(예: 여러 테라바이트 단위의 순서이지만 몇 초 만에 결과를 제공할 수 있음).

Apps Script에서 Google Sheets 및 Slides에 액세스

BigQuery와 달리 Google Sheets와 Slides에는 모두 내장된 서비스 (API뿐 아니라 기능에만 액세스하는 고급 서비스)가 포함되어 있습니다. 코드를 작성하기 전에 내장된 SheetsSlides 서비스 관련 문서를 참고하세요. 고급 서비스에 대한 문서도 제공합니다. 여기서 각각 SheetsSlides용 문서입니다.

소개

첫 번째 작업으로 이 Codelab을 크게 간소화할 것입니다. 실제로 여기서 Codelab을 완료하면 절반 정도를 완료했을 것입니다. 여러 하위 섹션으로 나뉘어 있으며 다음과 같은 모든 작업을 하게 됩니다.

  • 새 Google Apps Script 프로젝트 시작
  • BigQuery 고급 서비스에 대한 액세스 사용 설정하기
  • 개발 편집기로 이동하여 애플리케이션 소스 코드를 입력합니다.
  • 앱 승인 프로세스 (OAuth2) 진행
  • BigQuery에 요청을 보내는 애플리케이션 실행
  • BigQuery의 결과로 생성된 새로운 Google 시트 보기

설정

  1. a) script.google.com로 이동하여 새 Apps Script 프로젝트를 만듭니다. G Suite 제품군은 다양하며 새 프로젝트를 만드는 방법은 사용 중인 버전에 따라 다를 수 있습니다. Gmail 계정을 이제 막 사용 중이며 프로젝트를 처음 개발하는 경우에는 첫 프로젝트를 만드는 버튼과 함께 빈 화면이 표시됩니다.


b) 그러지 않으면 왼쪽 상단에 모든 프로젝트와 큰 +New 버튼이 표시될 수 있습니다. 이 버튼을 클릭합니다.



c) 위 두 가지 중 어느 것도 표시되지 않으면 화면은 다음과 같을 수 있습니다. 이 경우 왼쪽 상단에 있는 햄버거 메뉴 아이콘을 찾아 +새 스크립트를 선택합니다.



d) 명령줄을 선호하는 사용자 도구는 clasp이며, 특히 clasp create 명령어를 실행합니다.

e) 새 스크립트 프로젝트를 만드는 마지막 방법은 바로가기 링크(https://script.google.com/create)로 이동하는 것입니다.

  1. 새 프로젝트를 시작하는 데 사용한 기법과 관계없이 결론은 다음과 같은 화면인 Apps Script 코드 편집기에 드롭해야 합니다.


  2. File > Save를 클릭하고 프로젝트 이름을 지정합니다.
  3. 그런 다음 BigQuery 쿼리를 실행하려면 Google Cloud Console 프로젝트를 만들어야 합니다.
  1. 새 프로젝트를 만들고 이름을 지정하고, 결제 계정을 선택한 다음, 만들기를 클릭합니다.
  1. 프로젝트 생성이 완료되면 페이지 오른쪽 상단에 알림이 표시됩니다. Create Project: <Project Name> 항목을 클릭하여 프로젝트를 엽니다.
  2. 왼쪽 상단의 메뉴 아이콘 을 클릭하고 API 및 서비스; 사용자 인증 정보로 이동합니다. OAuth 동의 화면 탭(직접 링크)을 클릭합니다.
  3. Application name 필드에 "Big Data Codelab"를 입력하고 하단의 Save 버튼을 클릭합니다.
  4. 오른쪽 상단의 점 3개 아이콘을 클릭하여 메뉴를 펼치고 프로젝트 설정(직접 링크)을 선택합니다.
  5. 프로젝트 번호 아래에 표시된 값을 복사합니다. (Codelab 후반부에서 사용할 별도의 제품 ID가 있습니다.)
  6. App Script 편집기로 돌아가서 Resources > Cloud Platform project를 클릭합니다.
  7. 텍스트 상자에 프로젝트 번호를 입력하고 프로젝트 설정을 클릭합니다. 메시지가 표시되면 확인을 클릭합니다.
  8. 완료되면 닫기 버튼을 클릭하여 대화상자를 닫습니다.
  9. 이제 새 프로젝트 설정이 완료되었으므로 BigQuery 고급 서비스를 사용 설정해야 하므로 리소스 -> 고급 Google 서비스를 아래로 스크롤하여 BigQuery API에 대해 사용 설정합니다.


  10. 하단에 있는 '서비스'도 'Google Cloud Platform API 대시보드'에서 사용 설정해야 하므로 이 링크를 클릭하면 개발자 콘솔이나 'devconsole'에 대한 다른 브라우저 탭이 열립니다.
  11. devconsole에서 상단의 +API 및 서비스 사용 설정 버튼을 클릭하고 "bigquery"를 검색한 다음 BigQuery API (BigQuery Transfer Transfer API 아님)를 선택하고 사용을 클릭하여 사용 설정합니다. 이 브라우저 탭은 열어 두세요.

    참고: API를 사용 설정하면 이 페이지에 '이 API를 사용하려면 사용자 인증 정보를 만들어야 합니다...'라는 메모가 표시될 수 있습니다. 하지만 지금은 걱정하지 마세요. 이 단계는 Apps Script에서 대신 처리합니다.


  12. 코드 편집기 브라우저 탭으로 돌아가면 고급 Google 서비스 메뉴가 계속 표시되므로 확인을 클릭하여 대화상자를 닫고 코드 편집기에 그대로 둡니다. 상단에서 프로젝트 이름을 클릭하고 원하는 이름을 지정합니다. 'BigQuery 데모' 또는 이와 유사한 이름을 정합니다.

이제 애플리케이션 코드를 입력하고, 인증 프로세스를 거쳐, 첫 번째 애플리케이션 구현을 시작할 준비가 되었습니다.

애플리케이션 업로드 및 실행

  1. 아래 상자에 있는 코드를 복사하여 코드 편집기의 모든 항목에 붙여넣습니다.
// Filename for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud API project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into Sheet. You must enable
 * the BigQuery advanced service before you can run this code.
 * @see http://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see http://github.com/googleworkspace/apps-script-samples/blob/main/advanced/bigquery.gs
 *
 * @returns {Spreadsheet} Returns a spreadsheet with BigQuery results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BQ job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the new results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to Sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
}


이제 방금 만든 파일을 저장하고 Code.gs에서 bq-sheets-slides.js로 이름을 바꿉니다. 이 코드는 어떤 역할을 하나요? 이미 BigQuery를 쿼리하고 결과를 새 Google 시트에 씁니다. 하지만 이 쿼리란 무엇인가요? runQuery() 상단(
) 상단에서 확인할 수 있습니다.

SELECT
    LOWER(word) AS word,
    SUM(word_count) AS count
FROM [bigquery-public-data:samples.shakespeare]
GROUP BY word
ORDER BY count
DESC LIMIT 10


이 쿼리는 셰익스피어 작품 중 BigQuery의 공개 데이터 세트에 포함된 작품 중 가장 인기 있는 단어 10개를 인기순으로 정렬하여 보여줍니다. 직접 하는 것이 얼마나 재미있을지 상상해 보고 BigQuery가 얼마나 유용한지 아이디어를 얻어야 합니다.

  1. 이 기능을 사용할 준비가 거의 다 되었습니다. 이 코드 스니펫 상단 근처에서 확인할 수 있듯이 유효한 프로젝트 ID가 필요하므로, 애플리케이션 ID를 애플리케이션 코드에 추가해야 합니다. 개발자 창 페이지를 가져오려면 개발자 콘솔 페이지가 있는 브라우저 창이나 탭으로 돌아갑니다. (2번은 열어두라고 했지요?)
  2. Google 계정 아바타의 왼쪽 상단에 풀다운 메뉴 선택기 ()가 있습니다. 아바타를 클릭하고 프로젝트 설정을 선택하세요. 프로젝트 이름, ID, 번호가 표시됩니다. 프로젝트 ID를 복사하고 bq-sheets-slides.js 상단의 PROJECT_ID 변수를 개발자 콘솔에서 얻은 값으로 설정합니다. 참고: 메뉴 선택기가 고정되어 작동하지 않을 경우 페이지를 새로고침하세요.
  3. 프로젝트 ID가 없으면 애플리케이션이 더 이상 진행되지 않도록 if 문이 있습니다. 추가한 파일을 추가하고 파일을 저장한 후 메뉴 바로 이동하여 Run > Run Function > runQuery를 선택합니다. Review Permissions 대화상자를 클릭합니다. 이 앱은 인증되지 않은 상태입니다. 다음 몇 단계를 보여주는 애니메이션 GIF가 있습니다.
  4. 권한 검토를 요청하면 위에 표시된 것처럼 새 대화상자가 표시됩니다. 스크립트를 실행할 올바른 Google 계정을 선택하고 Advanced(고급)를 선택한 다음 아래로 스크롤하여 "Go & PROJECT NAME>(unsafe)(확인하기)를 클릭하여 OAuth2 애플리케이션 승인 화면으로 이동합니다. (확인 절차에 대해 자세히 알아보고 아래의 OAuth2 승인 대화상자 사이에 이 화면이 표시되는 이유를 자세히 알아보세요.)


    참고: 앱을 승인하고 나면 실행할 때마다 이 프로세스를 반복할 필요가 없습니다. 이 튜토리얼에서 태스크 3으로 다시 이동할 때까지 사용자에게 Google Slides 프레젠테이션을 만들고 관리할 수 있는 권한을 요청하는 메시지가 계속 표시됩니다.
  5. OAuth2 대화상자 창에서 허용을 클릭하면 스크립트가 실행됩니다. 상단에 파스텔 노란색 대화상자가 표시됩니다. 매우 빠르게 실행되므로 실행 중이거나 실행이 완료되었는지 알 수 없습니다.

  6. 이 대화상자는 완료되면 사라지므로 여기서 표시되지 않는다면 Google Drive (drive.google.com)로 이동하여 '셰익스피어 작업'이나 QUERY_NAME 변수에 할당한 단어 중 가장 일반적인 단어인 'Google 시트'를 찾습니다.


  7. 스프레드시트를 열면 10개 행의 단어와 총 개수가 내림차순으로 표시됩니다.

작업 1 요약

방금 일어난 일을 알아보세요. 셰익스피어 모든 작업을 쿼리한 코드를 실행했습니다. 엄청난 양의 데이터가 아니라 모든 놀이에서 모든 단어를 직접 훑어보며, 단어 수를 하나씩 관리하고 표시되는 단어의 내림차순으로 정렬하는 것보다 더 많은 텍스트가 존재합니다. 사용자를 위해 BigQuery에 이 작업을 수행하도록 요청했을 뿐만 아니라 Google Sheets용 Apps Script에 내장된 서비스를 사용하여 데이터를 손쉽게 사용할 수 있도록 했습니다.

위에 붙여넣은 bq-sheets-slides.js(선택한 파일 이름)의 코드(실제 프로젝트 ID가 있어야 하는 PROJECT_ID 제외)는 이 Codelab의 step1 폴더(github.com/googlecodelabs/bigquery-sheets-slides)에서도 확인할 수 있습니다. 이 코드는 약간 다른 쿼리를 실행하는 BigQuery 고급 서비스 페이지의 원본 예시에서 큰 영감을 얻었습니다. 셰익스피어가 10자(영문 기준) 이상 사용한 가장 인기 있는 단어는 무엇인가요? GitHub 저장소에서도 샘플을 확인할 수 있습니다.

셰익스피어 작품이나 다른 공개 데이터 표에 대해 살펴보려고 할 때 궁금한 점이 있다면 이 웹페이지이 웹페이지를 확인하세요. 사용하는 쿼리와 관계없이 Apps Script에서 쿼리를 실행하기 전에 언제든지 BigQuery 콘솔에서 쿼리를 테스트할 수 있습니다. BigQuery의 사용자 인터페이스는 bigquery.cloud.google.com에서 개발자에게 제공됩니다. 예를 들어 BigQuery UI를 사용하면 쿼리가 다음과 같이 표시됩니다.

위의 단계에서 Apps Script 코드 편집기를 활용했지만, 명령줄을 통해 로컬에서 개발하도록 선택할 수도 있습니다. 원하는 경우 bq-sheets-slides.js라는 스크립트를 만들고 위에 코드를 붙여넣은 다음 clasp push 명령어를 사용하여 Google에 업로드합니다. (이전에 놓친 경우 clasp 링크 및 사용 방법을 다시 확인해 보세요.)

runQuery()의 목적은 BigQuery와 대화하여 결과를 시트로 보내는 것입니다. 이제 데이터가 포함된 차트를 만들어야 합니다. Sheet의 newChart() 메서드를 호출하여 createColumnChart()라는 새 함수를 만들어 보겠습니다.

  1. 차트 만들기 아래에 나온 createColumnChart()의 본문을 runQuery() 바로 뒤에 bq-sheets-slides.js에 추가합니다. 데이터가 포함된 시트를 가져오고 모든 데이터가 포함된 열 형식 차트를 요청합니다. 첫 번째 행에는 데이터가 아닌 열 헤더가 포함되어 있으므로 A2 셀에서 범위가 시작됩니다.
/**
 * Uses spreadsheet data to create columnar chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} visualizing the results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first and only) Sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in Sheet is from cell A2 to B11
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on Sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the Sheet using above params.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);
}
  1. 스프레드시트 반환. 위의 createColumnChart()에는 스프레드시트 객체가 필요하므로 spreadsheet 객체를 반환하도록 createColumnChart()를 전달할 수 있도록 runQuery()를 업데이트해야 합니다. Google 시트 생성이 성공적으로 로깅되면 runQuery() 줄 끝의 로그 줄 바로 뒤에 spreadsheet 객체를 반환합니다.
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());

  // NEW: Return the spreadsheet object for later use.
  return spreadsheet;
}
  1. 운전 createBigQueryPresentation() 함수. BigQuery와 차트 생성 기능을 논리적으로 분리하는 것도 좋은 방법입니다. 이제 runQuery()createColumnChart()를 모두 호출하여 앱을 구동하는 createBigQueryPresentation() 함수를 만들어 보겠습니다. 추가하는 코드는 다음과 같습니다.
/**
 * Runs a BigQuery query, adds data and a chart in a Sheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  createColumnChart(spreadsheet);
}
  1. 코드 재사용 가능. 위에서 스프레드시트 객체를 반환하고 운전 함수를 만드는 두 가지 중요한 단계를 완료했습니다. 동료가 runQuery()를 재사용하고 URL이 기록되지 않도록 하려면 어떻게 해야 하나요? 일반적인 용도로 runQuery()을 더 쉽게 이해할 수 있도록 하려면 해당 로그 줄을 이동해야 합니다. 이동하기 가장 좋은 장소는 어디인가요? createBigQueryPresentation()번을 맞히셨네요. 정답입니다. 로그 행을 이동한 후에는 다음과 같이 표시됩니다.
/**
 * Runs a BigQuery query, adds data and a chart in a Sheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl()); // MOVED HERE
  createColumnChart(spreadsheet);
}

위의 변경이 적용된 경우 (PROJECT_ID 제외) 이제 bq-sheets-slides.js가 다음과 같이 표시됩니다 (또한 GitHub 저장소의 step2 폴더에 있음).

// Filename for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud API project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into Sheet. You must enable
 * the BigQuery advanced service before you can run this code.
 * @see http://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see http://github.com/googleworkspace/apps-script-samples/blob/main/advanced/bigquery.gs
 *
 * @returns {Sheet} Returns a sheet with results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/sheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BQ job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the new results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to Sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  // Return the spreadsheet object for later use.
  return spreadsheet;
}

/**
 * Uses spreadsheet data to create columnar chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} visualizing the results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first and only) Sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in Sheet is from cell A2 to B11
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on Sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the Sheet using above params.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);
}

/**
 * Runs a BigQuery query, adds data and a chart in a Sheet.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  createColumnChart(spreadsheet);
}

파일을 저장한 다음 코드 편집기의 상단으로 이동하여 runQuery() 대신 createBigQueryPresentation()를 실행합니다. 실행이 완료되면 다른 Google 시트를 가져오지만 이번에는 데이터 옆에 차트가 표시됩니다.

Codelab의 마지막 부분에는 새로운 Google Slides 프레젠테이션을 만들고, 제목 슬라이드에 제목과 부제목을 채우고, 데이터 셀과 차트에 하나씩 새 슬라이드를 두 개 추가합니다.

  1. 슬라이드 자료를 만듭니다. 슬라이드 자료의 모든 작업은 createColumnChart()에서 바로 bq-sheets-slides.js에 추가될 createSlidePresentation()에서 이루어집니다. 먼저 새 슬라이드 자료를 만듭니다. 그런 다음 모든 새 프레젠테이션에서 제공되는 기본 제목 슬라이드에 제목과 부제목을 추가합니다.
/**
 * Create presentation with spreadsheet data & chart
 * @param {Spreadsheet} Spreadsheet with results data
 * @param {EmbeddedChart} Sheets chart to embed on slide
 * @returns {Presentation} Slide deck with results
 */
function createSlidePresentation(spreadsheet, chart) {
  // Create the new presentation.
  var deck = SlidesApp.create(QUERY_NAME);

  // Populate the title slide.
  var [title, subtitle] = deck.getSlides()[0].getPageElements();
  title.asShape().getText().setText(QUERY_NAME);
  subtitle.asShape().getText().setText('via GCP and G Suite APIs:\n' +
    'Google Apps Script, BigQuery, Sheets, Slides');
  1. 데이터 표 추가. createSlidePresentation()의 다음 단계는 Google 시트에서 셀 데이터를 새 슬라이드 자료로 가져오는 것입니다. 다음 코드 스니펫이 함수에 추가됩니다.
  // Data range to copy is from cell A1 to B11
  var START_CELL = 'A1';  // include header row
  var END_CELL = 'B11';
  // Add the table slide and insert an empty table on it of
  // the dimensions of the data range; fails if Sheet empty.
  var tableSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  var sheetValues = spreadsheet.getSheets()[0].getRange(
      START_CELL + ':' + END_CELL).getValues();
  var table = tableSlide.insertTable(sheetValues.length, sheetValues[0].length);

  // Populate the table with spreadsheet data.
  for (var i = 0; i < sheetValues.length; i++) {
    for (var j = 0; j < sheetValues[0].length; j++) {
      table.getCell(i, j).getText().setText(String(sheetValues[i][j]));
    }
  }
  1. 차트 가져오기 createSlidePresentation()의 마지막 단계는 슬라이드를 하나 더 만들고 스프레드시트에서 차트를 가져온 다음 Presentation 객체를 반환하는 것입니다. 다음 최종 스니펫을 함수에 추가합니다.
  // Add a chart slide and insert the chart on it.
  var chartSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  chartSlide.insertSheetsChart(chart);

  // Return the presentation object for later use.
  return deck;
}
  1. 반품 차트 이제 최종 함수가 완료되었으므로 서명을 다시 한 번 살펴보겠습니다. 예. createSlidePresentation()에는 스프레드시트와 차트 객체가 모두 필요합니다. Spreadsheet 객체를 반환하도록 이미 runQuery()를 조정했지만, 이제 차트 (EmbeddedChart) 객체를 반환하도록 createColumnChart()를 비슷하게 변경해야 합니다. 애플리케이션으로 돌아가서 createColumnChart() 끝에 마지막 코드 줄을 추가하여 다음 작업을 수행합니다.
  // NEW: Return chart object for later use
  return chart;
}
  1. createBigQueryPresentation()를 업데이트합니다. createColumnChart()이 차트를 반환하므로 차트를 변수에 저장하고 스프레드시트와 차트를 createSlidePresentation()모두 전달해야 합니다. 새로 생성된 스프레드시트의 URL을 기록하기 때문에 새로운 슬라이드 프레젠테이션의 URL도 기록하게 됩니다. createBigQueryPresentation()을 다음과 같이 업데이트합니다.
/**
 * Runs a BigQuery query, adds data and a chart in a Sheet,
 * and adds the data and chart to a new slide presentation.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  var chart = createColumnChart(spreadsheet); // UPDATED
  var deck = createSlidePresentation(spreadsheet, chart); // NEW
  Logger.log('Results slide deck created: %s', deck.getUrl()); // NEW
}
  1. 저장하고 createBigQueryPresentation()를 다시 실행합니다. 하지만 앱이 실행되기 전에 이제 Google Slides 프레젠테이션을 보고 관리하려면 앱에 사용자로부터 한 가지 이상의 권한이 필요합니다. 이 권한을 부여하면 이전과 같이 실행됩니다.
  2. 이제 생성된 시트 외에도 다음과 같이 슬라이드 3개 (제목, 데이터 표, 데이터 차트)가 포함된 새 Slides 프레젠테이션도 제공됩니다.

수고하셨습니다. 이제 공개 데이터 세트 중 하나를 쿼리하여 Google BigQuery 요청을 실행하여 양측을 활용하는 애플리케이션을 만들고 결과를 저장할 새 Google 시트를 만들고, 방금 검색한 데이터를 기반으로 한 차트를 추가하고, 마지막으로 스프레드시트의 결과와 차트를 포함하는 Google Slides 프레젠테이션을 만듭니다.

기술적으로 수행하신 작업입니다. 엄밀히 말하면 빅데이터 분석에서 벗어나 이해관계자에게 제공할 수 있는 코드(코드 작성)를 모두 자동화했습니다. 이 샘플이 아이디어를 얻어 나만의 프로젝트에 맞게 구성되기를 바랍니다. 이 Codelab을 마치면 이 샘플 앱을 더욱 개선할 수 있는 몇 가지 제안사항을 제공합니다.

최종 작업 (위의 PROJECT_ID 제외)을 다시 변경하면 bq-sheets-slides.js가 다음과 같이 표시됩니다 (GitHub 저장소의 final 폴더에서도 확인 가능).

bq-sheets-slides.js

/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Filename for data results
var QUERY_NAME = "Most common words in all of Shakespeare's works";
// Replace this value with your Google Cloud API project ID
var PROJECT_ID = '';
if (!PROJECT_ID) throw Error('Project ID is required in setup');

/**
 * Runs a BigQuery query; puts results into Sheet. You must enable
 * the BigQuery advanced service before you can run this code.
 * @see http://developers.google.com/apps-script/advanced/bigquery#run_query
 * @see http://github.com/googleworkspace/apps-script-samples/blob/main/advanced/bigquery.gs
 *
 * @returns {Spreadsheet} Returns a spreadsheet with BigQuery results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/spreadsheet
 */
function runQuery() {
  // Replace sample with your own BigQuery query.
  var request = {
    query:
        'SELECT ' +
            'LOWER(word) AS word, ' +
            'SUM(word_count) AS count ' +
        'FROM [bigquery-public-data:samples.shakespeare] ' +
        'GROUP BY word ' +
        'ORDER BY count ' +
        'DESC LIMIT 10'
  };
  var queryResults = BigQuery.Jobs.query(request, PROJECT_ID);
  var jobId = queryResults.jobReference.jobId;

  // Wait for BQ job completion (with exponential backoff).
  var sleepTimeMs = 500;
  while (!queryResults.jobComplete) {
    Utilities.sleep(sleepTimeMs);
    sleepTimeMs *= 2;
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId);
  }

  // Get all results from BigQuery.
  var rows = queryResults.rows;
  while (queryResults.pageToken) {
    queryResults = BigQuery.Jobs.getQueryResults(PROJECT_ID, jobId, {
      pageToken: queryResults.pageToken
    });
    rows = rows.concat(queryResults.rows);
  }

  // Return null if no data returned.
  if (!rows) {
    return Logger.log('No rows returned.');
  }

  // Create the new results spreadsheet.
  var spreadsheet = SpreadsheetApp.create(QUERY_NAME);
  var sheet = spreadsheet.getActiveSheet();

  // Add headers to Sheet.
  var headers = queryResults.schema.fields.map(function(field) {
    return field.name.toUpperCase();
  });
  sheet.appendRow(headers);

  // Append the results.
  var data = new Array(rows.length);
  for (var i = 0; i < rows.length; i++) {
    var cols = rows[i].f;
    data[i] = new Array(cols.length);
    for (var j = 0; j < cols.length; j++) {
      data[i][j] = cols[j].v;
    }
  }

  // Start storing data in row 2, col 1
  var START_ROW = 2;      // skip header row
  var START_COL = 1;
  sheet.getRange(START_ROW, START_COL, rows.length, headers.length).setValues(data);

  // Return the spreadsheet object for later use.
  return spreadsheet;
}

/**
 * Uses spreadsheet data to create columnar chart.
 * @param {Spreadsheet} Spreadsheet containing results data
 * @returns {EmbeddedChart} visualizing the results
 * @see http://developers.google.com/apps-script/reference/spreadsheet/embedded-chart
 */
function createColumnChart(spreadsheet) {
  // Retrieve the populated (first and only) Sheet.
  var sheet = spreadsheet.getSheets()[0];
  // Data range in Sheet is from cell A2 to B11
  var START_CELL = 'A2';  // skip header row
  var END_CELL = 'B11';
  // Place chart on Sheet starting on cell E5.
  var START_ROW = 5;      // row 5
  var START_COL = 5;      // col E
  var OFFSET = 0;

  // Create & place chart on the Sheet using above params.
  var chart = sheet.newChart()
     .setChartType(Charts.ChartType.COLUMN)
     .addRange(sheet.getRange(START_CELL + ':' + END_CELL))
     .setPosition(START_ROW, START_COL, OFFSET, OFFSET)
     .build();
  sheet.insertChart(chart);

  // Return the chart object for later use.
  return chart;
}

/**
 * Create presentation with spreadsheet data & chart
 * @param {Spreadsheet} Spreadsheet with results data
 * @param {EmbeddedChart} Sheets chart to embed on slide
 * @returns {Presentation} Returns a slide deck with results
 * @see http://developers.google.com/apps-script/reference/slides/presentation
 */
function createSlidePresentation(spreadsheet, chart) {
  // Create the new presentation.
  var deck = SlidesApp.create(QUERY_NAME);

  // Populate the title slide.
  var [title, subtitle] = deck.getSlides()[0].getPageElements();
  title.asShape().getText().setText(QUERY_NAME);
  subtitle.asShape().getText().setText('via GCP and G Suite APIs:\n' +
    'Google Apps Script, BigQuery, Sheets, Slides');

  // Data range to copy is from cell A1 to B11
  var START_CELL = 'A1';  // include header row
  var END_CELL = 'B11';
  // Add the table slide and insert an empty table on it of
  // the dimensions of the data range; fails if Sheet empty.
  var tableSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  var sheetValues = spreadsheet.getSheets()[0].getRange(
      START_CELL + ':' + END_CELL).getValues();
  var table = tableSlide.insertTable(sheetValues.length, sheetValues[0].length);

  // Populate the table with spreadsheet data.
  for (var i = 0; i < sheetValues.length; i++) {
    for (var j = 0; j < sheetValues[0].length; j++) {
      table.getCell(i, j).getText().setText(String(sheetValues[i][j]));
    }
  }

  // Add a chart slide and insert the chart on it.
  var chartSlide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
  chartSlide.insertSheetsChart(chart);

  // Return the presentation object for later use.
  return deck;
}

/**
 * Runs a BigQuery query, adds data and a chart in a Sheet,
 * and adds the data and chart to a new slide presentation.
 */
function createBigQueryPresentation() {
  var spreadsheet = runQuery();
  Logger.log('Results spreadsheet created: %s', spreadsheet.getUrl());
  var chart = createColumnChart(spreadsheet);
  var deck = createSlidePresentation(spreadsheet, chart);
  Logger.log('Results slide deck created: %s', deck.getUrl());
}

이 Codelab에서는 아무 역할도 하지 않습니다. 이 Codelab에서는 Apps Script 매니페스트 파일인 appsscript.json에 액세스할 수 있습니다. 코드 편집기 브라우저 탭으로 이동하여 상단 메뉴에서 View > Show manifest file을 선택하여 액세스할 수 있습니다. 이 콘텐츠는 다음과 같이 표시됩니다.

appsscript.json

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {
    "enabledAdvancedServices": [{
      "userSymbol": "BigQuery",
      "serviceId": "bigquery",
      "version": "v2"
    }]
  },
  "exceptionLogging": "STACKDRIVER"
}

매니페스트 파일은 Apps Script에서 애플리케이션에 사용할 수 있는 실행 환경을 파악하기 위해 사용하는 시스템 수준 구성 파일입니다. 매니페스트 파일의 콘텐츠는 이 Codelab에서 다루지 않지만 이 작업의 내용을 이해할 수 있습니다.

다음은 이 Codelab에서 다룬 자료를 자세히 살펴보고 프로그래매틱 방식으로 Google 개발자 도구에 액세스하는 다른 방법을 살펴보는 데 도움이 되는 추가 리소스입니다. Google에서는 이 Codelab을 저장소와 동기화된 상태로 유지하는 것을 목표로 합니다.

이 애플리케이션의 리소스

문서

기타 Codelab

초급

중급

참조 앱

아래에는 이 Codelab에서 빌드한 샘플을 향상하거나 보강할 수 있는 다양한 방법을 소개합니다. 이 목록은 완전하지는 않지만 다음 단계를 위한 아이디어를 얻는 데 도움이 될 것입니다.

  • 애플리케이션. Apps Script가 부과하는 자바스크립트나 제한사항을 사용하여 제약을 받고 싶지 않으신가요? Google BigQuery, Sheets, Slides용 REST API를 사용하는 프로그래밍 언어로 이 애플리케이션을 포팅합니다.
  • BigQuery. 셰익스피어 데이터 세트에 관한 다른 검색어로 실험해 보세요. 원하는 쿼리를 찾을 수도 있습니다. 다른 샘플 쿼리는 기존 Apps Script BigQuery 샘플 앱에서 확인할 수 있습니다.
  • BigQuery. BigQuery의 다른 공개 데이터 세트에서 실험해 보는 것이 나에게 더 의미 있는 데이터 세트를 찾을 수도 있습니다.
  • BigQuery. 앞서 셰익스피어의 작업이나 기타 공개 데이터 표에 대해 시도할 수 있는 다른 쿼리를 언급했고, 이 웹페이지이 웹페이지를 다시 공유하고자 했습니다.
  • 스프레드시트. 다른 차트 유형 실험
  • 스프레드시트 및 BigQuery. 표를 둘러봅니다. 스프레드시트에 엄청난 양의 데이터가 설정되어 있을 수도 있습니다. 2016년 BigQuery팀은 개발자가 시트를 데이터 소스로 사용할 수 있는 기능을 도입했습니다 (자세한 내용은 블로그 게시물 12 참조).
  • 프레젠테이션. 생성된 프레젠테이션에 빅데이터 분석에 연결된 이미지나 기타 애셋과 같은 다른 슬라이드를 추가하세요. 시작하는 데 도움이 되는 Slides 내장 서비스 가이드를 참고하세요.
  • G Suite Apps Script에서 다른 G Suite 또는 Google 내장 서비스(예: Gmail, Google Drive, Calendar, Docs, 지도, 애널리틱스, YouTube 등 기타 고급 서비스 기본 제공 서비스와 고급 서비스에 대한 자세한 내용은 참조 개요를 확인하세요.