Как передать многозначное поле в запросе в функцию VBA - PullRequest
0 голосов
/ 30 июня 2018

В моем проекте у меня есть table1, который имеет идентификатор и текстовое поле. table2 имеет многозначное поле multifield, в котором я могу выбрать несколько значений из table (через поиск).

Теперь у меня есть query1, где я хочу получить значение из multifield, а не multifield.value и передать его в функцию VBA, например: IDsToNames: table2.multifield. Проблема в том, что VBA дает мне эту ошибку:

The multi-valued field 'table2.multifield` is not valied in the expression IDsToNames(table2.multifield)

Теперь я попробовал с IDsToNames([table2].[multifield]) с теми же результатами.

Вот SQL моего запроса:

SELECT table2.Title, table2.multifield, IDstoNames(table2.multifield) AS FieldNames
FROM table2;

Если я удалю функцию IDsToNames из SQL, то table2.multifield сама вернет идентификаторы, такие как: 5, 4, 1. Я пытаюсь получить второй столбец table1 вместо первого, который содержит идентификаторы. Итак, я решил, что попробую передать это поле в функцию и выполнить разбиение строки, и они будут искать их с помощью dlookup в цикле. Но я не могу получить полевые данные в функцию.

Есть ли способ сделать это?

1 Ответ

0 голосов
/ 30 июня 2018

Есть ли способ передать многозначное поле непосредственно в функцию VBA из инструкции SQL? Нет, к сожалению.

Однако существуют различные альтернативные методы, которые вы можете реализовать, чтобы получить список значений, хранящихся в поле. Легко рассуждать о плюсах и минусах многозначных полей Access. Я не буду подробно останавливаться на этом, но стоит отметить, что основным преимуществом многозначного поля является удобство и очевидная простота интерфейса доступа, позволяющего автоматически перечислять и разрешать выбор , кратного ценности отношения один ко многим. Попытка подражать такому поведению в Access может быть очень неловкой и громоздкой (а зачастую и невозможной). Многие детали реализации для многозначных полей являются «скрытыми» (то есть плохо документированы или не доступны стандартным программным интерфейсам SQL или VBA). Это включает в себя возможность передавать многозначное поле в функцию VBA из оператора SQL. Независимо от того, насколько интуитивно понятным кажется предполагаемое поведение, Access не просто передает тот же составной список значений, который он отображает, другой функции. Но бывают случаи, когда просто нужен список значений, доступный в простом списке. Информация , на которую ссылается Густав , полезна и должна быть хорошо понята для запроса многозначных полей, но она по-прежнему не касается других вполне разумных действий, требуемых для нескольких значений. Надеемся, что следующие указатели полезны.

  1. Если значения необходимы в стандартном операторе SQL, я предлагаю передать значения первичного ключа в функцию VBA. Затем попросите функцию VBA просмотреть запись и извлечь значения многозначных полей, используя наборы записей DAO .
    • Поскольку это вызовет функцию VBA для каждой строки , это может быть (очень) медленно. Можно оптимизировать функцию, используя различные методы, такие как открытие объекта статического набора записей. Дальнейшие подробности выходят за рамки этого ответа.
    • Поскольку на данный момент вы уже находитесь в коде и можете структурировать VBA и запросы так, как вам удобно, наиболее эффективный запрос обойдет само многозначное поле и использует стандартные объединения SQL, чтобы получить то, что вам нужно. Например, если вы хотите получить все связанные имена пользователей, откройте и перечислите следующий набор записей, чтобы построить свой список имен:

 sSQL = "SELECT table2.key, table2.multifield.value, UserTable.Username " & _
     " FROM UserTable INNER JOIN table2 ON UserTable.ID = table2.multifield.Value" & _
     " WHERE (table2.key = [KeyParameter])"
 Set qry = CurrentDb.CreateQueryDef(, sSQL)
 qry.Parameters("KeyParameter") = keyPassedToFunction
 Set rs = qry.OpenRecordset

  1. Если SQL-запрос может / будет открыт как набор записей DAO в контексте кода и , вам все равно нужно извлечь многозначное поле в виде единственного поля , существует способ перечислить многозначное поле в VBA.
    • Если код заканчивается многократным открытием и закрытием нескольких наборов записей, особенно в нескольких вложенных циклах, вероятно, вы могли бы повысить эффективность, реструктурировав SQL с помощью соответствующих объединений и изменив порядок обработки данных.
    • Rant: Как вы могли заметить, несколько противоречиво, что базовый объект набора записей оператора SQL действительно возвращает объект, который может быть перечислен в коде, хотя механизм SQL Access отказывается передавать такой объект в функцию VBA. , Механизм SQL уже имеет дело с упаковкой и распаковыванием данных в тип варианта VBA, поэтому кажется разумным, чтобы при реализации многозначных полей они могли иметь механизм SQL, просто упаковавший объект многозначного набора записей и передавший его в функцию VBA для обработки. похож на следующий код ... поэтому первоначальная попытка в этом вопросе не была необоснованной.
    • Следующий фрагмент кода показывает, что многозначное поле возвращается как объект DAO.Field, содержащий объект DAO.Recordset2:

Dim rs as Recordset2
Set rs = CurrentDB.OpenRecordset("SELECT table2.multifield ... FROM ...")

Dim sList As String
sList = ""
If TypeOf rs![multifield] Is Recordset2 Then
    Dim rsMVF As Recordset2
    Set rsMVF = rs![multifield]

    Dim bFirst As Boolean
    bFirst = True

    rsMVF.MoveFirst
    Do Until rsMVF.EOF
        If bFirst Then
            sList = rsMVF.Fields(0)
            bFirst = False
        Else
            sList = sList & "," & rs.Fields(0)
        End If
        rsMVF.MoveNext
    Loop
    '* DO NOT CLOSE the Recordset based on the Multivalue field.
    '*   Access will close it automatically.
End If
'* sList will contain comma-separated list of values

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...