无论如何,让ADO在保存之前从只读excel文件读取更新的数据? (VBA)

我正在使用下面的代码来读取来自同一个Excel工作表Sheet1的数据。 我将数据加载到返回数组中。 Excel工作表文件具有“只读”选项,并始终以“只读”模式打开。

问题是 ,如果我更改Sheet1上的任何数据,因为该文件打开为“只读”,它不会反映在ADO查询中。 ADO继续输出“已保存”文件中的内容,并忽略在临时只读版本中已更新的内容。 例如,下面从单元格“E6”拉取值“Col5:6”。 如果我将该值replace为“test”,ADO仍然输出“Col5:6”

如何让ADO读取Sheet1上的当前数据而不必“另存为”?

Sub sbADO() Dim sSQLSting As String Dim Conn As New ADODB.Connection Dim mrs As New ADODB.Recordset Dim DBPath As String, sconnect As String Dim returnArray DBPath = ThisWorkbook.FullName sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DBPath _ & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";" Conn.Open sconnect sSQLSting = "SELECT * From [Sheet1$] " mrs.Open sSQLSting, Conn returnArray = mrs.GetRows mrs.Close Conn.Close Debug.Print returnArray(4, 4) '>> "Col5:6" End Sub 

由于未保存的数据位于内存(RAM和可能的交换文件)中,因此您无法使用ADO从Excel工作表中读取未保存的更改,并且ADO旨在连接到数据库文件或基于服务器的数据库。

如果您认为SQL是唯一的方法,并且您的WHERE子句非常简单,那么您可以使用内置的ADO Recordsetfunction进行筛选和sorting,而无需build立连接。 请执行下列操作:

  1. 以XML格式获取源范围的值,修复字段名称。
  2. 创buildXML DOM文档并加载XMLstring。
  3. 创buildADOlogging集并转换文档。
  4. 进行必要的筛选和sorting。 请注意, 筛选条件语法存在一些限制 。
  5. 进一步处理结果logging集,例如输出到另一个工作表。

有一个代码的例子:

 Option Explicit Sub FilterSortRecordset() Dim arrHead Dim strXML As String Dim i As Long Dim objXMLDoc As Object Dim objRecordSet As Object Dim arrRows ' get source in XML format With Sheets("Sheet1") arrHead = Application.Index(.Range("A1:G1").Value, 1, 0) strXML = .Range("A2:G92").Value(xlRangeValueMSPersistXML) End With ' fix field names For i = 1 To UBound(arrHead) strXML = Replace(strXML, "rs:name=""Field" & i & """", "rs:name=""" & arrHead(i) & """", 1) Next ' load source XML into XML DOM Document Set objXMLDoc = CreateObject("MSXML2.DOMDocument") objXMLDoc.LoadXML strXML ' convert the document to recordset Set objRecordSet = CreateObject("ADODB.Recordset") objRecordSet.Open objXMLDoc ' filtering and sorting objRecordSet.Filter = "City='London' OR City='Paris'" objRecordSet.Sort = "ContactName ASC" ' populate another sheet with resulting recordset arrRows = Application.Transpose(objRecordSet.GetRows) With Sheets("Sheet2") .Cells.Delete .Cells.NumberFormat = "@" For i = 1 To objRecordSet.Fields.Count .Cells(1, i).Value = objRecordSet.Fields(i - 1).Name Next .Cells(2, 1).Resize(UBound(arrRows, 1), UBound(arrRows, 2)).Value = arrRows .Columns.AutoFit End With End Sub 

Sheet1上的Sourse数据如下:

SRC

然后我在Sheet2上得到结果:

结果