Как программно или типовыми средствами отметить выполнение плана производства в 1С?

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

В процессе работы с конфигурацией «Управление производственным предприятием» (УПП) 1.3 или аналогичными системами на обычных формах часто возникает задача визуально отметить, что документ ПланПроизводства выполнен. Это необходимо для того, чтобы в отчетах или списках документов можно было быстро отфильтровать закрытые позиции и сосредоточиться на актуальных задачах. Рассмотрим подробнее, как реализовать этот механизм — от использования типовых документов до программной доработки системы.

Метод 1: Использование штатного документа «Закрытие планов»

Прежде чем приступать к программированию, проанализируем возможности типовой конфигурации УПП 1.3. В системе существует специализированный документ «Закрытие планов». Его основное назначение — прекращение действия запланированных, но неисполненных потребностей.

Если план выполнен частично или его выполнение более не требуется, именно этот документ «снимает» остатки с регистров планирования. Рассмотрим преимущества этого подхода:

  1. Корректность регистров: В отличие от простой «галочки», документ делает движения по регистрам накопления (например, ПланыПроизводства), что напрямую влияет на результаты работы «Помощника планирования».
  2. План-фактный анализ: Типовые отчеты системы (например, «План-фактный анализ производства») автоматически учитывают состояние планов, если они были закрыты этим регламентным документом.

Если ваша задача — исключить старые планы из производственных отчетов, рекомендуется использовать именно этот механизм, не прибегая к изменению кода.

Метод 2: Добавление пользовательского признака выполнения (Доп. реквизит)

Если же требуется именно визуальная отметка в самом документе (флажок «План выполнен»), разберем по шагам, как это реализовать программно. Выясним причину, почему простая установка флажка в форме может не работать или работать некорректно.

Для начала добавим в документ ПланПроизводства новый реквизит ПланВыполнен с типом Булево. После этого его необходимо вывести на форму документа. Проанализируем типичную ошибку начинающих разработчиков: установка значения реквизита только в модуле формы. Если вы хотите, чтобы признак сохранялся, код должен находиться в модуле объекта.

Метод 3: Программный контроль выполнения плана при записи

Рассмотрим ситуацию, когда мы хотим, чтобы система сама проверяла, выполнен ли план, в момент нажатия кнопки «Записать» или «Провести». Для этого нам потребуется написать запрос к регистрам накопления, чтобы сравнить плановые показатели с фактическим выпуском или остатками на складах.

Важное методологическое замечание: Проверка выполнения плана по остаткам на складах (регистр ТоварыНаСкладах) является рискованной. Произведенная продукция может быть сразу отгружена покупателю, и остаток станет нулевым, хотя план фактически был выполнен. Правильнее проверять данные в регистре ВыпускПродукции.

Проанализируем пример кода, который можно разместить в процедуре ПередЗаписью модуля объекта документа:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // По умолчанию считаем план выполненным, пока не найдем обратное
    ПланВыполнен = Истина;
    
    Для Каждого СтрокаПлана Из СоставПлана Цикл
        
        КоличествоВыпущено = ПолучитьФактВыпуска(СтрокаПлана.Номенклатура, Дата);
        
        Если КоличествоВыпущено < СтрокаПлана.Количество Тогда
            // Если хотя бы по одной позиции выпуск меньше плана - план не выполнен
            ПланВыполнен = Ложь;
            Прервать;
        КонецЕсли;
        
    КонецЦикла;

КонецПроцедуры

Функция ПолучитьФактВыпуска(ВыбраннаяНоменклатура, ДатаПланирования)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   СУММА(ВыпускПродукцииОбороты.КоличествоОборот) КАК КоличествоФакт
        |ИЗ
        |   РегистрНакопления.ВыпускПродукции.Обороты(&НачалоПериода, &КонецПериода, , Номенклатура = &Номенклатура) КАК ВыпускПродукцииОбороты";
    
    // Настраиваем границы периода (например, месяц планирования)
    Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(ДатаПланирования));
    Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(ДатаПланирования));
    Запрос.УстановитьПараметр("Номенклатура", ВыбраннаяНоменклатура);
    
    Результат = Запрос.Выполнить().Выбрать();
    
    Если Результат.Следующий() Тогда
        Возврат ?(Результат.КоличествоФакт = NULL, 0, Результат.КоличествоФакт);
    Иначе
        Возврат 0;
    КонецЕсли;
    
КонецФункции

Почему флажок может «исчезать» при повторном открытии?

В процессе обсуждения на форуме возникла проблема: пользователь ставит галочку, записывает документ, но при повторном открытии она пропадает. Проанализируем ситуацию:

  1. Данные не привязаны к реквизиту объекта: Если вы добавили элемент управления на форму, но не связали его с Данными (реквизитом документа), значение не будет сохранено в базе данных.
  2. Код в процедуре ПриОткрытии: Проверьте, нет ли в модуле формы кода, который принудительно очищает или пересчитывает этот флаг при открытии формы, игнорируя записанное значение.
  3. Откат транзакции: Если при записи возникают ошибки (например, в коде запроса), документ не записывается, и изменения реквизита не фиксируются.

Оптимизация отчетов (СКД)

Когда реквизит ПланВыполнен успешно внедрен и заполняется, мы можем легко использовать его в отчетах на базе Системы компоновки данных (СКД). Рассмотрим, как это сделать:

В конструкторе запроса вашего отчета добавьте условие в секцию «ГДЕ» или используйте настройки отбора в пользовательском режиме. Например, чтобы увидеть только активные планы, добавьте отбор: ПланПроизводства.ПланВыполнен Равно Ложь.

Также можно использовать вычисляемые поля прямо в СКД, чтобы не перегружать документ лишними реквизитами. В выражении поля можно прописать логику:

ВЫБОР КОГДА Сумма(КоличествоПлан) <= Сумма(КоличествоФакт) ТОГДА "Выполнен" ИНАЧЕ "В работе" КОНЕЦ

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

← На главную