Срез последних в 1С
Срез последних отдаёт значение на дату, и на нём держатся цены и курсы. Условие среза в параметре и в ГДЕ дают разный результат, и на этом валятся даже опытные. Ещё спрашивают, как получить цену на дату каждой строки продаж, раз у среза дата одна. Запросы сверены на PostgreSQL.
// Так спрашивают: «Чем условие в параметре среза отличается от условия в ГДЕ?» «Что вернёт срез последних без даты?» «Как получить цену на дату каждой продажи?» «Чем СрезПервых отличается от СрезПоследних?»
Параметр и ГДЕ у среза
Курсы валют приходят из двух источников, и у записи есть реквизит Источник. Нужны курсы ЦБ на 15 октября. Условие на источник можно поставить в параметр среза или в ГДЕ:
В параметре срез ищет последнюю запись среди записей ЦБ, и доллар получает курс 92 от 1 октября. В ГДЕ срез сначала берёт последнюю запись вообще, для доллара это биржевые 93 от 10 октября, а потом условие отбрасывает её, и доллар исчезает из результата. У остатков и оборотов параметр и ГДЕ дают одно и то же, у среза нет.
ВЫБРАТЬ К.Валюта, К.Курс
ИЗ РегистрСведений.КурсыВалют.СрезПоследних(&Дата,
Источник = "ЦБ") КАК К
УПОРЯДОЧИТЬ ПО К.ВалютаГраница и срез без даты
Запись ровно на дату среза в срез попадает: граница включена. Срез без даты берёт последнюю запись вообще, включая будущие периоды: цену, которую уже завели на следующий месяц, срез без даты отдаст как текущую. Для текущих цен передают дату явно.
СрезПервых работает зеркально: первая запись не раньше даты, то есть ближайшее будущее значение. Например, ближайшая плановая цена после сегодняшнего дня. Для регистров с периодичностью «по позиции регистратора» срез берут на момент времени документа, а не на дату.
Срез на дату каждой строки
Параметр среза принимает значение, а не поле, поэтому у среза одна дата на весь запрос. Цену на дату каждой продажи собирают вручную: для каждой продажи находят максимальный период цены не позже даты продажи, затем соединяют с ценами по этому периоду.
Если соединить продажи с ценами по Период <= Дата и не выбрать максимум, продажа 20 октября размножится на две строки, по каждой прошлой цене, и сумма отчёта удвоится. Первый шаг с МАКСИМУМ оставляет ровно одну цену на продажу.
На больших регистрах цен срез текущих значений ускоряет свойство «Разрешить итоги: срез последних»: платформа держит таблицу последних значений и читает её напрямую.
ВЫБРАТЬ П.Дата, П.Номенклатура, МАКСИМУМ(Ц.Период) КАК ПериодЦены
ПОМЕСТИТЬ ВТ_Периоды
ИЗ ВТ_Продажи КАК П
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Ц
ПО Ц.Номенклатура = П.Номенклатура И Ц.Период <= П.Дата
СГРУППИРОВАТЬ ПО П.Дата, П.Номенклатура
;
ВЫБРАТЬ ВТ.Дата, Ц.Цена
ИЗ ВТ_Периоды КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК Ц
ПО Ц.Номенклатура = ВТ.Номенклатура И Ц.Период = ВТ.ПериодЦены
УПОРЯДОЧИТЬ ПО ВТ.ДатаКак отвечать: «Курсы ЦБ на дату: условие на источник поставишь в параметр среза или в ГДЕ?»
В параметр. Тогда срез ищет последнюю запись среди записей ЦБ, и каждая валюта получит последний курс ЦБ. Если поставить условие в ГДЕ, срез сначала возьмёт последнюю запись по валюте из любого источника, и если она биржевая, условие её отбросит, и валюта пропадёт целиком. У остатков и оборотов разницы в результате нет, а у среза она принципиальная.
Кандидат показывает механизм на примере, где валюта пропадает, и отделяет срез от остальных виртуальных таблиц. Это ровно то, что проверяет вопрос.
На чём валят
- −Ставят условие на реквизит после среза в ГДЕ. Пропадают ключи, у которых последняя запись «не та». Условие ставят в параметр.
- −Ждут, что срез на дату не увидит запись ровно на эту дату. Граница включена, запись на дату попадает.
- −Берут текущую цену срезом без даты. Попадут цены, заведённые на будущее. Дату передают явно.
- −Соединяют продажи с ценами по
Период <= Датабез максимума. Продажа размножится на все прошлые цены. Сначала МАКСИМУМ(Период), потом соединение.
Проверь себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Запись в регистр цен сделана с периодом ровно &Дата. Попадёт ли она в
СрезПоследних(&Дата)?A)Нет, строго раньшеB)Да: период не позже даты срезаC)Только если время записи 00:00:00D)Только для периодичности «День»показать ответ и разбор
+B)Да: период не позже даты среза// разбор: Срез последних отбирает записи с периодом меньше или равным дате среза, поэтому запись ровно на эту дату в него попадает. Цена, введённая на 1 марта, действует и в сам день 1 марта. Это отличает срез от остатков на дату, где граница по умолчанию не включает момент.
- Как получить последнюю цену товара без виртуальной таблицы среза?A)МАКСИМУМ(Период), затем соединениеB)ПЕРВЫЕ 1 без сортировки по периодуC)СУММА(Цена) по товаруD)Выгрузить регистр и искать в коде
показать ответ и разбор
+A)МАКСИМУМ(Период), затем соединение// разбор: Срез вручную: первым запросом находят максимальный период по каждому товару (при нужном условии на дату), затем соединяют с регистром по товару и этому периоду и берут цену. Так делают, когда нужен срез на разные даты для разных строк или особое условие.
- Курсы валют: условие
Источник = &Печатьв ГДЕ послеСрезПоследних(). Что вернётся для валюты, чей последний курс из интернета?A)Ошибка: реквизит в ГДЕ среза недоступенB)Последний курс из печатных изданийC)Последний курс из интернетаD)Ничего: строка отброшенапоказать ответ и разбор
+D)Ничего: строка отброшена// разбор: Срез сначала берёт последнюю запись по каждой валюте, и только потом ГДЕ проверяет источник. Если последний курс из интернета, строка отбрасывается целиком. Чтобы получить последний курс именно из печати, условие ставят в параметр среза — пример из методики ИТС.
- Что вернёт запрос для валюты USD, если записи: 19.03 USD 31,00 печать; 20.03 USD 31,10 интернет?
ВЫБРАТЬ К.Валюта, К.Курс ИЗ РегистрСведений.Курсы.СрезПоследних( , Источник = &Печать) КАК КA)Обе записи USDB)USD 31,10C)Ничего для USDD)USD 31,00показать ответ и разбор
+D)USD 31,00// разбор: С условием в параметре срез ищет последнюю запись только среди записей из печатных источников, и для USD это 31,00 от 19 марта. Более поздний интернет-курс в отбор не попал. Это пример из методики ИТС о разнице между отбором в параметре и в ГДЕ.
- Чем срез последних на текущую дату отличается от среза без параметра даты?A)Без даты — только записи за сегодняB)Без даты — ошибка: период обязателенC)На последний момент, будущие тожеD)Ничем: подставится текущая дата
показать ответ и разбор
+C)На последний момент, будущие тоже// разбор: Срез последних без параметра Период берёт последнюю запись по каждому ключу вообще, в том числе записи с периодом в будущем, например заранее введённые цены на следующий месяц. Срез на ТекущаяДатаСеанса() их не учтёт. Для «действующих сейчас» значений дату передают явно.
дальше
Теорию прочитал. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, бесплатная часть практики — одна сессия дня в сутки.