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