无论如何让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 
+1

我会使用一个公共变量,blnWorksheetDirty作为布尔值,然后在工作表中更改事件,如果发生更改,那么将其设置为true,那么如果存在,则保存临时副本并查询,如果不是,则使用您的有。 –

+0

是不是有一种方法可以指示ADO读取只读版本中的临时数据?还是必须始终从最后保存的版本中读取? –

+0

为什么要使用ADODB?当它似乎要求您先将文件保存在某个位置(您想要避免的位置)?为什么不直接将数据“抓”到数组中并跳过ADO连接?这只是两行VBA代码:http://stackoverflow.com/questions/18000617/how-to-copy-selected-range-into-given-array/18000989#18000989如果这不是一个选项,那么如何使用不同的像数据库服务器的后端数据? – Ralph

你不能用ADO读取Excel工作表中未保存的更改,因为未保存的数据位于内存(RAM,并可能交换文件),和ADO设计用于连接到DB 文件或服务器基于数据库。

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

  1. 以XML格式获取源范围的值,修复字段名称。
  2. 创建XML DOM文档并加载XML字符串。
  3. 创建ADO记录集并转换文档。
  4. 进行必要的筛选和排序。请注意,有some limitations on filter criteria语法。
  5. 进一步处理结果记录集,例如, 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数据如下:

src

然后我上Sheet2结果:

result