В практической работе программиста 1С часто возникает ситуация, когда техническое задание сталкивается с суровой реальностью человеческого фактора. Типичный пример: в документе «Производство» конфигурации «1С:Управление нашей фирмой» (УНФ) предусмотрены три строго разграниченные табличные части — Продукция, Материалы и Отходы. Каждая из них должна содержать строго определенные группы номенклатуры.
Однако на практике операторы могут вносить сырье в таблицу продукции, а готовую продукцию или возвратные отходы — в таблицу материалов. При этом перед разработчиком ставится задача: построить корректный отчет по периодам, который бы показывал реальные объемы произведенной продукции, потраченных материалов и полученных отходов, основываясь на реальной принадлежности номенклатуры к своим группам, а не на том, в какую табличную часть ее ошибочно записал пользователь.
В рамках этой статьи мы подробно разберем, как решить эту задачу с помощью Системы компоновки данных (СКД), проанализируем скрытые опасности такого подхода для складского учета и рассмотрим надежные методы превентивной защиты, которые навсегда заблокируют возможность ошибочного ввода данных.
Прежде чем перейти к написанию запросов, давайте проанализируем, почему простое «косметическое» исправление данных в отчете — это лишь временная мера. Документ «Производство» делает движения по регистру накопления Запасы (или Запасы и затраты в зависимости от версии УНФ), опираясь на логику табличных частей:
Если оператор вносит материал в ТЧ «Продукция», программа физически оформляет его выпуск, увеличивая остатки на складе, вместо того чтобы списать его. Это приводит к искажению себестоимости готовой продукции, возникновению виртуальных излишков и отрицательных остатков на складах. Поэтому параллельно с исправлением отчета критически важно внедрить контроль ввода данных, который мы рассмотрим в конце статьи.
Если справочник Номенклатура имеет четкую структуру папок (например, отдельные папки «Продукция», «Материалы», «Отходы»), мы можем пренебречь тем, из каких табличных частей были сделаны движения в регистре, и сгруппировать данные по их реальным «родителям» (папкам справочника).
Давайте разберем техническую ловушку этого метода. Если структура папок многоуровневая (например, Материалы -> Металл -> Метизы -> Болты), то прямое обращение к полю Номенклатура.Родитель вернет папку «Метизы», а не корневую папку «Материалы». В отчете СКД вместо трех аккуратных колонок образуется хаос.
Для решения этой проблемы мы используем оператор ВЫБОР с проверкой вхождения элемента в иерархию конкретных групп в запросе СКД. Рассмотрим пример такого запроса:
ВЫБРАТЬ
ЗапасыОбороты.ПериодСекунда КАК Период,
ЗапасыОбороты.Номенклатура КАК Номенклатура,
ЗапасыОбороты.КоличествоОборот КАК Количество,
ВЫБОР
КОГДА ЗапасыОбороты.Номенклатура В ИЕРАРХИИ (&ГруппаПродукция) ТОГДА "Продукция"
КОГДА ЗапасыОбороты.Номенклатура В ИЕРАРХИИ (&ГруппаМатериалы) ТОГДА "Материалы"
КОГДА ЗапасыОбороты.Номенклатура В ИЕРАРХИИ (&ГруппаОтходы) ТОГДА "Отходы"
ИНАЧЕ "Не определено"
КОНЕЦ КАК КатегорияУчета
ИЗ
РегистрНакопления.Запасы.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ЗапасыОбороты
Посмотрим на параметры &ГруппаПродукция, &ГруппаМатериалы и &ГруппаОтходы. Мы должны передать в них ссылки на соответствующие корневые папки справочника номенклатуры. На вкладке «Настройки» компоновки данных мы сможем выстроить структуру отчета типа «Таблица»:
Номенклатура.КатегорияУчета.Количество.СКД автоматически распределит количества по нужным колонкам («Продукция», «Материалы», «Отходы»), независимо от того, в какую ТЧ документа их добавил оператор.
Использование групп (папок) справочника для логики отчетов небезопасно, так как пользователи могут случайно перетащить карточку товара из одной папки в другую в режиме предприятия. В современных версиях 1С:УНФ для классификации используется механизм Категорий номенклатуры.
Давайте изменим наш запрос, чтобы классификация происходила на основе реквизита Категория номенклатуры. Этот реквизит жестко привязан к карточке и не зависит от структуры папок:
ВЫБРАТЬ
ЗапасыОбороты.ПериодСекунда КАК Период,
ЗапасыОбороты.Номенклатура КАК Номенклатура,
ЗапасыОбороты.КоличествоОборот КАК Количество,
ВЫБОР
КОГДА ЗапасыОбороты.Номенклатура.Категория = &КатегорияПродукция ТОГДА "Продукция"
КОГДА ЗапасыОбороты.Номенклатура.Категория = &КатегорияМатериалы ТОГДА "Материалы"
КОГДА ЗапасыОбороты.Номенклатура.Категория = &КатегорияОтходы ТОГДА "Отходы"
ИНАЧЕ "Не определено"
КОНЕЦ КАК КатегорияУчета
ИЗ
РегистрНакопления.Запасы.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК ЗапасыОбороты
Этот способ гарантирует стабильность работы отчета, даже если пользователи решат полностью реорганизовать структуру каталогов номенклатуры.
Чтобы начинающему программисту не приходилось регулярно придумывать костыли в отчетах, необходимо исключить саму возможность ошибочного заполнения документа «Производство». Рассмотрим три уровня защиты, которые можно внедрить в конфигурацию.
Мы можем настроить фильтрацию при выборе элементов в табличных частях формы документа. Для этого откроем форму документа «Производство», выберем элемент пути данных ТЧ и настроим свойство ПараметрыВыбора для поля Номенклатура:
Продукция в параметрах выбора установим отбор: СпособПополнения = ПредопределенноеЗначение("Перечисление.СпособыПополненияЗапасов.Производство").Материалы установим параметр выбора по категории «Сырье и материалы».После этой настройки оператор при попытке подобрать номенклатуру в ТЧ «Продукция» просто не увидит материалы в списке выбора.
Ошибки ручного ввода минимизируются, если использовать встроенный механизм спецификаций 1С:УНФ. Для готовой продукции должна быть жестко задана спецификация (какие материалы и в каком объеме на нее тратятся). Научите операторов использовать кнопку Заполнить по спецификации в документе «Производство». Ручной ввод в ТЧ «Материалы» при этом можно программно заблокировать для обычных пользователей.
Для стопроцентной гарантии добавим программную проверку в модуль объекта документа «Производство» в обработчик события ОбработкаПроведения. Напишем алгоритм, который заблокирует проведение документа, если в ТЧ «Материалы» попала готовая продукция:
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
// Выполняем стандартные движения документа
// ...
// Наша проверка корректности данных
Для Каждого СтрокаТЧ Из ЭтотОбъект.Материалы Цикл
Если Не СтрокаТЧ.Номенклатура.Пустая() Тогда
// Проверим, не является ли материал готовой продукцией по его типу или категории
Если СтрокаТЧ.Номенклатура.Категория = Справочники.КатегорииНоменклатуры.НайтиПоНаименованию("Готовая продукция") Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
НСтр("ru = 'Ошибка проведения! В табличную часть ""Материалы"" ошибочно добавлена готовая продукция: '") + СтрокаТЧ.Номенклатура,
ЭтотОбъект,
"Материалы[" + (ЭтотОбъект.Материалы.Индекс(СтрокаТЧ)) + "].Номенклатура",
,
Отказ
);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот код не позволит документу провестись, выведет понятное сообщение об ошибке пользователю и подсветит конкретную строку в табличной части, где была совершена ошибка. Таким образом, качество ведения учета мгновенно вырастет, а необходимость в сложных "выравнивающих" отчетах пропадет сама собой.