новое событие
Информационный поток
Задания вакансии материалы разработки сообщения форума

Особенность получения среза последних записей в регистре сведений

  • Добавить свою публикацию
  • для этого требуется регистрация

Исходные данные

В тестовой конфигурации у нас есть периодический регистр сведений "ЦеныНоменклатуры" со следующими исходными данными:

Изображение

На рисунке представлена также структура метаданных регистра. Как мы видим, регистр содержит измерение "Товар" с типом ссылки на справочник "Товары", а также числовой ресурс "Цена" и реквизит "СтараяЦена".

Допустим, в отчете нам нужно получить срез последних записей для товаров и их цен с условием, что старая цена меньше или равно 50. 

Два варианта запроса

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

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|	ЦеныНоменклатурыСрезПоследних.Период,
|	ЦеныНоменклатурыСрезПоследних.Товар,
|	ЦеныНоменклатурыСрезПоследних.Цена,
|	ЦеныНоменклатурыСрезПоследних.СтараяЦена
|ИЗ
|	РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних
|ГДЕ
|	ЦеныНоменклатурыСрезПоследних.СтараяЦена <= 50";

Обратите внимание на условие в секции "ГДЕ". В этом и заключается главная ошибка! Этот запрос не вернет ни одной записи, и вот почему: при использовании виртуальных таблиц, в нашем случае "СрезПоследних", сначала выполняется выборка данных из базы по условиям, описанным в виртуальной таблице, а затем выполняются действия, описанные в тексте запроса (группировки, условия в секции "ГДЕ", сортировка и т.д.).

Поэтому в нашем примере запрос и не возвращает результат. Сначала он получает срез последних, а уже после устанавливает условие на реквизит "СтараяЦена". Вот так это выглядит на схеме:

Изображение

Чтобы правильно решить задачу, условие на реквизит "СтараяЦена" нужно перенести в условия виртуальной таблицы. Вот так будет выглядеть правильный текст запроса:

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
	ЦеныНоменклатурыСрезПоследних.Период,
	ЦеныНоменклатурыСрезПоследних.Товар,
	ЦеныНоменклатурыСрезПоследних.Цена,
	ЦеныНоменклатурыСрезПоследних.СтараяЦена
ИЗ
	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, СтараяЦена <= 50) 
											КАК ЦеныНоменклатурыСрезПоследних"

Теперь запрос получит правильные данные, поскольку срез последних цен будет получать уже с учетом условия по реквизиту "СтараяЦена".

Изображение

Результаты

Следует понимать, что описанное выше относится ко всем случаям использования виртуальных таблиц в запросах (для регистров накопления, регистров бухгалтерии, задач и т.д.).

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

 
0
Читайте также
Создание и работа с запросами (для начинающих)
Запросы, работа с ними, отладка
Монитор дисковых ресурсов
Определив объекты метаданных, занимающих большой объем можно лишние данные вычищать, внести изменения в конфигурацию или в бизнес процесс.
Общие реквизиты и серверная SQL-база
"Снижают ли общие реквизиты производительность конфигурации"
Разработки
Консоль компоновки данных
Обработка состоит их запросов, СКД и объектов
Автоматическое резервное копирование: Effector saver 3
Резервное копирование методом архивирования баз данных
Учет бонусных карт в 1с8 УТ10, УПП, КА, Розница
Ведение, учет бонусных карт
Еще от автора
≡ к списку статей