Как заставить Excel учитывать ТОЛЬКО строки, которые имеют заданное значение

Вот изображение, за которым следует описание данных введите здесь описание изображения

Описание столбцов:

  • Столбец A (ключ) представляет собой строго возрастающую последовательность десятичных знаков.
  • Столбец B (Группа) представляет группу, к которой принадлежит значение в A.
  • Столбец C (Данные) представляет собой отсортированные данные.

Входы (в столбце F)

  • Точный номер группы, т.е. {1, 2, 3, 4} в F4
  • Десятичное значение (неограниченное), назовите его DecimalValue, в F5

Задача

Найдите строку, принадлежащую данному Group, где значение ABS(Key - DecimalValue) минимизировано. Верните Data из этой строки.

  • В идеале ищите решение только для Excel, использующее ИНДЕКС, ВПР, АБС и тому подобное.

Этот вопрос похож на мой предыдущий вопрос, но достаточно отличается (включает новый столбец _6), где с помощью комментариев было определено, что лучше задать новый вопрос, а не пытаться обновить/изменить существующий вопрос:

Отображать значения строк на основе ближайшего числового совпадения ключа

Добавление исправления для столбца Group, если это возможно, - это то, что мне нужно, поэтому заголовок отражает эту озабоченность.

(Неполное решение – не учитывается столбец Group)

=INDEX(C4:C33,MATCH(MIN(ABS(A4:A33-F5)),ABS(A4:A33-F5),0))

person Dennis    schedule 30.04.2014    source источник
comment
Каков ожидаемый ответ с учетом критериев в вашем примере?   -  person sous2817    schedule 25.06.2014
comment
Пример на изображении {group=3, value=8.01} = 'больше'. Другим примером может быть {group=1, value=3.00} = 'Китайский'.   -  person Dennis    schedule 25.06.2014


Ответы (3)


Попробуйте... кажется, это работает на моем тестовом листе. Обязательно отрегулируйте диапазоны в соответствии с вашей ситуацией. Опять же, это формула массива, и ее необходимо подтвердить с помощью Ctrl+Shift+Enter:

=INDEX(C2:C7,MATCH(MIN(ABS((B2:B7=F4)*A2:A7-F5)),ABS((B2:B7=F4)*A2:A7-F5),0),0)

Он работает путем обнуления клавиш, которые не соответствуют назначению вашей группы (это часть (B2:B7=F4)*A2:A7-F5). Таким образом, только ключи с допустимыми группами имеют некоторый номер, который будет использоваться для сопоставления со столбцом данных.

Надеюсь, это поможет объяснить это. Вы также можете использовать функцию «Оценить формулу» на панели инструментов «Формулы», чтобы увидеть ее в действии.

Примечание. Кажется, что возвращается 1-е значение данных, если 0 используется в качестве ближайшего значения (независимо от выбора группы). Не знаю, как обойти это...

person sous2817    schedule 25.06.2014
comment
Я считаю, что это лучший ответ (почти сам опубликовал его!). Однако было бы лучше обернуть ABS() массивы в IFERROR() функций. Тогда столбец Key мог бы содержать пустые ячейки, и столбцы не нужно было бы настраивать каждый раз при изменении длины данных. Вот так: =INDEX(Data,MATCH(MIN(IFERROR(ABS((GroupNo=Group)*Key-DecimalValue)," ")),IFERROR(ABS((GroupNo=Group)*Key-DecimalValue)," "),0)) (обратите внимание, что GroupNo — это столбец с номером группы, Group — группа, назначенная для поиска). - person Rick supports Monica; 26.06.2014

Вот ответ sous2817, скорректированный, чтобы избежать проблемы с получением неправильного результата при вводе 0:

=INDEX(Data,MATCH(MIN(IFERROR(ABS(IF(GroupNo=Group,1," ")*Key-DecimalValue),
" ")),IFERROR(ABS(IF(GroupNo=Group,1," ")*Key-DecimalValue)," "),0))

