Excel 자동화

개발 로그: 120,000행 스프레드시트의 실제 문제점

121,254개의 행과 180만 개의 셀로 구성된 스프레드시트에 대한 작업 세션과 대규모 교차 테이블 분석이 완료되고 출력을 확인하고 사용 가능한 형식의 보고서를 반환하기 전에 변경해야 했던 5가지 개별 항목이 있습니다.

대부분의 스프레드시트 기능은 화면에 맞는 데이터를 대상으로 테스트됩니다. 이 로그는 15개 열에 걸쳐 121,254개 행 — 대략 180만 개 셀를 사용한 판매 통합 문서에 대한 작업 세션과 평범해 보이는 요청을 다루고 있습니다. 제품, 고객, 주문 및 판매 테이블을 결합한 다음 감소하는 제품, 재입고 위험 및 가치가 낮은 고객에 플래그를 지정합니다.

그 요청에는 전혀 이상한 것이 없습니다. 어쨌든 분석 자체와는 거의 관련이 없는 이유로 여러 번 실패했습니다. 다음은 실제로 깨진 것과 달라진 점이다.

느린 쿼리가 아닌 플랫폼의 한계

첫 번째 실패는 내구성 있는 직업 시스템의 버그처럼 보였습니다. 실제 원인은 Google Apps Script의 규칙: **편집기 추가 기능은 한 시간에 한 번 이상 실행되는 시간 기반 트리거를 생성하지 못할 수 있습니다.**였습니다.

백그라운드 작업 설계에서는 1분 트리거를 가정했습니다. 컨테이너에 바인딩된 스크립트가 자유롭게 예약될 수 있다는 가정은 개발 중에 유지되었으며 동일한 코드가 설치된 추가 기능으로 실행되는 순간 유지를 중단했습니다. 트리거 설치 요청은 성능이 저하되지 않았습니다. 작업이 생성되었으므로 이전가 발생하여 작업이 시작되지 않았습니다.

두 가지 변화가 이어졌습니다. 이제 트리거를 설치하는 것이 최선입니다. 1분 단위로 시도하고, 매시간 단위로 되돌아가고, 마지막으로 전혀 트리거가 발생하지 않으며, 절대 실행되지 않습니다. 그리고 첫 번째 처리 단계는 이제 작업을 다시 찾아야 하는 두 번째 호출이 아니라 작업을 생성한 동일한 실행 내에서 실행됩니다.

두 번째 세부 사항은 들리는 것보다 더 중요했습니다. Apps Script 속성은 실행 전반에 걸쳐 안정적으로 읽고 쓸 수 없으므로 조금 전에 작성된 작업이 바로 다음 호출에서 *"작업을 찾을 수 없습니다"*로 돌아올 수 있습니다.

진행 상황 보고는 완료와 동일하지 않습니다.

드디어 작업이 시작됐는데도 아직 끝나지 않았습니다. 도구가 한 단계를 실행한 다음 작업이 "백그라운드에서 계속됩니다"라는 상태를 반환했습니다.

그 문장은 거짓이었습니다. 시간별 트리거를 사용할 수 없으면 백그라운드에서 아무것도 계속되지 않습니다. 어시스턴트는 상태를 읽고 사용자에게 백분율을 전달한 후 작업을 중지하여 121,253개 행 중 34,000개 행에 무기한 보관했습니다.

이제 런타임은 제한된 예산 내에서 작업 자체를 완료하도록 유도하고 모든 후속 상태 호출은 단순히 작업을 읽는 것이 아니라 작업을 진행시킵니다. 예산이 소진된 경우 상태 텍스트에는 작업이 완료되지 않았으며 다른 어떤 것도 작업을 진행할 수 없다는 내용이 분명하게 표시됩니다.

원칙은 직접적으로 언급할 가치가 있습니다. 진행 보고서는 결과물이 아닙니다. 사용자가 백분율이 아닌 테이블을 요청했습니다.

모델이 볼 수 있는 도구를 통해서만 요청을 처리할 수 있습니다.

도구 선택을 정확하게 유지하기 위해 GetSheetAI는 요청에 따라 턴당 도구 하위 집합을 공개합니다. 해당 메커니즘은 Excel 도구 세트를 중심으로 구축되었으며, Google Sheets 애드온은 거기에만 존재하는 22개의 도구를 등록합니다. 이러한 도구는 모든 요청에서 필터링되었습니다.

효과는 구체적이어서 놓치기 쉬웠습니다. 막대 차트를 요청하면 44개의 도구 중 6개가 공개되었으며, 차트 도구는 숨겨진 도구 중 하나였습니다. 정렬 도구를 사용하지 않고 범위 정렬을 요청하면 44개 중 5개가 공개되었습니다. 보조자는 거절한 것이 아닙니다. 실제로 작업을 수행하는 도구를 볼 수 없었습니다.

