Как импортировать данные из MS-Access, чтобы превзойти мощность запроса, используя оператор SQL и VBA? - PullRequest
1 голос
/ 24 апреля 2019

В компании, в которой я работаю, есть папка с множеством файлов базы данных доступа, которые создаются системой. Они имеют одинаковую структуру, но разные данные. Я пытаюсь создать инструмент Excel для сравнения и анализа некоторых из них с помощью мощного запроса (подключенного к модели данных рабочей книги и также использующего DAX). Люди, которые будут использовать систему, не очень хорошо знакомы с vba, мощными запросами (я тоже) или операторами SQL. Итак, я подумал о том, чтобы написать код функции vba, чтобы люди могли выбирать файлы, которые они хотят проанализировать, а затем обновить запросы рабочей силы на эти данные. Источники данных для мощных запросов должны быть операторами SQL.

Я использую свойство «Формула», чтобы внести все необходимые изменения (фактически, новый файл источника данных, добавить столбец с именем файла и добавить результат для других файлов источника данных (если выбрано более одного файла) Следующий код работает, если я импортирую таблицу, но я не могу сделать это с помощью оператора SQL. Я попытался изменить некоторые параметры Access.Database, например, используя Query = "Select XXX" вместо Item = «TableXXX», но это не сработало. Я нашел некоторую информацию об использовании ODBC, но мне не хотелось бы работать с ODBC, потому что, как мне кажется, этот инструмент может привести к тому, что многие соединения будут обрабатывать (открывать и удалять) всякий раз, когда пользователь решает изменить источник данных .

Ниже приведен пример, содержащий только свойство «Формула» для двух файлов источников данных. Я не написал цикл для построения строки strSource, потому что у меня нет проблем с ней. Я предполагаю, что проблема заключается в использовании оператора SQL в Access.Database. Спасибо за помощь.

strSource = "let
    Fonte = Access.Database(File.Contents("PathName\File01Name.mdb")),
    _TbEx_1 = Fonte{[Schema="",Item="TableExample"]}[Data],
    _TbEx_C1 = Table.AddColumn(_TbEx_1, "Case", each "File01Name", type text),
    Fonte_2 = Access.Database(File.Contents("PathName\File02Name.mdb")),
    _TbEx_2 = Fonte_2{[Schema="",Item="TableExample"]}[Data],
    _TbEx_C2 = Table.AddColumn(_TbEx_2, "Case", each "File02Name", type text),
    _TbExComb = Table.Combine({_TbEx_C1 , _TbEx_C2})
in
    _TbExComb"

ActiveWorkbook.Queries("PwQry01").Formula = strSource
ThisWorkbook.Connections("Qry-PwtQry01").Refresh

Выполняя поиск в Интернете, я нашел способ использования оператора SQL, но проблема заключалась в объединении соединений разных файлов в одном и том же запросе мощности. Следуя коду, который я нашел, но я полагаю, что свойство «Формула» ближе к окончательному ответу.

cnString = "OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
        "PathName\File01Name.mdb;Mode=Read"

    ThisWorkbook.Connections.Add2 _
        Name:="MyConnect", _
        Description:="Testing connection", _
        ConnectionString:=cnString, _
        CommandText:="SELECT * FROM TableExample", _
        lCmdtype:=XlCmdType.xlCmdSql, _
        CreateModelConnection:=True, _
        ImportRelationships:=True

Будучи наивным, я бы хотел увидеть что-то вроде:

strSource = "let
    Fonte = Access.Database(File.Contents("PathName\File01Name.mdb")),
    _TbEx_1 = Fonte{[Schema="",Query="SELECT XXXXX"]}[Data],
    _TbEx_C1 = Table.AddColumn(_TbEx_1, "Case", each "File01Name", type text),
    Fonte_2 = Access.Database(File.Contents("PathName\File02Name.mdb")),
    _TbEx_2 = Fonte_2{[Schema="",Query="SELECT XXXX"]}[Data],
    _TbEx_C2 = Table.AddColumn(_TbEx_2, "Case", each "File02Name", type text),
    _TbExComb = Table.Combine({_TbEx_C1 , _TbEx_C2})
in
    _TbExComb"

ActiveWorkbook.Queries("PwQry01").Formula = strSource
ThisWorkbook.Connections("Qry-PwtQry01").Refresh

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

Я последовал предложению @Wedge и использовал подход ODBC. Чтобы это работало, я создал ODBC без файла ms-access, связанного с источником данных Windows ODBC. В Excel пользователь выбирает файлы, которые он хочет проанализировать, и эта информация является переменной strPath (). С помощью цикла все файлы включаются в свойство формулы. Переменная tpPQSQLMap - это настраиваемый тип (я думаю, это может быть словарь) с strPQNames для имени запроса и strPQSQL для оператора SQL. После окончательного кода

For pq = 1 To ThisWorkbook.Queries.Count
    strSource = ""
    strSrcComb = ""
    For k = 1 To UBound(strPath)
        strSource = strSource + "SourceC" + CStr(k) + "=Odbc.Query(""dbq=" + strPath(k) + ";dsn=MyODBC"", """ + tpPQSQLMap(pq).strPQSQLs + """), " + vbCrLf
        strSrcComb = strSrcComb + "SourceC" + CStr(k) + ","
    Next k
    strSrcComb = Left(strSrcComb, Len(strSrcComb) - 1)
    strSource = "let " + vbCrLf + strSource + "Final = Table.Combine({" + strSrcComb + "}) " + vbCrLf + "in " + vbCrLf + "Final "


    ThisWorkbook.Queries(pq).Formula = strSource
    ThisWorkbook.Connections("Query - " + tpPQSQLMap(pq).strPQNames).Refresh
Next pq
0 голосов
/ 25 апреля 2019

Было бы намного проще "объединить" все данные с помощью Access в один файл mdb и использовать это для выполнения остальной части работы.

...