2016-09-16 9 views
0

Функция ISBETWEEN проверяет, падает ли значение между нижней границей и верхней границей. Если в Excel нет встроенной функции ISBETWEEN, проверяемое значение должно сравниваться дважды; сначала с '>', а затем с '<' (или '> =' и '< =' для теста ISBETWEEN, который включает в себя оценки.)Как реализовать ISBETWEEN-подобную функцию для массивов значений без необходимости вычислять массив более одного раза?

Сравнивая значение дважды, необходимо вычислить его дважды и это может быть чрезвычайно дорого, когда это значение является массивом. Поскольку функции массива являются несколько загадочными даже в лучшие времена, удвоение при таком вычислении также посылает читабельность функции plummeting.

Мой вопрос: знает ли кто-нибудь о методе, который предоставляет функциональные возможности ISBETWEEN для массива значений без двойного вычисления этого массива? Я предпочитаю делать это с помощью встроенных функций Excel, но если у кого-то есть отличный VBA, это тоже хорошо.

Большое спасибо за ваше время!

Will

+0

Что значит «ISBETWEEN-подобная функция для массива значений», вы проверяете каждое значение в этом массиве между макс и минусом или вы даете другое значение и видите, что это значение меньше, чем Макс (массив) и больше, чем Min (массив)? –

+0

afaik Существует нет разумного способа получить массив из CSE в функцию VBA и вернуть массив для CSE для продолжения обработки, поэтому VBA может быть не стартером здесь. Возможно, функция 'Lookup()' может быть здесь полезной, так как она будет «искать» диапазон и возвращать результат. Не уверен, что первым параметром 'Lookup()' может быть сам массив. Это было бы интересно ... – JNevill

+1

Как бы вы ожидали *** какой-либо *** реализации, чтобы проверить, находится ли значение между двумя числами только с одним сравнением? – Comintern

ответ

0

Так что я смог разработать кусок VBA, основанный на идее here.

Dim vValueArg As Variant, vLowerArg As Variant, vUpperArg As Variant, vTestLower As Variant, vTestUpper As Variant 

Function ISBETWEEN(vValue As Variant, vLower As Variant, vUpper As Variant, Optional bInc As Boolean = True) As Variant 

vValueArg = vValue 
vLowerArg = vLower 
vUpperArg = vUpper 

If bInc Then 
    vTestLower = [GetValue() >= GetLower()] 
    vTestUpper = [GetValue() <= GetUpper()] 
Else 
    vTestLower = [GetValue() > GetLower()] 
    vTestUpper = [GetValue() < GetUpper()] 
End If 

ISBETWEEN = [IF((GetTestLower() * GetTestUpper()) = 1, TRUE, FALSE)] 

End Function 

Function GetValue() As Variant 
    GetValue = vValueArg 
End Function 

Function GetLower() As Variant 
    GetLower = vLowerArg 
End Function 

Function GetUpper() As Variant 
    GetUpper = vUpperArg 
End Function 

Function GetTestLower() As Variant 
    GetTestLower = vTestLower 
End Function 

Function GetTestUpper() As Variant 
    GetTestUpper = vTestUpper 
End Function 

Первый аргумент может быть единственным значением, диапазоном или массивом. Если одно значение, то следующие два аргумента также должны быть одиночными (но этот вид поражает цель кода!)

Второй и третий аргументы могут также быть одним значением, диапазоном или массивом. Если диапазон, состоящий из нескольких ячеек или массива из нескольких значений, то размеры этих аргументов должны соответствовать размерам первого аргумента. (NB - я НЕ тестировал код с 2-мерными диапазонами или массивами!)

Последний, необязательный аргумент определяет, выполняется ли тест ISBETWEEN, включая или исключая границы. TRUE = включить границы; т. е. arg2 < = arg1 < = arg3 (по умолчанию и поэтому может быть опущен). FALSE = исключить границы; т.е. arg2 < arg1 < arg3.

Хотя это может быть не самый красивый код в мире, он компактный, быстрый (без циклов) и справляется с диапазонами и массивами любого размера.

Надеюсь, что некоторые из вас сочтут это полезным! :)

3

здание из моего комментария выше: Это не дает 100% ответ на на ваш вопрос, но так как он был довольно общий, я думаю, что это ближе всего к ответу, что я могу получить.

Представьте таблицу создать, как:

enter image description here

Мы можем получить количество всех значений, которые находятся между 3 и 5 с использованием CTE/формула массива:

={SUM(IF(LOOKUP(A1:A6,{3,"B";6,"C"})="B",1,0))} 

Результаты:

5 

Это довольно крутой способ сделать это, но массив A1:A6 должен быть указан только один раз. Это довольно круто.

Обратите внимание, что белки в скобках в приведенной выше формуле фактически не введены, но помещаются excel, когда вы вводите формулу массива, чтобы указать, что это формула массива ... вы, вероятно, уже знаете, что, если вы прочитайте это.

+0

Хороший ответ, JNeville, но прочитал его комментарий выше, я не думаю, что это то, чего он хотел достичь. –

+1

Я не согласен. Вместо того, чтобы возвращать true или false, я возвращаю 1 или 0, а затем суммирую это. 6 из одного, полдюжины других. Можно было бы удалить оператор 'if()' из CSE и иметь 'lookup() =" B "' вытолкнуть логическое значение непосредственно на то, что OP обертывает это. – JNevill

+0

Извините, вы правы. –

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

  • Нет связанных вопросов^_^