【问题标题】:Connection string passing all values as text将所有值作为文本传递的连接字符串
【发布时间】:2017-03-10 11:26:27
【问题描述】:

我正在努力将数据从 text file with header line

文本文件中的值用制表符分隔,因此我必须创建 Schema.ini 文件,该文件与文本文件保存在同一文件夹中:

[test no1.txt]
ColNameHeader=True
Format=TabDelimited
MaxScanRows=0
Col1="Column number 1" Float
Col2="Column number 2" Text
Col3="Column number 3" Text

我正在将文本文件中的所有值选择到记录集中。然后,我使用这个连接字符串来打开目标 excel:

Public Function getXlsConn() As ADODB.Connection
    Dim rv As New ADODB.Connection
    Dim strConn As String

    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source=" & targetFileName & ";" & _
    "Extended Properties=""Excel 12.0;HDR=YES;IMEX=0"";"

    rv.Open strConn
    Set getXlsConn = rv
End Function

我得到目标记录集(Excel 表中的范围),我正在遍历源记录集的所有行(来自文本文件的数据)并将它们传递到目标记录集中。在循环结束时,我正在使用命令 UpdateBatch 更新目标记录集:

Sub CopyToXls(pRecordSet As ADODB.Recordset, pSheetName As String)
    Dim con As ADODB.Connection, rs As ADODB.Recordset
    Dim i As Long
    Dim size As Integer
    Dim fieldsArray() As Variant
    Dim values() As Variant

    Set con = getXlsConn()

    Set rs = New ADODB.Recordset

    rs.CursorLocation = adUseServer
    'header starts from 2nd row
    rs.Open "select *  from [" & pSheetName & "$A2:C600000]", con, _
             adOpenDynamic, adLockOptimistic

    'get number of columns and their names
    size = rs.Fields.Count - 1
    ReDim values(size)
    ReDim fieldsArray(size)
    For i = 0 To size
        fieldsArray(i) = rs.Fields(i).Name
    Next i

    'get end of file
    If rs.EOF = False Then
        rs.MoveFirst
    End If

    'copy rows from source recordset (text file) to target recordset (excel sheet)
    Do Until pRecordSet.EOF = True
            For i = 0 To size
                    values(i) = pRecordSet.Fields(i).Value
            Next i
            rs.AddNew fieldsArray, values
        pRecordSet.MoveNext
        rs.MoveNext
    Loop

    rs.UpdateBatch

    rs.Close
    Set rs = Nothing
    Set con = Nothing

End Sub

不幸的是,所有值 are passed as text,因此第一列的 SUM 函数(位于 A1 单元格中)不起作用。

我尝试更改连接字符串的 IMEX 参数 - 对于值 1 和 2,我收到错误“无法更新。数据库对象是只读的”。

我想完全按照我在 Schema.ini 文件中定义的方式传递值。这可能吗?

【问题讨论】:

  • 您是否尝试在 select 语句中指定每一列并将其转换为正确的类型?例如。 Select CDbl(Field1) as MyField from MyTable
  • @RyanWildry 谢谢你的回复,我试过你的方法 - 在目标记录集上执行 UpdateBatch 之前,第一列中的值被转换为 double 类型,但是当我打开目标 Excel 表时,首先列是空的,其余列都被很好地传递(作为文本)。没有错误消息或异常。
  • 你能发布完整的代码吗?你在使用CopyFromRecordset 方法吗?

标签: vba excel connection-string ado


【解决方案1】:

这是连接到文本文档的一般方法。

我的示例文本文件如下所示:

1,a,b
1,a,b
1,a,b
1,a,b

为简单起见,我只是将分隔符设为逗号。

这是我正在使用的代码。需要特别注意的是,如果您有不同的分隔符,则需要更改分隔符类型。我已经注意到那部分代码。

Public Sub OutputToExcel()
    Dim mySheet     As Worksheet: Set mySheet = ThisWorkbook.Sheets("Sheet1")
    Dim FolderPath  As String: FolderPath = "C:\Users\Megatron\Desktop\"
    Dim SQL         As String: SQL = "SELECT CDbl(F1) as Field1, " & _
                                     "Cstr(F2) as Text1, CStr(F3) as Text2 " & _
                                     "FROM MyFile.txt"

    Dim myRs        As ADODB.Recordset: Set myRs = New ADODB.Recordset
    Dim conn        As ADODB.Connection: Set conn = New ADODB.Connection

    'Change the FMT=Delimited to FMT=TabDelimited,
    'or continue using the schema.ini which I prefer
    Dim connstr     As String: connstr = "Provider=Microsoft.Ace.OLEDB.12.0;" & _
                                         "Data Source=" & FolderPath & _
                                         ";Extended Properties='text;HDR=No;FMT=Delimited';"
    'Open a connection
    With conn
        .connectionstring = connstr
        .Open
    End With

    'Read the data
    myRs.Open SQL, conn, adOpenForwardOnly, adLockOptimistic

    'Output the data
    mySheet.Range("A1").CopyFromRecordset myRs

    'Clean Up
    If myRs.State = adStateOpen Then myRs.Close: Set myRs = Nothing
    If conn.State = adStateOpen Then conn.Close: Set conn = Nothing
End Sub

【讨论】:

  • Command CopyFromRecordset 完全符合我的要求 - 第一列中的值作为数字传递给 Excel 工作表。但是,现实生活中的 excel 包含 18 张工作表,每张工作表有 21 列和数万行 - 因此我不想使用命令 Workooks.Open 和 Workbook.Sheets(nameOfSheet) 打开目标 excel 以避免内存不足一半通过。相反,我使用连接字符串 (getXlsConn) 打开了 excel,并将行从源记录集复制到目标记录集(有问题的方法 CopyToXls)。是否有任何“优化”的方式来打开 excel,例如没有附加组件?
  • 使用ADO,相信方法叫OpenSchema。您可以直接写入文件,而无需使用 Excel 打开文件。
猜你喜欢
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2012-07-11
  • 1970-01-01
相关资源
最近更新 更多