Как запустить параметризованный запрос из VBA. Параметры получены из набора записей

У меня есть форма, в которой пользователь выбирает имя поставщика из поля со списком, чей файл каталога должен быть импортирован. Затем поле со списком запускает запрос для создания набора записей с одной записью (rsProfile), содержащего несколько переменных профиля, запрошенных из таблицы всех профилей поставщиков. Затем эти переменные используются в ряде различных запросов для переформатирования, перевода и нормализации уникально структурированных файлов поставщика в стандартизированный формат, который можно импортировать в нашу систему.

Я разочарован тем, что не могу понять, как создавать свои сохраненные запросы, которые будут использовать один или несколько параметров, которые автоматически заполняются из набора записей профиля.

Вот мой код сбора rsProfile. Оно работает. Обратите внимание, что intVdrProfileID — это набор глобальных переменных, который используется в других местах.

Private Sub btn_Process_Click()

Dim ws As Workspace
Dim db, dbBkp As DAO.Database
Dim qdf As DAO.QueryDef
Dim rsProfile, rsSubscrip As Recordset
Dim strSQL As String
Dim strBkpDBName As String
Dim strBkpDBFullName As String

strBkpDBName = Left(strVdrImportFileName, InStr(strVdrImportFileName, ".") - 1) & "BkpDB.mdb"
strBkpDBFullName = strBkpFilePath & "\" & strBkpDBName

Set db = CurrentDb
Set ws = DBEngine.Workspaces(0)

MsgBox ("Vendor Profile ID = " & intVdrProfileID & vbCrLf & vbCrLf & "Backup file path: " & strBkpFilePath)

' Harvest Vendor Profile fields used in this sub
strSQL = "SELECT VendorID, Div, VPNPrefix, ImportTemplate, " & _
                 "VenSrcID, VenClaID, ProTyp, ProSeq, ProOrdPkg, ProOrdPkgTyp, JdeSRP4Code, " & _
                 "PriceMeth, " & _
                 "ProCost1Frml, ProCost2Frml, " & _
                 "ProAmt1Frml, ProAmt2Frml, ProAmt3Frml, ProAmt4Frml, ProAmt5Frml " & _
         "FROM tZ100_VendorProfiles " & _
         "WHERE VendorID = " & intVdrProfileID & ";"

Set qdf = db.QueryDefs("qZ140_GetProfileProcessParms")
qdf.SQL = strSQL
Set rsProfile = qdf.OpenRecordset(dbOpenSnapshot)
DoCmd.OpenQuery "qZ140_GetProfileProcessParms"
' MsgBox (qdf.SQL)

Я использовал QueryDefs для перезаписи сохраненных запросов во время выполнения, и хотя это работает, это довольно громоздко и не работает для всего.

Я надеялся получить что-то вроде приведенного ниже примера в виде сохраненного запроса с использованием DLookups. Я могу заставить это работать в VBA, но я не могу заставить что-либо работать с сохраненными запросами. Я открыт для других предложений.

Сохраненный запрос "qP0060c_DirectImportTape":

