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