출결 현황 관리

관리자
← 메인으로

관리자 인증

비밀번호를 입력하세요

비밀번호가 틀렸습니다

카테고리 추가

카테고리 목록

순서이름유형서명록 URL순서 변경편집삭제
카테고리가 없습니다

강좌 관리

ID강좌명지도교사학년장소삭제
카테고리를 선택하세요

1인1기 서명록 설정

  1. Google 스프레드시트를 생성합니다
  2. 아래 헤더로 시트를 구성합니다:
    고유번호강좌 일자요일성명강좌명강좌 시간보강 날짜
    12026-03-04홍길동기타교실(13:00~14:00)
  3. 고유번호는 강좌목록의 순번과 일치해야 합니다
  4. 스프레드시트에서 확장 프로그램 > Apps Script를 클릭합니다
  5. 기존 코드를 모두 지우고, 아래 코드를 붙여넣습니다:
    function doGet(e) { var cache = CacheService.getScriptCache(); var cached = cache.get('schedule_json'); if (cached) { return ContentService.createTextOutput(cached).setMimeType(ContentService.MimeType.JSON); } var ss = SpreadsheetApp.getActiveSpreadsheet(); var schedule = []; ss.getSheets().forEach(function(sheet) { var data = sheet.getDataRange().getValues(); var headerIdx = -1; for (var i = 0; i < Math.min(5, data.length); i++) { if (String(data[i][0]).trim() === '고유번호') { headerIdx = i; break; } } if (headerIdx === -1) return; var headers = data[headerIdx].map(function(h) { return String(h).trim(); }); var ci = { uid: headers.indexOf('고유번호'), date: headers.indexOf('강좌 일자'), day: headers.indexOf('요일'), teacher: headers.indexOf('성명'), course: headers.indexOf('강좌명'), time: headers.indexOf('강좌 시간'), makeup: headers.indexOf('보강 날짜') }; var cur = { uid: null, teacher: '', course: '', time: '' }; for (var i = headerIdx + 1; i < data.length; i++) { var row = data[i]; var uid = ci.uid >= 0 ? row[ci.uid] : null; var dateVal = ci.date >= 0 ? row[ci.date] : null; var teacher = ci.teacher >= 0 ? row[ci.teacher] : ''; var course = ci.course >= 0 ? row[ci.course] : ''; var timeVal = ci.time >= 0 ? row[ci.time] : ''; var makeup = ci.makeup >= 0 ? row[ci.makeup] : null; if (uid !== '' && uid !== null && uid !== undefined) { cur.uid = Number(uid); } if (teacher) cur.teacher = String(teacher).trim(); if (course) cur.course = String(course).trim(); if (timeVal) cur.time = String(timeVal).trim(); var dateStr = toDateStr_(dateVal); if (!dateStr) continue; if (!cur.uid || !cur.course) continue; var timeMatch = cur.time.match(/\(([^)]+)\)/); schedule.push({ uid: cur.uid, course: cur.course, teacher: cur.teacher, date: dateStr, day: String(ci.day >= 0 ? row[ci.day] || '' : '').trim(), time: timeMatch ? timeMatch[1] : '', makeup: toDateStr_(makeup) }); } }); var output = JSON.stringify({ schedule: schedule, count: schedule.length, updatedAt: new Date().toISOString() }); cache.put('schedule_json', output, 300); return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JSON); } function toDateStr_(val) { if (!val) return null; if (val instanceof Date && !isNaN(val)) { return Utilities.formatDate(val, Session.getScriptTimeZone(), 'yyyy-MM-dd'); } var s = String(val).trim(); var m = s.match(/^(\d{2})-(\d{2})-(\d{2})$/); if (m) return '20' + m[1] + '-' + m[2] + '-' + m[3]; m = s.match(/^(\d{4})-(\d{2})-(\d{2})/); if (m) return m[1] + '-' + m[2] + '-' + m[3]; m = s.match(/^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})/); if (m) return m[1] + '-' + ('0' + m[2]).slice(-2) + '-' + ('0' + m[3]).slice(-2); return null; }
  6. 배포 > 새 배포 > 유형: 웹 앱 > 액세스 권한: 모든 사용자로 배포합니다
  7. 생성된 URL을 복사하여 카테고리 관리 탭에서 해당 1인1기 카테고리의 서명록 URL에 입력합니다

