在 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], "
我想使用 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], "