вторник, 31 мая 2011 г.

Вариант 2. Количество значений по полю "Данные" заранее не известно и может меняться


Этот случай более сложен. Необходимо создать дополнительное ключевое поле с уникальными значениями путем объединения полей IDTO и "Данные". Но вот в чем проблема, поле IDTO имеет ряд пустых значений, которые мешают. Поэтому придется создать дополнительный столбец (B) в котором с помощью логической функции ЕСЛИ проставить недостающие значения.

Смысл формулы состоит в том что если значение в ячейке столбца "С" равно ПУСТО, то подставлять предыдущее значение, если нет - то новое.
=ЕСЛИ(ЕПУСТО(C7);B6;C7)
После этого в столбце "A", с помощью функции СЦЕПИТЬ, создаем уникальный ключ на основании значений по столбцам "В" и "С".

Что с этим делать дальше? С помощью функции ВПР выбираем данные в выходной документ, так как это показано в примере в статье Объединение.
Учитывая, что сводная табличка может увеличиваться, есть смысл прокопировать формулы с запасом. При изменении/добавлении данных в исходной таблице обновить сводную таблицу и данные автоматически обновятся в выходном документе. Если настроить сводную таблицу так, что бы данные обновлялись при открытии файла, то достаточно перезагрузить файл.


Вариант 1. Количество значений по полю "Данные" заранее известно и постоянно


В этом случае можно развернуть значения по полю "Данные" в одну строку так, чтобы они находились в одной строке со значением IDTO.
Обращаю внимание, что в ячейках "D7" и "E7" надо ставить обычные ссылки на ячейки сводной таблицы, а не функцию
=ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ("Сумма по полю ВОЗН";$A$6;"IDTO";9501)
т.к. последняя при копировании не будет автоматически пересчитываться.
Далее осталось только выделить копируемую область и прокопировать вдоль всей сводной таблицы.
Если есть ожидание что количество уникальных значений по полю IDTO будет увеличиваться или заранее неизвестно (соответственно и сводная таблица будет расти), можно прокопировать с запасом.
Т.о. все данные у нас развернуты построчно соответственно значениям IDTO и далее, можно применять функцию ВПР для выборки данных в выходной документ. При изменении/добавлении данных в исходной таблице необходимо обновить данные сводной таблицы, и они автоматически пересчитаются через функцию ВПР в выходном документе. Что достаточно удобно.






Группировка данных


Допустим имеем достаточно большую табличку (фрагмент ее представлен на рисунке ниже) в которой сначала надо сгруппировать данные по полю IDTO, а затем уже результаты указанной группировки в помощью функции ВПР выводить в какой либо отчет.
Как видно из строки формул, табличка достаточно большая (1003 строки) и заниматься этим делом каждый раз в ручную при добавлении или изменении данных довольно "грустно". Кстати, в ячейке "E1" используется вместо суммы функция ПРОМЕЖУТОЧНЫЕ ИТОГИ, для того, чтобы отображать сумму только по выбранным фильтром строкам.
Чтобы сгруппировать данные используем сводную таблицу.
Однако полученный результат не позволяет использовать функцию ВПР, т.к. одному значению IDTO соответствует 3 значения "Данные". Тут, как в старом анекдоте, существуют два варианта.
Вариант 1: количество значений по полю "Данные" заранее известно и постоянно.
Вариант 2: количество значений по полю "Данные" заранее не известно и может меняться.




Объединение данных


Чтобы было понятнее о чем идет речь рассмотрим конкретный пример. Допустим, имеем две таблицы с данными по пациентам. В Таблице 2 представлены данные результатов анализов пациентов (А1, А2, Т1), ID_p это уникальный код пациента. В Таблице 1 представлены заболевания пациентов KOD_z. То что эти данные разделены в две разные таблицы связано с тем, что у одного пациента может быть несколько заболеваний. Задача заключается в том, чтобы каждому пациенту в Таблице 2 проставить признак всех имеющихся заболеваний из Таблицы 1.

Используя функцию СЦЕПИТЬ, в отдельном столбце для Таблицы 1 создадим уникальный код записи состоящий из кода пациента и кода заболевания
Теперь в Таблице 2, используя функцию ВПР можно перенести данные из Таблицы 1 опираясь на созданный уникальный код.


=ЕСЛИ(ЕНД(ВПР(СЦЕПИТЬ($F3;J$2);$A$3:$D$10;4;ЛОЖЬ));0;1)

Пояснения. В функции СЦЕПИТЬ($F3;J$2) адрес строки $2 и столбца $F выбраны абсолютными, чтобы при копировании формулы, номер строки/столбца не изменялся. Область данных - $A$3:$D$10, абсолютная по той же причине. Конструкция возвращает "0" если заболевания у пациента нет и "1" если есть.
Такая форма представления данных позволяет подсчитать сколько всего пациентов страдает конкретным заболеванием (сумма по столбцу) и сколько заболеваний у одного пациента (сумма по строке).



понедельник, 30 мая 2011 г.

Хитрый ход

Однажды столкнулся с уже ранее описанной проблемой. Надо связать две таблички, но ключевые поля в них имеют разный формат: в одной общий а в другой текстовый. Привожу пример.
Как видно из рисунка мне нужно поле TF_OKATO, таблички 1 "привпэрить" к табличке 2. Однако функция ВПР брыкается и выдает #Н/Д. Как вариант решения проблемы можно табличку 2 сохранить в формате .DBF и потом в монопольном доступе попытаться изменить формат поля KOD_TO на текстовый. Однако такие варианты не всегда проходят, да и возится долго и неудобно. Другой вариант - можно задать полю KOD_TO текстовый формат, а потом перебить вручную коды. Надежен, но возни еще больше, особенно если табличка большая. И тут пришла в голову мысль, если функция СЦЕПИТЬ возвращает данные в текстовом формате, нельзя ли её приспособить в этом случае. Попробовал и получилось вот так.

В данном случае у функции СЦЕПИТЬ только один аргумент, т.е. она ничего не сцепляет, да нам этого и не надо, а вот миссию по преобразованию в текстовый формат выполняет исправно.

=ВПР(СЦЕПИТЬ(D3);$A$3:$B$27;2;ЛОЖЬ)
Развивая идею дальше можно сказать что в каком бы формате небыли ключевые поля их всегда можно привести к текстовому формату и обеспечить связь данных.
Вот такие хитрости. Как говорил один известный персонаж - "Хорошо знать иностранные языки."
P.S. Не так давно народ предложил вместо функции СЦЕПИТЬ() для этих целей использовать имеющуюся стандартную функцию ТЕКСТ(). Да это вполне возможно, тогда формула будет выглядеть так.
=ВПР(ТЕКСТ(D3;"0");$A$3:$B$27;2;ЛОЖЬ)
Однако, если Вы заметили, функция ТЕКСТ(D3;"0"), кроме ссылки на ячейку, имеет еще второй параметр - формат. Что на мой взгляд усложняет ее применение в данном случае. Поэтому использование функции СЦЕПИТЬ() - хитрый ход!