1
2
3
4
5
1
2
3
4
5
1
2
3
4
1
2
3
4
// 변수 선언
let message = "Hello World";
const PI = 3.14;
// 함수 정의
function sayHello() {
Logger.log("Hello!");
}
// 조건문
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
2
3
4
1
2
3
function hello() {
// 현재 활성화된 스프레드시트 가져오기
const sheet = SpreadsheetApp.getActiveSheet();
// A1 셀에 텍스트 입력
sheet.getRange("A1").setValue("안녕하세요!");
// 알림 표시
Browser.msgBox("실행 완료!");
}
1
2
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;
}
// 스프레드시트 관련 기본 함수들
const sheet = SpreadsheetApp.getActiveSheet();
sheet.getRange("A1").getValue(); // 값 읽기
sheet.getRange("B1").setValue("테스트"); // 값 쓰기
sheet.getLastRow(); // 마지막 행 번호
sheet.getLastColumn(); // 마지막 열 번호
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
3
function writeData() {
const sheet = SpreadsheetApp.getActiveSheet();
// 데이터 준비
const data = [
["이름", "점수"],
["김철수", 85],
["이영희", 92],
["박지민", 88]
];
// 데이터 쓰기
sheet.getRange(1, 1, data.length, data[0].length)
.setValues(data);
}
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
2
3
4
function basicOperations() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
// 시트 이름 변경
sheet.setName("매출데이터");
// 열 너비 조정
sheet.setColumnWidth(1, 150);
// 행 높이 조정
sheet.setRowHeight(1, 30);
}
1
2
3
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);
}
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");
}
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);
}
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
2
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
2
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
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());
}
function addQuestions() {
const form = FormApp.getActiveForm();
// 객관식 질문
const multipleChoiceItem = form.addMultipleChoiceItem();
multipleChoiceItem.setTitle('전반적인 만족도는 어떠신가요?')
.setChoiceValues(['매우 만족', '만족', '보통', '불만족']);
// 체크박스 질문
const checkboxItem = form.addCheckboxItem();
checkboxItem.setTitle('관심있는 서비스를 모두 선택해주세요')
.setChoiceValues(['웹개발', '앱개발', '데이터분석']);
// 단답형
form.addTextItem()
.setTitle('개선사항을 자유롭게 적어주세요');
}
const form = FormApp.create('프로그램 참가 신청서'); form.setDescription('프로그램 참가를 위한 신청서입니다.') .setCollectEmail(true) .setLimitOneResponsePerUser(true);
const basicInfoSection = form.addSectionHeaderItem()
.setTitle('기본 정보')
.setHelpText('신청자 기본 정보를 입력해 주세요.');
const htmlBody = ` <div style="font-family: Arial, sans-serif; padding: 20px;"> <h2>${respondentName}님, 안녕하세요!</h2> <p>저희 폼에 응답해 주셔서 진심으로 감사드립니다.</p> </div> `; MailApp.sendEmail(respondentEmail, subject, '', options);
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();
}
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(); });
function createDailyTrigger() { ScriptApp.newTrigger('createAndSendDailyReport') .timeBased() .atHour(23) .everyDays(1) .create(); }
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
2
3
4