在 SQL 查询中拆分 NoName 列

Splitting NoName column in SQL Query

我想使用 CSV 文件 Test1.csv 来创建具有自定义列名的记录集。

CSV 文件格式:

    (Blank)  |  SomeAggr |   (Blank) |   Div1  |  Div2  |  Div3
    -----------------------------------------------------------
    G0.1     |  1.23     |           |   ABC   |  DEF   |  GHI
    G0.2     |  2.45     |           |   JKL   |  MNO   |  PQR
    G0.3     |  9.02     |           |   STU   |  VWX   |  YZA
    G1.1     |  3.32     |           |   ZYX   |  WVU   |  TSR
    G1.2     |  5.53     |           |   QPO   |  NML   |  KJI
    G1.3     |  1.15     |           |   HGF   |  EDC   |  BAZ
    G1.4     |  4.65     |           |   FKJ   |  OTU   |  WKL

第 1 和第 3 列有空白 headers。第一列包含我想将其拆分为两列的数据,如 SQL 查询中所示。

注意 - 我正在创建一个记录集,不想使用 WorkSheet 进行任何转换。

通过 SQL 查询的最终记录集应如下所示:

    GVal  |   Pos    |  Aggr     |   (Blank) |   DV A  |  DV B  |  DV C
    --------------------------------------------------------------------
    0     |    1     |  1.23     |           |   ABC   |  DEF   |  GHI
    0     |    2     |  2.45     |           |   JKL   |  MNO   |  PQR
    0     |    3     |  9.02     |           |   STU   |  VWX   |  YZA
    1     |    1     |  3.32     |           |   ZYX   |  WVU   |  TSR
    1     |    2     |  5.53     |           |   QPO   |  NML   |  KJI
    1     |    3     |  1.15     |           |   HGF   |  EDC   |  BAZ
    1     |    4     |  4.65     |           |   FKJ   |  OTU   |  WKL

我是运行以下代码:

Option Explicit

Sub Testing()
    Application.DisplayAlerts = False
    Application.ScreenUpdating = False

    Dim strDataSource$, strF1$, strFF1$, strSql$, oCon as Object, oRs as Object, i%, Fld
    strFF1 = "Test1.csv"
    strF1 = "`C:\Users\adam\Downloads\Test Folder`\"
    strDataSource = Thisworkbook.Path

    Set oCon = CreateObject("ADODB.Connection")
    Set oRs = CreateObject("ADODB.Recordset")

    strCon = "Driver=Microsoft Access Text Driver (*.txt, *.csv);Dbq=" & strDataSource & ";Extensions=asc,csv,tab,txt;HDR=Yes;"

   'Getting Top 1 row to loop through fields and create SQL string accordingly.
    strSql = "SELECT TOP 1 * FROM " & strF1 & strFF1
    oCon.Open strCon
    Set oRs = oCon.Execute(strSql)

    i = 1
    strSql = "SELECT "    
    For Each Fld In oRs.Fields

        Select Case True
            Case Is = Fld.Name = "NoName"    '1st NoName column
                If Fld.Value <> vbNullString Then
                    strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", ""."") - 1), ""G"", """"))" & " AS [GVal], "
                    strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", ""."")))" & " AS [Pos], "
                Else
                    strSql = strSql & Fld.Name & ", "  '2nd NoName column
                End If
            Case Is = Fld.Name = "SomeAggr"
                strSql = strSql & "[" & Fld.Name & "] AS [Aggr],"
            Case Is = InStr(1, Fld.Name, "Div") > 0
                strSql = strSql & "[" & Fld.Name & "] AS [DV " & Chr(i + 64) & "], "
                i = i + 1
        End Select
    Next Fld

    If Right(Trim(strSql), 1) = "," Then strSql = Left(Trim(strSql), Len(Trim(strSql)) - 1)
    strSql = strSql & " FROM " & strF1 & strFF1

    oRs.Close

' >>> getting error on below `Set oRs` line
  [Microsoft][ODBC Text Driver] '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.

    Set oRs = oCon.Execute(strSql)
Stop

ExitSub:
    oRs.Close
    oCon.Close
    Set oRs = Nothing
    Set oCon = Nothing

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True

Exit Sub
ErrorHandler:
    MsgBox "Error No: " & Err.Number & vbCrLf & "Description: " & Err.Description, vbCritical + vbOKOnly, "An Error occurred!"
    Err.Clear
    On Error GoTo 0
    Resume ExitSub

End Sub

这是 SQL 查询。

SELECT CLng(Replace(Left(NoName, InStr(NoName,".")-1), "G", "")) AS [GVal], 
CLng(Right(NoName, Len(NoName) - InStr(NoName,"."))) AS [Pos], 
[SomeAggr] AS [Aggr],
[Div1] AS [DV A], 
[Div2] AS [DV B], 
[Div3] AS [DV C] 
FROM `\C:\Users\Adam\Downloads\Test Folder`\Test1.csv

代码给出了以下错误:

[Microsoft][ODBC Text Driver] '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.

我不知道如何获取参考或select第一个空白列以将其值拆分为两列。

查询在 MSAccess 中有效,第一个 NoName 列 显示为 Field1第二个 NoName 列 显示为 Field3.

当我尝试复制您的代码时,我得到以下信息: a) 不确定这是否是问题所在,但您有两个列名称 [NoName],因此您需要区分两者。 (b) 能否将 NoName 列放在方括号中并尝试用单引号代替双引号?

SELECT 
    CLng(Replace(Left(NoName, InStr(NoName, ".") - 1), "G", "")) AS [GVal],
    CLng(Right(NoName, Len(NoName) - InStr(NoName, "."))) AS [Pos], [SomeAggr] AS [Aggr],
    NoName, 
    [Div1] AS [DV A], 
    [Div2] AS [DV B], 
    [Div3] AS [DV C] 
FROM 
    `C:\Temp`\Test.csv

SQL 代码需要单引号作为字符串分隔符而不是双引号。在 For Each Fld In oRs.Fields 循环中,有两行在构造 strSql:

时使用双引号而不是单引号
strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", ""."") - 1), ""G"", """"))" & " AS [GVal], "
strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", ""."")))" & " AS [Pos], "

这些应该改为:

strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", '.') - 1), 'G', ''))" & " AS [GVal], "
strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", '.')))" & " AS [Pos], "