Setup Environment:
我正在使用带有.NET framework 4的vb.net开发Excel 2010应用程序级外接程序 .
My goal:
-
让用户输入多个名称进行搜索
-
使用名称列表在LARGE电子表格上执行SQL查询(30,000行)
-
返回记录集并粘贴到新工作表中
表现是我的首要任务 . 我想通过利用.NET框架了解最快的方法 .
在我的代码中使用ADO连接对象可以工作,但这个过程需要很长时间(5 - 8秒) .
This is the SQL query I'm using on the table named wells:
SELECT *
FROM wells
WHERE padgroup in
(SELECT padgroup
FROM wells
WHERE name LIKE 'TOMCHUCK 21-30'
OR name LIKE 'FEDERAL 41-25PH')
Here's a portion of what the table looks like:
I'm using this code right now to create an ADO Connection Object to retrieve my results:
'Create Recordset Object
rsCon = CreateObject("ADODB.Connection")
rsData = CreateObject("ADODB.Recordset")
rsCon.Open(szConnect)
rsData.Open(mySQLQueryToExecute, rsCon, 0, 1, 1)
'Check to make sure data is received, then copy the data
If Not rsData.EOF Then
TargetRange.Cells(1, 1).CopyFromRecordset(rsData)
Else
MsgBox("No records returned from : " & SourceFile, vbCritical)
End If
'Clean up the Recordset object
rsData.Close()
rsData = Nothing
rsCon.Close()
rsCon = Nothing
根据我所知,Excel电子表格以Open XML格式存储,.NET框架包括解析XML的本机支持 .
After researching it, I came across a few different options:
有人可以提供一个指针,指出最好的方法吗?我真的很感激 .
Additional Notes:
-
所有查询都需要能够在不连接到在线数据库的情况下执行
-
我只需要访问一次电子表格就可以从行中提取原始数据
现在我只是将电子表格作为项目资源嵌入 .
然后,在运行时我创建文件,运行查询,将结果存储在内存中,并删除文件 .
'Create temp file path in the commonapplicationdata folder
Dim excelsheetpath As StringBuilder
excelsheetpath = New StringBuilder(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData))
excelsheetpath.Append("\MasterList.xlsm")
'Save resources into temp location in HD
System.IO.File.WriteAllBytes(excelsheetpath.ToString, My.Resources.MasterList)
'Now call the function to use ADO to get records from the MasterList.xlsm file just created
GetData(excelsheetpath.ToString, "Sheet1", "A1:S40000", True, False)
'Store the results in-memory and display by adding to a datagridview control (in a custom task pane)
'Delete the spreadsheet
System.IO.File.Delete(excelsheetpath.ToString())
3 回答
你正在以错误的方式做VSTO;)不要在Excel中使用SQL . 如果您需要速度,请利用VSTO和本机Excel API . 您可以跳过ADODB / OLEDB图层的开销,直接进入Excel对象模型,在Excel中使用超快速自动过滤器,
SpecialCells
方法仅将可见单元格放入多区域范围,并使用Value
方法快速复制范围到数组 .以下是VSTO 2010自定义工作簿示例,可快速搜索包含"aba","cat"或"zon"的a list of 58k words for words .
Excel 2010文件不是完全XML . 获取XLSX(或XMSM)文件,并使用.zip扩展名重命名该文件 . 然后将其解压缩到一个新文件夹 . 子文件夹中的文件将是XML文件,是的,但实际的XLSX文件是一个zip文件,其中包含包含XML文件的文件夹集合 .
我认为,您最好的选择是使用ACE驱动程序(不再支持JET)并通过ODBC访问它 . 如果这还不够快,您可以在特定时间提取摘录并将其上传到可以运行查询的数据库;查询应该更快,但可能会过时 .
My Solution:
我尝试了三种不同的方法:
带SQL的ADO连接对象(最慢)
VSTO和Excel的自动过滤器(可靠)
LINQ to XML (fastest)
LINQ to XML提供了最佳性能 . 我将我的表转换为XML文件:
然后,在我的代码中,我使用StringReader引入XMLwellData文件(将其保存为项目资源) .
做我想做的事情简直太简单了,最棒的是它很快 .
感谢您的所有帮助和建议 . 这对我来说很有意义 .
Alternative Method using Excel's Autofilter
如果您尝试使用其他答案中建议的代码,则只会过滤两个值:
因此,对于filter with multiple criteria using Excel's Auotfilter,您必须将参数作为数组传递并过滤xlFilterValues .