본문으로 건너뛰기
엑셀·구글시트 자동화 실험

엑셀·구글시트 자동화 실험No. 190

앱스 스크립트 트리거 시간 설정 후 실행 시각이 다를 때

노트북과 시각이 다른 두 탁상시계
노트북과 시각이 다른 두 탁상시계

매일 실행할 함수와 기준 시간 정하기

구글시트에서 매일 반복하는 작업을 자동화하려면 먼저 실행할 함수를 정합니다. 시트 내용을 정리하는 함수와 예약을 등록하는 함수는 역할이 다릅니다. 예약 등록 함수는 설정할 때 실행하고, 실제 작업 함수는 등록된 일정에 따라 실행되도록 구성합니다.

닫힌 노트북과 아홉 시의 탁상시계
닫힌 노트북과 아홉 시의 탁상시계

아래 예시는 매일 오전 9시 부근에 실행 기록을 남기는 구성입니다. 아직 시트의 값을 수정하지 않으므로, 실제 업무 코드를 넣기 전에 예약 구조를 살펴보는 용도로 사용할 수 있습니다. 로그에 시각을 남기는 부분을 데이터 정리 코드로 바꾸면 같은 구조를 응용할 수 있습니다.

시트에 연결된 스크립트는 해당 문서의 확장 프로그램 메뉴에서 Apps Script를 열어 확인합니다. 편집기에서 프로젝트 설정으로 이동해 시간대를 한국에 맞는 항목으로 지정합니다. 코드에서도 Asia/Seoul을 지정하면 예약을 읽는 기준을 분명하게 유지할 수 있습니다.

설정 전에 오전 중 실행이면 충분한지, 특정 시각 이전에 작업이 끝나야 하는지 구분합니다. 오전 중 자료를 정리하는 작업과 마감 직전 자료를 전달하는 작업은 허용할 수 있는 지연이 다릅니다. 완료 기한이 있다면 작업에 걸리는 시간까지 고려해 실행 시간대를 앞당겨 잡습니다.

화면에서 직접 설정할 경우에는 편집기 왼쪽의 트리거 메뉴에서 실행할 함수를 고르고, 이벤트 소스를 시간 기반으로 지정합니다. 일 단위 반복을 선택하면 실행 시간대를 고를 수 있습니다. 아래처럼 코드로 등록한다면 같은 함수를 화면에서 다시 등록하지 않도록 확인합니다.

예약한 시각과 실제 실행 기록을 나란히 확인해야 시간 설정을 판단할 수 있습니다.

복사해서 사용하는 일일 예약 코드

아래 코드는 실행 기록을 남기는 dailyJob 함수와 예약을 등록하는 setupDailyTrigger 함수로 구성합니다. 같은 이름의 시간 기반 예약이 이미 있으면 먼저 삭제한 뒤 새로 만듭니다. 등록 함수를 다시 실행하면서 같은 예약이 쌓이는 일을 줄이기 위한 구성입니다.

function dailyJob() {

const now = new Date();

const stamp = Utilities.formatDate(

now,

'Asia/Seoul',

'yyyy/MM/dd HH:mm:ss'

);

console.log('작업 시작: ' + stamp);

}

function setupDailyTrigger() {

const handler = 'dailyJob';

같은 시각을 가리키는 두 탁상시계
같은 시각을 가리키는 두 탁상시계

ScriptApp.getProjectTriggers().forEach(function(trigger) {

const sameHandler =

trigger.getHandlerFunction() === handler;

const isClock =

trigger.getEventType() === ScriptApp.EventType.CLOCK;

if (sameHandler && isClock) {

ScriptApp.deleteTrigger(trigger);

}

});

ScriptApp.newTrigger(handler)

.timeBased()

.atHour(9)

.nearMinute(0)

.everyDays(1)

.inTimezone('Asia/Seoul')

.create();

}

등록과 확인은 다음 순서로 진행합니다.

  1. 코드를 붙여 넣고 프로젝트를 저장합니다
  2. 함수 목록에서 dailyJob을 선택해 수동 실행합니다
  3. 필요한 권한을 확인하고 실행 기록을 살펴봅니다
  4. setupDailyTrigger를 선택해 실행합니다
  5. 트리거 목록에서 dailyJob의 등록 상태를 확인합니다

수동 실행은 함수가 현재 조건에서 동작하는지 확인하는 절차입니다. 이 실행만으로 다음 날 자동 실행이 등록되지는 않습니다. 반대로 등록 함수를 실행해도 dailyJob이 즉시 실행되는 구성은 아닙니다. 두 함수를 구분하면 설정 뒤 로그가 바로 생기지 않는 이유를 이해하기 쉽습니다.

기존 프로젝트에 적용할 때는 삭제 조건을 먼저 읽습니다. 이 코드는 현재 계정이 해당 프로젝트에 만든 예약 가운데 dailyJob을 실행하는 시간 기반 항목을 삭제합니다. 같은 함수에 여러 시간대를 의도적으로 연결해 둔 경우에는 그 일정도 삭제 대상이므로 그대로 적용하기 전에 구조를 조정합니다.

