Почему очищается реквизит табличной части документа в 1С и как правильно организовать выбор данных из другого объекта?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке документов в среде 1С начинающие разработчики часто сталкиваются с ситуацией: в коде обработчика табличной части значения успешно считываются и выводятся через функцию Сообщить(), но при попытке присвоить значение в строку табличной части ячейка остается пустой. Разберем по шагам, почему возникает такое поведение платформы и как правильно реализовать выбор данных одного документа из табличной части другого документа.

Анализ причин возникновения проблемы

Проанализируем ситуацию, с которой столкнулся разработчик. При выполнении кода в обработчике события присвоение реквизита не сохраняется:


к = Элемент.Значение.ФИО2;
должн = Элемент.Значение.Должность;
Сообщить(к); // Значение отображается
стрТЧ = ЭлементыФормы.ВедомостьНаВыдачуСИЗ.ТекущиеДанные;
стрТЧ.ФИО = к; // Поле в табличной части остается пустым
стрТЧ.Должность = должн; // Успешно заполняется

Выделим две ключевые причины, приводящие к некорректной работе алгоритма:

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

Способ 1. Архитектурно правильное разделение реквизитов

Рассмотрим наиболее надежный подход, исключающий путаницу с типами данных и сохраняющий ссылочную целостность базы.

Вместо попытки совместить в одной колонке и документ-основание, и данные физического лица, разделим табличную часть документа на самостоятельные реквизиты:

  1. Карточка — тип ДокументСсылка.КарточкаУчетаВыдачи (ссылка на документ, откуда берутся данные).
  2. Сотрудник (или ФИО) — тип СправочникСсылка.КВ_Сотрудники (целевая ссылка на справочник).
  3. Должность — тип СправочникСсылка.Должности или строковый тип.

В этом случае пользователь стандартным образом выбирает документ в колонке «Карточка». В обработчике события ПриИзменении для поля ввода «Карточка» автоматически заполняются зависимые реквизиты строки:


Процедура ТабличнаяЧастьКарточкаПриИзменении(Элемент)
    
    СтрокаТЧ = ЭлементыФормы.ТабличнаяЧасть.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем заполненность выбранного документа
    Если ЗначениеЗаполнено(СтрокаТЧ.Карточка) Тогда
        СтрокаТЧ.Сотрудник = СтрокаТЧ.Карточка.Фамилия;
        СтрокаТЧ.Должность = СтрокаТЧ.Карточка.Должность;
    Иначе
        СтрокаТЧ.Сотрудник = Справочники.КВ_Сотрудники.ПустаяСсылка();
        СтрокаТЧ.Должность = Неопределено;
    КонецЕсли;

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

Способ 2. Подмена формы выбора через событие «НачалоВыбора» (модальный режим)

Если по условиям задачи в табличной части требуется оставить только одно поле «Сотрудник» (с типом СправочникСсылка.КВ_Сотрудники), но при нажатии на кнопку выбора пользователь должен видеть список документов-карточек, переопределим выбор через событие элемента управления.

Разберем реализацию по шагам:

  1. В конфигураторе открываем свойства поля ввода в колонке табличной части.
  2. Назначаем обработчик для события НачалоВыбора.
  3. Отключаем стандартную обработку и открываем форму выбора нужного документа модально.

Процедура ТабличнаяЧастьСотрудникНачалоВыбора(Элемент, СтандартнаяОбработка)
    
    // Отменяем стандартное открытие формы выбора справочника
    СтандартнаяОбработка = Ложь;
    
    // Получаем форму выбора другого документа
    ФормаВыбора = Документы.КарточкаУчетаВыдачи.ПолучитьФормуВыбора();
    
    // Открываем форму модально и ожидаем выбор пользователя
    ВыбранныйДокумент = ФормаВыбора.ОткрытьМодально();
    
    Если ЗначениеЗаполнено(ВыбранныйДокумент) Тогда
        СтрокаТЧ = ЭлементыФормы.ТабличнаяЧасть.ТекущиеДанные;
        Если СтрокаТЧ <> Неопределено Тогда
            СтрокаТЧ.Сотрудник = ВыбранныйДокумент.Фамилия;
            СтрокаТЧ.Должность = ВыбранныйДокумент.Должность;
        КонецЕсли;
    КонецЕсли;

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

Способ 3. Немодальный выбор через связку событий «НачалоВыбора» и «ОбработкаВыбора»

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

Для реализации потребуется задействовать два события поля ввода табличной части:

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

Важное замечание: не рекомендуется использовать строковый тип для хранения ФИО сотрудников в документах. Хранение ссылочных данных (СправочникСсылка) гарантирует однозначную идентификацию записей при формировании аналитических отчетов и смене фамилий сотрудниками.

← На главную