【发布时间】:2020-08-01 21:14:51
【问题描述】:
我将数据存储在 excel 文件中,我正在尝试使用 VBA 对它们运行 SQL 查询。 问题是我正在使用的数据非常脏,不幸的是我对其内容的控制非常有限。因为那个 excel 已经吓坏了,并且不断地为列分配错误的数据类型。
我最好的猜测是类型是由表格第一行中的值决定的。但不幸的是,这种行为确实是不可预测的,而且并非总是如此。示例如下:
我有包含字符串和空值、零或错误的列。此列被视为双列而不是文本。因此,在执行CopyFromRecordset 后,此列中的每个非数字值都会被删除。
我也有带有数字和偶尔为空值的列,然后该列被视为文本。
它与带有WHERE 或JOIN 子句的SQL 查询相混淆。因为如果我在具有 double 类型的列上进行字符串比较,它将不起作用。如果我试图在字符串列上进行数字比较,如果它反过来发生也是一样的。
有时可以通过在有问题的列上设置适当的格式来避免问题,有时可以通过在第一行中写入其他内容来避免问题。但正如我所说,这真的是不可预测的,有时它不起作用。
尝试过这样的事情(遵循this type table):
dbRecordset.Fields(2).Type = 200
但我得到Operation is not allowed when the object is open。
我也尝试在 SQL 查询中进行手动转换,但我觉得它慢得多,语法也很乱。例如这里断言类型为 double (它只有一列,我还有几十个):
Cdbl(IIf(IsNull(c.[Column4]), 0, c.[Column4])) > 0
那么 - 有没有办法告诉 excel 每列中的数据类型是什么?或者如何避免我的问题?
这是我的代码:
Option Explicit
Sub RunCopy()
Dim dbConnection As Object
Dim dbRecordset As Object
Dim strSQL As String
Dim dbField As Variant
Dim fieldCounter As Long
Dim src_wks As Worksheet
Dim dst_wks As Worksheet
Set src_wks = Worksheets("Src")
Set dst_wks = Worksheets("Dst")
Set dbConnection = CreateObject("ADODB.Connection")
Set dbRecordset = CreateObject("ADODB.Recordset")
' CONNECTION WITH EXCEL ODBC DRIVER
dbConnection.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
& "DBQ=" & ThisWorkbook.FullName & ";"
' OPEN RECORDSET
dst_wks.UsedRange.Clear
dbRecordset.Open "SELECT d.* FROM [Src$] d WHERE d.[Column4] > 0", dbConnection
dbRecordset.Fields(2).Type = 200
With dst_wks
' HEADERS
fieldCounter = 0
For Each dbField In dbRecordset.Fields
fieldCounter = fieldCounter + 1
.Cells(1, fieldCounter).Value = dbField.name
Next dbField
' DATA ROWS
.Range("A2").CopyFromRecordset dbRecordset
End With
dbRecordset.Close
dbConnection.Close
Set dbRecordset = Nothing: Set dbConnection = Nothing
End Sub
【问题讨论】: