2009-08-31 6 views
9

VBA for Access carece de una función simple Max(x,y) para encontrar el máximo matemático de dos o más valores. Estoy acostumbrado a tener esa función ya en la base API proveniente de otros lenguajes como perl/php/ruby ​​/ python, etc.Sin función max (x, y) en Access

Sé que se puede hacer: IIf(x > y, x,y). ¿Hay otras soluciones disponibles?

Respuesta

7

Voy a interpretar la pregunta para leer:

¿Cómo se puede implementar una función de acceso que devuelve el Max/Min de un conjunto de números? Aquí está el código que utilizo (llamado "Imax" por analogía con SiInm, es decir, "if inmediato"/"inmediata 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 

En cuanto a por qué el acceso no sería ponerlo en práctica, que no es muy común cosa que necesita, me parece a mí. No es muy "databasy", tampoco. Ya tiene todas las funciones que necesita para encontrar Máx/Min en todo el dominio y en conjuntos de filas. Tampoco es muy difícil de implementar, o simplemente codificar como una comparación de una sola vez cuando lo necesite.

Quizás lo anterior ayude a alguien.

+1

Eso es más útil que rechazar votos un año después de la pregunta. :) – DGM

+2

Me sorprende que no haya recibido una respuesta antes, dado lo trivial que es el problema.Tal vez se deba a que la pregunta era de confrontación (es decir, acceso malicioso) para que las personas que conocían la respuesta estuvieran demasiado desconectadas como para molestarse en tratar de ayudar a alguien que parece tener algo así como un chip en su hombro. –

+1

¿COMPRENDE por qué una herramienta de desarrollo de bases de datos no tendría una función así? Hay omisiones mucho mayores relacionadas con la base de datos que una función como esta. –

1

Porque probablemente pensaron que usaría DMAX y DMIN o sql MAX y solo trabajaría con la base de datos en acceso?

También tengo curiosidad acerca de por qué .. Parece una exageración tener que crear una tabla temporal y agregar valores de formulario a la tabla y luego ejecutar una consulta DMAX o MAX en la tabla para obtener el resultado ...

+0

Sí, y los valores que estoy usando están en la base de datos, pero en dos columnas de la misma fila. Simplemente no es un Max agregado, sino un Max matemático simple. – DGM

1

Se me conoce por crear una pequeña función projMax() solo para hacer frente a esto. No es probable que VBA sea mejorado, pero en caso de que agreguen una función Max (y Min) adecuada, no entrará en conflicto con mis funciones. Por cierto, el cartel original sugiere hacer IIF ... Eso funciona, pero en mi función, suelo lanzar un par de Nz() para evitar que un nulo arruine la función.

1

Me gustó el uso de DGM de la instrucción IIF y el uso de David del bucle For/Next, así que los estoy combinando.

Como VBA en acceso no tiene una verificación de tipo estricta, voy a utilizar varients para conservar todos los números, enteros y decimales, y volver a escribir el valor de retorno.

Felicitaciones a HansUP por capturar mi verificación de parámetros :)
Comentarios añadidos para hacer que el código sea más amigable.

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 

La única diferencia entre las 2 funciones es el orden de vVal y vNumeric en la instrucción IIF.
El para cada cláusula usa lógica interna de VBA para controlar el bucle y la comprobación de límites de matriz, mientras que "Base 0" inicia el índice de matriz en 0.

+1

'IsNull (NumericItems)' nunca será 'True'. Si nos referimos a salir de la función cuando se le llama sin argumentos, trata de leer para 'UBound (NumericItems) = -1' – HansUp

+0

Buen ojo, utilizado sus sugerencias sobre algunos datos de ejemplo y funcionó como dicen, sigue así! – CoveGeek

0

Ambas funciones tienen problemas con Null. Creo que esto será mejor.

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

Usted puede hacer Worksheetfunction.max() o worksheetfunction.min() dentro de Access VBA. Espero que esto ayude.

Cuestiones relacionadas