В практике работы с таблицами формы встречаются ситуации, когда в разных колонках таблицы хранятся взаимосвязанные значения.
Пример:
Допустим у нас есть реквизит, хранящий тип "ДеревоЗначений". В составе дерева есть колонки "Источник" типа "Число" и "Значение" типа "Произвольный". Дерево вместе с колонками вынесено на форму. Мы хотим, чтобы в момент, когда пользователь приступает к редактированию данных в колонке "Значение", он оперировал конкретным типом данных, а не выбирал его из всех, что предлагает платформа. При этом выбор типа данных зависит от значения, установленного в поле "Источник".
Для упрощения понимания, опустим наличие других полей в составе дерева колонок и сосредоточимся только на тех, которые нам необходимы для решения задачи.
Проблема заключается в том, что при решении этой задачи "в лоб" мы сталкиваемся с особенностью поведения платформы, когда поймать нужные нам события, находясь внутри режима редактирования строки, не получается. В частности событие "ПриНачалеРедактирования", которым интуитивно хочется воспользоваться для установки нужного нам типа, в данном режиме не наступает.
Для справки: режим редактирования строки наступает в табличной части, когда пользователь начинает изменение данных в любой ячейке этой строки и завершается только тогда, когда заканчивается последняя редактируемая ячейка в ней в порядке обхода, либо когда пользователь, нарушив порядок обхода, кликает мышью вне редактируемой области.
На решение этой задачи может уйти долгое время и масса экспериментов, если решать ее с нуля самостоятельно. В данной статье рассмотрим способ организации нужной нам механики обработки строки на управляемых формах.
Предлагаемый подход состоит в том, чтобы воспользоваться следующими событиями:
- Событие "ПриНачалеРедактирования" для элемента "ДеревоКолонок";
- Событие "ОбработкаВыбора" для элемента "ДеревоКолонокИсточник";
- Событие "ПриИзменении" для элемента "ДеревоКолонокИсточник";
- Событие "ПриИзменении" для элемента "ДеревоКолонокЗначение".
Событие ПриНачалеРедактирования для элемента "ДеревоКолонок"
Событие нужно, чтобы отловить начало редактирования колонки "ДеревоКолонокЗначение" и установить в нем нужный тип поля в зависимости от каких-то условий. Примерный код обработчика может выглядеть так:
// Процедура устанавливает правильный тип данных колонке "Значение" // непосредственно перед началом редактирования этого значения Процедура ДеревоКолонокПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование) Если Элемент.ТекущийЭлемент.Имя <> "ДеревоКолонокЗначение" Тогда Возврат; КонецЕсли; ТекущиеДанные = Элементы[Элемент.Имя].ТекущиеДанные; ТипПоля = ТекущиеДанные.ТипЗначения; Если ТекущиеДанные.Источник = 0 Тогда // файл загрузки ТипПоля = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(3, 0, ДопустимыйЗнак.Неотрицательный)); КонецЕсли; Элемент.ТекущийЭлемент.ОграничениеТипа = ТипПоля; КонецПроцедуры
Важным свойством, влияющим на ограничение типа данных в колонке, является ОграничениеТипа. Ограничение типа может принимать массив элементов типа "ОписаниеТипов" или единичное значение.
Установка этого значение в процедуре "При начале редактирования" позволит пользователю приступить непосредственно к вводу значения, минуя выбор типа.
Событие "ОбработкаВыбора" для элемента "ДеревоКолонокИсточник"
Обработка выбора подходит для ячеек, значение которых определяется выпадающим списком. Именно такой способ выбора был определен в данном примере, но на практике он может быть любым другим, тогда вы будете использовать более подходящие события.
В данной процедуре мы должны, в зависимости от нашего выбора, сохранить или сбросить данные в колонке "Значение".
Это можно сделать примерно следующим кодом:
// Процедура сбрасывает значение в колонке, при изменении источника Процедура ДеревоКолонокИсточникОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка) ТекущиеДанные = Элементы.ДеревоКолонок.ТекущиеДанные; СтароеЗначение = ТекущиеДанные.Источник; Если СтароеЗначение <> ВыбранноеЗначение Тогда ТипПоля = ТекущиеДанные.ТипЗначения; Если ВыбранноеЗначение = 0 Тогда // файл загрузки ТипПоля = Новый ОписаниеТипов("Число"); КонецЕсли; ТекущиеДанные.Значение = ТипПоля.ПривестиЗначение(); КонецЕсли; КонецПроцедуры
Здесь мы проверяем меняется ли выбранное значение и, если меняется, то очищаем данные в колонке "Значение". Но почему мы не пишем просто:
ТекущиеДанные.Значение = Неопределенно;
а действуем через ПривестиЗначение()?
Потому что платформенное представление разных типов данных для их значений по умолчанию разное. Например, для числовых значений это 0 (ноль). А для значений типа "СправочникСсылка" - это обычно (если не предопределено программистом) ПустаяСсылка, которая никак не отображается в ячейке.
Идем далее.
Событие "ПриИзменении" для элемента "ДеревоКолонокИсточник"
А вот это, пожалуй, ключевой момент данной статьи. Событие "ПриИзменении" наступает при выходе из режима редактирования колонки, но - надо помнить! - режим редактирования строки в этот момент еще активен. А это значит, что будет осуществлен переход к следующей колонке, но событие "ПриНачалеРедактирования" активировано не будет! И вот тут-то пригодится следующий код:
Процедура ДеревоКолонокЗначениеПриИзменении(Элемент) ЗапретитьАвтоПереходКСледующейЯчейке(); КонецПроцедуры
Здесь мы вызываем процедуру ЗапретитьАвтоПереходКСледующейЯчейке(), которая принудительно осуществляет выход из режима редактирования строки. Это позволяет нам заново активировать событие ПриНачалеРедактирования на входе в ячейку колонки "Значение" и осуществить в нем нужные действия по установке типа данных.
Вот нехитрый код самой процедуры:
// Процедура решает следующие проблемы: // 1. Запрещает автоматическое перемещение активной ячейки в редактируемой строке по Enter // 2. Запрещает переход к новой строке по Enter Процедура ЗапретитьАвтоПереходКСледующейЯчейке(ОтменаРедактирования = Ложь) Элементы.ДеревоКолонок.ЗакончитьРедактированиеСтроки(ОтменаРедактирования); КонецПроцедуры
Событие "ПриИзменении" для элемента "ДеревоКолонокЗначение"
Здесь пропишем тот же самый код:
Процедура ДеревоКолонокЗначениеПриИзменении(Элемент) ЗапретитьАвтоПереходКСледующейЯчейке(); КонецПроцедуры
Таким образом, мы решили проблему выбора типа данных и облегчили пользователю работу с формой.
Теперь, надеюсь, что в вашей практике данная задача будет решаться гораздо быстрее.
Для добавления комментария необходимо авторизоваться.
Вход | Регистрация