Книга знаний

1С:Предприятие / v8 / Приемы программирования / Формы

v8: Цивилизованная работа с событиями табличного поля формы

В 1С 80 просто ужасно реализована обработка событий изменения ячеек табличных полей формы. Здесь приводится пример, как сделать работу с событиями цивилизованной.Автор статьи: Гений 1С | Редакторы:
Последняя редакция №2 от 31.01.07 | История
URL: http://kb.mista.ru/article.php?id=448

Ключевые слова: форма,события


Ячейку табличного поля можно редактировать различными способами - вводить начальные буквы значения, выбирать из списка, ставить галочку.
Казалось бы - зачем изобретать велосипед, обеспечьте события:
  1. Перед началом изменения - чтобы можно было отказать в доступе к ячейке

  2. При изменении - чтобы можно было посмотреть что введено и если введено неверное значение, вернуть предыдущее значение. Предыдущее значение должно быть доступно

Но нет же, 1С имеет кучу событий для каждого из трех способов редактирования ячейки и ни одного, нужного нам.

Поэтому предлагаю отлавливать событие активизации ячейки, запоминать в глобальной переменной предыдущее значение этой ячейки и если ячейка недоступна, устанавливать у нее свойство ТолькоПросмотр или сбросить это свойство, если ячейка доступна.

Второй важный момент - при добавлении новой строки ее нужно заполнить. Однако в событии ПередНачаломДобавления новой строки еще нет, а в событии ПриНачалеРедактирования непонятно, новая строка редактируется или нет.
Опять делаем финт ушами и запоминаем, была ли новая строка, чтобы в ПриАктивизацииЯчейки заполнить новую строку. Если новая строка была добавлена, то событие ПриАктивизацииЯчейки произойдет пренепременно, чем мы и воспользуемся.

Вот такие плачевные исследования событий табличного поля.


//Используются глобальные переменные модуля 
 
//    глмПредЗн - хранит предыдущее значение поля ввода/флажка
 
//    глмНоваяСтрока - признак того, что обрабатываемая строка - новая (использовать нельзя, используется для вызова события НоваяСтрока)
 


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

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

Процедура ПодразделенияПодразделениеПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение", Элемент); 
КонецПроцедуры

Процедура РолиПриАктивизацииЯчейки(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "Активизация"); 
КонецПроцедуры

Процедура РолиМодификацияПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение"); 
КонецПроцедуры

Процедура РолиРольПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
КонецПроцедуры

Процедура ПраваДоступаПриАктивизацииЯчейки(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "Активизация"); 
КонецПроцедуры

Процедура ПраваДоступаМодификацияПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение"); 
КонецПроцедуры

Процедура ПраваДоступаВидДокументаПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение"); 
КонецПроцедуры

Процедура ПраваДоступаПодразделениеПриИзменении(Элемент)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "Изменение"); 
КонецПроцедуры

Процедура ПраваДоступаПриИзмененииФлажка(Элемент, Колонка)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(ЭлементыФормы.Подразделения, "ИзменениеФлажка"); 
КонецПроцедуры

Процедура ОбновлениеОтображения()
    // Вставить содержимое обработчика.
 
    ЭлементыФормы.ОсновныеДействияФормы.Кнопки.кнОбработать.Доступность=Проведен;
КонецПроцедуры

Процедура ПодразделенияПередНачаломДобавления(Элемент, Отказ, Копирование)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование); 
КонецПроцедуры

Процедура РолиПередНачаломДобавления(Элемент, Отказ, Копирование)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование); 
КонецПроцедуры

Процедура ПраваДоступаПередНачаломДобавления(Элемент, Отказ, Копирование)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "ДобавлениеСтроки", Отказ, Копирование); 
КонецПроцедуры

Процедура ПраваДоступаПередУдалением(Элемент, Отказ)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ); 
КонецПроцедуры

Процедура РолиПередУдалением(Элемент, Отказ)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ); 
КонецПроцедуры

Процедура ПодразделенияПередУдалением(Элемент, Отказ)
    // Вставить содержимое обработчика.
 
    КонтрольЯчейки(Элемент, "УдалениеСтроки", Отказ); 
КонецПроцедуры


Замечания автора:
= При копировании строки событие активизации ячейки вызывается дважды или один раз, событие ПередНачаломРедактирования тоже не всегда вызывается для новой строки - отсюда лучше обрабатывать событие "Перед началом добавления", отменять добавление и добавлять строку программно, позиционируя на нее.
= Кроме свойства просмотр, можно динамически менять свойства "Редактирование текста" и "Кнопка выбора", разрешая или запрещая виды редактирования в ячейке.

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика