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