IMEX = 1似乎没有效果

时间:2016-02-09 11:41:50

标签: excel-vba connection-string oledb adodb ms-jet-ace

我使用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,但我发现它不起作用,尽管它存在于连接属性树中:
connection properties - IMEX

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

1。创建一个文件C:/Temp/Source.xlsx,您应在其中输入以下9个值:
Source
保存并关闭此文件。

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

运行后我得到了这个:
outcome

知道原因,以及如何解决这个问题?我非常感谢您的评论。

完整的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:数据库密码=“”; Jet OLEDB:引擎类型= 37; Jet OLEDB:数据库锁定模式= 0; Jet OLEDB:全局部分批量操作= 2; Jet OLEDB:全局批量事务= 1; Jet OLEDB:新数据库密码=“”; Jet OLEDB:创建系统数据库= False; Jet OLEDB:加密数据库= False; Jet OLEDB:不复制Compact上的区域设置= False; Jet OLEDB:Compact没有副本修复= False; Jet OLEDB:SFP = False; Jet OLEDB:支持复杂数据= False; Jet OLEDB:绕过UserInfo验证= False; Jet OLEDB:有限DB缓存= False; Jet OLEDB:绕过ChoiceField验证= False;

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

2 个答案:

答案 0 :(得分:2)

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

文字值 >数值> 文字格式> (自定义格式)>数字格式> 格式化的单元格>一般格式空单元格

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

详细的测试结果:

如果前8个单元格中有任何实际文本值,则始终会成功导入列中的所有值:
enter image description here
如果前8个单元格中有任何数字值且没有文本值,则无法导入该列中的文本值(将导入空白值):
enter image description here enter image description here
现在,如果前8个单元格中没有值,并且其中至少有一个格式化为文本,则会导入文本值:
enter image description here enter image description here
如果所有8个第一个单元格都为空并且至少有一个数字格式的单元格(没有文本格式的单元格),则无法导入该列中的文本值(将导入空白值): enter image description here enter image description here
但是,如果源工作簿未打开,后者(只有一种数字格式) 会在 列中成功导入文本值 在导入时的任何Excel实例中。

然后我们有空的格式化单元格(例如颜色格式) - 列中的文本值将被成功导入:
enter image description here
另一种情况 - 清空未格式化的单元格,但在另一列中包含数据或格式
enter image description here
最后,如果其他列中没有数据或格式(完全清除的行),您的第一行可能会从输出中消失:
enter image description here

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

答案 1 :(得分:0)

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

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