시간을 정하는 코드 한 줄씩 읽기

ScriptApp.newTrigger(handler)는 예약으로 실행할 함수 이름을 지정합니다. handler에 담긴 dailyJob은 문자열이며, 실제 함수 이름과 일치해야 합니다. 함수를 다른 이름으로 바꿨다면 이 문자열도 함께 바꾸고 예약을 다시 등록합니다. 함수 이름의 대소문자도 구분합니다.

timeBased()는 시간 기준으로 실행하는 예약을 선택합니다. atHour(9)는 오전 9시대를 기준으로 삼습니다. nearMinute(0)는 해당 시간의 0분 부근을 요청하는 설정입니다. 두 값을 함께 적어도 오전 9시 정각에 실행을 시작한다고 해석하면 안 됩니다.

everyDays(1)은 매일 반복하는 주기입니다. inTimezone('Asia/Seoul')은 이 예약이 시간을 해석할 기준을 지정합니다. 마지막 create()가 실제 예약을 생성합니다. 편집기에서 숫자만 고치고 저장한 상태로는 이미 등록된 예약이 바뀌지 않습니다.

십 분 차이로 나란히 놓인 시계
십 분 차이로 나란히 놓인 시계

예를 들어 오전 10시 부근으로 옮기려면 atHour(9)를 atHour(10)으로 바꾸고 setupDailyTrigger를 다시 실행합니다. 이때 기존 항목이 삭제되고 변경한 조건으로 새 항목이 생성됩니다. 실행 후에는 트리거 목록을 열어 같은 작업이 중복 등록되지 않았는지도 살펴봅니다.

dailyJob 안의 Utilities.formatDate는 실행 시각을 한국 시간 문자열로 바꿉니다. 이 줄은 기록의 표시 방식을 정할 뿐, 예약 시각을 변경하지 않습니다. 로그에 표시되는 시간과 트리거가 기준으로 삼는 시간을 같은 것으로 혼동하지 않는 편이 좋습니다.

코드에 적은 시간대가 모든 날짜 처리에 자동으로 적용되는 것도 아닙니다. 시트의 날짜 표시가 예상과 다르면 스프레드시트 자체의 시간대도 별도로 확인합니다. 예약 설정, 코드에서 날짜를 계산하는 방식, 시트에 표시하는 형식을 나눠 살펴보면 차이가 생긴 지점을 좁힐 수 있습니다.

코드의 시간 숫자를 바꾼 뒤에는 등록 함수를 다시 실행해야 일정이 반영됩니다.

실제 작업에 적용할 때 살필 한계

오전 중 한 번 자료를 정리하면 되는 경우에는 일 단위 예약을 적용하기 수월합니다. 정확한 분에 외부 작업과 맞물려야 하는 경우에는 실행 시각의 변동을 고려한 별도 설계가 필요합니다. 한 번만 실행할 작업이라면 매일 반복하는 예시를 그대로 사용하지 않고 일회성 예약으로 구성합니다.

실제 처리 코드를 넣을 때는 편집기에서 열어 둔 시트나 선택된 셀에 기대지 않도록 구성합니다. 자동 실행 시점에는 사람이 문서를 열어 두지 않을 수 있습니다. 대상 문서는 식별자로 열고, 작업할 시트 이름과 범위를 코드에 명시하면 실행 대상을 분명하게 정할 수 있습니다.

설치형 트리거는 만든 계정의 권한으로 실행됩니다. 공동 편집 문서라도 다른 계정이 만든 예약까지 자신의 트리거 목록에서 모두 관리하는 구조는 아닙니다. 담당자가 달라졌다면 누가 예약을 만들었는지 확인하고, 필요한 문서 접근 권한과 함께 관리합니다.

실행 여부는 편집기의 실행 내역에서 확인합니다. 등록 목록에 항목이 있다는 사실과 작업이 정상 완료됐다는 사실은 다릅니다. 실행이 실패했다면 해당 기록의 오류 메시지를 먼저 읽고, 함수 이름이나 문서 접근 권한, 처리 중 발생한 예외를 확인합니다.

같은 자료를 반복 처리하면 문제가 생기는 작업에는 처리 여부를 확인하는 조건을 둡니다. 수동 실행과 예약 실행이 겹쳐도 같은 행을 다시 추가하지 않도록 대상 날짜나 고유한 값을 검사하는 방식입니다. 작업이 오래 걸린다면 실행 시간 제한과 사용량 제한도 함께 검토합니다.

예약이 예상대로 동작하는지는 실행 기록으로 판단합니다. 시작 시각과 완료 시각을 남기고, 업무에서 허용할 지연 기준을 정해 직접 비교합니다. 시간대와 반복 주기, 실제 처리 결과를 함께 확인하면 숫자 하나를 바꾸는 설정에서 끝나지 않고 관리 가능한 자동화로 이어집니다.

목록으로

이 글은 엑셀·구글시트 자동화 실험에서 발행했습니다. 인용·링크는 자유롭고, 본문·그림의 복제 게시는 삼가 주세요.