sql >> Database >  >> RDS >> Access

Alternatieve oplossing voor DCount en DLookup met MS SQL Server Backend

Alternatieve oplossing voor DCount en DLookup met MS SQL Server Backend

Een van de belangrijkste problemen die we zijn tegengekomen met Access is het gebruik van DLookup en DCount bij het gebruik van SQL Server-tabellen. We hebben onlangs gewerkt aan het migreren van een pure Access-oplossing naar SQL-server en hebben vertragingen ondervonden bij het laden van verschillende formulieren. Dit kwam door het gebruik van DLookup en DCount in de VBA-code.

We kwamen toen met een oplossing om de meerdere instanties snel op te lossen met een aantal functies. We werden geleid door een andere oplossing van Allen Browne die de Extended DLookup hier in deze link heeft ontworpen.

De oplossing van Allen verbetert de prestaties van de DLookup door:

  • Inclusief een sorteervolgorde om ervoor te zorgen dat u het gewenste resultaat krijgt.
  • Opruimen na zichzelf.
  • Kunt een Null-tekenreeks en een tekenreeks met lengte nul correct onderscheiden.
  • Algemene prestatieverbetering.

We zijn nu een stap verder gegaan om specifiek met SQL-tabellen of views te werken. Deze werken niet met lokale Access-tabellen omdat we specifiek een ADO-verbinding gebruiken.

Ik voeg de code voor beide functies toe om zowel DLookup als DCount te vervangen

Public Function ESQLLookup(strField As String, strTable As String, Optional Criteria As Variant, _
    Optional OrderClause As Variant) As Variant
 
    Dim rs As ADODB.Recordset         'To retrieve the value to find.
    Dim rsMVF As ADODB.Recordset      'Child recordset to use for multi-value fields.
    Dim varResult As Variant        'Return value for function.
    Dim strSQL As String            'SQL statement.
    Dim strOut As String            'Output string to build up (multi-value field.)
    Dim lngLen As Long              'Length of string.
    Const strcSep = ","             'Separator between items in multi-value list.

    'Initialize to null.
    varResult = Null

    'Encapsulate Domain in brackets if none exist to allow special characters in the Domain string
    If Left$(strTable, 1) <> "[" Then
        strTable = "[" & strTable & "]"
    End If

    'Build the SQL string.
    strSQL = "SELECT TOP 1 " & strField & " FROM " & strTable
    If Not IsMissing(Criteria) Then
        strSQL = strSQL & " WHERE " & Criteria
    End If
    If Not IsMissing(OrderClause) Then
        strSQL = strSQL & " ORDER BY " & OrderClause
    End If
    strSQL = strSQL & ";"

    'Lookup the value.
    OpenMyRecordset rs, strSQL, rrOpenForwardOnly, rrLockReadOnly, True
    If rs.RecordCount > 0 Then
        'Will be an object if multi-value field.
        If VarType(rs(0)) = vbObject Then
            Set rsMVF = rs(0).Value
            Do While Not rsMVF.EOF
                If rs(0).Type = 101 Then        'dbAttachment
                    strOut = strOut & rsMVF!FileName & strcSep
                Else
                    strOut = strOut & rsMVF![Value].Value & strcSep
                End If
                rsMVF.MoveNext
            Loop
            'Remove trailing separator.
            lngLen = Len(strOut) - Len(strcSep)
            If lngLen > 0& Then
                varResult = Left(strOut, lngLen)
            End If
            Set rsMVF = Nothing
        Else
            'Not a multi-value field: just return the value.
            varResult = rs(0)
        End If
    End If
    rs.Close

    'Assign the return value.
    ESQLLookup = varResult
   
ErrEx.Catch 11 ' Division by Zero
    Debug.Print strSQL
    MsgBox "To troubleshoot this error, please evaluate the data that is being processed by:" _
            & vbCrLf & vbCrLf & strSQL, vbCritical, "Division by Zero Error"

ErrEx.CatchAll
    MsgBox "Error " & err.Number & ": " & err.Description, vbCritical, "Unexpected error"
    
ErrEx.Finally
    Set rs = Nothing

End Function


Public Function ESQLCount(strField As String, strTable As String, Optional Criteria As Variant) As Variant
    Dim rs As ADODB.Recordset         'To retrieve the value to find.
    Dim varResult As Variant        'Return value for function.
    Dim strSQL As String            'SQL statement.
    Dim lngLen As Long              'Length of string.

    'Initialize to null.
    varResult = Null

    'Encapsulate Domain in brackets if none exist to allow special characters in the Domain string
    If Left$(strTable, 1) <> "[" Then
        strTable = "[" & strTable & "]"
    End If

    'Build the SQL string.
    strSQL = "SELECT COUNT(" & strField & ") AS TotalCount FROM " & strTable
    If Not IsMissing(Criteria) Then
        strSQL = strSQL & " WHERE " & Criteria
    End If
    strSQL = strSQL & ";"

    'Lookup the value.
    OpenMyRecordset rs, strSQL, rrOpenForwardOnly, rrLockReadOnly, True
    
    varResult = Nz(rs.Fields("TotalCount"), 0)
    rs.Close

    'Assign the return value.
    ESQLCount = varResult
    
   
ErrEx.CatchAll
    MsgBox "Error " & err.Number & ": " & err.Description, vbCritical, "Unexpected error"
    Resume Next
    
ErrEx.Finally
    Set rs = Nothing

End Function

Als u een instantie heeft die het gebruik van DSum vereist, kunt u de DCount-functie eenvoudig aanpassen om u het vereiste resultaat te geven.

Na het toepassen van deze oplossing vonden we een dramatische verbetering in de prestaties van het laden van formulieren en het ontwerp helpt ons om deze oplossing op meerdere projecten toe te passen. Ik hoop dat deze oplossing nuttig voor je is en als je andere problemen hebt waarmee we je kunnen helpen, neem dan contact met ons op via accessexperts.com.


  1. Hoe kan ik een JSON-bestand importeren in PostgreSQL?

  2. Disaster Recovery-opties voor PostgreSQL geïmplementeerd in een hybride cloud

  3. SQL SELECT-instructie

  4. Oracle-taalparameters instellen voor DG4ODBC