2009-08-31 3 views
9

У VBA for Access нет простой функции Max(x,y), чтобы найти математический максимум двух или более значений. Я привык иметь такую ​​функцию уже в базовом API, поступающем с других языков, таких как perl/php/ruby ​​/ python и т. Д.Функция max (x, y) в Access

Я знаю, что это можно сделать: IIf(x > y, x,y). Существуют ли другие решения?

ответ

7

Я буду интерпретировать этот вопрос следующим образом:

Как один реализовать функцию в Access, которая возвращает Max/Min из массива чисел? Вот код, я использую (названный «IMAX» по аналогии с IIf, то есть, «Немедленное Если»/«Немедленное 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 

Как почему Access не будет выполнять его, это не очень распространено мне кажется, что нужно. Это тоже не «база данных». У вас уже есть все функции, необходимые для поиска Max/Min через домен и в наборах строк. Это также не очень сложно реализовать или просто кодировать как одноразовое сравнение, когда оно вам нужно.

Возможно, это поможет кому-то.

+1

Это более полезно, чем пустые голоса в год после вопроса. :) – DGM

+2

Я удивлен, что он не получил ответа раньше, учитывая, насколько тривиальна проблема.Возможно, это связано с тем, что вопрос был конфронтационным (т. Е. Плохой доступ), чтобы люди, которые знали ответ, были слишком отключены, чтобы попытаться помочь кому-то, у кого, похоже, есть что-то вроде чипа на плече. –

+1

Вы понимаете, почему инструмент разработки базы данных не будет иметь такую ​​встроенную функцию, верно? Есть гораздо большие упущения, связанные с базой данных, чем такая функция. –

1

Потому что они, вероятно, думали, что вы будете использовать DMAX и DMIN или sql MAX и работать только с базой данных в доступе?

Мне также интересно узнать, почему .. Кажется, что это излишне, чтобы создать временную таблицу и добавить значения формы в таблицу, а затем запустить DMAX или MAX-запрос в таблице, чтобы получить результат ...

+0

Да, и значения, которые я использую, находятся в базе данных, но в двух столбцах одной и той же строки. Это просто не агрегированный Макс, а простой математический Макс. – DGM

1

Известно, что я создал небольшую функцию projMax(), чтобы справиться с ними. Не то, что VBA, вероятно, когда-либо будет улучшено, но на всякий случай, когда они когда-либо добавят правильную функцию Max (и Min), она не будет конфликтовать с моими функциями. Кстати, оригинальный плакат предлагает делать IIF ... Это работает, но в моей функции я обычно бросаю пару Nz(), чтобы предотвратить пустую ошибку от функции.

1

Мне понравилось использование DGM заявления IIF и использование Дэвидом цикла For/Next, поэтому я объединять их.

Поскольку VBA в доступе не имеет строгой проверки типов, я буду использовать переменные для сохранения всех чисел, целочисленных и десятичных чисел и повторного ввода возвращаемого значения.

Претензии к HansUP для обнаружения моей проверки параметров :)
Комментарии добавлены, чтобы сделать код более дружественным.

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 

Единственная разница между двумя функциями - это порядок vVal и vNumeric в инструкции IIF.
Для каждого предложения используется внутренняя логика VBA для обработки проверок циклов и массивов, тогда как «Base 0» запускает индекс массива в 0.

+1

'IsNull (NumericItems)' никогда не будет 'True'. Если вы хотите выйти из функции при вызове без аргументов, попробуйте проверить 'UBound (NumericItems) = -1' – HansUp

+0

Хороший глаз, воспользовались вашими предложениями по некоторым образцовым данным, и он работал как рекламируемый, держите его! – CoveGeek

0

Обе функции имеют проблемы с Null. Я думаю, это будет лучше.

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

Вы можете сделать Worksheetfunction.max() или worksheetfunction.min() в Access VBA. Надеюсь это поможет.

Смежные вопросы