구글 앱스 스크립트
구글 워크스페이스란?

1

클라우드 기반 생산성 및 협업 도구 모음
구글 워크스페이스는 다양한 업무 도구를 클라우드 환경에서 제공하는 서비스입니다.

2

브라우저 기반 (설치 불필요)
별도의 소프트웨어 설치 없이 웹 브라우저만으로 모든 기능을 사용할 수 있습니다.

3

실시간 협업 지원
여러 사용자가 동시에 문서를 편집하고 공유할 수 있어 팀 협업에 최적화되어 있습니다.

4

자동 저장 기능
작업 내용이 자동으로 저장되어 데이터 손실 걱정 없이 안전하게 작업할 수 있습니다.

5

크로스 플랫폼 지원
다양한 기기와 운영체제에서 동일한 환경으로 작업할 수 있습니다.
주요 애플리케이션 구성
Gmail
기업용 이메일 서비스
Drive
클라우드 스토리지
Docs
문서 작성 도구
Sheets
스프레드시트
Forms
설문/양식 제작
Slides
프레젠테이션
구글 드라이브 핵심 기능
클라우드 스토리지 서비스
구글 드라이브는 클라우드 기반의 파일 저장 및 관리 서비스입니다.
15GB 무료 저장 공간
기본적으로 15GB의 무료 저장 공간을 제공하여 다양한 파일을 저장할 수 있습니다.
실시간 파일 동기화
여러 기기에서 파일을 실시간으로 동기화하여 언제 어디서나 최신 버전에 접근할 수 있습니다.
강력한 검색 기능
구글의 검색 기술을 활용하여 저장된 파일을 빠르고 정확하게 찾을 수 있습니다.
파일 공유 및 협업
다른 사용자와 쉽게 파일을 공유하고 함께 작업할 수 있는 협업 기능을 제공합니다.
구글 설문지 (Google Forms)
온라인 설문조사 도구
구글 설문지는 쉽고 빠르게 온라인 설문조사를 만들고 배포할 수 있는 도구입니다.
핵심 기능
  • 다양한 질문 유형
  • 실시간 응답 분석
  • 스프레드시트 연동
  • 맞춤형 테마 적용
활용 예시
고객 만족도 조사, 이벤트 참가 신청, 퀴즈 제작 등 다양한 목적으로 활용할 수 있습니다.
구글 스프레드시트

1

웹 기반 스프레드시트 도구
구글 스프레드시트는 온라인에서 사용할 수 있는 강력한 스프레드시트 도구입니다.

2

실시간 다중 사용자 협업
여러 사용자가 동시에 같은 스프레드시트를 편집하고 변경 사항을 실시간으로 확인할 수 있습니다.

3

풍부한 내장 함수
다양한 내장 함수를 제공하여 복잡한 데이터 처리와 계산을 쉽게 수행할 수 있습니다.

4

차트 및 그래프 기능
데이터를 시각적으로 표현할 수 있는 다양한 차트와 그래프 옵션을 제공합니다.

5

앱스 스크립트 확장
구글 앱스 스크립트를 통해 사용자 정의 기능을 추가하고 자동화할 수 있습니다.
스프레드시트 활용 예시
데이터 분석 및 시각화
대량의 데이터를 분석하고 인사이트를 도출하는 데 활용할 수 있습니다.
프로젝트 관리
프로젝트 일정, 작업 할당, 진행 상황 등을 관리할 수 있습니다.
예산 및 재무 관리
개인 또는 기업의 예산을 계획하고 재무 상태를 추적할 수 있습니다.
일정 및 리소스 관리
팀 일정을 조율하고 리소스를 효율적으로 할당할 수 있습니다.
구글 앱스 스크립트 소개
구글 워크스페이스 자동화 도구
구글 앱스 스크립트는 구글 워크스페이스 애플리케이션을 자동화하고 확장할 수 있는 강력한 도구입니다.
JavaScript 기반
JavaScript를 기반으로 하여 웹 개발자들이 쉽게 접근할 수 있습니다.
구글 서비스 API 활용
구글의 다양한 서비스 API를 활용하여 확장된 기능을 구현할 수 있습니다.
사용자 정의 기능 개발
특정 업무나 워크플로우에 맞는 맞춤형 기능을 개발할 수 있습니다.
웹 앱 개발 가능
독립적인 웹 애플리케이션을 개발하여 배포할 수 있습니다.
앱스 스크립트 활용 사례
1
이메일 자동 발송
특정 조건에 따라 자동으로 이메일을 발송하는 스크립트를 작성할 수 있습니다.
2
문서 자동 생성
템플릿을 기반으로 다수의 문서를 자동으로 생성하는 기능을 구현할 수 있습니다.
3
데이터 자동 처리
스프레드시트의 데이터를 자동으로 정리, 분석, 변환하는 스크립트를 만들 수 있습니다.
4
맞춤형 기능 추가
구글 워크스페이스 앱에 사용자 정의 메뉴나 사이드바를 추가할 수 있습니다.
5
워크플로우 자동화
복잡한 업무 프로세스를 자동화하여 효율성을 높일 수 있습니다.
워크스페이스 통합 환경
앱 간 원활한 연동
구글 워크스페이스의 다양한 앱들이 서로 유기적으로 연결되어 작동합니다.
통합 검색 기능
모든 앱과 문서에 대해 통합된 검색 기능을 제공하여 필요한 정보를 빠르게 찾을 수 있습니다.
단일 로그인
하나의 계정으로 모든 구글 워크스페이스 서비스에 접근할 수 있습니다.
공유 설정 통합
문서나 파일의 공유 설정을 일관되게 관리할 수 있습니다.
정리 및 Q&A
워크스페이스의 장점
구글 워크스페이스는 다음과 같은 주요 장점을 제공합니다:
클라우드 기반 접근성
언제 어디서나 인터넷 연결만 있으면 작업할 수 있습니다.
실시간 협업
팀원들과 실시간으로 문서를 공유하고 편집할 수 있습니다.
자동화 가능
앱스 스크립트를 통해 반복적인 작업을 자동화할 수 있습니다.
비용 효율성
기존의 오피스 솔루션에 비해 비용 효율적인 선택이 될 수 있습니다.
이것으로 구글 워크스페이스에 대한 소개를 마치겠습니다. 다음 섹션에서는 구글 앱스 스크립트를 더 자세히 살펴보고 실제 활용 방법에 대해 알아보겠습니다.
구글 앱스 스크립트 완벽 마스터
Section 1 - 구글 앱스 스크립트 소개
구글 앱스 스크립트란?

