【问题标题】:IMEX=1 seems to have no effectIMEX=1 好像没有效果
【发布时间】:2016-05-19 09:16:20
【问题描述】:

我使用 ADODB 将数据从 Excel 文件提取到另一个 Excel 文件而不打开源代码。我强烈怀疑我的连接不接受IMEX=1 参数。我这样开始我的连接:

con1.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
 "Data Source=" & sFile & ";" & _
 "Extended Properties=""Excel 12.0;HDR=No;IMEX=1;"""

所以我明确声明我希望使用IMEX=1,但我发现它不起作用,尽管它存在于连接属性树中:

最小、完整且可验证的示例

1. 创建一个文件C:/Temp/Source.xlsx,您应该在其中输入这 9 个值:

保存并关闭此文件。

2. 将以下代码粘贴到应具有名为“Sheet1”的工作表的任何其他(新)工作表中并运行它:

Sub PullData()

    Dim con1 As Object
    Dim rst1 As Object
    Dim sFile As String
    Dim x As Long, Y As Long, Xupper As Long, Yupper As Long
    Dim arrData() As Variant, arrTransp() As Variant
    Dim rngTargStart As Range

    Set con1 = CreateObject("ADODB.Connection")
    Set rst1 = CreateObject("ADODB.Recordset")
    sFile = "C:\Temp\Source.xlsx"

    con1.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
     "Data Source=" & sFile & ";" & _
     "Extended Properties=""Excel 12.0;HDR=No;IMEX=1;"""

    'pulling
    rst1.Open "SELECT * FROM [Sheet1$A1:A9];", con1, 3, 1
    x = rst1.RecordCount '.GetRows sometimes yields "Record is too large". This line fixes it.
    arrData = rst1.GetRows
    rst1.Close

    'transposing
    Xupper = UBound(arrData, 2)
    Yupper = UBound(arrData, 1)
    ReDim arrTransp(Xupper, Yupper)
    For x = 0 To Xupper
        For Y = 0 To Yupper
            arrTransp(x, Y) = arrData(Y, x)
        Next
    Next

    'updating worksheet
    Set rngTargStart = ThisWorkbook.Sheets("Sheet1").Range("A1")
    rngTargStart.Resize(UBound(arrTransp, 1) + 1, UBound(arrTransp, 2) + 1).Value = arrTransp

    con1.Close
    Set con1 = Nothing
    Set rst1 = Nothing
End Sub

运行后我得到了这个:

知道为什么,以及如何解决吗?我将非常感谢任何 cmets。

完整的con1.connectionstring 如下所示:

Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=C:\Temp\Source.xlsx;Mode=Share Deny None;Jet OLEDB:System database="";Jet OLEDB:Registry Path ="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=37;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:不要在 Compact=False 上复制区域设置;Jet OLEDB:Compact without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet OLEDB:Bypass UserInfo Validation=False;Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False;

我在 Windows 7 64 位上使用 Office Pro Plus 2013 32 位。

【问题讨论】:

    标签: excel vba connection-string oledb adodb


    【解决方案1】:

    所以最初我认为IMEX=1 阻止对任意数量的值进行任何评估,并且只是将每个值作为文本导入。显然不能阻止评估值(默认情况下评估 8 个值)。 IMEX=1 实际上所做的是将列中的每个值存储为文本,前提是这 8 个评估单元格满足某些条件。我测试了不同的源数据集,以了解如何评估这 8 个值(在决定是否将列中的所有值都视为文本并因此导入时,哪些值优先于其他值)。这就是结果。

    文本值 > 数值 > 文本格式 >(自定义格式)> 数值格式 > 格式化单元格 > 通用格式空单元格

    仅当这 8 个评估单元格中没有更高优先级的值时,粗体值才允许导入整个列(视为文本)。例如,如果在前 8 个单元格中有 7 个空单元格被格式化为文本,而一个单元格内部有一个实际数字,则不会导入文本数据(将导入空白值)。

    详细测试结果:

    如果您在前 8 个单元格中有任何实际文本值,您将始终成功导入列中的所有值:

    如果前 8 个单元格中有任何数字值且没有文本值,您将无法在该列中导入文本值(将导入空白值):

    现在,如果您的前 8 个单元格中没有值,并且其中至少一个被格式化为文本,您将导入文本值:

    如果前 8 个单元格全部为空并且至少有一个数字格式的单元格(没有文本格式的单元格),您将无法在该列中导入文本值(将导入空白值):
    但是,后者(只有一种数字格式)将成功导入列中的文本值如果来源工作簿在导入时没有在任何 Excel 实例中打开

    然后我们有空的格式化单元格(例如颜色格式) - 列中的文本值将被成功导入:

    另一种情况 - 未格式化的空单元格,但有一些数据或格式在另一列

    最后,如果其他列(完全清除的行)中没有数据或格式,您的第一行可能会从输出中消失:

    我跳过了自定义格式,因为我认为结果可能取决于实际格式。我的结果很有趣,当源书打开时,我成功导入了列中的文本数据,但是当它关​​闭时,我没有。我的猜测是,当工作簿关闭时,自定义格式可能会被视为数字格式。

    【讨论】:

    • 这真的很奇怪 - 我注意到只有在我要加入的表在特定列中的前 10 个单元格有空白单元格时,我才会在连接期间获得空白列。无论我做什么,更改格式似乎都不会带来数据 - 唯一带来列的是用数据填充一些顶部单元格。多么奇怪,令人沮丧的错误。如果我这样做SELECT * FROM TableName,它就可以正常工作-无论如何他们都会过来。但是,如果我将一个表连接到另一个表,则前 11 行左右为空白的那 3 列在连接后完全为空白。
    【解决方案2】:

    page 解释得很好。基本上,可以确定输入列是数字的。当它到达第 9 行并找到文本时,它可能会崩溃并且通常会崩溃。由于 IMEX 设置为 1,因此它不会崩溃,而是为该值返回 null。如果您有第 10 行,其中包含 8,则它将作为 8 导入第 10 行。

    但是,如果未设置 IMEX,则会生成错误,因此就我所见,它按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-05
      • 2018-02-25
      • 2019-04-06
      • 2012-03-10
      • 2014-05-01
      • 2017-05-10
      • 1970-01-01
      • 2014-08-12
      相关资源
      最近更新 更多