无法使用ADBA中的ADODB更新字段

时间:2017-03-11 14:18:34

标签: excel vba field adodb

我的目标是能够从已关闭的工作簿中读取和写入单元格值。我使用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

以下是示例工作簿的屏幕截图:

screenshot

我尝试了几种方法:

  1. strFieldNames = "*" 我得到工作表中的所有列。但司机试图猜测字段类型,我不喜欢它,因为它的猜测是错误的。例如,单元格I3应该是字符串,但实际上它是adDouble。所以阅读可能没问题,但我不能回写为字符串。 我尝试使用IMEX=1,但它没有帮助,尝试MAXSCANROWS=1Readonly=0但也没有运气。我不想触摸Windows注册表来修改猜测行。

  2. strFieldNames = "[Proj_Year]" 我只收到一列,但我遇到了与1相同的限制。

  3. strFieldNames = "CInt([Proj_Year]) as [Proj_Year]" 我收到了我想要的类型所需的列。但当我运行我收到的代码时:

  4. 字段无法更新

    代码中的

    .Fields(0).Value = intValue

    在上面的代码中,我一次只读一个记录。我尝试使用GetRows读取所有数据(30列,3000行),然后将数据数组解析到我自己的类中。读完所有数据后,我会修改这些数据,并一次将其写回工作表一条记录。

    为了让这段代码有效,我需要做些什么?

1 个答案:

答案 0 :(得分:0)

我通常只使用Execute对象的Connection方法。

我的之前数据集(这是位于FilePath变量的文件中的数据):

Field1  Field2
   1    a
   2    b
   3    c
   4    d
   5    e

我的之后数据集:

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,F2,F3(F1 = Field1)。如果您想要两全其美,请使用Sheet AND 范围限定范围,如下所示:[Sheet1$A1:B10]。请参阅here详细信息。