c# Excel 如何在不循环遍历每个 row/record 的情况下找到特定范围
c# Excel How to find a specific range without looping through every row/record
我正在制作一个工具来检查现有 excel 文件(>20k 条记录)是否在特定列中包含特定字符串。
到目前为止,我已经尝试使用 for 循环来检查每个单元格,但是找到单元格花了将近 2 分钟。
示例:
row name price
-------------------------
7000 AAA 10
7001 AAA 5
7002 AAA 10
7003 AAA 5
7004 AAA 10
7005 AAA 10
7006 AAA 10
7007 BBB 5
7008 BBB 5
7009 AAA 10
7010 BBB 5
...
30000 AAA 10
我的伪代码:
static void Main(string[] args) {
var xlApp = new Excel.Application();
var xlWorkbook = xlApp.Workbooks.Open(@"A_PATH");
Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
var xlRange = xlWorksheet.UsedRange;
int lastRow = xlWorksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
for (int i = 2; i < lastRow; i++) {
if(xlRange.Cells[i, 1].Value2 != null) {
string value = xlRange.Cells[i, 1].Value2.ToString();
if(value == "BBB") {
Console.WriteLine(((Excel.Range)xlRange.Cells[i, 3]).Value2.ToString());
}
}
}
Console.ReadLine();
}
那么有没有办法让 'query' 更快而不是读取每一行?
我知道 SQL 中有索引跳过扫描之类的东西。也许我可以在 C# 中实现相同的目标。
提前致谢!
我不太擅长 Excel 自动化,但也许您可以尝试使用内置的 Excel 过滤功能?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace ExcelTest1
{
class Program
{
static void Main(string[] args)
{
var excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = true;
var book = excel.Workbooks.Open(@"D:\test.xlsx");
var sheet = book.Sheets[1];
var range = sheet.UsedRange;
//Filter the sheet itself.
range.AutoFilter(Field: 2, Criteria1: "BBB");
//and get only visible cells after the filter.
var result = range.SpecialCells(XlCellType.xlCellTypeVisible, Type.Missing);
Console.WriteLine(result.Rows.Count);
foreach (Range row in result.Rows)
{
Console.WriteLine(row.Cells[1,3].Value2());
}
book.Close(SaveChanges:false);
excel.Quit();
Console.ReadLine();
}
}
}
在一个普通的系统上,这发现 "BBB" 这是 30,000 行测试数据中的最后一行,不到一秒钟。
我正在制作一个工具来检查现有 excel 文件(>20k 条记录)是否在特定列中包含特定字符串。 到目前为止,我已经尝试使用 for 循环来检查每个单元格,但是找到单元格花了将近 2 分钟。
示例:
row name price
-------------------------
7000 AAA 10
7001 AAA 5
7002 AAA 10
7003 AAA 5
7004 AAA 10
7005 AAA 10
7006 AAA 10
7007 BBB 5
7008 BBB 5
7009 AAA 10
7010 BBB 5
...
30000 AAA 10
我的伪代码:
static void Main(string[] args) {
var xlApp = new Excel.Application();
var xlWorkbook = xlApp.Workbooks.Open(@"A_PATH");
Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
var xlRange = xlWorksheet.UsedRange;
int lastRow = xlWorksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
for (int i = 2; i < lastRow; i++) {
if(xlRange.Cells[i, 1].Value2 != null) {
string value = xlRange.Cells[i, 1].Value2.ToString();
if(value == "BBB") {
Console.WriteLine(((Excel.Range)xlRange.Cells[i, 3]).Value2.ToString());
}
}
}
Console.ReadLine();
}
那么有没有办法让 'query' 更快而不是读取每一行? 我知道 SQL 中有索引跳过扫描之类的东西。也许我可以在 C# 中实现相同的目标。 提前致谢!
我不太擅长 Excel 自动化,但也许您可以尝试使用内置的 Excel 过滤功能?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace ExcelTest1
{
class Program
{
static void Main(string[] args)
{
var excel = new Microsoft.Office.Interop.Excel.Application();
excel.Visible = true;
var book = excel.Workbooks.Open(@"D:\test.xlsx");
var sheet = book.Sheets[1];
var range = sheet.UsedRange;
//Filter the sheet itself.
range.AutoFilter(Field: 2, Criteria1: "BBB");
//and get only visible cells after the filter.
var result = range.SpecialCells(XlCellType.xlCellTypeVisible, Type.Missing);
Console.WriteLine(result.Rows.Count);
foreach (Range row in result.Rows)
{
Console.WriteLine(row.Cells[1,3].Value2());
}
book.Close(SaveChanges:false);
excel.Quit();
Console.ReadLine();
}
}
}
在一个普通的系统上,这发现 "BBB" 这是 30,000 行测试数据中的最后一行,不到一秒钟。