Объяснение того, как это работает, такое же. Проблема решается заменой нулей ошибками.

Обратите внимание, что Key — ключевой столбец, GroupNo — столбец номера группы, Data — столбец данных, Group — группа, назначенная для поиска, а DecimalNumber — номер, введенный для поиска.

РЕДАКТИРОВАТЬ: Как обсуждалось в комментариях ниже, эту формулу можно сделать гораздо более читабельной, используя именованный диапазон (именованная формула AKA). Установите именованный диапазон searchRange равным:

IFERROR(ABS(IF(GroupNo=Group,1," ")*Key-DecimalValue)," ")

Тогда формула становится:

=INDEX(Data,MATCH(MIN(searchRange),searchRange,0))

Это дает дополнительное преимущество в виде меньших накладных расходов Excel, поскольку именованная формула вычисляется только один раз (тогда как в другой версии она вычисляется каждый раз, когда появляется).

person Rick supports Monica    schedule 25.06.2014
comment
На самом деле нет. Просто используйте именованный диапазон. Вот так: Установите searchRange равным IFERROR(ABS(IF(GroupNo=Group,1," ")*Key-DecimalValue)," ") Формула теперь: =INDEX(Data,MATCH(MIN(searchRange),searchRange,0)). searchRange оценивается Excel только один раз. :) - person Rick supports Monica; 26.06.2014
comment
Теперь ЭТО прекрасный ответ. Мне действительно нужно научиться использовать именованные (вычисленные) диапазоны... Я когда-либо использовал их только статически. Это был мой учебный момент в течение дня. Благодарю вас! - person Floris; 26.06.2014
comment
Они очень мощные. Просто будьте осторожны, чтобы не сделать их изменчивыми (используйте INDEX() и MATCH() вместо OFFSET(), INDIRECT() и т. д. и т. д.), и не устанавливайте их так, чтобы они перемалывали целые столбцы, например. A:A. Вы пожалеете об этом позже.... медленные таблицы. - person Rick supports Monica; 26.06.2014

Вы должны быть в состоянии сделать следующее

Function getLastRow()
    Dim i As Integer
    Dim l_row As Integer
    For i = 1 To 35
        If Sheet1.Cells(Rows.Count, i).End(xlUp).Row > l_row Then
            l_row = Sheet1.Cells(Rows.Count, i).End(xlUp).Row
        End If
    Next i
    getLastRow = l_row
End Function
Sub data_lookup
    Dim last_row As Integer
    Dim lcell as Range
    Dim col_a_lookup As Double
    Dim col_b_lookup AS Double
    Dim row_collection As New Collection
    Dim variance AS Double
    Dim closest_row AS Integer

    col_b_lookup = 0.04
    col_a_lookup = 8
    variance = 50

    last_row = getLastRow
    'Find All the Cells that match your lookup value for column B
    For Each lcell in Sheet1.Range("$B$2", "$B$" & last_row)
       If lcell.value = col_b_lookup Then
          row_collection.Add lcell
       End If
    Next lcell
    'Loop through the collection created above to find the closest absolute value to
    'your lookup value for Column A 
    For Each lcell in row_collection
        If Abs(Sheet1.Cells(lcell.row,"A") - col_a_lookup) < variance then
            variance = Abs(Sheet1.Cells(lcell.row,"A") - col_a_lookup)
            closest_row = lcell.row
        End If
    Next lcell
    'Return Results 
    If closest_row > 0 Then
        Msgbox "Closest Data: " & Sheet1.Cells(closest_row,"G")
    Else
        Msgbox "Cannot Locate"
    End If
End Sub

Очевидно, вам придется установить col_a_lookup и col_b_lookup в указанные значения, и я уверен, что вы хотите изменить Msgbox. Но это должно помочь вам на вашем пути.

person engineersmnky    schedule 30.04.2014