Как в запросе 1С из интервала дат получить таблицу плановых дат замены?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

Зачастую перед разработчиками 1С встает нетривиальная задача: имеется таблица с номенклатурой, датой установки и сроком полезного использования в месяцах. Нужно получить список всех будущих дат замены для каждой позиции в рамках заданного периода. Так как язык запросов 1С является декларативным, прямого цикла в нем нет, и мы сейчас разберем, как эффективно решить эту проблему.

Метод 1: Использование календаря месяцев

Самый наглядный способ — это создание вспомогательной временной таблицы, содержащей список всех месяцев в периоде. Мы можем получить их из РегламентированныйПроизводственныйКалендарь или сгенерировать программно.

Разберем логику:

  1. Формируем временную таблицу Календарь, содержащую начало каждого месяца в заданном интервале.
  2. Соединяем исходную таблицу с календарем.
  3. Используем математическое условие для отбора только тех месяцев, которые кратны сроку полезного использования.

ВЫБРАТЬ НАЧАЛОПЕРИОДА(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря, МЕСЯЦ) КАК Месяц 
ПОМЕСТИТЬ Календарь 
ИЗ РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь 
ГДЕ РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ДатаНачала И &ДатаОкончания 
СГРУППИРОВАТЬ ПО НАЧАЛОПЕРИОДА(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря, МЕСЯЦ);

ВЫБРАТЬ ИсходнаяТаблица.Номенклатура, ИсходнаяТаблица.ДатаУстановки, Календарь.Месяц 
ИЗ ИсходнаяТаблица КАК ИсходнаяТаблица, Календарь КАК Календарь 
ГДЕ РАЗНОСТЬДАТ(ИсходнаяТаблица.ДатаУстановки, Календарь.Месяц, МЕСЯЦ) % ИсходнаяТаблица.СрокПолезногоИспользования = 0
И Календарь.Месяц > ИсходнаяТаблица.ДатаУстановки;

Метод 2: Использование таблицы множителей (генерация строк)

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

Пошаговый алгоритм:

  1. Создаем временную таблицу втЧислоПовторений, содержащую числа от 1 до 12 (или больше, если период велик).
  2. Рассчитываем количество необходимых замен для каждой позиции через РАЗНОСТЬДАТ и деление на срок использования.
  3. Делаем соединение исходных данных с этой таблицей чисел, прибавляя к ДатаУстановки результат произведения СрокПолезногоИспользования * ЧислоПовторений.

ВЫБРАТЬ 1 КАК ЧислоПовторений ПОМЕСТИТЬ втЧислоПовторений 
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 2 ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ 3 ... // и так далее до нужного количества

ВЫБРАТЬ ИсходнаяТаблица.Номенклатура, 
       ДОБАВИТЬКДАТЕ(ИсходнаяТаблица.ДатаУстановки, МЕСЯЦ, ИсходнаяТаблица.СрокПолезногоИспользования * втЧислоПовторений.ЧислоПовторений) КАК ДатаЗамены
ИЗ ИсходнаяТаблица КАК ИсходнаяТаблица
ЛЕВОЕ СОЕДИНЕНИЕ втЧислоПовторений КАК втЧислоПовторений 
ПО (втЧислоПовторений.ЧислоПовторений <= ИсходнаяТаблица.МаксЧислоЗамен);

Важные рекомендации и предостережения

При реализации подобных задач всегда помните о производительности:

Рассмотренные способы позволяют решить задачу средствами языка запросов 1С без написания тяжелых циклов в коде модуля. Выбор метода зависит от того, насколько гибким должен быть интервал и каков объем данных в вашей системе.

← На главную