Невозможно использовать значения ListBox в MS Access 2007 для передачи в запрос - PullRequest
0 голосов
/ 26 июня 2018

Доброе утро,

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

ОБНОВЛЕНИЕ - благодаря некоторым отличным отзывам на этом форуме, основная проблема была решена. Моя второстепенная проблема в настоящее время не в состоянии выполнить запрос. Когда я пытаюсь получить сообщение об ошибке, запрос не может быть выполнен.

Мой код (как процедура события) для кнопки:

Option Explicit
Private Sub btnSearchCars_Click()
    MsgBox "Starting Sub"
    Call QueryCars.myQuery
    MsgBox "Ending Sub"
End Sub

Тогда мой модуль QueryCars выглядит так:

Sub myQuery()
    Dim strWhere As String
    Dim strSQL As String
    Dim varItem As Variant

    For Each varItem in Forms!FormSelect!listCarID.SelectedItems
        strWhere = strWhere & "'" & Forms!FormSelect!listCarID.ItemData(varItem) & "',"
    Next

strWhere = Слева (strWhere, Len (strWhere) -1)

    strSQL = "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & strWhere & ");"
    DoCmd.RunSQL strSQL

End Sub

Моя ошибка - это ошибка "RunSQL требует аргумент оператора SQL" в строке.

DoCmd.RunSQL strSQL

Я был бы очень признателен, если бы кто-то мог помочь. Все, что я пытаюсь сделать, это взять значения из списка, выбранного пользователем, и использовать их в качестве критерия WHERE в моем запросе. Я искал различные форумы SO и Access все утро и не нашел ничего, что могло бы помочь.

Спасибо. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.

Ответы [ 2 ]

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

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

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

Public Function getListBoxSelection(ctl As Access.ListBox) As Variant
   Dim arr() As Variant
   Dim varItem As Variant, i As Long

   If ctl.ItemsSelected.Count > 0 Then
      ReDim arr(0 To ctl.ItemsSelected.Count - 1)
      i = 0

      For Each varItem In ctl.ItemsSelected
         arr(i) = ctl.ItemData(varItem)
         i = i + 1
      Next varItem

   End If

   getListBoxSelection = arr
End Function

Тогда вы бы назвали это в генерации SQL. Что-то вроде

whereClause = join(getListBoxSelection(me.listCarID), " AND ")
debug.Print whereClause

qdf.SQL = _
    "select tblBig.* " & _
    "from tblCars " & _
    "inner join tblBig on tblCars.Cat_ID = tblBig.Car_ID " & _
    "where tblCars.Card_ID in (" & whereClause & ")"
0 голосов
/ 26 июня 2018

Это не идеальный ответ, который я надеялся вам дать, но не могу понять, как использовать запросы параметров в команде IN.

Я предполагаю, что ваш список содержит два столбца данных, а значения CarID находятся в первом столбце.

Основная функция называется ProcessQuery и принимает в качестве аргумента ссылку на список:
Public Sub ProcessQuery(myList As ListBox)

Затем вы можете вызвать свой код из события в списке и передать ему ссылку на список.

Private Sub btnSearchCars_Click()
    ProcessQuery Me.listCarID
End Sub  

Затем процедура ProcessQuery просматривает первый столбец, чтобы получить индексные числа, создает SQL, открывает результирующий набор записей и извлекает информацию из каждой записи.

Public Sub ProcessQuery(myList As ListBox)

    Dim vItem As Variant
    Dim IDList As String
    Dim qdf As dao.QueryDef
    Dim rst As dao.Recordset

    For Each vItem In myList.ItemsSelected
        'Column 0 is first column in listbox.
        IDList = IDList & "'" & myList.Column(0, vItem) & "',"
    Next vItem
    'Removes the final ,
    IDList = Left(IDList, Len(IDList) - 1)

    'Create a temporary query definition & open the recordset.
    Set qdf = CurrentDb.CreateQueryDef("", _
        "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & IDList & ")")
    Set rst = qdf.OpenRecordset

    'Move through the recordset and output the first two fields from each record
    'to the Immediate window.
    With rst
        If Not (.BOF And .EOF) Then
            .MoveFirst
            Do While Not .EOF
                Debug.Print .Fields(0) & " - " & .Fields(1)
                .MoveNext
            Loop
        End If
    End With

End Sub 

Чтобы отобразить результат запроса в виде таблицы, вы можете использовать следующее, но я бы предпочел использовать сохраненный запрос с параметром для IN. Я постараюсь выяснить это.

Public Sub ProcessQuery(myList As ListBox)

    Dim vItem As Variant
    Dim IDList As String
    Dim qdf As dao.QueryDef
    Dim rst As dao.Recordset

    For Each vItem In myList.ItemsSelected
        'Column 0 is first column in listbox.
        IDList = IDList & "'" & myList.Column(0, vItem) & "',"
    Next vItem
    'Removes the final ,
    IDList = Left(IDList, Len(IDList) - 1)

    'Create a temporary query definition & open the recordset.
    Set qdf = CurrentDb.CreateQueryDef("TempQDF", _
        "SELECT tblBig.* FROM tblCars INNER JOIN tblBig ON tblCars.Car_ID = tblBig.Car_ID WHERE tblCars.Car_ID IN (" & IDList & ")")

    DoCmd.OpenQuery "TempQDF", acViewNormal

End Sub
...