Code to Perform a Specification Search of a Catalog

Performing a specification search is an iterative process. The ProductCatalog.PerformSpecificationSearch method can return more than the recordset of matching data. This additional information can be useful for controlling program flow.

The ProductCatalog.PerformSpecificationSearch method indicates the total number of matching records. You might need to force the user to refine a search if there are too many hits. For performance reasons, you should limit the size of the returned recordset to what can be displayed on a single page. The PerformSpecificationSearch method can provide a recordset of searchable properties and existing values for those properties in an optional parameter. Display these properties and values to the user so that the search can be refined.

The following steps demonstrate the use of the PerformSpecificationSearch method:

  1. A specification search is always in the context of a single catalog. Call the BeginSpecificationSearch method to create the search handle:

    ' oCatalog is catalog object to search.
    ' sCategoryName is a string containing the name of the
    ' category to search.
    Dim bNoResults      ' Test flag.
    Dim sSearchHandle   ' String to hold the accumulated search clauses.
    Dim rsFields        ' Recordset to hold the searchable fields
                        ' in the category.
    Dim iMatchesFound   ' Holds the number of hits.
    
    ' Call BeginSpecificationSearch to create the search handle.
    sSearchHandle = oCatalog.BeginSpecificationSearch(sCategoryName, _
                                                      rsFields, _
                                                      iMatchesFound)
    ' Test if the category is specification searchable.
    bNoResults = (rsFields Is Nothing)
    If bNoResults Then
        ' Display a message to the user that the
        ' category is not specification searchable.
    Else
        ' Process the rsFields recordset to find
        ' searchable Fields (see step 2).
        ' Perform the search (see step 3).
    End If
    
  2. The rsFields recordset contains one field for each property in the category. Each field in the recordset contains a SafeArray of all the available values for that property. Display this information to the user as a series of drop-down lists. After the user has made a selection and posted the form, you add specification clauses for each selected value:

    Dim arr1, arr2
    Dim bQuote
    Dim sValue
    Dim objField, iFieldType
    Dim sSearchClause, sPropertyName
    Dim iConstraintFieldsCount
    Dim iNonConstraintFieldsCount
    
    ' Initialize variables.
    iConstraintFieldsCount = 0
    iNonConstraintFieldsCount = 0
    
    ' Separate Fields into searchable and non-searchable arrays.
    ' GetRequestString() is a wrapper function that strips
    ' illegal characters from a call to AppFrameWork.RequestString.
    ReDim arr1(rsFields.Fields.Count)
    ReDim arr2(rsFields.Fields.Count)
    For Each objField In rsFields.Fields
        sValue = GetRequestString(objField.Name, _
                      mscsMessageManager.GetMessage( _
                           "L_STEPSEARCH_NO_PREFERENCE_TEXT", _
                           sLanguage) )
    
        ' sValue will contain the selected value where the user has
        ' made a selection. Where the user did not make a selection 
        ' sValue will contain L_STEPSEARCH_NO_PREFERENCE_TEXT
        If sValue = mscsMessageManager.GetMessage( _
                      "L_STEPSEARCH_NO_PREFERENCE_TEXT", sLanguage) Then
            ' Field is not a search constraint.
            arr1(iNonConstraintFieldsCount) = objField.Name
            iNonConstraintFieldsCount = iNonConstraintFieldsCount + 1
        Else
            ' Field is a Search Constraint.
            sPropertyName = objField.Name
            arr2(iConstraintFieldsCount) = sPropertyName
            ' Some data types must be enclosed in quotes.
            ' Look up the DataType attribute for the property
            ' from the property attributes cache.
            iFieldType = _
                MSCSCatalogAttribs.Value(sPropertyName).Value("DataType")
    
            If (iFieldType = cscString) Or _
               (iFieldType = cscDateTime) Or _ 
               (iFieldType = cscFilePath) Or _ 
               (iFieldType = cscEnumeration) Then
                ' If Text OR DateTime OR FilePath OR Multiple Choice.
                bQuote = True
            Else
                bQuote = False
            End If
            ' Build the search clause for one property.
            sSearchClause = ""
            For Each sValue In Request.QueryString(sPropertyName)
                If bQuote Then sValue = """" & sValue & """"
                sSearchClause = sSearchClause & ", " & sValue
            Next
            ' Add the Specification Search Clause that you just built.
            sSearchClause = "[" & sPropertyName & "]" & _
                            " IN (" & _
                            Right(sSearchClause, _
                                  Len(sSearchClause) - 2) & _
                            ")"
            Call oCatalog.AddSpecificationSearchClause(sSearchClause, _
                                                       sSearchHandle)
    
            iConstraintFieldsCount = iConstraintFieldsCount + 1
        End If
    
    ' Process the next Field.
    Next
    
    ReDim Preserve arr1(iNonConstraintFieldsCount)
    ReDim Preserve arr2(iConstraintFieldsCount)
    
  3. After all the parameters have been built, perform the specification search:

    Set rsResults = _
           oCatalog.PerformSpecificationSearch(sSearchHandle, _
                                               iSearchType, _
                                               , _
                                               iMatchesFound, _
                                               rsFields, _
                                               sColList)
    
  4. Display the results so that the user can refine the search.

Copyright © 2005 Microsoft Corporation.
All rights reserved.