Как отфильтровать запрос кросс-таблицы MS Access для множественного выбора в списке со множественным выбором - PullRequest
1 голос
/ 30 марта 2020

Я искал inte rnet, ища ответ на этот вопрос безрезультатно. То, что я пытаюсь сделать в Access, должно быть простым, но я не могу понять это. Я делаю базу данных сотрудников для HR с легкостью использования. Конечный пользователь не знает Access, поэтому чем больше я могу автоматизировать, тем лучше. Итак, вот так:

Мне нужен простой перекрестный запрос на заголовки должностей и рабочие единицы, где metri c представляет собой количество идентификаторов сотрудников. Я легко могу сделать запрос, который включает все комбинации названий позиций и рабочих единиц; тем не менее, у нас много названий должностей и много рабочих подразделений. Наш специалист по персоналу должен выбрать любую комбинацию рабочих единиц и должностей, чтобы провести значимые сравнения.

Вот полная таблица. Я не добавил тестовых сотрудников для всех рабочих единиц и должностей, поэтому полная таблица пока невелика, но будет очень большой при добавлении всех сотрудников: Full Crosstab Query

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

Моя текущая попытка состоит в том, чтобы использовать VBA для перебора элементов списка и создать строку для оператора SQL. Вот мой код VBA, основанный на полезном коде из запросов inte rnet:

Private Sub btnPosLibCrossTab_Click()

Dim strLIB As String
Dim strPOS As String
Dim ctl As Control
Dim varItem As Variant

' if nothing is selected
If Me.lstWorkUnitDesc.ItemsSelected.Count = 0 Then
    ' MsgBox "Pick a Work Unit"
    ' Exit Sub
    For i = 0 To Me.lstWorkUnitDesc.ListCount - 2
        Me.lstWorkUnitDesc.Selected(i) = True
    Next i
End If

If Me.lstPosTitle.ItemsSelected.Count = 0 Then
    ' MsgBox "Pick a Position Title"
    ' Exit Sub
    For i = 0 To Me.lstPosTitle.ListCount - 2
        Me.lstPosTitle.Selected(i) = True
    Next i
End If

' create a string based on selected list box items in Work Unit choices
Set ctl = Me.lstWorkUnitDesc
For Each varItem In ctl.ItemsSelected
    strLIB = strLIB & "'" & ctl.ItemData(varItem) & "',"
Next varItem

' create a string based on selected list box items in Position Title choices
Set ctl = Me.lstPosTitle
For Each varItem In ctl.ItemsSelected
    strPOS = strPOS & "'" & ctl.ItemData(varItem) & "',"
Next varItem

' remove last comma
strLIB = Left(strLIB, Len(strLIB) - 1)
strPOS = Left(strPOS, Len(strPOS) - 1)

' open the form with a where clause based on list box selections
DoCmd.OpenForm "Crosstab Emp Count Lib PosTitle Form", , , "[LibraryUnit] IN(" & strLIB & ") AND [Position Title] IN(" & strPOS & ")"

End Sub

Это прекрасно работает для предложения where в отчетах. Но я не хочу, чтобы это был отчет. Таблицы запросов в этом случае намного приятнее.

Когда я изменяю DoCmd.OpenReport на OpenForm, я получаю ошибку во время выполнения: Run-Time Error Snapshot

Вот пример того, что я хочу сделать с Access, который я легко могу сделать в нашем ILS-отчете BlueCLOUD Analytics от SirsiDynix: BCA crosstab with all values which I can currently do in Access

И вот как я хочу, чтобы кросс-таблица Access работала с фильтром: BCA crosstab with filter.  This is what I want Access to do

Спасибо всем, кто может помочь мне с этим Кажется, это должно быть невероятно просто.

Corey

edit: вот запрос, на котором основана форма в режиме конструктора. Имеет поле LibraryUnit. Запрос этой формы основан на поле LibraryUnit, вызывающем ошибку

1 Ответ

2 голосов
/ 31 марта 2020

Я наткнулся на DAO и разработал решение. Мой код грязный, но он работает.

Private Sub btnPosLibCrossTab_Click()

Dim strLIB As String
Dim strPOS As String
Dim ctl As Control
Dim varItem As Variant

' if nothing is selected
If Me.lstWorkUnitDesc.ItemsSelected.Count = 0 Then
    ' MsgBox "Pick a Work Unit"
    ' Exit Sub
    For i = 0 To Me.lstWorkUnitDesc.ListCount - 2
        Me.lstWorkUnitDesc.Selected(i) = True
    Next i
End If

If Me.lstPosTitle.ItemsSelected.Count = 0 Then
    ' MsgBox "Pick a Position Title"
    ' Exit Sub
    For i = 0 To Me.lstPosTitle.ListCount - 2
        Me.lstPosTitle.Selected(i) = True
    Next i
End If

' create a string based on selected list box items in Work Unit choices
Set ctl = Me.lstWorkUnitDesc
For Each varItem In ctl.ItemsSelected
    strLIB = strLIB & "'" & ctl.ItemData(varItem) & "',"
Next varItem

' create a string based on selected list box items in Position Title choices
Set ctl = Me.lstPosTitle
For Each varItem In ctl.ItemsSelected
    strPOS = strPOS & "'" & ctl.ItemData(varItem) & "',"
Next varItem

' remove last comma
strLIB = Left(strLIB, Len(strLIB) - 1)
strPOS = Left(strPOS, Len(strPOS) - 1)

' open the form with a where clause based on list box selections
' DoCmd.OpenForm "Crosstab Emp Count Lib PosTitle Form", , , "[LibraryUnit] IN(" & strLIB & ") AND [Position Title] IN(" & strPOS & ")"

' create SQL statement

Dim db As DAO.Database
Dim qDef As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strSQL As String

Dim strWorkUnitSQL As String
Dim strWorkUnit As String

' user selection put into string for sql where statement

strWorkUnit = strLIB


'

Set db = CurrentDb
Set qDef = db.QueryDefs("TestSet")
strSQL = "TRANSFORM Count([Main Form Extended].[Employee ID]) AS [CountOfEmployee ID]" _
& "SELECT [Main Form Extended].[Position Title]FROM [Main Form Extended] WHERE ((([Main Form Extended].LibraryUnit) In (" & strWorkUnit & ")))" _
& "GROUP BY [Main Form Extended].[Position Title]" _
& "PIVOT [Main Form Extended].LibraryUnit"


qDef.SQL = strSQL




'Set rs = db.OpenRecordset("TestSet")

DoCmd.Close acQuery, "TestSet"
DoCmd.OpenQuery "TestSet"

'


End Sub
...