Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Handling DsLookup (by Hondo)

Begonnen von Doming, Mai 22, 2025, 13:32:09

⏪ vorheriges - nächstes ⏩

Doming

Moin,

ich bin heute ,,aus Versehen" auf dem Blog von Hondo gelandet und habe dort den Ersatz für Dlookup gefunden.
In der Doku ist der Code auch als Ersatz für DCount angekündigt, wie kann ich die Anzahl der Einträge damit zurückgeben?

Wenn ich von dem Geschwindigkeitsvorteil auch noch nicht ganz überzeugt bin, die Abfrage von mehreren Feldern damit finde ich definitiv gelungen.

Gruß
 Doming

Hondo

#1
Hallo,
der Code ist ja schon ein paar Jahre alt, inzwischen verwende ich eine ganz andere Funktion als Ersatz für die Domänenfunktionen:

Edit: siehe hier: https://www.access-o-mania.de/forum/index.php?topic=24528.0
Edit2: das Orginal stammt mutmaßlich von hier: https://www.tksoft-online.de/ms-access/codes/codeschnipsel-sonstiges/82-domaenenfunktionen-ersatz.html

Folgenden Code in ein Modul kopieren:

Public Function fcDomWert(Expression As String, Domain As String, _
                   Optional Criteria As String, _
                   Optional ltDomArt As ltDomWert) As Variant
    Dim bytWert As Byte
    Dim strSQL As String
    Dim rs As DAO.Recordset
    If IsMissing(ltDomArt) Then
        bytWert = 0
    Else
        bytWert = ltDomArt
    End If
    Select Case bytWert
        Case 0: strSQL$ = "SELECT " & Expression$ & " FROM " & Domain$
        Case 1: strSQL$ = "SELECT COUNT(" & Expression$ & ") FROM " & Domain$
        Case 2: strSQL$ = "SELECT MAX(" & Expression$ & ") FROM " & Domain$
        Case 3: strSQL$ = "SELECT SUM(" & Expression$ & ") FROM " & Domain$
        Case 4: strSQL$ = "SELECT FIRST(" & Expression$ & ") FROM " & Domain$
        Case 5: strSQL$ = "SELECT LAST(" & Expression$ & ") FROM " & Domain$
        Case 6: strSQL$ = "SELECT SUM(" & Expression$ & ") FROM " & Domain$
        Case 7: strSQL$ = "SELECT AVG(" & Expression$ & ") FROM " & Domain$
    End Select
    If Nz(Criteria$, "") <> "" Then strSQL$ = strSQL$ & " WHERE " & Criteria$
    Set rs = CurrentDbC.OpenRecordset(strSQL$, dbOpenForwardOnly)
    If rs.EOF Then
        fcDomWert = Null
    Else
        fcDomWert = rs.Fields(0)
    End If
    rs.Close
    Set rs = Nothing
End Function

In den Deklarationsteil schreibst du folgendes:
Public Enum ltDomWert
    ltDLookup = 0
    ltDCount = 1
    ltDMax = 2
    ltDMin = 3
    ltDFirst = 4
    ltDLast = 5
    ltDSum = 6
    ltDAvg = 7
End Enum


Jetzt kannst du alle Domänenfunktionen aufrufen.

Also z.B. DLookup:
MeinWert = fcDomWert("Feldname1", "Tabelle1","ID=4711", ltDLookup)
Oder DCount:
Anzahl = fcDomWert("*", "Tabelle1", "Nachname='Meier'", ltDCount)

Durch den Enum hast du im VBA-Editor dann automatisch eine Intellisense.
Ob der Code von mir selbst stammt kann ich nicht sagen. Möchte mich da auch nicht mit fremden Federn schmücken.
Gruß Andreas

PhilS

Zitat von: Hondo am Mai 22, 2025, 15:03:52If rs.EOF Then
    fcDomWert = Null
Das ist teilweise falsch. Für COUNT und SUM muss der Rückgabewert 0 sein und nicht NULL.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Hondo

Zitat von: PhilS am Mai 22, 2025, 16:20:50Das ist teilweise falsch. Für COUNT und SUM muss der Rückgabewert 0 sein und nicht NULL.
Ist halt Definitionssache. Die Null Könnte man auch im Funktionsaufruf behandeln. Oder einfach die Funktion entsprechend abändern.

Frank200

Zitat von: Hondo am Mai 22, 2025, 17:30:22
Zitat von: PhilS am Mai 22, 2025, 16:20:50Das ist teilweise falsch. Für COUNT und SUM muss der Rückgabewert 0 sein und nicht NULL.
Ist halt Definitionssache. Die Null Könnte man auch im Funktionsaufruf behandeln. Oder einfach die Funktion entsprechend abändern.
Da bin ich doch eher bei PhilS. Denn wenn das SELECT keinen Treffer liefert, dann sind COUNT und SUM mit Bestimmtheit = 0 und nicht NULL.
Die kleine Ergänzung sollte noch rein.
If rs.EOF Then
    If bytWert = ltDCount Or bytWert = ltDSum Then
        fcDomWert = 0
    Else
        fcDomWert = Null
    End If
Else
...

Gruß
Frank

Hondo

#5
Hallo
Zitat von: Frank200 am Mai 22, 2025, 19:26:19Da bin ich doch eher bei PhilS. Denn wenn das SELECT keinen Treffer liefert, dann sind COUNT und SUM mit Bestimmtheit = 0 und nicht NULL.

Ich glaube ihr überseht da was total.
Beispiel:
MsgBox fcDomWert("*", "tabmitglieder", "fname='test'", ltDCount)
Liefert die Abfrage keine Datensätze so ist der Rückgabewert 0 und nicht Null. Denn rs.EOF wird dabei nicht wahr. Und als Ergebnis steht in rs.Fields(0) die "0"

Man braucht aber den rs.EOF um z.B. beim DLookup-Ersatz die Null als Rückgabewert zu bekommen wenn kein Datensatz geliefert wird.

Die Ergänzung des Codes ist also total überflüssig.

Gruß Andi

Frank200

Sorry Andreas, Du hast Recht.
PhilS Worte hatten mich wohl auf's Glatteis geführt.
Natürlich liefern die Statements von SUM und COUNT bei fehlenden Treffern von Haus aus die 0.
Die Ergänzung war somit Unsinn.
Gruß
Frank

Doming

Hihi, jetzt habe ich mir zuert das ,,Original" aus dem Link oben gezogen und prompt hat sich der Compiler an dem Dlookup/DCount in der DomWert-Deklarierung gestört...

Kaum macht mans richtig, funktionierts

Gruß
 Doming

PhilS

Zitat von: Hondo am Mai 22, 2025, 20:53:01Ich glaube ihr überseht da was total.
Mea culpa! Das habe ich tatsächlich komplett übersehen. - Damit ist meine Anmerkung natürlich Unfug.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Hondo

Zitat von: PhilS am Mai 23, 2025, 10:00:16Mea culpa! Das habe ich tatsächlich komplett übersehen.
Danke, hatte schon an mir gezweifelt.
Gruß Andi

Josef P.

[OT]
ZitatNatürlich liefern die Statements von SUM und COUNT bei fehlenden Treffern von Haus aus die 0.
Sum wird Null (nicht 0) liefern und das ist gut so. ;)

Gruß
Josef