Excel 无法使用VBA中的ADODB更新字段
我的目标是能够从关闭的工作簿中读取和写入单元格值。我使用ADODB获取所需的信息。 文件是由公司网站生成的,因此在使用实际文件之前,我无法更改内容。该文件为Excel格式。单元格中没有公式,只有值。 我想从工作表中获取日期、字符串和整数,但我遇到了一些限制 我编写示例代码是为了向您展示发生了什么:Excel 无法使用VBA中的ADODB更新字段,excel,vba,field,adodb,Excel,Vba,Field,Adodb,我的目标是能够从关闭的工作簿中读取和写入单元格值。我使用ADODB获取所需的信息。 文件是由公司网站生成的,因此在使用实际文件之前,我无法更改内容。该文件为Excel格式。单元格中没有公式,只有值。 我想从工作表中获取日期、字符串和整数,但我遇到了一些限制 我编写示例代码是为了向您展示发生了什么: Dim rsConn As ADODB.Connection Dim rsData As ADODB.Recordset Dim strFileName As String Dim strFieldN
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_年])作为[Proj_年]”
我收到我想要的类型的所需列。但当我运行代码时,我收到:.Fields(0).Value=intValue
在上面的代码中,我一次读写一条记录。我尝试使用GetRows读取所有数据(30列,3000行),然后将数据数组解析到我自己的类中。读取所有数据后,我修改这些数据,并将其一次一条记录写回工作表
要使此代码正常工作,我需要做什么?我通常只使用
连接
对象的执行
方法
MyBefore数据集(这是位于文件路径
变量处的文件中的数据):
我的之后的数据集:
Field1 Field2
1 b
2 b
3 c
4 d
5 e
这是对我有用的代码
Const FilePath As String = "C:\Users\MyComputerName\Desktop\Book1.xlsx"
Const ConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FilePath & _
";Extended Properties='Excel 12.0 Xml;HDR=YES';"
Public Sub testUpdate()
Dim conn As ADODB.Connection: Set conn = New ADODB.Connection
With conn
.connectionstring = ConnStr
.Open
.Execute "Update [Sheet1$] set Field2='b' where Field1=1"
End With
If conn.State = adopenstate Then conn.Close: Set conn = Nothing
End Sub
其他一些观察结果
- 此
似乎不是有效的文件名。所以这可能会给你带来悲伤strFileName=“C:\Tests\Sample.xlxs”
- 数据集的第一行不包含标题,因此使用工作表名称
例如,我认为默认值为[Sheet1$]
,表示字段名(F1=Field1)。如果您想要两全其美,请使用以下表格和范围来限定范围:F1、F2、F3
。请参阅更多详细信息[Sheet1$A1:B10]
连接
对象的执行
方法
MyBefore数据集(这是位于文件路径
变量处的文件中的数据):
我的之后的数据集:
Field1 Field2
1 b
2 b
3 c
4 d
5 e
这是对我有用的代码
Const FilePath As String = "C:\Users\MyComputerName\Desktop\Book1.xlsx"
Const ConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & FilePath & _
";Extended Properties='Excel 12.0 Xml;HDR=YES';"
Public Sub testUpdate()
Dim conn As ADODB.Connection: Set conn = New ADODB.Connection
With conn
.connectionstring = ConnStr
.Open
.Execute "Update [Sheet1$] set Field2='b' where Field1=1"
End With
If conn.State = adopenstate Then conn.Close: Set conn = Nothing
End Sub
其他一些观察结果
- 此
似乎不是有效的文件名。所以这可能会给你带来悲伤strFileName=“C:\Tests\Sample.xlxs”
- 数据集的第一行不包含标题,因此使用工作表名称
例如,我认为默认值为[Sheet1$]
,表示字段名(F1=Field1)。如果您想要两全其美,请使用以下表格和范围来限定范围:F1、F2、F3
。请参阅更多详细信息[Sheet1$A1:B10]
从A2:AE500中选择“&strFieldNames&”代码>?它是否应该类似于strSQL=“SELECT*from[sheet1$]
()?from
后面的应该是工作表名称,而不是范围(在任何给定的工作表上)即使您的文件中只有一个工作表。此外,工作表名称后面应该跟一个$
,并封装在方括号中。添加工作表名称没有任何区别。我怀疑ACE驱动程序在Excel中使用静态光标更改记录集时有问题。您可能需要尝试adOpenKeyset
.Perso最后,我会使用第二个命令对象发出UPDATE
请求。如果我使用adOpenKeyset
和strFieldNames=“CInt([Proj_Year])作为[Proj_Year]“
程序将像以前一样运行。UPDATE
怎么样?你能给我一些例子吗?你需要一个动态的,adlock选择”&strFieldNames&“FROM A2:AE500;
?是否应该类似于strSQL=“SELECT*FROM[sheet1$]”
()?在From
后面应该是工作表名称,而不是范围(在任何给定工作表上),即使您的文件中只有一张工作表。此外,图纸名称后面应跟一个$
,并封装在方括号中。添加工作表名称没有任何区别。我怀疑ACE驱动程序在Excel中使用静态光标更改记录集时存在问题。您可能需要尝试adOpenKeyset
。就我个人而言,我会使用第二个命令对象来发出UPDATE
请求。如果我使用adOpenKeyset
和strFieldNames=“CInt([Proj_Year])作为[Proj_Year]”,
程序将像以前一样运行。更新怎么样?你能给我举一些例子吗?你需要adOpenDynamic、ADLockOptimistic,然后我想知道更多的例子:。执行“更新[Sheet1$]set Field2='b',其中Field1=1”
。如果我想修改以下单元格:B6=“打开”、C12=123、E9=345、I17=Null等等。如果我有300行要修改怎么办。怎么样?关于观察。我写了一个假文件名,因为这只是一个例子。当我使用第二行作为标题行时,我不知道你为什么要说第一行。sheetname不是必需的,我被问到了上面同样的问题。我的观点是Xlxs不是有效的文件扩展名,如果这是一个问题的话。您正在编写更新记录的SQL语句