計算與轉換保真度
計算後的陣列可以在選取、排序、查閱、矩陣與重塑函式之間組合,具備自動的 XLSX 溢出歸屬、明確的 CSE 目的地,以及有界的評估資源
動態陣列與明確 CSE 陣列
把會產生陣列的運算式指派給一個 TXLSXCell.Formula,再呼叫 TXLSXWorkbook.Recalculate;結果會擁有以該儲存格為錨點的矩形溢出,包括 SEQUENCE(3,2)、A1:A3*10、陣列常數與陣列型 LET 結果等公式
Sheet.Cells.Item[1, 1].Formula := 'SEQUENCE(3,2)'; Sheet.Cells.Item[1, 4].Formula := 'SUM(A1#)'; Workbook.Recalculate;
重新計算會讓結果長大或縮小,只清空由錨點持有的過時後續儲存格,並在範圍改變時重建相依性;對新產生後續儲存格的參照與 A1# 溢出運算子使用當下的範圍
既有值、公式、rich text、其他陣列、合併範圍、資料表與工作表邊界都會擋住溢出並產生 #SPILL!;空儲存格上的樣式仍可使用,清除阻擋物之後的下一次重新計算會讓錨點重試
以值或 rich text 編輯後續儲存格會把該儲存格從錨點分離,下一次計算會把這個編輯保留為阻擋物;移除或清空錨點會釋放其持有的後續儲存格,而 ConvertFormulasToValues 會把算出的值保留成普通儲存格
XLSX 儲存會記錄目前的陣列範圍與中繼資料,載入則在重新計算之前還原既有快取後續儲存格的歸屬;含錯誤的陣列公式只要錯誤屬於個別元素,仍會保留其範圍
SetArrayFormula 仍是兩套活頁簿引擎中明確固定範圍的 CSE 入口;原始範圍算術會在該範圍內逐元素評估,普通純量公式則保留隱含交集
一元 @ 運算子把參照與公式儲存格相交並取計算後陣列的第一個元素;SINGLE 與 ANCHORARRAY 是隱含交集與溢出參照的儲存別名
MAP 接受多個輸入陣列與對應的 LAMBDA 參數清單,會傳遞元素錯誤,並以 #CALC! 拒絕巢狀陣列結果;FILTER 接受計算後陣列與列或欄遮罩,包括錯誤傳遞,以及未提供後備值時的空結果 #CALC!
動態溢出的變動即使設定了多個計算執行緒仍序列執行;範圍穩定化最多 32 輪,循環迭代計算中的動態陣列會被拒絕,而不是當成純量結果
INDEX 接受參照、陣列常數與計算後陣列;當兩個選擇器都是純量時,正數的列與欄選擇器傳回單一值,零選擇器傳回選定的列或欄,兩個零選擇器傳回完整陣列;帶純量選擇器的參照來源對 ROW 與 ISREF 這類消費者保留參照行為
列與欄選擇器也可以是陣列,包括常數、計算後向量、範圍值與 LET 繫結;相對的列與欄方向會廣播成矩形叉積,相同方向則按位置配對;單一維度會廣播,不等形狀中缺漏的位置回傳個別的 #N/A
當任一選擇器是陣列時,零或省略的選擇器選該軸的第一個成員,而不是展開整列或整欄;小數選擇器向零截斷,負數選擇器在截斷前就回傳個別的 #VALUE!,超出來源邊界的選擇器回傳個別的 #REF!;選出的字串、布林值與具型別錯誤保留其型別
SORT 與 UNIQUE 接受範圍、常數與計算後陣列,包括巢狀的 FILTER、SEQUENCE 與 LET 結果;列與欄方向、遞增或遞減排序、首次出現順序與「恰好一次」去重,對每種來源形式都遵循同一契約
活頁簿定義名稱可以提供參照、純量或計算後陣列來源;ISREF(INDEX(...)) 可區分真正的參照結果與具名的計算值;純量 INDEX 選擇器與 SORT 數值選項會截斷小數值,選用的布林引數拒絕 TRUE 或 FALSE 以外的文字
Sheet.Cells.Item[1, 6].Formula := 'SORT(UNIQUE(FILTER(A1:B5,A1:A5>1)),1,-1)'; Sheet.Cells.Item[1, 9].Formula := 'INDEX(SORT(UNIQUE(A1:B5)),0,2)'; Sheet.Cells.Item[1, 12].Formula := 'INDEX(SEQUENCE(2,3,10,2),2,3)'; Workbook.Recalculate;
Sheet.Cells.Item[1, 1].Formula := 'INDEX(SEQUENCE(3,3),{1;3},{1,3})';
Workbook.Recalculate;
這個選擇器範例把 {1,3;7,9} 溢出成二乘二的結果;INDEX(SEQUENCE(3,3),{1;3},{1;3}) 則回傳配對欄 {1;9};陣列選擇器即使來源是參照也產生值,而純量參照選擇器保留參照身分
這些運算式可以在 XLSX 中溢出與調整大小,也可以在明確的 CSE 目的地內評估;陣列來源的錯誤保持具型別,「恰好一次」的空結果回傳 #CALC!;選擇器輸出消耗評估步驟預算,來源、選擇器與結果矩陣承載的合計則對照陣列記憶體預算檢查
INDEX 對計算後來源接受明確的第四個 area_num 引數值 1,且列、欄與區域選擇器可以在受支援的同工作表參照聯集上一併廣播;真正的多區域參照透過本機定義名稱與 LET 保留身分,而純量 CHOOSE 保留選定的參照,包括選到另一張工作表;選擇器陣列的結果是值而非巢狀參照陣列;零、缺漏、強制轉型與錯誤規則請見INDEX 區域選擇與參照身分
若要獨立計算,TXLSCalculator.OnGetSpillRange 接受 TXLSGetSpillRange 回呼來解析錨點目前的含端邊界;以活頁簿為後盾的評估器會自動安裝這個回呼
TXLSGetSpillRange = function(SheetIndex, AnchorRow, AnchorCol: Integer; var LastRow, LastCol: Integer): Integer of object;
lxNormalizeStorageFormula 為 OOXML 正規化撰寫的公式語法,lxTryStorageFormulaOperators 轉換溢出與隱含交集運算子,lxApplyXlfnPrefix 套上必要的未來函式前綴;受保護的文字與陣列列分隔符保持原樣,指派公式時記憶體中仍保留呼叫端的文字
儲存不會改變記憶體中撰寫的運算式;重新開啟新撰寫的 XLSX 公式會回傳標準儲存語法,使用逗號引數且無前置 =,與原生 Excel 匯入一致;未變動的已匯入公式 XML 仍走既有的保留路徑
查閱、矩陣與重塑組合
TRANSPOSE 接受參照、常數與計算後陣列,並保留文字、布林值與個別錯誤;空白來源儲存格變成數值零
MMULT、MDETERM 與 MINVERSE 接受計算後矩陣與 MMULT(MUNIT(2),SEQUENCE(2,2)) 這類巢狀運算式;矩陣元素必須是數值,文字、布林值與空白會被拒絕而非強制轉型,來源錯誤則保留其錯誤碼
CHOOSECOLS 與 CHOOSEROWS 接受純量或一維選擇器向量,按引數順序串接選擇器、保留重複項,並從尾端起算負索引;小數選擇器向零截斷,零與超出範圍的選擇器會被拒絕,二維選擇器矩陣不支援
XLOOKUP、XMATCH 與 MATCH 接受計算後的查閱向量與陣列型查閱請求;鍵值必須佔據一列或一欄,XLOOKUP 的回傳陣列必須對齊該查閱軸
純量 XLOOKUP 可以回傳整個相符的列或欄,包括具型別錯誤;陣列型查閱請求保留自身形狀,並取每個相符切片或後備陣列的第一個成分
精確查閱掃描會跳過鍵值向量中的錯誤項目;布林、數值與文字鍵值保持可區分,普通純量參照路徑保留其既有的串流與重算快取行為;二進位搜尋模式仍要求鍵值正確排序
VSTACK、HSTACK、TAKE、DROP、TOROW、TOCOL、WRAPROWS、WRAPCOLS 與 EXPAND 接受計算後輸入與具型別填充;沒有列或欄的結果回傳 #CALC!,換繞(wrap)要求一維輸入
矩陣運算、查閱掃描、選擇器走訪、複製與填充消耗評估步驟預算;同時保留的輸入、工作與輸出矩陣承載會在配置前對照設定的陣列記憶體上限檢查
Sheet.Cells.Item[1, 1].Formula := 'XLOOKUP({1;3},SEQUENCE(3),SEQUENCE(3,2))';
Sheet.Cells.Item[1, 4].Formula := 'CHOOSECOLS(SEQUENCE(2,3),{-1;1})';
Sheet.Cells.Item[1, 7].Formula := 'TRANSPOSE(UNIQUE({"A";"B";"A"}))';
Workbook.Recalculate;
具型別的現代計算錯誤
#SPILL! 與 #CALC! 在計算、顯示、快取檢查與 XLSX 重新開啟的整個過程中都保持具型別的儲存格錯誤;XLSX 輸出攜帶其 rich value 中繼資料,同時保留標準的快取錯誤後備,供不理解該擴充的讀取端使用
公式文字結果,包括 CSE 與動態陣列後續儲存格,使用字面字串快取,讓 Excel 能在重算前顯示;普通值儲存格繼續使用共用字串
現代 rich error 輸出包含 Excel 在重算前解讀這些快取所需的活頁簿版本與 Rich Data 計算功能宣告;輸出的 calcId 至少為 191029,更高的請求值照樣保留,且不改變活頁簿記憶體中的 CalcId 屬性
匯入的儲存格與值中繼資料、無關的 rich value 結構與不透明區塊(bucket),在追加新的錯誤區塊時保留原始身分;取代錯誤儲存格會在儲存時清掉過時的具型別錯誤中繼資料
TXLSXRichErrorCodes 是解碼 rich error 區塊所用的整數陣列型別;應用程式碼從儲存格的 Variant 值讀取具型別錯誤
BIFF8 無法如實表達這些現代錯誤與溢出運算子;傳統序列化器會拒絕不受支援的現代表示法,而不是塞給它一個不相關的舊版錯誤碼
轉換前置檢查
TXLSXWorkbook.GetConversionReport 回傳由呼叫端持有的 TXLSConversionReport,不重算也不改動活頁簿;型別宣告在 lxDiagnostics
Report := Workbook.GetConversionReport(xlsConversionOpenDocument);
try
for I := 0 to Report.Count - 1 do
InspectIssue(Report.Items[I]);
finally
Report.Free;
end;
| Target | xlsConversionOpenXmlWorkbook, xlsConversionOpenXmlTemplate, xlsConversionMacroEnabledTemplate, xlsConversionOpenDocument, xlsConversionExcel97Workbook, or xlsConversionExcelBinaryWorkbook |
| Fidelity | TXLSConversionFidelity: xlsConversionPreserved, xlsConversionDegraded, xlsConversionDropped, or xlsConversionUnsupported |
| Issue | TXLSConversionIssue exposes Feature, Fidelity, SheetIndex, SheetName, Location, and Message; HasLoss includes degraded, dropped, and unsupported entries |
這份報告盤點已知的格式損失,例如 VBA、保護、活頁簿檢視、連線、查詢表、註解、外部連結、XML 地圖、資料表結構、篩選條件、繪圖、具型別錯誤快取、不支援的驗證或公式語法、陣列歸屬與不透明擴充部分;它描述的是已實作的轉換路徑,並不保證每項功能在每個外部應用程式中的表現
ODS 保留普通表格儲存格、快取的公式結果、受支援的註解文字與作者、無密碼的工作表保護與可表達的篩選,同時失去 Excel 資料表物件、更豐富的圖表幾何或不支援的規則語意;當目標無法承載時,不透明的 OOXML 保留承載會被回報為 dropped
XLSX 外觀層把 BIFF8 輸出回報為不支援;受支援的 BIFF 工作流程請使用傳統活頁簿 API;版本 2.384.93 新增了有界的 XLSB 值與樣式後端,在受檢查與未檢查的儲存中都拒絕無法表達的公式、功能物件、中繼資料與計算設定
受檢查的儲存
Status := Workbook.SaveAsChecked(Stream, xlsxOpenDocumentSpreadsheet, False);
檔案與串流多載會在寫出前執行已知損失前置檢查;AllowLossy=False 以轉換診斷拒絕 degraded 或 dropped 的功能,AllowLossy=True 則明確接受這些損失,但仍拒絕不支援的轉換
被拒絕的前置檢查不會動到目的地的位元組與串流位置;成功的請求使用既有的儲存交易,並回傳與 SaveAs 相同的儲存狀態慣例
普通 SaveAs 仍可用且行為不變;需要明確損失決策的應用程式應先檢視報告,再使用受檢查的儲存
範本格式
xlsxOpenXMLTemplate 選擇無巨集的 XLTX,xlsxOpenXMLMacroEnabledTemplate 選擇 XLTM 並保留既有的 VBA 專案;格式是明確指定的,不會從副檔名或匯入的範本推斷
無巨集的 XLTX 即使啟用容損的受檢查儲存,仍拒絕帶 VBA 的活頁簿;XLTM 套件可以不含 VBA 專案輸出,HotXLS 也不會建立 VBA 程式碼
ODS 驗證公式
自訂布林驗證使用 of:is-true-formula(...);受支援的純量邊界、清單來源、限定的 A1 參照、字串與引數分隔符可轉換為 OpenFormula,並在匯入時對驗證的基準儲存格位址重新定基
不支援的結構化、外部或三維驗證運算式會連同其儲存格參照一起省略,避免懸空的驗證定義;轉換前置檢查會回報被省略的規則
ODS 註解、保護與篩選
普通儲存格註解會連同文字與作者匯出為 OpenDocument 註解,包括空白備註、tab、空格與換行;位於不存在儲存格或遙遠座標的備註使用稀疏的重複列欄區段,不會建立工作表儲存格
合併範圍錨點儲存格上的註解保留其位址;被覆蓋儲存格上或工作表格線之外的備註會被回報為 dropped;rich 註解文字會攤平為其顯示文字,轉換報告會指出 run 樣式、自訂框尺寸與恆常顯示設定的損失
OpenDocument 的受保護旗標與受支援的鎖定或未鎖定儲存格樣式會保留;這個無損的工作表子集不使用密碼或可編輯範圍例外,只允許選取鎖定與未鎖定儲存格
Sheet.Protect; Sheet.SheetProtectionOptions := [xlsxSpoSelectLockedCells, xlsxSpoSelectUnlockedCells]; Sheet.Range['B2:B100'].Locked := False;
Excel 密碼雜湊、現代密碼設定、可編輯範圍與該子集之外的動作權限會被回報為 degraded,受保護旗標則保留;Excel 寬鬆的預設權限組合同樣需要明確的損失決策
OpenDocument 匯入保留受保護旗標與儲存格鎖定樣式;原生密碼雜湊不會轉成 Excel 雜湊,未表達的匯入權限中繼資料在後續的轉換報告中仍是具名的損失
AutoFilter 匯出支援六種純量比較運算子、每欄最多兩個以 AND 或 OR 連接的純量條件,以及欄之間的一個 AND;受支援的純值選取清單與空白選取沒有兩值限制,並保持為原生篩選中繼資料
數值純量條件使用不變的有限值;文字選取保留其字面字元,包括選取清單內的萬用字元,而自訂篩選中的萬用字元運算式、模糊的布林條件、日期群組、動態日期、色彩與圖示篩選沒有可支援的對等轉換
不支援的篩選運算式會以完整運算式為單位省略,而不是弱化部分條件;篩選範圍保留,轉換報告會指出被省略的條件
ODS 串流儲存會先把完成的套件暫存在已註冊的暫存檔,再寫到目的地的原位置;既有的前綴位元組與絕對 ZIP 偏移照樣保留,包括超出原檔結尾的位置;提交前的取消或進度回呼例外會保留目的地的位元組、大小與位置並釋放暫存檔;最後的寫入通知仍不可取消
OpenDocument 匯入支援相同的純量連詞與同欄文字選言或值組;跨欄 OR、正規表示式、區分大小寫的比較與不支援的原生篩選運算子仍是明確的匯入損失
TXLSXOdsImportLoss 與 TXLSXOdsImportLosses 描述私有的工作表來源類別;轉換報告使用 ImportedOdsProtectionPassword、ImportedOdsProtectionOptions、ImportedOdsFilterCriteria 與 ImportedOdsCommentFormatting;這些類別能在工作表複製後存留,且同時出現在 OpenDocument 與 Open XML 轉換目標
篩選轉換保留中繼資料與既有的列可見性,不套用篩選也不重算儲存格;原生應用程式自己的篩選與編輯行為仍由其自行負責