【发布时间】:2018-06-16 17:04:01
【问题描述】:
我的目标是能够从已关闭的工作簿中读取和写入单元格值。我使用 ADODB 来获取所需的信息。 文件是由公司网站生成的,所以在使用实际文件之前我无法更改内容。该文件为 Excel 格式。单元格中没有公式,只有值。 我想从工作表中获取日期、字符串、整数,但遇到了一些限制。
我编写了示例代码来向您展示发生了什么:
Dim rsConn As ADODB.Connection
Dim rsData As ADODB.Recordset
Dim strFileName As String
Dim strFieldNames As String
Dim intValue As Integer
strFileName = "C:\Tests\Sample.xlsx" ' Fullpath to a workbook
'strFieldNames = "CInt([Proj_Year]) as [Proj_Year]"
'strFieldNames = "[Proj_Year]"
strFieldNames = "*"
Set rsConn = New ADODB.Connection
With rsConn
.ConnectionString = "Data Source=" & strFileName & "; Extended Properties=""Excel 12.0; HDR=YES; "";"
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open
End With
Set rsData = New ADODB.Recordset
With rsData
.Source = "SELECT " & strFieldNames & " FROM A2:AE500;" ' Sheetname not required
.ActiveConnection = rsConn
'.CursorType = adOpenKeyset ' Tried this - didn't work
'.CursorType = adOpenDynamic ' Tried this - didn't work
.CursorType = adOpenStatic
.LockType = adLockOptimistic
.Open
End With
With rsData
.MoveFirst
Do While Not .EOF
' Getting the value
intValue = .Fields(0).Value
' Make some crazy modifications of the value
intValue = intValue + 10
' Updating
.Fields(0).Value = intValue ' this is place where crash happens
' Move to the next record
.MoveNext
Loop
End With
rsData.Close
Set rsData = Nothing
rsConn.Close
Set rsConn = Nothing
这是示例工作簿的屏幕截图:
我尝试了几种方法:
strFieldNames = "*"我得到工作表中存在的所有列。但是驱动程序试图猜测字段类型,我不喜欢它,因为它的猜测是错误的。例如,单元格 I3 应该是字符串,但实际上它是adDouble。所以阅读可能没问题,但我不能写回字符串。 我尝试使用IMEX=1,但没有帮助,尝试了MAXSCANROWS=1,Readonly=0,但也没有运气。我不想触摸 Windows 注册表来修改猜测行。strFieldNames = "[Proj_Year]"我只收到一列,但我遇到了与 1 中相同的限制。strFieldNames = "CInt([Proj_Year]) as [Proj_Year]"我收到所需类型的所需列。但是当我运行我收到的代码时:
无法更新字段
输入代码:.Fields(0).Value = intValue
在上面的代码中,我一次读取和写入一条记录。我尝试使用 GetRows 读取所有数据(30 列,3000 行),然后将数据数组解析到我自己的类中。读取所有数据后,我会修改此数据并将其一次写回工作表中的一条记录。
我需要做什么才能让这段代码正常工作?
【问题讨论】:
-
SELECT " & strFieldNames & " FROM A2:AE500;?不应该是strSQL = "SELECT * from [sheet1$](stackoverflow.com/questions/24193112/…) 之类的吗?From之后应该是工作表名称而不是范围(在任何给定工作表上),即使文件中只有一张工作表。此外,工作表名称后应跟$并用方括号括起来。 support.microsoft.com/en-us/help/278973/… -
添加工作表名称没有任何区别。
-
我怀疑 ACE 驱动程序在 Excel 中使用静态游标更改记录集时存在问题。你可能想试试
adOpenKeyset。就个人而言,我会使用第二个命令对象来发出UPDATE请求。 -
如果我使用
adOpenKeyset和strFieldNames = "CInt([Proj_Year]) as [Proj_Year]"程序将像以前一样运行。UPDATE呢?可以举几个例子吗? -
你需要 adOpenDynamic、adLockOptimistic