一个非常简单的查询函数,它接收源CSV文件的路径和作为字符串的SQL语句(我也是从VBA函数转置数据),
Public Function RunQuery(FilePath As String, SQLStatement As String)
Dim Conn As New ADODB.Connection
Dim RecSet As New ADODB.Recordset
With Conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=" & FilePath & ";" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited;IMEX=1"""
End With
Conn.Open
RecSet.Open SQLStatement, Conn
RecSet.MoveFirst
RunQuery = RecSet.GetRows()
Conn.Close
Set RecSet = Nothing
Set Conn = Nothing
End Function
此代码对CSV文件间歇性地工作,一些数据被正确检索而一些数据没有。
这两个CSV文件就是一个例子 - Abbreviated和Full。以下SQL查询在缩写文件上完美运行,但在完整文件中返回#VALUE。
SELECT birthYear FROM [File]
这绝对不是数据限制/大小问题,因为Full文件只包含1800行。我完全被迷惑了,并会感激任何想法/指示。
顺便说一句,如果我将逻辑包装成Sub而不是UDF,那么它可以完美地运行而不会出现任何错误,
Public Sub RunQuerySub()
Dim Conn As New ADODB.Connection
Dim RecSet As New ADODB.Recordset
Dim FilePath As String
FilePath = ActiveSheet.Range("Path")
With Conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=" & FilePath & ";" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited;IMEX=1"""
End With
Dim SQLStatement As String
SQLStatement = ActiveSheet.Range("SQL")
Conn.Open
RecSet.Open SQLStatement, Conn
ActiveSheet.Cells(1, 8).CopyFromRecordset RecSet
Conn.Close
Set RecSet = Nothing
Set Conn = Nothing
End Sub
我很困惑,并且会感激任何指示。
答案 0 :(得分:0)
当我建议从Sub运行它时,我并不是说 as 是Sub。
我的意思是做类似下面的事情,你的功能没有改变,唯一的区别是你是从VBA而不是UDF运行它。
从VBA运行时,您将能够看到任何错误,而不仅仅是在工作表单元格中获取#VALUE。
Sub Tester()
Dim arr
arr = RunQuery("yourPath", "yourSQL")
End sub
Public Function RunQuery(FilePath As String, SQLStatement As String)
Dim Conn As New ADODB.Connection
Dim RecSet As New ADODB.Recordset
With Conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=" & FilePath & ";" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited;IMEX=1"""
End With
Conn.Open
RecSet.Open SQLStatement, Conn
RecSet.MoveFirst
RunQuery = RecSet.GetRows()
Conn.Close
Set RecSet = Nothing
Set Conn = Nothing
End Function
答案 1 :(得分:0)
此按钮单击事件处理程序通过调用RunQuerySub
生成结果。在B2,B3中定义了三个输入参数。 B4。
Sub Button1_Click()
Dim FilePath As String, SQLStatement As String, TargetColumn As String
FilePath = Sheet1.Range("B2").Text
SQLStatement = Sheet1.Range("B3").Text
TargetColumn = Sheet1.Range("B4").Text
Call RunQuerySub(FilePath, SQLStatement, TargetColumn)
End Sub
子程序和你一样,但有一些Null值导致分配给Range对象的问题,所以我用零替换它们。 RecSet.GetRows()的结果集是一个2D变体数组,其第二维中的birthYear值。我将这些值分配给一个数组,其中的值在第一个维度中,因此它将按行填充范围。
功能似乎不允许您为范围指定值 - 无论如何我无法找到方法。
Public Sub RunQuerySub(FilePath As String, SQLStatement As String, TargetColumn As String)
Dim Conn As New ADODB.Connection
Dim RecSet As New ADODB.Recordset
Dim rows As Variant
On Error GoTo ErrHandler
With Conn
.Provider = "Microsoft.Jet.OLEDB.4.0"
.ConnectionString = "Data Source=" & FilePath & ";" & _
"Extended Properties=""text;HDR=Yes;FMT=Delimited;IMEX=1"""
End With
Conn.Open
RecSet.Open SQLStatement, Conn
RecSet.MoveFirst
rows = RecSet.GetRows()
Conn.Close
Set RecSet = Nothing
Set Conn = Nothing
Dim dest As Range
Dim nrows As Integer, i As Integer, valu As Integer
nrows = UBound(rows, 2) + 1
ReDim arr2(1 To nrows, 1 To 1) As Integer
For i = 1 To nrows
If IsNull(rows(0, i - 1)) Then
valu = 0
Else
valu = rows(0, i - 1)
End If
arr2(i, 1) = valu
Next
Dim rangeDefn As String
rangeDefn = TargetColumn & "1:" & TargetColumn & CStr(nrows)
With ThisWorkbook.Sheets("Sheet1")
Set dest = .Range(rangeDefn)
End With
dest = arr2
Exit Sub
ErrHandler:
Debug.Print Err.Number, Err.Description
Resume Next
End Sub
答案 2 :(得分:0)
我改编了使用Article::withCount('comments')->orderBy('comments_count')->get();
的技术并设法获得了withCount()
,它返回了缩写文件和完整文件的数组。
在列中突出显示1892个细胞的范围。使用此数组函数
Sub
这是功能。它将结果集中的Function
值替换为零。
=RunQuery("C:\stackoverflow", "SELECT birthYear FROM [full.csv]")