1

클라우드 기반 스크립팅 플랫폼
구글 앱스 스크립트는 구글 서비스를 자동화하는 클라우드 기반 스크립팅 플랫폼입니다.

2

JavaScript 기반
JavaScript 기반의 프로그래밍 언어를 사용합니다.

3

무료 사용
무료로 사용 가능한 강력한 자동화 도구입니다.

4

클라우드 실행
별도의 서버 없이 구글 클라우드에서 실행됩니다.
구글 앱스 스크립트로 할 수 있는 것
스프레드시트 데이터 자동 처리
구글 앱스 스크립트를 사용하여 스프레드시트의 데이터를 자동으로 처리할 수 있습니다.
구글 폼 응답 자동화
구글 폼의 응답을 자동으로 처리하고 관리할 수 있습니다.
이메일 자동 발송
이메일을 자동으로 작성하고 발송할 수 있습니다.
문서 자동 생성
필요한 문서를 자동으로 생성할 수 있습니다.
지원되는 구글 서비스
Google Sheets (스프레드시트)
데이터 관리와 분석을 위한 강력한 도구입니다.
Google Docs (문서)
문서 작성과 협업을 위한 플랫폼입니다.
Google Forms (설문지)
설문조사와 데이터 수집을 위한 도구입니다.
Google Calendar (캘린더)
일정 관리를 위한 서비스입니다.
이 외에도 Gmail (이메일)과 Google Drive (드라이브)를 지원합니다.
개발 환경 설정 (1)

1

Chrome 브라우저 접속
구글 앱스 스크립트 개발을 위해 Chrome 브라우저에 접속합니다.

2

Google 계정 로그인
개발을 시작하기 전 Google 계정에 로그인합니다.

3

구글 드라이브 접속
구글 드라이브에 접속하여 작업 환경을 준비합니다.

4

새 스프레드시트 생성
새로운 스프레드시트를 생성하여 작업을 시작합니다.
개발 환경 설정 (2)
1
스크립트 편집기 열기
1. 도구 메뉴 클릭
2
스크립트 편집기 선택
2. 확장 프로그램 > App Script 선택
3
새 프로젝트
새 프로젝트
JavaScript 기초 문법 (1)
변수 선언
// 변수 선언 let message = "Hello World"; const PI = 3.14;
함수 정의
// 함수 정의 function sayHello() { Logger.log("Hello!"); }
JavaScript 기초 문법 (2)
조건문
// 조건문 if (score >= 90) { Logger.log("A grade"); } else { Logger.log("Try again"); }
반복문
// 반복문 for (let i = 0; i < 5; i++) { Logger.log(i); }
첫 번째 스크립트 실행하기
function myFirstScript() { const sheet = SpreadsheetApp.getActiveSheet(); sheet.getRange("A1").setValue("My First Script!"); Browser.msgBox("완료되었습니다!"); }
주요 개발 도구
스크립트 편집기 인터페이스와 실행 버튼
스크립트를 작성하고 실행할 수 있는 주요 인터페이스입니다.
디버깅 도구와 로그 보기
코드의 오류를 찾고 실행 과정을 추적할 수 있는 도구입니다.
프로젝트 설정
스크립트 프로젝트의 다양한 설정을 관리할 수 있는 패널입니다.
실습 과제
실습 1: Hello World 출력하기

1

1. 새 스크립트 프로젝트 생성
새로운 구글 앱스 스크립트 프로젝트를 시작합니다.

2

2. 기본 함수 작성
"Hello World"를 출력하는 간단한 함수를 작성합니다.

3

3. 스프레드시트에 텍스트 입력
작성한 함수를 사용하여 스프레드시트에 텍스트를 입력합니다.

4

4. 실행 및 결과 확인
스크립트를 실행하고 결과를 확인합니다.
구글 앱스 스크립트 완벽 마스터
Section 2 - 시작하기
"실전 예제로 배우는 기초 활용법"
첫 스크립트 만들기 (1)

1

1. script.google.com 접속
구글 앱스 스크립트 공식 웹사이트에 접속합니다.

2

2. 새 프로젝트 버튼 클릭
메인 화면에서 새 프로젝트 버튼을 찾아 클릭합니다.

3

3. 프로젝트 이름 설정
새로 생성된 프로젝트의 이름을 원하는 대로 설정합니다.
첫 스크립트 만들기 (2)
함수 정의
function hello() { ... }
스프레드시트 접근
const sheet = SpreadsheetApp.getActiveSheet();
셀 값 설정
sheet.getRange("A1").setValue("안녕하세요!");
알림 표시
Browser.msgBox("실행 완료!");
function hello() { // 현재 활성화된 스프레드시트 가져오기 const sheet = SpreadsheetApp.getActiveSheet(); // A1 셀에 텍스트 입력 sheet.getRange("A1").setValue("안녕하세요!"); // 알림 표시 Browser.msgBox("실행 완료!"); }
스크립트 편집기 주요 기능
파일 메뉴
새 프로젝트 생성, 저장, 버전 관리 등
편집 메뉴
복사, 붙여넣기, 찾기/바꾸기 등
보기 메뉴
실행 로그, 프로젝트 매니페스트 등
실행 메뉴
함수 실행, 디버그 등
디버깅 방법 (1)

1

Logger.log() 사용
코드 실행 중 중요한 지점에 로그를 남겨 진행 상황을 확인할 수 있습니다.

2

변수 값 확인
Logger.log()를 사용하여 특정 변수의 값을 출력하고 확인할 수 있습니다.

3

실행 흐름 추적
함수의 시작과 끝, 반복문의 각 단계 등에 로그를 남겨 실행 흐름을 추적할 수 있습니다.
function calculateSum() { Logger.log("함수 시작"); // 디버깅 로그 const numbers = [1, 2, 3, 4, 5]; let sum = 0; for (let num of numbers) { Logger.log("현재 숫자: " + num); // 진행상황 확인 sum += num; } Logger.log("최종 합계: " + sum); // 결과 확인 return sum; }
디버깅 방법 (2)
중단점(Breakpoint) 설정
코드 실행을 특정 지점에서 멈추고 상태를 확인할 수 있습니다.
변수 상태 확인
중단점에서 각 변수의 현재 값을 확인할 수 있습니다.
스텝 실행
코드를 한 줄씩 실행하며 상태 변화를 관찰할 수 있습니다.
로그 확인
실행 로그를 통해 전체적인 실행 흐름을 파악할 수 있습니다.
기본 함수와 메서드
// 스프레드시트 관련 기본 함수들 const sheet = SpreadsheetApp.getActiveSheet(); sheet.getRange("A1").getValue(); // 값 읽기 sheet.getRange("B1").setValue("테스트"); // 값 쓰기 sheet.getLastRow(); // 마지막 행 번호 sheet.getLastColumn(); // 마지막 열 번호
실전 예제 - 데이터 읽기
1
스프레드시트 접근
SpreadsheetApp.getActiveSheet()를 사용하여 현재 활성화된 시트에 접근합니다.
2
데이터 범위 설정
getRange() 메서드를 사용하여 읽을 데이터의 범위를 지정합니다.
3
데이터 읽기
getValues() 메서드로 지정된 범위의 데이터를 2차원 배열로 읽어옵니다.
4
데이터 처리
읽어온 데이터를 반복문을 통해 처리하고 로그에 출력합니다.
function readData() { const sheet = SpreadsheetApp.getActiveSheet(); const lastRow = sheet.getLastRow(); // A1:B10 범위의 데이터 읽기 const data = sheet.getRange("A1:B" + lastRow).getValues(); // 데이터 출력 for (let row of data) { Logger.log(row[0] + ": " + row[1]); } }
실전 예제 - 데이터 쓰기

1

데이터 준비
쓰고자 하는 데이터를 2차원 배열로 준비합니다.

2

범위 지정
getRange() 메서드로 데이터를 쓸 범위를 지정합니다.

3

데이터 쓰기
setValues() 메서드를 사용하여 준비된 데이터를 지정된 범위에 씁니다.
function writeData() { const sheet = SpreadsheetApp.getActiveSheet(); // 데이터 준비 const data = [ ["이름", "점수"], ["김철수", 85], ["이영희", 92], ["박지민", 88] ]; // 데이터 쓰기 sheet.getRange(1, 1, data.length, data[0].length) .setValues(data); }
오류 처리하기
try-catch 구문
오류가 발생할 수 있는 코드를 try 블록으로 감싸고, catch 블록에서 오류를 처리합니다.
오류 메시지 표시
Browser.msgBox()를 사용하여 사용자에게 오류 메시지를 표시합니다.
로그 기록
Logger.log()를 사용하여 오류의 상세 정보를 로그에 기록합니다.
예외 발생
throw 키워드를 사용하여 필요한 경우 직접 예외를 발생시킬 수 있습니다.
function safeFunction() { try { const sheet = SpreadsheetApp.getActiveSheet(); const value = sheet.getRange("A1").getValue(); if (!value) { throw new Error("값이 없습니다!"); } // 처리 로직 } catch (error) { Browser.msgBox("오류 발생: " + error.message); Logger.log("오류 상세: " + error.stack); } }
실습 과제

1

데이터 입력
A열에 이름, B열에 점수를 입력합니다.

2

평균 계산
입력된 점수들의 평균을 계산합니다.

3

결과 출력
계산된 평균을 C1 셀에 출력합니다.

4

오류 처리
데이터 입력 오류나 계산 오류에 대한 처리를 포함합니다.
과제: 간단한 성적 처리 프로그램 만들기
  1. A열에 이름, B열에 점수 입력
  1. 점수 평균 계산
  1. 결과를 C1 셀에 출력
  1. 오류 처리 포함
구글 앱스 스크립트 완벽 마스터
Section 3 - 스프레드시트 자동화
"실무에서 바로 사용하는 자동화 기법"
스프레드시트 기본 조작
시트 이름 변경
sheet.setName("매출데이터");
열 너비 조정
sheet.setColumnWidth(1, 150);
행 높이 조정
sheet.setRowHeight(1, 30);
function basicOperations() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const sheet = ss.getActiveSheet(); // 시트 이름 변경 sheet.setName("매출데이터"); // 열 너비 조정 sheet.setColumnWidth(1, 150); // 행 높이 조정 sheet.setRowHeight(1, 30); }
데이터 읽기 고급 기술

1

전체 데이터 범위 가져오기
const dataRange = sheet.getDataRange(); const values = dataRange.getValues();

2

특정 열만 읽기
const columnB = sheet.getRange("B:B").getValues();

3

조건부 데이터 읽기
const filteredData = values.filter(row => row[1] > 1000); Logger.log(filteredData);
function advancedReading() { const sheet = SpreadsheetApp.getActiveSheet(); // 전체 데이터 범위 가져오기 const dataRange = sheet.getDataRange(); const values = dataRange.getValues(); // 특정 열만 읽기 const columnB = sheet.getRange("B:B").getValues(); // 조건부 데이터 읽기 const filteredData = values.filter(row => row[1] > 1000); Logger.log(filteredData); }
데이터 쓰기 고급 기술
1
배열 데이터 준비
const data = [ ["부서", "매출", "지출", "이익"], ["영업팀", 5000, 3000, "=B2-C2"], ["마케팅팀", 4500, 2800, "=B3-C3"] ];
2
데이터 쓰기
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
3
서식 적용
sheet.getRange("B2:B3").setNumberFormat("#,##0");
function advancedWriting() { const sheet = SpreadsheetApp.getActiveSheet(); // 배열 데이터 한 번에 쓰기 const data = [ ["부서", "매출", "지출", "이익"], ["영업팀", 5000, 3000, "=B2-C2"], ["마케팅팀", 4500, 2800, "=B3-C3"] ]; // 수식 포함하여 데이터 쓰기 sheet.getRange(1, 1, data.length, data[0].length) .setValues(data); // 서식 적용 sheet.getRange("B2:B3").setNumberFormat("#,##0"); }
셀 서식 설정
글꼴 설정
range.setFontFamily("Arial"); range.setFontSize(12);
정렬 설정
range.setHorizontalAlignment("center");
배경색 설정
sheet.getRange("A1:D1").setBackground("#f3f3f3");
테두리 설정
range.setBorder(true, true, true, true, true, true);
function formatCells() { const sheet = SpreadsheetApp.getActiveSheet(); const range = sheet.getRange("A1:D4"); // 글꼴 설정 range.setFontFamily("Arial"); range.setFontSize(12); // 정렬 설정 range.setHorizontalAlignment("center"); // 배경색 설정 sheet.getRange("A1:D1").setBackground("#f3f3f3"); // 테두리 설정 range.setBorder(true, true, true, true, true, true); }
시트 관리 기능
새 시트 만들기
const newSheet = ss.insertSheet("보고서");
시트 복사하기
const copiedSheet = ss.getActiveSheet().copyTo(ss); copiedSheet.setName("복사본");
시트 보호하기
const protection = newSheet.protect(); protection.setDescription("편집 금지");
function sheetManagement() { const ss = SpreadsheetApp.getActiveSpreadsheet(); // 새 시트 만들기 const newSheet = ss.insertSheet("보고서"); // 시트 복사하기 const copiedSheet = ss.getActiveSheet().copyTo(ss); copiedSheet.setName("복사본"); // 시트 보호하기 const protection = newSheet.protect(); protection.setDescription("편집 금지"); }
데이터 필터링과 정렬

1

정렬 설정
range.sort([ {column: 2, ascending: false}, {column: 1, ascending: true} ]);

2

필터 설정
const filter = range.createFilter();
function filterAndSort() { const sheet = SpreadsheetApp.getActiveSheet(); const range = sheet.getDataRange(); // 정렬 range.sort([ {column: 2, ascending: false}, // B열 기준 내림차순 {column: 1, ascending: true} // A열 기준 오름차순 ]); // 필터 설정 const filter = range.createFilter(); }
조건부 서식 설정

1

조건부 서식 규칙 설정
const rule = SpreadsheetApp.newConditionalFormatRule() .whenNumberGreaterThan(5000) .setBackground("#93c47d") .setRanges([range]) .build();

2

규칙 적용
const rules = sheet.getConditionalFormatRules(); rules.push(rule); sheet.setConditionalFormatRules(rules);
function conditionalFormatting() { const sheet = SpreadsheetApp.getActiveSheet(); const range = sheet.getRange("B2:B10"); // 조건부 서식 규칙 설정 const rule = SpreadsheetApp.newConditionalFormatRule() .whenNumberGreaterThan(5000) .setBackground("#93c47d") .setRanges([range]) .build(); // 규칙 적용 const rules = sheet.getConditionalFormatRules(); rules.push(rule); sheet.setConditionalFormatRules(rules); }
실전 예제 - 일일 보고서 자동화

1

createDailyReport(): 메인 함수로, 보고서 생성을 총괄합니다.
데이터가 없는 경우를 위한 샘플 데이터를 생성합니다.
원본 데이터를 가져와 처리합니다.

2

calculateSummary(): 데이터 분석 함수입니다.
제품별 판매 수량과 금액을 집계합니다.
전체 합계를 계산합니다.

3

createReportLayout(): 보고서 레이아웃을 생성합니다.
보고서 제목과 날짜를 입력합니다.
제품별 판매 현황을 표시합니다.
합계 행을 추가합니다.

4

applyReportFormatting(): 보고서 서식을 적용합니다.
제목, 헤더, 데이터 영역의 서식을 지정합니다.
테두리와 열 너비를 조정합니다.
function createDailyReport() { const ss = SpreadsheetApp.getActiveSpreadsheet(); // "원본데이터" 시트 확인 및 생성 let sourceSheet = ss.getSheetByName("원본데이터"); if (!sourceSheet) { sourceSheet = ss.insertSheet("원본데이터"); // 샘플 데이터 생성 const sampleData = [ ['날짜', '제품명', '수량', '단가', '금액'], [new Date(), '제품A', 10, 1000, 10000], [new Date(), '제품B', 5, 2000, 10000], [new Date(), '제품C', 8, 1500, 12000], [new Date(), '제품A', 12, 1000, 12000], [new Date(), '제품B', 6, 2000, 12000] ]; sourceSheet.getRange(1, 1, sampleData.length, sampleData[0].length).setValues(sampleData); } // 새로운 보고서 시트 생성 const reportSheet = ss.insertSheet("일일보고서_" + new Date().toLocaleDateString()); // 데이터 가져오기 const data = sourceSheet.getDataRange().getValues(); // 데이터 처리 및 보고서 작성 const summary = calculateSummary(data); createReportLayout(reportSheet, summary); applyReportFormatting(reportSheet); } function calculateSummary(data) { // 헤더를 제외한 실제 데이터만 처리 const realData = data.slice(1); // 제품별 판매 현황 집계 const productSummary = {}; realData.forEach(row => { const productName = row[1]; // 제품명 const quantity = row[2]; // 수량 const amount = row[4]; // 금액 if (!productSummary[productName]) { productSummary[productName] = { totalQuantity: 0, totalAmount: 0 }; } productSummary[productName].totalQuantity += quantity; productSummary[productName].totalAmount += amount; }); // 전체 합계 계산 const totalSummary = { totalQuantity: 0, totalAmount: 0 }; Object.values(productSummary).forEach(summary => { totalSummary.totalQuantity += summary.totalQuantity; totalSummary.totalAmount += summary.totalAmount; }); return { productSummary: productSummary, totalSummary: totalSummary }; } function createReportLayout(sheet, summary) { // 보고서 제목 sheet.getRange("A1").setValue("일일 판매 보고서"); sheet.getRange("A2").setValue("작성일자: " + new Date().toLocaleDateString()); // 제품별 현황 헤더 sheet.getRange("A4").setValue("제품별 판매 현황"); sheet.getRange("A5:D5").setValues([["제품명", "판매수량", "판매금액", "비고"]]); // 제품별 데이터 입력 let row = 6; for (const [productName, data] of Object.entries(summary.productSummary)) { sheet.getRange(row, 1, 1, 4).setValues([[ productName, data.totalQuantity, data.totalAmount, "" ]]); row++; } // 합계 행 추가 sheet.getRange(row, 1, 1, 4).setValues([[ "합계", summary.totalSummary.totalQuantity, summary.totalSummary.totalAmount, "" ]]); } function applyReportFormatting(sheet) { // 제목 서식 sheet.getRange("A1").setFontSize(14).setFontWeight("bold"); // 헤더 서식 sheet.getRange("A4").setFontWeight("bold"); const headerRange = sheet.getRange("A5:D5"); headerRange.setBackground("#f3f3f3") .setFontWeight("bold") .setBorder(true, true, true, true, true, true); // 데이터 영역 테두리 const dataLastRow = sheet.getLastRow(); const dataRange = sheet.getRange(6, 1, dataLastRow - 5, 4); dataRange.setBorder(true, true, true, true, true, true); // 열 너비 자동 조정 sheet.autoResizeColumns(1, 4); }
실습 과제
프로젝트: 매출 데이터 자동 분석 시스템
1. 일별 매출 데이터 정리
2. 부서별 실적 계산
매출 데이터를 기반으로 각 부서의 실적을 자동으로 계산합니다.
3. 조건부 서식으로 목표달성 표시
목표 달성 여부를 시각적으로 표시하는 조건부 서식을 적용합니다.
4. 자동 보고서 생성
처리된 데이터를 바탕으로 일일 자동 보고서를 생성합니다.
구글 앱스 스크립트 완벽 마스터
Section 4 - 구글 폼 연동 자동화
구글 폼 기본 설정

1

새 폼 생성
function createCustomForm() 함수를 사용하여 '고객 만족도 설문'이라는 이름의 새 폼을 생성합니다.

2

기본 설정
form.setDescription()을 사용하여 설명을 추가하고, form.setCollectEmail(true)로 이메일 수집을 설정하며, form.setAllowResponseEdits(true)로 응답 수정을 허용합니다.

3

응답 시트 연결
SpreadsheetApp.create()로 새 스프레드시트를 만들고, form.setDestination()을 사용하여 폼 응답을 해당 스프레드시트로 연결합니다.
function createCustomForm() { // 새 폼 생성 const form = FormApp.create('고객 만족도 설문'); // 기본 설정 form.setDescription('고객님의 소중한 의견을 들려주세요.'); form.setCollectEmail(true); form.setAllowResponseEdits(true); // 응답 시트 연결 const ss = SpreadsheetApp.create('설문 응답'); form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId()); }
다양한 질문 유형 추가
객관식 질문
form.addMultipleChoiceItem()을 사용하여 '전반적인 만족도는 어떠신가요?'라는 객관식 질문을 추가합니다.
체크박스 질문
form.addCheckboxItem()으로 '관심있는 서비스를 모두 선택해주세요'라는 체크박스 질문을 만듭니다.
단답형
form.addTextItem()을 사용하여 '개선사항을 자유롭게 적어주세요'라는 단답형 질문을 추가합니다.
function addQuestions() { const form = FormApp.getActiveForm(); // 객관식 질문 const multipleChoiceItem = form.addMultipleChoiceItem(); multipleChoiceItem.setTitle('전반적인 만족도는 어떠신가요?') .setChoiceValues(['매우 만족', '만족', '보통', '불만족']); // 체크박스 질문 const checkboxItem = form.addCheckboxItem(); checkboxItem.setTitle('관심있는 서비스를 모두 선택해주세요') .setChoiceValues(['웹개발', '앱개발', '데이터분석']); // 단답형 form.addTextItem() .setTitle('개선사항을 자유롭게 적어주세요'); }
자동 이메일 발송
프로그램 참가 신청 시스템 개요
주요 기능
  1. 폼 생성 및 구성
const form = FormApp.create('프로그램 참가 신청서'); form.setDescription('프로그램 참가를 위한 신청서입니다.') .setCollectEmail(true) .setLimitOneResponsePerUser(true);
  1. 섹션 구성
const basicInfoSection = form.addSectionHeaderItem() .setTitle('기본 정보') .setHelpText('신청자 기본 정보를 입력해 주세요.');
  • 기본 정보 섹션:
  • 프로그램 선택 섹션
  • 추가 정보 섹션
폼 특징
  • 이메일 수집 활성화
  • 사용자당 1회 응답 제한
  • 응답 수정 가능
  • 개인정보 수집 동의 필수
폼 제출 후 프로세스
  1. 자동 이메일 발송
const htmlBody = ` <div style="font-family: Arial, sans-serif; padding: 20px;"> <h2>${respondentName}님, 안녕하세요!</h2> <p>저희 폼에 응답해 주셔서 진심으로 감사드립니다.</p> </div> `; MailApp.sendEmail(respondentEmail, subject, '', options);
  1. 데이터 관리
const logSheet = ss.getSheetByName('이메일발송로그') || ss.insertSheet('이메일발송로그'); logSheet.appendRow([ new Date(), respondentEmail, respondentName, '발송 성공' ]);
전체 시스템 코드
function createRegistrationForm() { // 새 폼 생성 const form = FormApp.create('프로그램 참가 신청서'); // 폼 설정 form.setDescription('프로그램 참가를 위한 신청서입니다. 모든 항목을 정확히 작성해주세요.') .setCollectEmail(true) .setLimitOneResponsePerUser(true) .setAllowResponseEdits(true); // 1. 기본 정보 섹션 const basicInfoSection = form.addSectionHeaderItem() .setTitle('기본 정보') .setHelpText('신청자 기본 정보를 입력해 주세요.'); // 이름 form.addTextItem() .setTitle('이름') .setRequired(true); // 연락처 form.addTextItem() .setTitle('연락처') .setHelpText('"-" 없이 숫자만 입력해주세요.') .setRequired(true); // 생년월일 form.addTextItem() .setTitle('생년월일') .setHelpText('YYYYMMDD 형식으로 입력해주세요. (예: 19901231)') .setRequired(true); // 2. 프로그램 선택 섹션 const programSection = form.addSectionHeaderItem() .setTitle('프로그램 선택') .setHelpText('참가를 희망하는 프로그램을 선택해 주세요.'); // 프로그램 종류 form.addMultipleChoiceItem() .setTitle('희망 프로그램') .setChoiceValues([ 'A 프로그램 (오전 9:00-12:00)', 'B 프로그램 (오후 2:00-5:00)', 'C 프로그램 (저녁 7:00-9:00)' ]) .setRequired(true); // 참가 날짜 form.addDateItem() .setTitle('희망 참가 날짜') .setRequired(true); // 3. 추가 정보 섹션 const additionalSection = form.addSectionHeaderItem() .setTitle('추가 정보') .setHelpText('프로그램 참가에 필요한 추가 정보를 입력해 주세요.'); // 경험 여부 form.addMultipleChoiceItem() .setTitle('유사 프로그램 참가 경험') .setChoiceValues([ '있음', '없음' ]) .setRequired(true); // 특이사항 form.addParagraphTextItem() .setTitle('특이사항') .setHelpText('알레르기, 기타 특이사항이 있다면 작성해 주세요.'); // 개인정보 동의 form.addCheckboxItem() .setTitle('개인정보 수집 및 이용 동의') .setChoiceValues([ '본인은 개인정보 수집 및 이용에 동의합니다.' ]) .setRequired(true); // 제출 확인 메시지 설정 form.setConfirmationMessage('신청이 완료되었습니다. 확인 이메일을 발송해드리겠습니다.'); // 응답을 스프레드시트에 연결 const ss = SpreadsheetApp.create('프로그램 참가 신청 응답'); form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId()); Logger.log('폼 URL: ' + form.getPublishedUrl()); Logger.log('수정 URL: ' + form.getEditUrl()); return form; } function onFormSubmit(e) { // 폼 응답 데이터 가져오기 const formResponse = e.response; const itemResponses = formResponse.getItemResponses(); // 응답자 이메일 주소 가져오기 const respondentEmail = formResponse.getRespondentEmail(); // 응답자 이름 찾기 (폼에 '이름' 질문이 있다고 가정) let respondentName = "고객"; itemResponses.forEach(function(item) { const title = item.getItem().getTitle(); if (title.includes('이름')) { respondentName = item.getResponse(); } }); // 이메일 제목 const subject = `${respondentName}님, 폼 제출 감사드립니다`; // 이메일 본문 작성 const htmlBody = ` <div style="font-family: Arial, sans-serif; padding: 20px;"> <h2>${respondentName}님, 안녕하세요!</h2> <p>저희 폼에 응답해 주셔서 진심으로 감사드립니다.</p> <p>귀하의 소중한 의견을 잘 검토하여 반영하도록 하겠습니다.</p> <br> <p>좋은 하루 보내세요!</p> <br> <p style="color: #666;">본 메일은 자동발송되었습니다.</p> </div> `; // 이메일 옵션 설정 const options = { htmlBody: htmlBody, name: '폼 관리자', replyTo: Session.getEffectiveUser().getEmail() }; try { // 이메일 발송 if (respondentEmail) { MailApp.sendEmail(respondentEmail, subject, '', options); // 로그 기록 (스프레드시트에 기록하기) const form = FormApp.getActiveForm(); const ss = SpreadsheetApp.openById(form.getDestinationId()); const logSheet = ss.getSheetByName('이메일발송로그') || ss.insertSheet('이메일발송로그'); logSheet.appendRow([ new Date(), respondentEmail, respondentName, '발송 성공' ]); } } catch (error) { // 오류 발생 시 관리자에게 알림 const adminEmail = Session.getEffectiveUser().getEmail(); MailApp.sendEmail( adminEmail, '폼 자동 응답 이메일 발송 오류', `오류 발생: ${error.toString()}\n응답자: ${respondentName} (${respondentEmail})` ); } } // 트리거 설정 함수 function createFormTrigger() { const form = FormApp.getActiveForm(); ScriptApp.newTrigger('onFormSubmit') .forForm(form) .onFormSubmit() .create(); }
PDF 보고서 자동 생성
주요 기능
  1. 자동 통계 생성
function createAndSendDailyReport() { const form = FormApp.getActiveForm(); const ss = SpreadsheetApp.openById(form.getDestinationId()); // 오늘 날짜 기준으로 데이터 필터링 const today = new Date(); const todayResponses = data.filter(row => { const responseDate = new Date(row[0]); return responseDate.getTime() === today.getTime(); });
보고서 구성요소
  1. 데이터 집계
  • 일일 총 신청 건수
  • 프로그램별 신청 현황
  • 날짜별 통계
  1. 자동화 설정
function createDailyTrigger() { ScriptApp.newTrigger('createAndSendDailyReport') .timeBased() .atHour(23) .everyDays(1) .create(); }
PDF 보고서 상세
보고서 디자인
let htmlContent = ` <html> <head> <style> body { font-family: Arial, sans-serif; } table { border-collapse: collapse; width: 100%; } th { background-color: #f2f2f2; } .header { background-color: #4CAF50; color: white; } </style> </head> <body> <div class="header"> <h1>일일 프로그램 신청 현황 보고서</h1> <h2>${reportDate}</h2> </div> </body> </html> `;
자동 이메일 발송
MailApp.sendEmail({ to: adminEmail, subject: `[일일보고서] 프로그램 신청 현황 (${reportDate})`, attachments: [pdf.setName(`프로그램_신청현황_${reportDate}.pdf`)] });
전체 시스템 코드
// 일일 통계 보고서 생성 및 전송 함수 function createAndSendDailyReport() { const form = FormApp.getActiveForm(); const ss = SpreadsheetApp.openById(form.getDestinationId()); const responseSheet = ss.getSheets()[0]; // 오늘 날짜 기준으로 데이터 필터링 const today = new Date(); today.setHours(0,0,0,0); const responses = responseSheet.getDataRange().getValues(); const headers = responses[0]; const data = responses.slice(1); // 프로그램별 신청 현황 집계 const programStats = {}; todayResponses.forEach(row => { const program = row[programColumnIndex]; programStats[program] = (programStats[program] || 0) + 1; }); // HTML 보고서 생성 const reportDate = today.toLocaleDateString('ko-KR'); let htmlContent = ` <html> <head> <style> body { font-family: Arial, sans-serif; } table { border-collapse: collapse; width: 100%; } th { background-color: #f2f2f2; } </style> </head> <body> <div class="header"> <h1>일일 프로그램 신청 현황 보고서</h1> </div> </body> </html> `; // PDF 변환 및 이메일 발송 const blob = Utilities.newBlob(htmlContent, 'text/html', 'report.html'); const pdf = blob.getAs('application/pdf'); MailApp.sendEmail({ to: adminEmail, subject: `[일일보고서] 프로그램 신청 현황 (${reportDate})`, attachments: [pdf] }); } // 트리거 설정 function createDailyTrigger() { ScriptApp.newTrigger('createAndSendDailyReport') .timeBased() .atHour(23) .everyDays(1) .create(); }
주요 특징
  1. 자동화된 일일 보고서
  • 매일 오후 11시 자동 생성
  • PDF 형식으로 변환
  • 이메일 자동 발송
  1. 데이터 시각화
  • 테이블 형식의 통계
  • 스타일이 적용된 전문적인 디자인
  • 직관적인 데이터 표현
  1. 유지보수 용이성
  • 모듈화된 코드 구조
  • 확장 가능한 리포트 템플릿
  • 간편한 트리거 관리
실습 프로젝트

1

프로젝트: 완전 자동화된 고객 설문 시스템 구축
1. 맞춤형 설문 폼 생성

2

자동화 단계
2. 자동 응답 처리

3

고객 관리
3. 감사 이메일 발송

4

데이터 분석
4. 일간 분석 보고서 생성