我使用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
运行后我得到了这个:
知道原因,以及如何解决这个问题?我非常感谢您的评论。
完整的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位。
答案 0 :(得分:2)
所以最初我认为IMEX=1
阻止对任意数量的值进行任何评估,只是将每个值作为文本导入。显然,人们无法阻止评估值(默认情况下会评估8个值)。 IMEX=1
实际上做的是,如果在这8个评估的单元格上满足某些条件,则仅将列中的每个值存储为文本。我测试了不同的源数据集,以了解如何评估这8个值(在决定列中的所有值是否将被视为文本时,哪些值优先于其他值,因此导入)。这就是结果。
文字值 >数值> 文字格式> (自定义格式)>数字格式> 格式化的单元格>一般格式空单元格
只有在这8个已评估的单元格中没有更高优先级的值时,以粗体显示的值才能导入整个列(视为文本)。例如,如果在前8个单元格中有7个空单元格被格式化为文本,而一个单元格内部具有实际数字,则不会导入文本数据(将导入空白值)。
详细的测试结果:
如果前8个单元格中有任何实际文本值,则始终会成功导入列中的所有值:
如果前8个单元格中有任何数字值且没有文本值,则无法导入该列中的文本值(将导入空白值):
现在,如果前8个单元格中没有值,并且其中至少有一个格式化为文本,则会导入文本值:
如果所有8个第一个单元格都为空并且至少有一个数字格式的单元格(没有文本格式的单元格),则无法导入该列中的文本值(将导入空白值):
但是,如果源工作簿未打开,后者(只有一种数字格式) 会在 列中成功导入文本值 在导入时的任何Excel实例中。
然后我们有空的格式化单元格(例如颜色格式) - 列中的文本值将被成功导入:
另一种情况 - 清空未格式化的单元格,但在另一列中包含数据或格式 :
最后,如果其他列中没有数据或格式(完全清除的行),您的第一行可能会从输出中消失:
我跳过自定义格式,因为我认为结果可能取决于实际格式。我的结果很有趣,因为当源书打开时,我成功地在列中导入了文本数据,但是当它关闭时,我没有。我的猜测是,当工作簿关闭时,自定义格式可能会被视为数字格式
答案 1 :(得分:0)
这page解释得非常好。基本上,它确定输入列是数字。当它到达第9行并找到文本时,它可能会崩溃并且通常会崩溃。由于IMEX设置为1,因此它不会崩溃,而是为值返回null。如果你有一个第10行,其中包含8,那么它将作为8导入到第10行。
但是,如果未设置IMEX,则会生成错误,因此就我所见,它会按预期工作。