v8: Цивилизованная работа с событиями табличного поля формыВ 1С 80 просто ужасно реализована обработка событий изменения ячеек табличных полей формы.
Здесь приводится пример, как сделать работу с событиями цивилизованной. | | Автор статьи: Гений 1С | Редакторы: Последняя редакция №2 от 31.01.07 | История URL: http://kb.mista.ru/article.php?id=448 | |
Ключевые слова: форма,события
Ячейку табличного поля можно редактировать различными способами - вводить начальные буквы значения, выбирать из списка, ставить галочку.
Казалось бы - зачем изобретать велосипед, обеспечьте события:
- Перед началом изменения - чтобы можно было отказать в доступе к ячейке
- При изменении - чтобы можно было посмотреть что введено и если введено неверное значение, вернуть предыдущее значение. Предыдущее значение должно быть доступно
Но нет же, 1С имеет кучу событий для каждого из трех способов редактирования ячейки и ни одного, нужного нам.
Поэтому предлагаю отлавливать событие активизации ячейки, запоминать в глобальной переменной предыдущее значение этой ячейки и если ячейка недоступна, устанавливать у нее свойство ТолькоПросмотр или сбросить это свойство, если ячейка доступна.
Второй важный момент - при добавлении новой строки ее нужно заполнить. Однако в событии ПередНачаломДобавления новой строки еще нет, а в событии ПриНачалеРедактирования непонятно, новая строка редактируется или нет.
Опять делаем финт ушами и запоминаем, была ли новая строка, чтобы в ПриАктивизацииЯчейки заполнить новую строку. Если новая строка была добавлена, то событие ПриАктивизацииЯчейки произойдет пренепременно, чем мы и воспользуемся.
Вот такие плачевные исследования событий табличного поля.
//Используются глобальные переменные модуля
// глмПредЗн - хранит предыдущее значение поля ввода/флажка
// глмНоваяСтрока - признак того, что обрабатываемая строка - новая (использовать нельзя, используется для вызова события НоваяСтрока)
//Событие:
// Активизация - активизация ячейки.
// Изменение - событие при изменении поля ввода, без параметров.
// ИзменениеФлажка - событие при изменении флажка, без параметров.
// ДобавлениеСтроки - событие перед добавлением строки, Прм1=Отказ, Прм2=Копирование
// УдалениеСтроки - событие при удалении строки, Прм1=Отказ
// НоваяСтрока - событие, чтобы заполнить новую строку, нет параметров, вызывается само.
//
// В событиях Изменение, ИзменениеФлажка доступно предыдущее значение в переменной глмПредЗН
// В событиях Активизация, Изменение, ИзменениеФлажка - доступна текущая колонка через ЭлементТП.ТекущаяКолонка
Функция КонтрольЯчейки(ЭлементТП, Событие, Прм1=Неопределено, Прм2=Неопределено, Прм3=Неопределено)
ИмяТП=ЭлементТП.Имя;
//Особенности строки...
флНовый=ЭлементТП.ТекущаяСтрока.Модификация=Перечисления.Изменения.Добавить;
Если Событие="Активизация" Тогда
Если глмНоваяСтрока<>Неопределено Тогда
КонтрольЯчейки(ЭлементТП, "НоваяСтрока");
глмНоваяСтрока=Неопределено;
КонецЕсли;
Колонка=ЭлементТП.ТекущаяКолонка.Имя;
//Запоминаем предыдущее значение в глобальной переменной ПредЗН
глмПредЗН=ЭлементТП.ТекущаяСтрока[ЭлементТП.ТекущаяКолонка.Имя];
//Контролируем возможность редактирования ячеек через ТолькоПросмотр
Если Колонка="Подразделение" ИЛИ Колонка="ВидДокумента" ИЛИ Колонка="Роль" Тогда
ЭлементТП.Колонки[Колонка].ТолькоПросмотр=НЕ флНовый;
КонецЕсли;
ИначеЕсли Событие="Изменение" Тогда
Колонка=ЭлементТП.ТекущаяКолонка.Имя;
ИначеЕсли Событие="ИзменениеФлажка" Тогда
Колонка=ЭлементТП.ТекущаяКолонка.Имя;
ИначеЕсли Событие="УдалениеСтроки" Тогда
Если НЕ флНовый Тогда
Если ЭлементТП.ТекущаяСтрока.Модификация<>Перечисления.Изменения.Удалить Тогда
ЭлементТП.ТекущаяСтрока.Модификация=Перечисления.Изменения.Удалить;
Иначе
ЭлементТП.ТекущаяСтрока.Модификация=Неопределено;
КонецЕсли;
Прм1=истина; //Запрещаем удаление
// Предупреждение("Нельзя удалять строки таблицы");
КонецЕсли;
ИначеЕсли Событие="ДобавлениеСтроки" Тогда
//Если не отказ
Если Прм1=ложь Тогда
глмНоваяСтрока=ЭлементТП.ТекущаяСтрока;
КонецЕсли;
ИначеЕсли Событие="НоваяСтрока" Тогда
//Для новой строки проставляем флаг
ЭлементТП.ТекущаяСтрока.Модификация=Перечисления.Изменения.Добавить;
КонецЕсли;
КонецФункции
Процедура ПодразделенияПодразделениеПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение", Элемент);
КонецПроцедуры
Процедура РолиПриАктивизацииЯчейки(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "Активизация");
КонецПроцедуры
Процедура РолиМодификацияПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение");
КонецПроцедуры
Процедура РолиРольПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонецПроцедуры
Процедура ПраваДоступаПриАктивизацииЯчейки(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "Активизация");
КонецПроцедуры
Процедура ПраваДоступаМодификацияПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение");
КонецПроцедуры
Процедура ПраваДоступаВидДокументаПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение");
КонецПроцедуры
Процедура ПраваДоступаПодразделениеПриИзменении(Элемент)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение");
КонецПроцедуры
Процедура ПраваДоступаПриИзмененииФлажка(Элемент, Колонка)
// Вставить содержимое обработчика.
КонтрольЯчейки(ЭлементыФормы.Подразделения, "ИзменениеФлажка");
КонецПроцедуры
Процедура ОбновлениеОтображения()
// Вставить содержимое обработчика.
ЭлементыФормы.ОсновныеДействияФормы.Кнопки.кнОбработать.Доступность=Проведен;
КонецПроцедуры
Процедура ПодразделенияПередНачаломДобавления(Элемент, Отказ, Копирование)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование);
КонецПроцедуры
Процедура РолиПередНачаломДобавления(Элемент, Отказ, Копирование)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование);
КонецПроцедуры
Процедура ПраваДоступаПередНачаломДобавления(Элемент, Отказ, Копирование)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование);
КонецПроцедуры
Процедура ПраваДоступаПередУдалением(Элемент, Отказ)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ);
КонецПроцедуры
Процедура РолиПередУдалением(Элемент, Отказ)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ);
КонецПроцедуры
Процедура ПодразделенияПередУдалением(Элемент, Отказ)
// Вставить содержимое обработчика.
КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ);
КонецПроцедуры
Замечания автора:
= При копировании строки событие активизации ячейки вызывается дважды или один раз, событие ПередНачаломРедактирования тоже не всегда вызывается для новой строки - отсюда лучше обрабатывать событие "Перед началом добавления", отменять добавление и добавлять строку программно, позиционируя на нее.
= Кроме свойства просмотр, можно динамически менять свойства "Редактирование текста" и "Кнопка выбора", разрешая или запрещая виды редактирования в ячейке. |