无论如何让ADO在保存之前从只读excel文件读取更新的数据? (VBA)
问题描述:
我正在使用以下代码从Sheet1的Sheet读取数据。我将数据加载到返回数组中。 Excel工作表文件具有“只读”选中状态并始终以“只读”模式打开。无论如何让ADO在保存之前从只读excel文件读取更新的数据? (VBA)
问题是如果我更改Sheet1上的任何数据,因为该文件打开为“只读”,它不会反映在ADO查询中。 ADO继续输出“已保存”文件中的内容,并忽略在临时只读版本中更新的内容。 例如,下面从单元格“E6”中拉取值“Col5:6”。如果我将值替换为“测试”,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
答
你不能用ADO读取Excel工作表中未保存的更改,因为未保存的数据位于内存(RAM,并可能交换文件),和ADO设计用于连接到DB 文件或服务器基于数据库。
如果您认为SQL是唯一的方法,并且您的WHERE
子句非常简单,那么您可以使用内置的ADO Recordset功能进行筛选和排序,而无需建立连接。执行以下操作:
- 以XML格式获取源范围的值,修复字段名称。
- 创建XML DOM文档并加载XML字符串。
- 创建ADO记录集并转换文档。
- 进行必要的筛选和排序。请注意,有some limitations on filter criteria语法。
- 进一步处理结果记录集,例如, G。输出到另一个工作表。
有代码的一个例子:
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数据如下:
然后我上Sheet2
结果:
我会使用一个公共变量,blnWorksheetDirty作为布尔值,然后在工作表中更改事件,如果发生更改,那么将其设置为true,那么如果存在,则保存临时副本并查询,如果不是,则使用您的有。 –
是不是有一种方法可以指示ADO读取只读版本中的临时数据?还是必须始终从最后保存的版本中读取? –
为什么要使用ADODB?当它似乎要求您先将文件保存在某个位置(您想要避免的位置)?为什么不直接将数据“抓”到数组中并跳过ADO连接?这只是两行VBA代码:http://stackoverflow.com/questions/18000617/how-to-copy-selected-range-into-given-array/18000989#18000989如果这不是一个选项,那么如何使用不同的像数据库服务器的后端数据? – Ralph