방과후학교 서명록 설정

  1. 방과후학교 강사 서명록 Google 스프레드시트를 준비합니다
  2. 각 학과별 시트에 다음 헤더가 포함되어야 합니다:
    고유번호강좌 일자교시강좌 시간직위성명학년강좌명서명비고
    13월 18일(수)ET16:50~19:10교사홍길동1강좌이름
  3. 고유번호는 강좌목록의 순번과 일치해야 합니다
  4. 스프레드시트에서 확장 프로그램 > Apps Script를 클릭합니다
  5. 기존 코드를 모두 지우고, 아래 코드를 붙여넣습니다:
    function doGet(e) { var cache = CacheService.getScriptCache(); var cached = cache.get('schedule_json'); if (cached) { return ContentService.createTextOutput(cached).setMimeType(ContentService.MimeType.JSON); } var ss = SpreadsheetApp.getActiveSpreadsheet(); var schedule = []; var titleMatch = ss.getName().match(/(\d{4})/); var year = titleMatch ? titleMatch[1] : String(new Date().getFullYear()); ss.getSheets().forEach(function(sheet) { var data = sheet.getDataRange().getValues(); var headerIdx = -1; for (var i = 0; i < Math.min(5, data.length); i++) { for (var j = 0; j < data[i].length; j++) { if (String(data[i][j]).trim() === '강좌 일자') { headerIdx = i; break; } } if (headerIdx >= 0) break; } if (headerIdx === -1) return; var headers = data[headerIdx].map(function(h) { return String(h).trim(); }); var uidIdx = -1; for (var j = 0; j < headers.length; j++) { if (headers[j] === '고유번호' || headers[j].endsWith('고유번호')) { uidIdx = j; break; } } var ci = { uid: uidIdx, date: headers.indexOf('강좌 일자'), time: headers.indexOf('강좌 시간'), teacher: headers.indexOf('성명'), course: headers.indexOf('강좌명') }; var cur = { uid: null, teacher: '', course: '', time: '' }; for (var i = headerIdx + 1; i < data.length; i++) { var row = data[i]; var uid = ci.uid >= 0 ? row[ci.uid] : null; var dateVal = ci.date >= 0 ? row[ci.date] : null; var teacher = ci.teacher >= 0 ? row[ci.teacher] : ''; var course = ci.course >= 0 ? row[ci.course] : ''; var timeVal = ci.time >= 0 ? row[ci.time] : ''; if (uid !== '' && uid !== null && uid !== undefined) { cur.uid = Number(uid); } if (teacher) cur.teacher = String(teacher).trim(); if (course) cur.course = String(course).trim(); if (timeVal) cur.time = String(timeVal).trim(); var dateInfo = parseDateVal_(dateVal, year); if (!dateInfo) continue; if (!cur.uid || !cur.course) continue; schedule.push({ uid: cur.uid, course: cur.course, teacher: cur.teacher, date: dateInfo.date, day: dateInfo.day, time: cur.time, makeup: null }); } }); var output = JSON.stringify({ schedule: schedule, count: schedule.length, updatedAt: new Date().toISOString() }); cache.put('schedule_json', output, 300); return ContentService.createTextOutput(output).setMimeType(ContentService.MimeType.JSON); } function parseDateVal_(val, defaultYear) { if (!val) return null; if (val instanceof Date && !isNaN(val)) { return { date: Utilities.formatDate(val, Session.getScriptTimeZone(), 'yyyy-MM-dd'), day: ['일','월','화','수','목','금','토'][val.getDay()] }; } var s = String(val).trim(); var m = s.match(/(\d+)월\s*(\d+)일/); if (m) { var month = ('0' + m[1]).slice(-2); var day = ('0' + m[2]).slice(-2); var dayOfWeek = ''; var dm = s.match(/\(([월화수목금토일])\)/); if (dm) dayOfWeek = dm[1]; return { date: defaultYear + '-' + month + '-' + day, day: dayOfWeek }; } m = s.match(/^(\d{4})-(\d{2})-(\d{2})/); if (m) return { date: m[1] + '-' + m[2] + '-' + m[3], day: '' }; m = s.match(/^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})/); if (m) return { date: m[1] + '-' + ('0' + m[2]).slice(-2) + '-' + ('0' + m[3]).slice(-2), day: '' }; return null; }
  6. 배포 > 새 배포 > 유형: 웹 앱 > 액세스 권한: 모든 사용자로 배포합니다
  7. 생성된 URL을 복사하여 카테고리 관리 탭에서 해당 방과후학교 카테고리의 서명록 URL에 입력합니다