2009-08-31 12 views
9

VBA für Access fehlt eine einfache Max(x,y) Funktion, um das mathematische Maximum von zwei oder mehr Werten zu finden. Ich bin daran gewöhnt, eine solche Funktion bereits in der Basis-API aus anderen Sprachen wie Perl/PHP/Ruby/Python usw.Nein max (x, y) Funktion in Access

Ich weiß, es kann getan werden: IIf(x > y, x,y). Gibt es andere verfügbare Lösungen?

Antwort

7

Ich werde die Frage interpretieren zu lesen:

Wie man eine Funktion in Access nicht implementiert, der die Max/Min aus einer Anordnung von Zahlen zurückgibt? Hier ist der Code, den ich verwende (mit dem Namen „iMax“ analog zu IIf, dh „Immediate If“/„Immediate Max“):

Public Function iMax(ParamArray p()) As Variant 
    ' Idea from Trevor Best in Usenet MessageID [email protected] 
    Dim i As Long 
    Dim v As Variant 

    v = p(LBound(p)) 
    For i = LBound(p) + 1 To UBound(p) 
     If v < p(i) Then 
     v = p(i) 
     End If 
    Next 
    iMax = v 
    End Function 

    Public Function iMin(ParamArray p()) As Variant 
    ' Idea from Trevor Best in Usenet MessageID [email protected] 
    Dim i As Long 
    Dim v As Variant 

    v = p(LBound(p)) 
    For i = LBound(p) + 1 To UBound(p) 
     If v > p(i) Then 
     v = p(i) 
     End If 
    Next 
    iMin = v 
    End Function 

Wie, warum Zugang es nicht umsetzen würde, ist es nicht ein sehr häufiger etwas zu brauchen, scheint mir. Es ist auch nicht sehr "datenbehaftet". Sie haben bereits alle Funktionen, die Sie benötigen, um Max/Min domänenübergreifend und in Reihen zu finden. Es ist auch nicht sehr schwer zu implementieren oder einfach nur als einmaliger Vergleich zu programmieren, wenn Sie es brauchen.

Vielleicht wird das obige jemandem helfen.

+1

Das ist nützlicher als Down-Stimmen ein Jahr nach der Frage. :) – DGM

+2

Ich bin überrascht, dass es früher keine Antwort bekommen hat, wenn man bedenkt, wie trivial das Problem ist.Vielleicht liegt es daran, dass die Frage konfrontativ war (d. H. Schlechtes Access), so dass die Leute, die die Antwort kannten, zu sehr ausgeschaltet waren, um jemanden zu helfen, der etwas von einem Chip auf seiner Schulter zu haben scheint. –

+1

Sie verstehen, warum ein Datenbankentwicklungswerkzeug keine solche Funktion eingebaut hat, oder? Es gibt viel größere Lücken, die datenbankbezogen sind als eine Funktion wie diese. –

1

Weil sie wahrscheinlich dachten, dass Sie DMAX und DMIN oder sql MAX verwenden und nur mit der Datenbank im Zugriff arbeiten würden?

Ich bin auch neugierig auf warum .. Es scheint wie ein Overkill zu haben, eine Temp-Tabelle zu erstellen und fügen Sie Formularwerte in die Tabelle und führen Sie dann eine DMAX oder MAX-Abfrage auf der Tabelle, um das Ergebnis zu erhalten ...

+0

Ja, und die Werte, die ich verwende, sind in der Datenbank, aber in zwei Spalten derselben Zeile. Es ist einfach kein Aggregat Max, sondern ein einfacher mathematischer Max. – DGM

1

Ich bin dafür bekannt, eine kleine projMax() -Funktion zu erstellen, nur um mit diesen umzugehen. Nicht, dass VBA wahrscheinlich jemals verbessert wird, aber nur für den Fall, dass sie jemals eine richtige Max- (und Min-) Funktion hinzufügen, wird es keinen Konflikt mit meinen Funktionen geben. Übrigens schlägt das ursprüngliche Poster vor, IIF zu machen ... Das funktioniert, aber in meiner Funktion werfe ich normalerweise ein paar Nz() 's, um zu verhindern, dass eine Null die Funktion ruiniert.

1

Ich mochte DGM die Verwendung der IIF-Anweisung und Davids Verwendung der For/Next-Schleife, also kombiniere ich sie zusammen.

Da VBA im Zugriff keine strenge Typprüfung hat, verwende ich varients, um alle numerischen Werte zu erhalten, ganzzahlig und dezimal, und gebe den Rückgabewert neu ein.

Kudos zu HansUP für das Abfangen meiner Parameterüberprüfung :)
Kommentare hinzugefügt, um Code freundlicher zu machen.

Option Compare Database 
Option Base 0 
Option Explicit 

Function f_var_Min(ParamArray NumericItems()) As Variant 
If UBound(NumericItems) = -1 Then Exit Function ' No parameters 
Dim vVal As Variant, vNumeric As Variant 
vVal = NumericItems(0) 
For Each vNumeric In NumericItems 
    vVal = IIf(vNumeric < vVal, vNumeric, vVal) ' Keep smaller of 2 values 
Next 
f_var_Min = vVal ' Return final value 
End Function 

Function f_var_Max(ParamArray NumericItems()) As Variant 
If UBound(NumericItems) = -1 Then Exit Function ' No parameters 
Dim vVal As Variant, vNumeric As Variant 
vVal = NumericItems(0) 
For Each vNumeric In NumericItems 
    vVal = IIf(vNumeric < vVal, vVal, vNumeric) ' Keep larger of 2 values 
Next 
f_var_Max = vVal ' Return final value 
End Function 

Der einzige Unterschied zwischen den 2-Funktionen ist die Reihenfolge der vVal und vNumeric in der Anweisung IIF.
Die for eachle-Klausel verwendet interne VBA-Logik, um die Schleifen- und Arraygrenzenprüfung zu verarbeiten, während "Base 0" den Arrayindex bei 0 startet.

+1

'IsNull (NumericItems)' wird nie 'True' sein. Wenn Sie die Funktion beenden wollten, wenn sie ohne Argumente aufgerufen wird, versuchen Sie, nach 'UBound (NumericItems) = -1' zu suchen. – HansUp

+0

Gutes Auge, haben Ihre Vorschläge für einige Beispieldaten verwendet und es funktionierte wie angekündigt, weiter so! – CoveGeek

0

Beide Funktionen haben Probleme mit Null. Ich denke, das wird besser.

Public Function iMin(ParamArray p()) As Variant 
    Dim vVal As Variant, vMinVal As Variant 

    vMinVal = Null 
    For Each vVal In p 
    If Not IsNull(vVal) And (IsNull(vMinVal) Or (vVal < vMinVal)) Then _ 
     vMinVal = vVal 
    Next 

    iMin = vMinVal 
End Function 
0

Sie können Worksheetfunction.max() oder worksheetfunction.min() in Access VBA tun. Hoffe das hilft.