HotXLS는 Excel을 띄우지 않고 XLSX 파일에 이미 저장된 AutoFilter 기준을 평가합니다. v2.384.136부터 TXLSXWorksheet.PreviewAutoFilterRows, ApplyAutoFilter, AutoFilterRowVisible이 값 목록, 날짜 그룹, Top/Bottom-n 및 백분율 필터, 상대 날짜와 평균 필터, 채우기 및 폰트 색 필터, 조건부 서식 아이콘 필터를 고정된 기준 날짜와 명시적 리소스 한계 아래에서 실행합니다
흔한 방아쇠는 사람이 Excel에서 필터를 걸어 둔 통합 문서와 그에 맞춰 동작해야 하는 서버입니다. 누군가 매출 Top 10, 주문 날짜의 이번 달, 연체 행의 빨간 채우기를 설정하고 저장해 파일을 올립니다. 이제 여러분의 Delphi 서비스는 Excel이 보여 줄 행 집합이 필요합니다. 그것을 세거나, 내보내거나, 맞는 행을 숨긴 채 파일을 되돌려 쓰거나요. 파일은 정의만 담고 있습니다. 이 릴리스 전까지 HotXLS는 평범한 커스텀 기준을 평가할 수 있었지만 고급 종류들은 저장된 XML에만 앉아 실행해 주는 것이 없었으므로, 정직한 답은 "Excel에서 열어 보세요"였습니다
HotXLS는 저장된 AutoFilter에서 실제로 무엇을 실행하나
HotXLS는 Excel이 기록한 filterColumn 요소에서 열마다 필터 종류 하나를 실행하고, Excel 드롭다운과 똑같이 열을 AND로 결합합니다. 요소들은 ECMA-376 Part 1 §18.3.2의 AutoFilter 그룹에서 나오며 각각 별개의 평가 경로로 갑니다:
filters와 그 자식filter,dateGroupItem: 체크된 값 목록과 선택적 빈 항목, 연도부터 초까지의 달력 날짜 그룹이 OR로 묶입니다customFilters: AND 또는 OR로 이어진 하나 또는 둘의 비교 기준, 이미 존재하던 경로입니다top10: Top 또는 Bottom n개 항목, 또는 n퍼센트이며,val은 1-500개 항목 또는 1-100퍼센트로 제한됩니다dynamicFilter: 오늘, 어제, 내일, 이번/지난/다음 주, 월, 분기, 연도, 연초부터, M1-M12, Q1-Q4, 평균 위, 평균 아래colorFilter와iconFilter: 차등 스타일을 통해 해석된 유효 채우기 또는 폰트 색, 아이콘 집합과 0부터 시작하는 icon id별 조건부 서식 아이콘
이 목록 밖의 것은 추측한 행 집합을 만드는 대신 EXLSXAutoFilterUnsupported로 실패합니다. ST_DynamicFilterType의 above/below 표준편차 타입, 비그레고리력 calendarType 값, 알 수 없는 확장 요소, 해석되지 않는 dxfId 참조, 우연히 두 필터 종류를 동시에 달고 있는 열이 여기 포함됩니다. 조용히 "그럴듯하게 근접한" 행을 돌려주는 필터 엔진은 거부하는 엔진보다 나쁩니다. 잘못된 고객이 실린 보고서가 나가기 전까지는 아무도 눈치채지 못하니까요
먼저 미리보기, 다음 적용
HotXLS는 일을 읽기 전용 미리보기와 트랜잭션 적용으로 나누며, 둘 다 같은 TXLSXAutoFilterExecutionOptions 레코드를 받습니다. PreviewAutoFilterRows는 일치하는 데이터 행 수를 반환할 뿐 행 가시성을 건드리지 않습니다. ApplyAutoFilter(AResetVisible, Options)는 모든 행 판정을 먼저 준비한 뒤에야 새 숨김 행 집합을 한 번에 발행하므로, 준비 중 예외가 나면 시트는 정확히 그대로입니다
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
Options: TXLSXAutoFilterExecutionOptions;
Matching: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('orders-filtered-by-sales.xlsx');
Sheet := Book.Sheets[1]; // Sheets 인덱서는 1부터 시작
// 항상 기본값에서 출발한 뒤 개별 필드만 바꿉니다
Options := XLSDefaultAutoFilterExecutionOptions;
Options.ReferenceDate := EncodeDate(2026, 10, 19);
Matching := Sheet.PreviewAutoFilterRows(nil, Options); // 개수만
WriteLn('Rows Excel would show: ', Matching);
// True: 일치 행은 이전에 숨겨져 있었더라도 보이게 됩니다
Sheet.ApplyAutoFilter(True, Options);
Book.SaveAs('orders-applied.xlsx');
finally
Book.Free;
end;
end;
레코드는 매번 XLSDefaultAutoFilterExecutionOptions로 초기화하십시오. 이 함수는 레코드를 0으로 채운 뒤 모든 한도를 설정하고, 실행 문맥은 한도가 하나라도 양수가 아니면 EXLSXAutoFilterLimit으로 거부합니다. 스택에 선언하고 필드별로 채운 레코드는 잊은 필드에 보통 쓰레기나 0을 갖고 있습니다. 매개변수 없는 오버로드들(ApplyAutoFilter(True), PreviewAutoFilterRows(Callback), AutoFilterRowVisible(Row))은 현재 날짜를 기준으로 같은 기본값을 씁니다
AResetVisible 플래그는 필터를 통과했지만 이미 숨겨져 있던 행들의 운명을 정합니다. True는 모든 일치 행을 보이게 하는데, 재적용할 때 Excel이 하는 동작입니다. False는 일치 행의 이전 수동 숨김을 유지하고 실패한 행에만 숨김을 더합니다. AutoFilter 범위 밖의 행은 어느 쪽이든 상태를 유지합니다. 준비와 발행 사이에 통합 문서가 바뀌면 ApplyAutoFilter는 낡은 데이터로 계산한 판정을 발행하는 대신 예외를 던집니다
값 목록은 왜 별표와 물음표를 무시할까
filters 요소의 값 목록 항목은 리터럴 표시 토큰이므로, HotXLS는 *와 ?를 평범한 문자로 비교합니다. 드롭다운에서 체크된 A* 항목은 셀이 정확히 A*를 보여 준다는 뜻이지 "A로 시작"이 아닙니다. 와일드카드는 customFilters의 소관이고, 거기서 "시작한다"와 "포함한다"는 진짜 패턴이며, HotXLS가 Excel 와일드카드 기준과 틸드 이스케이프를 대조하는 방법에서 다룬 별도 규칙을 유지합니다. 두 의미론을 섞는 것이 부품 번호 컬럼을 엉터리로 필터링하는 가장 빠른 길입니다
비교는 표시 값에 대해 이뤄지는데, 그러면 어느 표시인지가 문제가 됩니다. HotXLS는 셀을 저장된 스타일 오버레이를 포함한 기본 숫자 서식으로 포매팅하고, 조건부 서식이 그 위에 얹는 숫자 서식은 의도적으로 무시합니다. HotXLS 픽스처의 네이티브 Excel 컨트롤이 토큰이 왜 중요한지 보여 줍니다. 숫자 1과 텍스트 "1"은 둘 다 1 선택에 일치하고, 0.0으로 서식된 숫자 1은 대신 텍스트 "1.0"과 함께 1.0에 일치하며, 텍스트 "01"은 둘과 구별됩니다. 날짜처럼 보이는 텍스트는 절대 날짜로 파싱되지 않으므로, "2026-10-19"를 담은 텍스트 셀은 날짜 그룹에 들어가지 않습니다
Top 10, 평균, 동적 날짜 필터는 어떻게 판단하나
HotXLS는 순위와 평균 컷오프를 다른 필터가 남겨 둔 보이는 행이 아니라 전체 소스 컬럼에 걸쳐 한 번 계산합니다. 유한 수만 모집단에 들어가므로 "100" 같은 숫자처럼 보이는 텍스트는 제외되고, 모집단은 행 판정이 시작되기 전에 수집됩니다. 네이티브 컨트롤 통합 문서에서 평균 위 필터는 두 번째 컬럼이 값 50을 숨긴 뒤에도 전체 컬럼의 평균 27을 유지합니다. 남은 행들의 21.25 평균으로 갈아타지 않습니다
무승부는 컷오프에서 포함되며, Excel과 같습니다. 20에서 두 항목이 같은 값들의 Top 3 필터는 네 행을 고릅니다. 백분율 모드는 숫자 모집단의 잘린 몫을 취하되 한 항목의 바닥을 두므로, 다섯 값의 Top 50퍼센트는 임계값 30으로 두 값을 고릅니다. Bottom 변형은 비교를 거울상으로 합니다. 이 숫자들은 사양을 읽어서가 아니라 HotXLS 테스트 픽스처에 기록된 Excel 자체 행 집합에서 나온 것이며, 사양은 대부분에 대해 침묵합니다
동적 날짜에는 고정된 기준 날짜가 필요
TXLSXAutoFilterExecutionOptions.ReferenceDate는 한 연산 전체에 대해 "오늘"의 의미를 고정합니다. 이번 주나 지난 분기 같은 상대 필터와 색 필터에 먹이가 되는 조건부 서식 날짜 규칙은 모두 그 하나의 날짜에 대해 평가되므로, 23:59:59의 미리보기와 1초 뒤의 적용이 일치합니다. 0 값은 연산이 시작될 때 현재 날짜를 한 번 고르고, serial 값은 M2와 Q1 필터를 위한 1900 체계의 Excel 가상 serial 60을 포함해 통합 문서의 1900 또는 1904 날짜 체계를 존중합니다
창은 반열린 달력 구간입니다. 이번 주는 일요일부터 다음 일요일까지, 이번 분기는 분기 첫날부터 다음 분기 첫날까지, 연초부터는 1월 1일부터 기준 날의 끝까지입니다. 배치나 테스트에서 도는 것은 무엇이든 ReferenceDate를 명시적으로 고정하십시오. 자정을 넘기는 야간 작업이나 10월에 쓴데 1월에도 통과해야 하는 단위 테스트는, 그렇지 않으면 눈에 보이는 이유 없이 다른 행 집합을 만들어 냅니다
수식 셀은 캐시된 값으로 필터링됩니다. 필터 엔진은 통합 문서를 조용히 재계산하지 않으므로, 캐시된 결과를 남기지 않은 라이터가 저장한 파일은 필터가 의미 있는 숫자나 날짜를 보기 전에 명시적인 계산 패스가 필요합니다
색 필터는 어느 색을 보나
HotXLS 색 필터는 직접 셀 서식과 일치하는 조건부 서식 오버라이드의 유효 색을 보고, 표 스타일에서만 오는 것은 보지 않습니다. Excel도 똑같이 동작합니다. 내장 표 스타일이 옅은 파란색으로 칠한 줄무늬 행은 필터 드롭다운에게 "옅은 파란색"이 아닙니다. 네이티브 컨트롤에서 조건부 서식이 빨갛게 칠한 셀은 빨간 채우기 필터에 선택되고, 직접 빨갛게 서식됐지만 활성인 노란 규칙이 덮은 셀은 제외됩니다
세 가지 세밀화가 후속 릴리스로 왔습니다. v2.384.138은 선형 및 경로 그라데이션 채우기를 솔리드 색과 무채우기 양쪽과 구별되는 것으로 취급해, stop 하나가 정확히 그 색을 갖고 있어도 그라데이션이 솔리드 색 기준과 일치하지 않게 했습니다. v2.384.140은 리치 텍스트에 대한 폰트 색 필터링을 더했는데, 비어 있지 않은 run이 요청된 RGB, 자동, 상속 색을 실으면 셀이 일치합니다. v2.384.150은 조건부 리치 텍스트 판정을 완성했는데, 이것이 별난 사례로 밝혀졌습니다
네이티브 Excel은 같은 텍스트와 같은 기본 스타일, 같은 조건부 규칙 경로를 가진 리치 텍스트 셀과 평범한 셀 사이에서 색 판정을 재사용할 수 있으므로, 보이는 행 집합이 그 셀들의 순서에 의존할 수 있습니다. HotXLS는 여러분이 AutoFilterRowVisible로 한 행만 물었더라도 데이터 범위 전체를 오름차순 행 순서로 준비해 그것을 재현합니다. 따라서 40행의 검사는 범위 한 바퀴의 비용이 들지만, 행 검사, 미리보기, 적용은 같은 행에 대해 항상 같은 답을 돌려줍니다
모든 리소스에는 한도가 있고 잡아야 할 것들
HotXLS는 업로드 폼에서 온 필터된 통합 문서가 신뢰할 수 없는 입력이기 때문에, AutoFilter 연산의 각 작업 종류를 TXLSXAutoFilterExecutionOptions의 자체 필드로 묶습니다. 기본값은 MaxXmlCharacters에 1048576, MaxXmlNodes에 16384, MaxFilterItems에 4096, MaxExaminedCells에 4000000, MaxEffectiveFormatCells와 MaxPopulationValues에 각각 1000000, MaxContextBytes에 67108864바이트, MaxConditionalSteps에 16000000입니다. MaxContextBytes는 프로세스 메모리가 아니라 유지되는 논리 상태와 예약된 임시 봉투를 잽니다
type
TFilterJob = class
public
Deadline: TDateTime;
VisibleRows: TList<Integer>;
procedure HandleRow(Sender: TObject; SheetIndex, Row: Integer;
Visible: Boolean; var Cancel: Boolean);
procedure HandleWork(Sender: TObject; ACompleted: Int64;
var ACancel: Boolean);
end;
procedure TFilterJob.HandleRow(Sender: TObject; SheetIndex, Row: Integer;
Visible: Boolean; var Cancel: Boolean);
begin
// 모든 데이터 행마다 호출됩니다. Visible이 필터 판정입니다
if Visible then
VisibleRows.Add(Row);
end;
procedure TFilterJob.HandleWork(Sender: TObject; ACompleted: Int64;
var ACancel: Boolean);
begin
// ACompleted는 조사된 셀을 세며 서식 지정 중에는 제자리일 수 있습니다
ACancel := Now > Deadline;
end;
PreviewAutoFilterRows의 행 콜백은 일치하는 것만이 아니라 판정과 함께 모든 데이터 행을 받고, 함수는 여전히 일치 개수를 반환합니다. 그 Cancel 매개변수를 설정하면 예외 없이 방문이 일찍 멈춥니다. OnWork가 취소 훅입니다. ACancel을 True로 하면 EXLSXAutoFilterCancelled를 던집니다. 연산이 판정을 준비하는 동안 통합 문서에 읽기 임대를 쥐고 있으므로, 어느 콜백도 그 통합 문서를 수정해서는 안 됩니다
Options := XLSDefaultAutoFilterExecutionOptions;
Options.ReferenceDate := Date;
Options.MaxExaminedCells := 500000; // 업로드 파일용 더 타이트한 한도
Options.OnWork := Job.HandleWork;
try
Sheet.PreviewAutoFilterRows(Job.HandleRow, Options);
Sheet.ApplyAutoFilter(True, Options);
except
on E: EXLSXAutoFilterUnsupported do
Log('Filter needs Excel: ' + E.Message);
on E: EXLSXAutoFilterLimit do
Log('Filter exceeded a budget: ' + E.Message);
on E: EXLSXAutoFilterCancelled do
Log('Filter cancelled at deadline');
on E: EXLSXAutoFilterExecution do
Log('Filter state invalid: ' + E.Message);
end;
세 가지 구체 예외는 모두 EXLSXAutoFilterExecution에서 파생되는데, 이것 자체는 지원 달력 밖의 기준 날짜나 발행 전에 바뀐 통합 문서 같은 잘못된 상태를 커버하므로, 기본 클래스는 마지막에 두십시오. 모든 경우에 시트의 행 가시성은 변하지 않으므로, "기록하고, 건너뛰고, 파일을 수동 검토 대상으로 표시"가 안전한 기본 정책입니다
경계가 있는 곳
커버리지는 넓지만, 고객에게 동등성을 약속하기 전에 알아 둘 가장자리가 몇 개 있습니다:
- 표준편차 동적 필터는 검증된 정책이 존재할 때까지 거부됩니다. 열거형에는 그 값들이 있음에도입니다
- 주 창은 일요일에 시작됩니다. 다른 주 시작에 의존하는 통합 문서는 모델링되지 않습니다
- 수식 결과는 저장된 캐시에서만 나오며, 필터 호출 안의 재계산은 없습니다
- 표 스타일 색은 설계상 그리고 Excel과 합의하여 색 필터와 절대 일치하지 않습니다
- 알 수 없는 리치 텍스트 구조나 알 수 없는 색 메타데이터는 명시적으로 실패하지만, 폰트 패밀리 같은 알려진 비색 속성은 색 일치를 막지 않습니다
- XLS 파사드와 그 BIFF8 저장소는 별도 경로이며, HotXLS가 BIFF8 AutoFilter DOPER 기준을 쓰는 방법이 다룹니다
직접 생성하는 통합 문서에서 AutoFilter 정의, 데이터 유효성 검사, 표가 어떻게 연관되는지 아직 고민 중이라면 HotXLS의 데이터 유효성 검사, AutoFilter, 표부터 시작하십시오. SetAutoFilter, 컬럼 id, 필터가 실제로 효과를 내는 시점을 다룹니다
FAQ
PreviewAutoFilterRows는 숨겨진 행을 바꾸나요?
아니요. PreviewAutoFilterRows는 저장된 기준만 평가하고 반환값과 선택적 콜백으로 판정을 보고합니다. 새 숨김 행 집합을 발행하는 것은 ApplyAutoFilter뿐이며, 모든 판정이 준비된 뒤에 그러므로, 실패하면 원래 가시성이 그대로입니다
상대 날짜 필터가 날마다 다른 행을 주는 이유는요?
오늘, 이번 주, 지난달 같은 필터는 현재 날짜에 상대적으로 정의되며 Excel과 정확히 같습니다. 반복 가능한 결과가 필요하면 TXLSXAutoFilterExecutionOptions의 ReferenceDate를 고정 날짜로 설정하십시오. 0 값은 연산이 시작되는 시점의 날짜를 뜻합니다
HotXLS는 표 스타일에서 오는 색으로 필터링할 수 있나요?
아니요, Excel도 마찬가지입니다. HotXLS 색 필터는 직접 셀 서식과 지원되는 조건부 서식 오버라이드만 일치시킵니다. 내장이든 커스텀이든 표 스타일만이 칠한 색은 참여하지 않으므로, 색 필터 결과는 Excel 드롭다운이 선택할 것과 일치합니다
고급 AutoFilter 실행은 v2.384.136부터 Excel 없이 Excel 파일을 읽고 쓰는 Delphi 스프레드시트 컴포넌트인 HotXLS의 XLSX 워크시트 API와 함께 제공되며, 그라데이션, 리치 텍스트, 조건부 리치 텍스트 색 처리는 v2.384.150까지 더해졌습니다