2017-02-16 17 views
1

Я создал фиктивный пример ниже с таблицей поиска цен Таблица 2 и таблица транзакций Таблица1. Таблицы ниже.Таблица индексов Excel для таблицы поиска по диапазону

Table1

+----------+--------+ 
| CATEGORY | VOLUME | 
+----------+--------+ 
| Orange | 12  | 
+----------+--------+ 
| Orange | 25  | 
+----------+--------+ 
| Grape | 40  | 
+----------+--------+ 
| Grape | 700 | 
+----------+--------+ 

Table2

+----------+-------+-------+ 
| CATEGORY | RANGE | PRICE | 
+----------+-------+-------+ 
| Orange | 10 | 2.50 | 
+----------+-------+-------+ 
| Orange | 20 | 2.00 | 
+----------+-------+-------+ 
| Orange | 30 | 1.50 | 
+----------+-------+-------+ 
| Grape | 50 | 5.00 | 
+----------+-------+-------+ 
| Grape | 100 | 2.00 | 
+----------+-------+-------+ 

Надежда состоит в том, чтобы ссылаться на таблицу поиска и потяните ЦЕНУ связанный с диапазоном менее или равной громкости для данной категории , В случаях, когда VOLUME больше, чем любой из RANGE в таблице поиска, он будет тянуть ЦЕНУ для наивысшего значения RANGE.

Желаемая Выход

+----------+--------+-------+ 
| CATEGORY | VOLUME | PRICE | 
+----------+--------+-------+ 
| Orange | 12  | 2.00 | 
+----------+--------+-------+ 
| Orange | 25  | 1.50 | 
+----------+--------+-------+ 
| Grape | 40  | 5.00 | 
+----------+--------+-------+ 
| Grape | 700 | 2.00 | 
+----------+--------+-------+ 

Моя голова сразу же пошел к использованию двойных одинарные - (функции массива, но производительность не будет работать, когда обе таблицы сотни тысяч записей

Любой. Идеи очень ценятся. Использование Excel 2016.

+0

Сколько у вас разных категорий? – CallumDA

+1

Около 500 категорий. Каждый из них должен иметь 40-50 интервалов для диапазона – Blake

+0

_ с 'RANGE', меньше или равным' VOLUME' для заданной 'CATEGORY'_. Разве вы не имеете в виду наименьший« RANGE », который больше или равен« VOLUME » для данной «КАТЕГОРИИ»? –

ответ

1

Я бы предложил использовать инструкцию SQL для двух таблиц/таблиц и вставить результаты с помощью CopyFromRecordset.

SQL:

SELECT t1.CATEGORY, t1.VOLUME, (
     SELECT PRICE 
     FROM [Table2$] AS t2 
     WHERE t1.CATEGORY = t2.CATEGORY 
      AND (
       t1.VOLUME <= t2.RANGE 
       OR t2.RANGE = MAXRANGE 
      ) 
     ORDER BY t2.RANGE 
    ) AS FINALPRICE 
FROM [Table1$] AS t1 
LEFT JOIN (
    SELECT CATEGORY, MAX(RANGE) AS MAXRANGE 
    FROM [Table2$ AS t2a] 
    GROUP BY CATEGORY 
) AS MAXRANGES ON t1.CATEGORY = MAXRANGES.CATEGORY 

Добавить ссылку (Tools ->Список использованной литературы ...) до максимальной версии Microsoft ActiveX Data Objects (на моей машине это 6.1).

Он принимает три рабочих листа — Table1, Table2 и Results. (Также можно использовать именованные диапазоны, или конкретные диапазоны ячеек в виде таблиц.)

Sub main() 
Dim conn As New ADODB.Connection 
With conn 
    .Provider = "Microsoft.ACE.OLEDB.12.0" 
    .ConnectionString = "Data Source=""" & ActiveWorkbook.FullName & """;" & _ 
     "Extended Properties=""Excel 12.0;HDR=Yes""" 
    .Open 
End With 

Dim sql As String 
sql = _ 
    "SELECT t1.CATEGORY, t1.VOLUME, (" & _ 
      "SELECT TOP 1 PRICE " & _ 
      "FROM [Table2$] AS t2 " & _ 
      "WHERE t1.Category = t2.Category " & _ 
       "AND (" & _ 
        "t1.VOLUME <= t2.RANGE " & _ 
        "OR t2.RANGE = MAXRANGE " & _ 
       ") " & _ 
      "ORDER BY t2.RANGE " & _ 
     ") AS FINALPRICE " & _ 
    "FROM [Table1$] AS t1 " & _ 
    "LEFT JOIN (" & _ 
     "SELECT CATEGORY, MAX(RANGE) AS MAXRANGE " & _ 
     "FROM [Table2$] AS t2a " & _ 
     "GROUP BY CATEGORY " & _ 
    ") AS MAXRANGES ON t1.CATEGORY = MAXRANGES.CATEGORY" 

Dim rs As ADODB.Recordset 
Set rs = conn.Execute(sql) 

Worksheets("Results").Cells(1, 1).CopyFromRecordset rs 

conn.Close 
Set conn = Nothing 
Set rs = Nothing 
End Sub 
1

Не уверен, что если вы можете конвертировать таблицу 2 в сводной таблице. Если вы можете, ниже должно работать

Преобразуйте таблицу 2 в сводную таблицу. Добавьте два вспомогательных столбцов («Row» и «Колонка»)

Row =MATCH(E11,$E$3:$E$5,0) 

это дает вам ряд категорий в сводной таблице

Column =IFERROR(1/AGGREGATE(14,6,1/(($F$2:$O$2>F11)*COLUMN($F$2:$O$2)*(OFFSET($F$2:$O$2,H11,0)>0)),1)-COLUMN($E$2),COLUMN($O$2)-COLUMN($E$2)) 

Здесь я также с помощью операции над массивами (для которого было проблема с производительностью), но это ограничивается двумя массивами строк, а не целыми данными.До сих пор не могу сказать о производительности

$F$2:$O$2>F11 дает все диапазоны больше, чем текущий объем

COLUMN($F$2:$O$2) дает номер столбца

OFFSET($F$2:$O$2,H11,0)>0 проверки в текущей категории строки, какие ячейки имеют значения.

Сочетание выше трех условий дает номера столбцов, которые имеют диапазон, превышающий требуемый объем, и имеет соответствующую ему цену.

Часть 1/AGGREGATE() дает минимальное количество столбцов, которое вычитается из номера первого столбца COLUMN($E$2).

Если объем больше максимального диапазона, формула выдаст ошибку, которая будет зафиксирована в части IFERROR. COLUMN($O$2)-COLUMN($E$2) дает вам последний номер столбца в сводной таблице.

После того, как у вас есть строки и столбца, то цена может быть получена по следующей формуле

=INDEX($E$3:$O$5,H11,I11+1) 

Обратите внимание на +1 за номер столбца в этой формуле

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

Sceenshot

Для проверки производительности я создал набор данных 391 категорий, каждый из которых имеет 40 диапазонов , Не делает первенствует медленно .... но ваш случай может отличаться

Performance screenshot

Позвольте мне знать, если вам нужна помощь с пониманием. Моих объяснений может быть недостаточно: P

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

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