This is the entire module I wrote for building SQL strings for my application. All of this was previously contained in a single sub so I broke it up into individual 'tasks', if that makes any sense. Since I'm still pretty new at this I don't know if that's good or bad practice.

Good, bad, inefficient, maintainable? Do your worst; I'm prepared to take it! There are several functions so if you have any questions about how they work or if I've left anything out please let me know.

TIA.

VB Code:
  1. ' This function fetches the subfilter condition from the Conditions table
  2. ' on SQL Server and returns it to the calling sub only if there is a selected
  3. ' value on the subfilter.  If there is no selected value or the selected
  4. ' value is 'All', the function returns nothing.  The sub-filter is the combo
  5. ' box on Criteria Selection where the user can choose values for Application
  6. ' Type, Critical Illness, Missing Items, or Sum Assured.
  7.  
  8. Public Function GetCondition(strSubFilterValue As String, strSQL As String) As String
  9.  
  10. ' Check to make sure connection still exists.  If it doesn't, set it up.  If connection
  11. ' is closed then open it.
  12. ' Call CheckConnection
  13.  
  14. Dim strCondition As String
  15.  
  16. ' // If the LENGTH of the subfilter value is 0 then nothing is selected, strCondition
  17. ' is set to empty; if the value is 'ALL' then no filtering needs to be applied and
  18. ' strCondition is likewise set to empty.
  19. If Len(strSubFilterValue) = 0 Then
  20.     strCondition = ""
  21. ElseIf strSubFilterValue = "All" Then
  22.     strCondition = ""
  23.    
  24. ' // If the LENGTH of the subfilter value is greater than zero this indicates the user
  25. ' has selected something, so a recordset is opened and the SQL source passed to the function
  26. ' is executed.
  27. ElseIf Len(strSubFilterValue) > 0 Then
  28.     Dim rst As ADODB.Recordset
  29.     Set rst = New ADODB.Recordset
  30.     rst.Open strSQL, cnConn, adOpenForwardOnly, adLockReadOnly, adCmdText
  31.     strCondition = rst.GetString
  32.     rst.Close
  33.     Set rst = Nothing
  34. End If
  35.  
  36. GetCondition = strCondition
  37.  
  38. End Function

VB Code:
  1. ' This function uses the tab the user is on and the value of the filter they've
  2. ' selected to construct part of the 'WHERE' clause SQL Server will need to return
  3. ' the appropriate data.  Example 'filter' values are York, Bankhall, CONTROL, etc.
  4. ' This function does not actually include 'WHERE' or 'AND'; that part of the string
  5. ' is constructed by another function.
  6.  
  7. Public Function GetClause(strTabValue As String, strFilterValue As String) As String
  8.  
  9. ' Check to make sure connection still exists.  If it doesn't, set it up.  If connection
  10. ' is closed then open it.
  11. ' Call CheckConnection
  12.  
  13.     Dim strClause As String
  14.  
  15.     ' Builds a SQL clause based on what tab the user is currently using; if the tab value
  16.     ' is "Headof" then no clause is built as no filter is actually being used.
  17.     Select Case strTabValue
  18.         Case Is = "HeadOf"
  19.             strClause = ""
  20.         Case Is = "Distributor"
  21.             strClause = "Distributor = " & "'" & "'" & strFilterValue & "'" & "'"
  22.         Case Is = "Site"
  23.             strClause = "Site = " & "'" & "'" & strFilterValue & "'" & "'"
  24.         Case Is = "Team"
  25.             strClause = "Team = " & "'" & "'" & strFilterValue & "'" & "'"
  26.         Case Is = "Parent"
  27.             strClause = "ParentCompany = " & "'" & "'" & strFilterValue & "'" & "'"
  28.         Case Else
  29.             strClause = ""
  30.     End Select
  31.    
  32.     GetClause = strClause
  33.  
  34. End Function

VB Code:
  1. ' This function uses the values of strCondition and strClause plus
  2. ' what tab the user is on to determine how to build the parameter string.
  3. ' On the HeadOf tab, the only time there will be a WHERE clause is if
  4. ' a sub-filter value is selected; otherwise there is no WHERE clause.
  5. '
  6. ' On other tabs if a sub-filter value is selected it must be preceded by AND,
  7. ' not WHERE, as you can only use the WHERE keyword once in a normal query
  8. ' and we'll already be using WHERE for Distributor, Site, Team, or ParentCompany.
  9.  
  10. Public Function GetParameter(strCondition As String, strTabValue As String _
  11.     , strClause As String) As String
  12.  
  13.     ' Check to make sure connection still exists.  If it doesn't, set it up.  If connection
  14.     ' is closed then open it.
  15.     'Call CheckConnection
  16.    
  17.     Dim strParameter As String
  18.    
  19.     Select Case strTabValue
  20.         ' If the user is on HeadOf and no condition is selected then no WHERE clause is built
  21.         ' If a condition (subfilter) is selected then a WHERE clause is constructed
  22.         Case Is = "HeadOf"
  23.             If strCondition = "" Then
  24.                 strParameter = ""
  25.             Else:
  26.                 strParameter = " WHERE " & strCondition
  27.             End If
  28.         ' If the user is on any other tab and no condition (subfilter) is selected then the
  29.         ' WHERE clause is constructed using only the selected distributor, site, etc.
  30.         ' If a condition (subfilter) is selected then an AND clause is tacked onto the
  31.         ' end of the WHERE clause
  32.         Case Is = "Distributor", "Site", "Team", "Parent"
  33.             If strCondition = "" Then
  34.                 strParameter = " WHERE " & strClause
  35.             Else: If Len(strCondition) > 0 Then strParameter = " WHERE " & strClause & " AND " & strCondition
  36.             End If
  37.         ' This should never happen, but in case it does GetParameter returns a zero-length string
  38.         Case Else
  39.             strParameter = ""
  40.     End Select
  41.    
  42.     GetParameter = strParameter
  43.  
  44. End Function

