Почему при программном создании документа «Ввод остатков» не заполняется табличная часть и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При переносе данных или начальной настройке конфигураций на платформе «1С:Предприятие 8.3» (таких как «1С:Управление торговлей 11», «1С:Комплексная автоматизация 2» или «1С:ERP») разработчики часто сталкиваются с неожиданным поведением: документ ВводОстатков создается, в отладчике строки табличной части заполняются, но после выполнения метода Записать() или при открытии формы табличная часть оказывается абсолютно пустой. Рассмотрим подробно, почему так происходит, какие скрытые механизмы конфигурации очищают данные и как правильно написать алгоритм создания документа.

Причина 1. Автоматическая очистка табличных частей в модуле объекта

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

В модуле объекта документа в процедуре-обработчике ПередЗаписью заложен алгоритм контроля целостности данных. Если ключевой реквизит операции не заполнен или заполнен некорректно, система считает строки чужими и принудительно очищает все табличные части, не соответствующие выбранному направлению. В результате в момент вызова Док.Записать() табличная часть Товары попросту стирается типовым кодом конфигурации.

В зависимости от версии конфигурации имя реквизита и состав перечисления могут различаться:

  1. В современных редакциях (УТ 11.4, 11.5): реквизит ХозяйственнаяОперация, принимающий значение Перечисления.ХозяйственныеОперации.ВводОстатковСобственныхТоваров.
  2. В более ранних сборках (УТ 11.2, 11.3): реквизит ТипОперации со значением Перечисления.ТипыОперацийВводаОстатков.ОстаткиСобственныхТоваров.
  3. В некоторых отраслевых решениях: реквизит РазделУчета со значением Перечисления.РазделыУчетаДляВводаОстатков.СобственныеТовары.

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

Причина 2. Ошибки открытия формы и передачи контекста на клиенте

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

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

Причина 3. Несовпадение имен полей и некорректная агрегация данных

При использовании процедуры ЗаполнитьЗначенияСвойств() крайне важно, чтобы псевдонимы полей в запросе точно совпадали с именами реквизитов табличной части документа. Например, если в запросе указано КоличествоОстаток КАК Колво, а в табличной части реквизит называется Количество, поле останется пустым.

Кроме того, при получении остатков из регистра ПартииТоваровОрганизаций поле СтоимостьОстаток отражает общую себестоимость партии, а не цену за единицу товара. Если просто присвоить значение стоимости полю Цена, данные по остаткам будут искажены. Также следует учитывать, что измерение АналитикаУчетаНоменклатуры может содержать не только ссылку на номенклатуру, но и характеристики со складами, поэтому при выборке важно производить группировку или использовать специализированный регистр ТоварыНаСкладах.

Правильный код создания и открытия документа «Ввод остатков»

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


&НаКлиенте
Процедура СоздатьИОткрытьДокумент(Команда)
    
    // Создаем и записываем документ на сервере
    СсылкаНаДокумент = СоздатьВводОстатковНаСервере();
    
    Если ЗначениеЗаполнено(СсылкаНаДокумент) Тогда
        // Способ 1: Открытие через стандартный параметр формы "Ключ"
        ПараметрыОткрытия = Новый Структура("Ключ", СсылкаНаДокумент);
        ОткрытьФорму("Документ.ВводОстатков.Форма.ФормаТовары", ПараметрыОткрытия);
        
        // Способ 2 (альтернативный): Быстрое открытие значения
        // ОткрытьЗначение(СсылкаНаДокумент);
    КонецЕсли;

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

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

КонецФункции

Альтернативные способы переноса остатков без программирования

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

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