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