SELECT 
    DLookUp("[VPNPrefix]","rsProfile","[VendorID]=" & intVdrProfileID) & [PartNo] AS VenPrtId,
    Description AS Des,
    DLookup("[Jobber]","rsProfile",[VendorID=" & intVdrProfileID) AS Amt1,
INTO tP006_DirectImportTape
FROM tJ000_VendorFileIn;

ПРИЛОЖЕНИЕ: Позвольте мне изменить задачу, чтобы сделать ее немного более сложной. У меня есть набор из примерно 40 запросов, каждый из которых использует разные наборы параметров (или ни один). У меня также есть таблица, содержащая определенный набор запросов, на которые «подписывается» каждый поставщик. Цель состоит в том, чтобы иметь базу данных, в которой пользователь, не умеющий кодировать, может добавлять новые профили поставщиков и создавать/изменять определенный набор запросов, которые будут выполняться для этого файла поставщиков. На данный момент у меня почти 100 поставщиков, поэтому кодировать каждого поставщика отдельно нецелесообразно. Каждый файл поставщика будет подвергаться в среднем 14 различным запросам на обновление.

Упрощенный пример: файл Vendor1 необходимо обработать с помощью запросов 1, 2 и 5. Файлу Vendor2 могут потребоваться только запросы на обновление 2 и 4. Параметры для этих запросов могут быть следующими:

query1 (parm1) query2 (parm1, parm4, parm8, parm11) query4 (parm5, parm6, parm7, parm8, parm9, parm10, parm11) query5 () - параметры не требуются

Это основная обработка запросов, которая циклически обрабатывает только те запросы, которые относятся к текущему файлу поставщика. rsSubscrip — это набор записей (запрошенный из главной таблицы), содержащий этот отфильтрованный список запросов.

' Run all subscribed queries
MsgBox "Ready to process query subscription list."
With rsSubscrip
    Do While Not .EOF
        db.Execute !QueryName, dbFailOnError
        .MoveNext
    Loop
    .Close
End With

person Thomas Kerber    schedule 25.06.2015    source источник
comment
Итак, как только вы определили, какие запросы выполнять для конкретного поставщика, вы должны предоставить значения для любых параметров, которые требуются для этих запросов. Значения параметров для текущего поставщика доступны в наборе записей rsProfile, верно? Как вы можете сопоставить одно значение rsProfile с параметром запроса?   -  person HansUp    schedule 26.06.2015
comment
Ваш вывод правильный. Ваш вопрос тоже вполне правильный вопрос. Я пытаюсь закодировать DLookup в сохраненных запросах для каждого поля, требующего параметра, тем самым устраняя необходимость наличия параметров. После дальнейшего размышления, если бы у меня был только один параметр, идентифицирующий уникальный идентификатор поставщика, возможно, DLookups работал бы независимо от фактического количества переменных профиля, необходимых в запросе?   -  person Thomas Kerber    schedule 26.06.2015
comment
Таким образом, если ваши запросы включают DLookup выражений в качестве заменителей параметров запроса, все пересмотренные запросы будут включать не более одного фактического параметра (для поставщика). Тогда вам не понадобится набор записей rsProfile. И оставшаяся задача состоит в том, чтобы определить, требует ли каждый запрос в наборе запросов поставщика указать значение для параметра поставщика. Это все правильно? (Боюсь, я теряюсь в деталях здесь.)   -  person HansUp    schedule 26.06.2015
comment
Вы прекрасно уловили мысль. Я думаю, вы правы, предполагая, что набор записей rsProfile является избыточным и ненужным. Я безуспешно пытался использовать его в качестве источника поиска, но Access это не понравилось. Если я сошлюсь на реальную таблицу (tblVendorProfile) в качестве источника поиска... это может не так сильно сопротивляться.   -  person Thomas Kerber    schedule 26.06.2015
comment
Я думаю, что любой способ может работать. Решите, какой подход кажется вам (и вашим коллегам?) проще... проще создать изначально, а затем понять/расширить/устранить неполадки/обслуживать.   -  person HansUp    schedule 26.06.2015


Ответы (1)


Вы можете установить параметры предопределенного запроса, используя синтаксис;

Set qdf = CurrentDB.QueryDefs(QueryName)
qdf.Parameters(ParameterName) = MyValue

Чтобы добавить параметры в запрос, добавьте следующее перед оператором SELECT в sql.

PARAMETERS [ParameterOne] DataType, [ParameterTwo] DataType;
SELECT * FROM tblTest;
person jhTuppeny    schedule 26.06.2015
comment
Я добавил в пост несколько других функциональных критериев. - person Thomas Kerber; 26.06.2015
comment
Мне придется подумать о том, как использовать это, когда я не знаю, какой запрос вызывается, а идентификатор и количество используемых параметров зависят от конкретного запроса. - person Thomas Kerber; 26.06.2015
comment
Код останавливается на строке: qdf.Parameters(Parm1) = intVdrProfileID. Я получаю элемент, не найденный в этой коллекции. Я использовал то же имя параметра, что и в моем запросе. Я пробовал Dim Parm1 как Integer, и как Parameter оба результата приводят к одной и той же ошибке. Также попробовал без оператора Dim и получил переменную, не определенную. Не уверен, что делать, чтобы исправить. Помощь? - person Thomas Kerber; 26.06.2015
comment
Хорошо, исправил эту проблему, но теперь нужно решить эту: Err: слишком мало параметров. Ожидается (1). Вот код. Останавливается при выполнении инструкции. Dim Parm1 As Long Set qdf = db.QueryDefs(!QueryName) qdf.Parameters(Parm1) = intVdrProfileID MsgBox (!QueryName) & ( & qdf.Parameters(Parm1) & ) db.Execute !QueryName, dbFailOnError - person Thomas Kerber; 26.06.2015