Excel 物件模型無 Find 物件 (Word 有),但 Range 提供 Find() 方法。另一種方式是取得 UsedRange 逐列逐欄掃描 Cells[i,j].Text。
using Excel = Microsoft.Office.Interop.Excel;
public bool SearchWorkbook(string filePath, string keyword)
{
var app = new Excel.Application();
try
{
var wb = app.Workbooks.Open(filePath, ReadOnly: true);
string searchText = keyword.Trim().ToUpper();
foreach (Excel.Worksheet ws in wb.Worksheets)
{
// 索引從 1 開始!非 0
Excel.Range used = ws.UsedRange;
Excel.Range found = used.Find(
What: searchText,
LookIn: Excel.XlFindLookIn.xlValues,
LookAt: Excel.XlLookAt.xlPart,
SearchOrder: Excel.XlSearchOrder.xlByRows,
SearchDirection: Excel.XlSearchDirection.xlNext,
MatchCase: false
);
if (found != null)
{
// 找到:found.Row, found.Column 為位置
wb.Close(false);
return true;
}
}
wb.Close(false);
return false;
}
finally
{
app.Quit();
// 建議 Marshal.ReleaseComObject 清理
}
}
LookIn:xlValues (值)、xlFormulas (公式)、xlComments (批註)LookAt:xlPart (部分符合)、xlWhole (完整符合)SearchDirection:xlNext (向下/向右)、xlPrevious (向上/向左) —— 必須明確指定,不可用 Type.Missing
foreach (Excel.Worksheet ws in wb.Worksheets)
{
Excel.Range used = ws.UsedRange;
int startRow = used.Row; // 起始列 (通常 1)
int startCol = used.Column; // 起始欄 (通常 1)
int rowCount = used.Rows.Count;
int colCount = used.Columns.Count;
// 特殊現象:單一儲存格 UsedRange 索引從 1 開始;多儲存格從 0 開始?
// 實測:Cells 集合索引**永遠從 1 開始** (Excel 物件模型一致)
for (int r = startRow; r < startRow + rowCount; r++)
{
for (int c = startCol; c < startCol + colCount; c++)
{
string cellText = ((Excel.Range)used.Cells[r, c]).Text?.ToString() ?? "";
if (cellText.ToUpper().Contains(searchText))
return true; // 找到
}
}
}
| 指標 | Range.Find | 逐儲存格掃描 |
|---|---|---|
| 速度 | 極快 (C++ 內建搜尋) | 慢 (每儲存格跨程序呼叫) |
| 記憶體 | 低 | 高 (大量 COM 呼叫) |
| 搜尋公式結果 | 支援 (LookIn=xlValues) | 僅顯示文字 |
| 搜尋隱藏儲存格 | 可控制 | 全部掃描 |
| 適用場景 | 一般全文搜尋 | 需自訂比對邏輯/正則表達式 |
Workbooks.Open(..., ReadOnly: true)app.ScreenUpdating = false