Как рассчитывается пробег (наработка) ножа в 1С?

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

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

Анализ чтения данных: как считается пробег за период

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


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

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

В данном фрагменте кода сразу видны узкие места:

  1. Отсутствие агрегатной функции в запросе. Обход выборки в цикле Пока Выборка.Следующий() неоправданно расходует ресурсы сервера и память. СУБД выполняет агрегацию значительно быстрее.
  2. Граница периода. Использование конструкции МЕЖДУ с датой окончания, не приведенной к концу дня через КонецДня(), приводит к потере документов, проведенных в течение последних суток периода.

Оптимизируем данный запрос, переложив расчет суммы на сторону СУБД:


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

    Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(НачалоИспользования));
    Запрос.УстановитьПараметр("КонецПериода",  КонецДня(ОкончаниеИспользования));
    Запрос.УстановитьПараметр("Нож",           Объект.Ссылка);

    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.ОбщийПробег;
    КонецЕсли;

    Возврат 0;
КонецФункции

Откуда берутся данные: формула и алгоритм проведения

Чтобы понять, что именно физически означает числовое значение пробега, выясним причину появления записей в регистре. Для этого обратимся к модулю документа-регистратора (документа выпуска продукции или отчета производства за смену) в процедуру ОбработкаПроведения.

Формирование записи выглядит следующим образом:


// движения по регистру ножей
Если ЗначениеЗаполнено(Нож) Тогда
    ВремТабДвиженияПробег = Движения.ПробегНожей.ВыгрузитьКолонки();
    Движение = ВремТабДвиженияПробег.Добавить();
    Движение.Период    = Дата;
    Движение.Регистратор = Ссылка;
    Движение.Нож       = Нож;
    Движение.Пробег    = Материалы.Итог("КоличествоФактическиИзрасходорванноеПогМ") / Нож.Раппорт * 1000;
    Движения.ПробегНожей.Загрузить(ВремТабДвиженияПробег);
    Движения.ПробегНожей.Записывать = Истина;
КонецЕсли;

Разберем математическую и отраслевую составляющую формулы:

Пробег = КоличествоФактическиИзрасходорванноеПогМ / Нож.Раппорт * 1000

  1. КоличествоФактическиИзрасходорванноеПогМ — суммарный метраж обработанного сырья (бумаги, пленки) за смену по табличной части Материалы в погонных метрах.
  2. Нож.Раппорт — характеристика высекального цилиндра (ножа) в миллиметрах, означающая длину развертки окружности вала (шаг повтора формы высечки). В коде встречается проверка соотношения с константой 3.175 — это стандартный шаг шестерни цилиндра в полиграфии ($1/8$ дюйма), где деление раппорта на 3,175 определяет количество зубьев ($Z$).
  3. Множитель 1000 — перевод погонных метров в миллиметры для согласования единиц измерения с раппортом.

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

Исправление ошибок в коде записи движений

В коде проведения присутствуют критические ошибки и неоптимальные конструкции платформы 1С:

  1. Опасность деления на ноль. Если в справочнике у ножа не заполнен или равен нулю реквизит Раппорт, документ упадет с ошибкой времени выполнения.
  2. Некорректная работа с коллекцией движений. Конструкция с выгрузкой структуры колонок через ВыгрузитьКолонки() и последующей загрузкой таблицы является антипаттерном. Она может затирать ранее добавленные строки и неэффективно использует память. Поле Регистратор заполнять вручную в коде не нужно — платформа назначает его автоматически.

Перепишем блок формирования движений по стандартам разработки 1С:


Если ЗначениеЗаполнено(Нож) Тогда
    Если Нож.Раппорт = 0 Тогда
        ВызватьИсключение "Для ножа """ + Строка(Нож) + """ не указан раппорт! Проведение невозможно.";
    КонецЕсли;

    // Корректное добавление движения напрямую в коллекцию
    Движение = Движения.ПробегНожей.Добавить();
    Движение.Период = Дата;
    Движение.Нож    = Нож;
    
    // Расчет количества оборотов (ударов) инструмента
    РасходМетров = Материалы.Итог("КоличествоФактическиИзрасходорванноеПогМ");
    Движение.Пробег = (РасходМетров * 1000) / Нож.Раппорт;
КонецЕсли;

Рекомендации по развитию архитектуры

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

Для правильного учета наработки оборудования рекомендуется использовать Регистр накопления:

  1. С видом «Обороты» — если требуется исключительно накапливать факт наработки (оборотов, погонных метров) и быстро получать суммы за любые периоды через виртуальную таблицу Обороты.
  2. С видом «Остатки» — если у оснастки есть нормативный ресурс до переточки или списания. В таком случае ввод в эксплуатацию фиксирует ресурс как «Приход», а каждый выпуск списывает его в «Расход», позволяя моментально видеть остаточный ресурс инструмента срезом остатков.
← На главную