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