搜索功能 - 加入具有多行和where子句的查找表

时间:2015-06-16 21:42:10

标签: vba access-vba ms-access-2013

我正在使用Microsoft Access 2013和VBA构建搜索功能。我的数据库有三个表,tblCandidatetblCandidateSkilllutSkill,虽然lutSkill对于这次讨论来说并不是必需的,但我认为无论如何分享可能都是有益的。

以下是我的表格定义:

tblCandidate              tblCandidateSkill           lutSkill
----------------          -----------------           -------------
CandidateId               CandidateSkillId            SkillId          
FirstName                 CandidateId                 Name
MiddleName                SkillId                     Description
LastName                  YearsExp
etc...                 

候选人可以拥有多种技能,tblCandidateSkill中的每个记录都与lutSkill中的单个记录相关。我创建了一个加入viewCandidatetblCandidate的查询/视图(tblCandidateSkill)。这按预期工作。如果候选人具有多种技能,则每项技能与候选人信息一起列在单独的行中。

我在VBA中的搜索功能基本上只是一堆生成动态SQL的嵌套If Else语句。

以下是我的好奇代码。

Private Sub Search_Click()

' Declare variables
Dim stateId As Integer
Dim skillId1 As Integer
Dim skillId2 As Integer
Dim skillId3 As Integer
Dim yearsExp1 As Integer
Dim yearsExp2 As Integer
Dim yearsExp3 As Integer

Dim count As Integer

Dim db As DAO.Database
Dim qdf As DAO.QueryDef

Dim strQuery As String
Dim strWhere As String
Dim strSQL As String

On Error GoTo errHandler

strQuery = "qryCandidateSearchResults"
strSQL = "SELECT FirstName, MiddleName, LastName, Phone, Email FROM viewCandidate WHERE "

'===========================================================
' Start dynamic query

' Check for state id
If Not IsNull(Me.ddlState.Value) Then
    strWhere = strWhere & " ([StateId] = " & Me.ddlState.Column(0) & ") AND "
End If

' Check for skillId1 and yearsExp1
If Not IsNull(Me.ddlSkill1.Value) Then

    ' if yearsExp1 is not null, include it,
    ' otherwise dont.
    If Not IsNull(Me.ddlYearsExp1.Value) Then
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill1.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp1.Column(0) & ") AND "
    Else
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill1.Column(0) & ") AND "
    End If
End If

' Check for skillId2 and yearsExp2
If Not IsNull(Me.ddlSkill2.Value) Then

    If Not IsNull(Me.ddlYearsExp2.Value) Then
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill2.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp2.Column(0) & ") AND "
    Else
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill2.Column(0) & ") AND "
    End If
End If

' Check for skillId3 and yearsExp4
If Not IsNull(Me.ddlSkill3.Value) Then

    If Not IsNull(Me.ddlYearsExp3.Value) Then
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill3.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp3.Column(0) & ") AND "
    Else
        strWhere = strWhere & " (SkillId = " & Me.ddlSkill3.Column(0) & ") AND "
    End If
End If


'============================================================

' Remove the last "AND"
If Right(strWhere, 4) = "AND " Then
    strWhere = Mid(strWhere, 1, Len(strWhere) - 4)
End If

strSQL = strSQL & strWhere

' Check for criteria and exit if none exists
' else set CurrentDb, QueryDef and SQL string
If Len(strWhere) = 0 Then
    MsgBox "You didn't enter any criteria for this report, now exiting", vbExclamation
    Exit Sub
Else
    Set db = CurrentDb
    Set qdf = db.QueryDefs(strQuery)
    qdf.SQL = strSQL
End If

DoCmd.OpenReport "rptCandidateSearch", acViewPreview
Debug.Print strSQL


Exit Sub

errHandler:
Select Case Err.Number
    Case 2501
        'No data
        Resume Next
    Case Else
        MsgBox Err.Number & " - " & Err.Description
End Select

End Sub

我的问题源于每个技能在一个单独的行上。例如,如果我想在数据库中搜索具有三种技能的候选人,那么如何过滤该数据以仅显示符合搜索条件的候选人?我的所有尝试都失败了,因为每个skillId都列在一个单独的行上。如果我在where子句中使用And,则没有任何捕获,如果我使用OR,则结果不准确。

1 个答案:

答案 0 :(得分:0)

就涉及SQL而言,我希望你能做的事情是:

Select CandidateId, Count(*)
from viewCandidate
where CandidateSkillId in (skill1,skill2,skill3)
having count(*) = skillCt