VB Code:
  1. ' Executes GetClause, GetCondition, and GetParameter to build an appropriate
  2. ' SQL string based on the user's selections on the CriteriaSelection form.
  3. ' This is the string that will be passed to the appropriate stored procedure
  4. ' as its parameter.
  5.  
  6. Public Function DeriveWhereClause() As String
  7.  
  8. ' Check to make sure connection still exists.  If it doesn't, set it up.  If connection
  9. ' is closed then open it.
  10.  Call CheckConnection
  11.  
  12. Dim strParameter As String          ' Holds value of parameter
  13. Dim strCondition As String          ' Holds value of condition
  14. Dim strClause As String             ' Holds value of clause
  15. Dim strTabValue As String           ' Holds what tab user is currently on
  16. Dim strFilterValue As String        ' Holds value of filter, i.e. 'York', 'Bankhall', etc
  17. Dim strSubFilterValue As String     ' Holds value of subfilter, i.e. 'paper', 'dirty', etc
  18. Dim strAddInfoType As String        ' Holds value of subfilter type, i.e. 'Missing Items', 'Critical Illness', etc
  19. Dim strSQL As String                ' Source SQL
  20.  
  21. ' Call global variable functions and assign results to local variables
  22. strTabValue = GetgVarActiveTab()
  23. strFilterValue = GetgVarPrimInfoValue()
  24. strSubFilterValue = GetgVarAddInfoValue()
  25. strAddInfoType = GetgVarAddInfoType()
  26.  
  27. ' Initialize strSQL
  28. strSQL = "SELECT SQLResult FROM Conditions WHERE QueryField = " _
  29.     & "'" & strAddInfoType & "'" & " AND Value = " & "'" & strSubFilterValue & "'"
  30.  
  31. ' Call GetCondition function and assign result to strCondition variable
  32. If Len(strSubFilterValue) > 0 Then
  33.     strCondition = GetCondition(strSubFilterValue, strSQL)
  34. Else
  35.     strCondition = ""
  36. End If
  37.  
  38. ' Call GetClause function and assign result to strClause variable
  39. If Len(strTabValue) > 0 Then
  40.     strClause = GetClause(strTabValue, strFilterValue)
  41. Else
  42.     strClause = ""
  43. End If
  44.  
  45. ' Call GetParameter function and assign result to strParameter variable
  46. strParameter = GetParameter(strCondition, strTabValue, strClause)
  47.  
  48. DeriveWhereClause = strParameter
  49.  
  50. End Function

VB Code:
  1. Public Function MakeSQLString() As String
  2.  
  3.     ' Check to make sure connection still exists/is open.
  4.     Call CheckConnection
  5.  
  6.     Dim strSQL As String
  7.     Dim strSQLObject As String
  8.     Dim strSource As String
  9.    
  10.     Dim rst As ADODB.Recordset
  11.    
  12.     strSource = "SELECT SQLObject FROM tblReports WHERE ReportName = " & _
  13.         "'" & GetgVarReportSelected() & "'"
  14.    
  15.     Set rst = cnConn.Execute(strSource)
  16.     strSQLObject = rst.GetString
  17.    
  18.     ' Status History and CELT Data Summary cannot be filtered in any
  19.     ' way so their SQL strings are hard-coded here.  Weekly Summary
  20.     ' is not handled by this function at all.
  21.     Select Case GetgVarReportSelected()
  22.         Case Is = "Status History"
  23.             strSQL = "EXEC sp_StatusPositionSummary"
  24.         Case Is = "CELT Data Summary"
  25.             strSQL = "EXEC sp_FEWATCELT"
  26.         Case Else
  27.             strSQL = "EXEC " & strSQLObject & " @Filter = " _
  28.                 & "'" & DeriveWhereClause & "'"
  29.     End Select
  30.      
  31.     MakeSQLString = strSQL
  32.    
  33.     rst.Close
  34.     Set rst = Nothing
  35.    
  36. End Function