Разделение столбца NoName в SQL-запросе - PullRequest
0 голосов
/ 08 октября 2019

У меня есть Test1.csv 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-й столбцы имеют пустые заголовки. Так как 1-й столбец содержит данные, я хочу разделить их на 2 разных столбца, как показано в 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] '' не является допустимым именем. Убедитесь, что он не содержит недопустимых символов или знаков препинания и не слишком длинный.

Сейчас я не знаю, как получить ссылку или выберите 1-й пустой столбец, чтобы разделить егозначения в 2 других столбцах.

Кстати, запрос хорошо работает в MSAccess, а 1-й столбец NoName отображается как Field1 и 2-й столбец NoName отображается как Поле 3 .

Оцените чью-либо помощь здесь.

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Код 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], "
0 голосов
/ 08 октября 2019

когда я пытаюсь повторить ваш код, я получаю следующее: a) Не уверен, что это проблема, но у вас есть имена двух столбцов [NoName], поэтому вам нужно различать их. (б) Не могли бы вы поставить столбцы 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
...