Sheets에는 이제 각 Excel 대응 항목을 미러링하는 자체 도구-번들 매핑이 있으며 필터는 도구를 삭제하는 대신 의견이 없는 모든 도구를 통과합니다. 이제 테스트는 등록된 도구 이름을 소스에서 직접 읽으므로 도구를 분류하지 않고 추가하면 조용히 접근할 수 없게 되는 대신 빌드가 실패합니다.

문구에서도 같은 등급의 공백이 나타났습니다. "새 시트 만들기"를 의미하는 중국어 요청은 규칙과 일치하지 않습니다. 패턴이 시트에 대한 두 가지 일반적인 단어 중 하나만 인식했기 때문입니다. 시트 생성 도구는 숨겨져 있었고 보조자는 워크시트 생성이 불가능하다고 보고했습니다. 그렇지 않았습니다.

오류 메시지는 제품의 일부입니다.

탈출구를 명시하지 않고 문제를 언급하는 메시지로 인해 여러 가지 실패가 발생했습니다.

존재하지 않는 시트에 쓰면 *"요청한 리소스가 존재하지 않습니다."*가 반환되었습니다. 이는 손상된 추가 기능처럼 읽힙니다. 이제 시트가 존재하지 않고 쓰기 도구가 시트를 생성하지 않으며 두 호출이 시트를 생성한다고 말합니다.

매우 넓은 범위에 대한 행 수준 분류를 거부하면 단순한 거부가 반환됩니다. 집계된 결과에 라벨을 지정하는 것은 모든 크기에서 작동하므로 이제 메시지에서는 해당 경로의 이름을 그룹으로 지정한 다음 그룹화된 결과에 분류 규칙을 적용합니다.

덮어쓰기 가드가 blocked: true만 반환했는데 이는 실패로 읽혀졌습니다. 이제 대상이 이미 데이터를 보유하고 있음과 진행 방법을 설명합니다.

이 중 어느 것도 화장품이 아닙니다. 각각의 경우 이전 메시지는 아직 완료 가능한 작업을 종료했습니다.

더 많은 산술이 필요한 결정론적 표현

20170702와 같은 정수 날짜 키에서 201707와 같은 연월을 파생하려면 floor(x / 100) 또는 모듈로가 필요합니다. 둘 다 존재하지 않았습니다. 두 번의 시도가 실패하고 파생 열이 중단되었습니다.

이제 표현식 레이어에는 floor, round, absmod가 포함되며 지원되지 않는 함수 오류는 거부된 항목의 이름만 지정하는 대신 전체 세트를 나열하고 정확한 표현식을 제공합니다.

그것이 서 있는 곳

동일한 통합 문서에서 이제 내구성 있는 경로가 완료됩니다. 모든 121,253개의 행이 처리되고, 그룹화되고, 기록되고, 서식이 지정되고 모든 결과 청크가 확인됩니다. Excel에서 동일한 요청으로 397개 제품 전체(최근 판매가 없는 132개, 재입고 위험이 표시된 101개, 감소 중 99개, 정상 65개)에 대한 분류가 생성되었습니다. 이 분류는 데이터를 어디로든 이동하는 대신 원본 테이블에 대해 기본 SUMIFS를 사용하여 계산되었습니다.

알아야 할 작동 값:

  • 내구성 있는 라우팅 임계값: 100,000셀 이상;
  • 소스 청크: 제한된 읽기, 쓰기 저장 시 청크별로 확인됩니다.
  • 회귀 적용 범위: 공유 런타임 전반에 걸친 826 테스트;
  • Google 스프레드시트 추가 기능의 백그라운드 실행: 기껏해야 시간당, 따라서 사이드바는 열려 있는 동안 긴 작업을 수행합니다.

마지막 지점은 일시적인 한계가 아니라 실제 한계입니다. 설치된 추가 기능은 작업을 더 자주 예약할 수 없으므로 사이드바가 열려 있는 동안 대규모 작업이 진행됩니다. 내구성 있는 체크포인트는 완료된 작업이 손실되지 않고 닫히는 것을 의미하지만 정직하게 설명하면 작업이 예정된 것이 아니라 추진된다는 것입니다.

이번 세션의 더 폭넓은 교훈은 규모에 관한 것이 아닙니다. 이러한 실패는 모두 플랫폼 규칙, 숨겨진 도구, 오류에 이름이 없는 지원 경로 등 사용자가 볼 수 없는 것을 시스템이 알고 있는 경우였습니다. 크기는 그것들을 모두 한 번에 볼 수 있게 만든 것이었습니다.