1с событие при изменении любого реквизита формы

  Маркет42 - Место для твоих разработок  

Событие «При изменении» для реквизита программно добавленного на форму.

Я
   Юзер123

15.09.20 — 15:32

Доброго времени.

В Справочник Договора Клиентов добавил реквизит.   На форму справочника добавляю его программно через общий модуль «МодификацияКонфигурацииПереопределяемый»

Как вызвать обработчик события при изменении для этого реквизита?

  

Партнерская программа EFSOL Oblako

   Юзер123

1 — 15.09.20 — 15:44

Т.е. надо при выборе  на форме значения этого нового реквизита заполнять другие реквизиты.

   RomanYS

2 — 15.09.20 — 15:50

Элементы.Твойреквизит.УстановитьДействие(«ПриИзменении», «ИмяПроцедуы»);

Только процедура должна быть в самой форме вроде

   Юзер123

3 — 15.09.20 — 15:55

(2)  Сама процедура «ПриИзменении» или Процедура  добавления элемента.

   Юзер123

4 — 15.09.20 — 15:57

Да все ок.  

РАботает.

  

RomanYS

5 — 15.09.20 — 15:58

(3) процедура-обработчик. Добавить элемент и установить действие можно и в ОМ

TurboConf — расширение возможностей Конфигуратора 1С

Получаем доступ к событиям элементов формы дополнительных реквизитов на примере конфигурации «Управление торговлей 11.2».

Допустим, для документа «Поступление услуг и прочих активов» у нас создан дополнительный реквизит «Не выгружать при синхронизации» с типом «Булево».  Задача: использовать событие элемента формы «При изменении».

Дополнительные реквизиты – штука тонкая. Они могут присутствовать на форме объекта, а могут и не присутствовать. Например, в конфигурации «Управление торговлей 11.2», когда мы открываем форму документа «Поступление услуг и прочих активов», дополнительные реквизиты там отсутствуют. Это можно видеть в отладчике. И только когда мы переходим на вкладку «Дополнительно», происходит отложенная инициализация формы и после этого дополнительные реквизиты появляются в форме.

В связи с таким поведением формы, нам придётся назначать обработчик для события элемента формы дополнительного реквизита программно. Сделаем это с помощью метода УстановитьДействие().

Как мы уже отметили, в УТ 11.2 в документе «Поступление услуг и прочих активов» дополнительные реквизиты появляются на форме при переходе на вкладку «Дополнительно». Переход обрабатывается в следующей процедуре, которая расположена в модуле формы документа:

&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)

	// Текст процедуры

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

В этой процедуре дополнительные реквизиты уже должны появиться на форме. Воспользуемся отладчиком. Поставим точку останова в конце процедуры и запустим отладку. Создадим условия для захода в точку останова. Далее в «Табло» найдём элемент формы необходимого нам дополнительного реквизита. Примерный его вид и расположение:

ЭтаФорма.Элементы.ДополнительныйРеквизитЗначение_AFD1AFD8xC18C

Метод УстановитьДействие() выполняется в контексте «На сервере», поэтому мы не можем использовать его в процедуре ГруппаСтраницыПриСменеСтраницы(), так как её контекст – «На клиенте». Значит, в конце процедуры мы дописываем вызов своей, серверной, процедуры, которая, собственно, и будет устанавливать обработчик для события «ПриИзменении» элемента формы.

&НаКлиенте
Процедура ГруппаСтраницыПриСменеСтраницы(Элемент, ТекущаяСтраница)

	// Текст процедуры
	
	УстановитьДействиеДляДопРеквизита();
	
КонецПроцедуры

В модуле формы создаём серверную процедуру:

&НаСервере
Процедура УстановитьДействиеДляДопРеквизита()
		
	ЭтаФорма.Элементы.ДополнительныйРеквизитЗначение_AFD1AFD8xC18C.УстановитьДействие("ПриИзменении", "МойОбработчик");
	
КонецПроцедуры

В этой процедуре мы задали, что событие элемента формы «ПриИзменении» будет обрабатываться в процедуре с названием «МойОбработчик». Нам осталось только создать эту процедуру. Нужно учесть, что контекст её выполнения должен быть «На клиенте».

&НаКлиенте
Процедура МойОбработчик()
	
	// Текст процедуры
	
КонецПроцедуры

Вот вроде бы и всё.

Ранее мы добавили свой дополнительный реквизит «СНИЛС» для внутреннего документа и сделали закладку с дополнительными реквизитами первой на форме.

Пришло время улучшить юзабилити нашего реквизита. Как известно СНИЛС имеет определённый формат ввода. Кроме того, он содержит контрольное число в виде двух последних цифр для проверки корректности его ввода. Учитывая это, будет хорошим тоном по отношению к пользователям, если мы поможем ему корректно указать СНИЛС для сотрудника, а в случае ошибки предупредить его об этом.

Делаем маску ввода для дополнительного реквизита

Номер СНИЛС представляет собой строку следующего формата «XXX-XXX-XXX XX», где Х это цифра от 0 до 9. Последняя группа символов XX представляет собой контрольное число. К сожалению типовой механизм не позволяет задать маску ввода для дополнительных реквизитов. Поэтому внесем изменения в программный код. Создание полей на форме для дополнительных реквизитов происходит динамически при создании формы на сервере, либо при изменении некоторых реквизитов в уже открытой форме. Первичный вызов процедуры создания дополнительных реквизитов выглядит так:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

...

УправлениеСвойствами.ПриСозданииНаСервере(ЭтаФорма, ДополнительныеПараметры);

...

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

Само создание полей формы происходит в процедуре

УправлениеСвойствами.ЗаполнитьДополнительныеРеквизитыВФорме()

Откроем общий модуль УправлениеСвойствами и найдем там эту процедуру. Внесем туда изменения — добавим в конце вызов своей процедуры:

Процедура ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект = Неопределено, ПоляНадписей = Ложь, СкрытьУдаленные = Неопределено) Экспорт

...

маг_РаботаСДокументами.ЗаполнитьДополнительныеРеквизитыВФорме(Форма, ОписаниеОбъекта, ПоляНадписей) ;

...

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

Теперь в общий модуль маг_РаботаСДокументами добавим  саму реализацию этой процедуры:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

Процедура ЗаполнитьДополнительныеРеквизитыВФорме(Форма, Объект, ПоляНадписей) Экспорт

Если ТипЗнч(Объект.Ссылка) <> Тип(«СправочникСсылка.ВнутренниеДокументы») Тогда

Возврат;

КонецЕсли;

ВидДокументаСтрокой = «»+Форма.Объект.ВидДокумента;

Если ВидДокументаСтрокой = «Заявка на прием» тогда

//Получим уникальное имя для реквизита СНИЛС

ИмяДопРеквизита = маг_ПовторноеИспользование.УникальноеИмяДопРеквизита(Объект.ВидДокумента, «СНИЛС»);

Рек = Форма.Элементы.Найти(ИмяДопРеквизита);

Если Рек <> Неопределено тогда

Рек.Маска = «999-999-999 99»;

Рек.УстановитьДействие(«ПриИзменении», «маг_СНИЛСПриИзменении»);

КонецЕсли;

КонецЕсли;

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

Здесь мы сначала получаем уникально имя для нашего реквизита. По нему мы сможем обращаться как к самому реквизиту формы, так и к полю формы. Для получения уникального имени используем следующую функцию, поместим ее в общий модуль маг_ПовторноеИспользование:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

Функция УникальноеИмяДопРеквизита(ВидДокумента, ИмяРеквизита)  Экспорт

УстановитьПривилегированныйРежим(Истина);

Набор = ВидДокумента.НаборСвойств;

Результат  = «»;

Запрос = Новый Запрос;

Запрос.Текст =

«ВЫБРАТЬ ПЕРВЫЕ 1

| ВЫБОР

| КОГДА Наборы.ПометкаУдаления

| ТОГДА &ПустойНабор

| ИНАЧЕ Наборы.Ссылка

| КОНЕЦ КАК Набор,

| Наборы.Свойство

|ИЗ

| Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК Наборы

|ГДЕ

| Наборы.Ссылка = &Ссылка

| И Наборы.Свойство.Заголовок = &Наименование»;

Запрос.УстановитьПараметр(«Наименование», ИмяРеквизита);

Запрос.УстановитьПараметр(«Ссылка», Набор);

Запрос.УстановитьПараметр(«ПустойНабор», Справочники.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка());

РезультатЗапроса = Запрос.Выполнить();

Выб = РезультатЗапроса.Выбрать();

Если Выб.Следующий() тогда

ИмяУникальнаяЧасть =

СтрЗаменить(ВРег(Строка(Выб.Набор.УникальныйИдентификатор())), «-«, «x»)

+ «_»

+ СтрЗаменить(ВРег(Строка(Выб.Свойство.УникальныйИдентификатор())), «-«, «x»);

Результат = «ДополнительныйРеквизитЗначение_» + ИмяУникальнаяЧасть;

КонецЕсли;

Возврат Результат;

КонецФункции

После того как по уникальному имени получили ссылку на поле формы, устанавливаем для него маску ввода, а так же назначаем обработчик ПриИзменении для проверки корректности ввода СНИЛСа (об этом ниже). После внесения этих дополнений, значение СНИЛСа на форме должно вводиться по маске как показано на картинке ниже:

Ввод СНИЛС по маске

Маска для поля СНИЛС

Подключаем обработчик события для дополнительного реквизита

Для проверки корректности ввода СНИЛС используем типовую функцию из 1С:ЗУП. Поместим данную функцию в наш общий модуль маг_РаботаСДокументами. Ниже сама функция:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

Функция СтраховойНомерПФРСоответствуетТребованиям(СтраховойНомер) Экспорт

Результат = Истина;

СтрокаЦифр=СтрЗаменить(Лев(СтраховойНомер,11),«-«,«»);

Если ПустаяСтрока(СтрокаЦифр) Тогда

Возврат Ложь;

КонецЕсли;

Попытка

П1 = Число(СтрокаЦифр);

КонтрольноеЧисло=Число(Прав(СтраховойНомер,2));

Исключение

Возврат Ложь;

КонецПопытки;

Если Число(Лев(СтрокаЦифр,9)) > 1001998 Тогда

Всего=0;

Для Сч = 1 По 9 Цикл

Всего=Всего+Число(Сред(СтрокаЦифр,10Сч,1))*Сч

КонецЦикла;

Остаток=Всего%101;

Остаток=?(Остаток=100,0,Остаток);

Если Остаток<>КонтрольноеЧисло Тогда

Результат = Ложь;

КонецЕсли;

Иначе

Результат = Ложь;

КонецЕсли;

Возврат Результат;

КонецФункции

Помните, мы программно назначили обработчик на поле дополнительного реквизита. Теперь добавим саму процедуру для обработчика ПриИзменении в модуль формы элемента справочника «ВнтуренниеДокументы»:

&НаКлиенте

Процедура маг_СНИЛСПриИзменении(Элемент)

Если НЕ маг_РаботаСДокументами.СтраховойНомерПФРСоответствуетТребованиям(Элемент.ТекстРедактирования) тогда

ПоказатьПредупреждение(,«СНИЛС указан неверно!!!»);

КонецЕсли;

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

Теперь, если пользователь ошибется при вводе СНИЛСа, то система предупредит его и выдаст сообщение о некорректном значении:

Предупреждение о некорректном СНИЛСе

Предупреждение

Итоги

После небольших изменений в программе, поведение нашего дополнительного реквизита стало более дружелюбным к пользователю. Теперь при заполнении поля СНИЛСа легче визуально контролировать его правильность за счет маски ввода. Кроме того, даже если если пользователь ошибется при вводе, программа предупредит его об этом.

Phil

Эксперт 1С

434 / 305 / 92

Регистрация: 28.05.2014

Сообщений: 1,247

1

1C 8.x

Программно вызвать процедуру при изменении( поля формы тч документа)

24.01.2016, 21:18. Показов 38920. Ответов 4

Метки нет (Все метки)


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

Получаю список счетчиков по которым передали показания

1C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
&НаСервере
Функция ЗагрузитьИзРегистраНаСервере()
    Запрос = Новый Запрос;
    Запрос.Текст =  "ВЫБРАТЬ
                    |   КУ_ПоказанияСчетчиковССайта.Счетчик.Ссылка КАК Счетчик,
                    |   КУ_ПоказанияСчетчиковССайта.ПоказаниеССайта
                    |ИЗ
                    |   РегистрСведений.КУ_ПоказанияСчетчиковССайта КАК КУ_ПоказанияСчетчиковССайта
                    |ГДЕ
                    |   КУ_ПоказанияСчетчиковССайта.ДатаВнесения МЕЖДУ &НачалоПериода И &КонецПериода
                    |   И КУ_ПоказанияСчетчиковССайта.Счетчик.Здание = &Здание";
                    Запрос.УстановитьПараметр("НачалоПериода",НачалоМесяца(объект.Дата));
                    Запрос.УстановитьПараметр("КонецПериода",КонецМесяца(объект.Дата));
                    Запрос.УстановитьПараметр("Здание",объект.Здание);
 
    Результат = Запрос.Выполнить().выгрузить();
    Возврат Результат;
КонецФункции

заполняю все найденные счетчики в документе данными из запроса.

1C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    ТЧПоиска = ЗагрузитьИзРегистраНаСервере();
    Если объект.ПоказанияСчетчиков.Количество() > 0 тогда
        ПараметрыОтбора = Новый Структура;
        Для каждого строка из ТЧПоиска Цикл
            ПараметрыОтбора.Вставить("Счетчик", строка.Счетчик);
            НайденныеСтроки = объект.ПоказанияСчетчиков.НайтиСтроки(ПараметрыОтбора);
            Если НайденныеСтроки.Количество() > 0 Тогда
                Если ЗначениеЗаполнено(НайденныеСтроки[0].ТекущееПоказание) тогда 
                    Сообщить("для лицевого счета: " + НайденныеСтроки[0].ЛицевойСчет + " проверьте показание счетчика: " + НайденныеСтроки[0].Счетчик);
                Иначе
                    СтрокаТЧ = объект.ПоказанияСчетчиков.Получить(НайденныеСтроки[0].НомерСтроки - 1);
                    СтрокаТЧ.ТекущееПоказание = строка.ПоказаниеССайта;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;
    Иначе
        Сообщить("Заполните документ перед выгрузкой данных из регистра!");
    КонецЕсли;

при заполнении

1C
1
СтрокаТЧ.ТекущееПоказание

должно срабатывать событие при изменении
где рассчитывается расход проводится ряд проверок. Как мне программно получить поле которое я изменяю на форме. Т.к. при вызове процедуры передаются именно оно.

1C
1
2
&НаКлиенте
Процедура ПоказанияСчетчиковТекущееПоказаниеПриИзменении(Элемент)



0



856 / 655 / 111

Регистрация: 01.11.2012

Сообщений: 2,410

25.01.2016, 11:56

2

Цитата
Сообщение от Phil
Посмотреть сообщение

должно срабатывать событие при изменении

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



0



Эксперт 1С

434 / 305 / 92

Регистрация: 28.05.2014

Сообщений: 1,247

25.01.2016, 12:01

 [ТС]

3

Xomych, я так и сделал, добавил процедуру и и передал строку. Просто может есть способ определить поле на форме при программном заполнении, тогда не пришлось бы по сути копировать процедуру.



0



2923 / 844 / 324

Регистрация: 30.04.2009

Сообщений: 2,633

25.01.2016, 18:09

4

Цитата
Сообщение от Phil
Посмотреть сообщение

Просто может есть способ определить поле на форме при программном заполнении, тогда не пришлось бы по сути копировать процедуру.

Вы выполняете все программно, соответственно процедуру формы вы получить не сможете. Но вы можете посмотреть в процедуре формы «ПриИзменении» какая в ней вызывается процедура, обычно в ней вызывается серверная процедура, вот она то вам и нужна будет.



0



Модератор

Эксперт 1С

3708 / 2905 / 572

Регистрация: 10.03.2011

Сообщений: 11,442

Записей в блоге: 1

26.01.2016, 02:43

5

Цитата
Сообщение от Xomych
Посмотреть сообщение

Событие при изменении срабатывает только при интерактивном изменении.

А вот на обычных формах можно было и при программном изменении заставить сработать событие ПриИзменении



0



У каждого программиста за время работы накапливается полезный инструментарий, которым он привык пользоваться. Естественно и у меня он тоже имеется. И вот решено было немного поделиться с сообществом. Возможно идеи не новые. Более того, допускаю, что реализованы они не самым оптимальным образом. Но ведь для этого сообщество и существует, чтобы делиться с ним, получая обратную связь.

У каждого программиста за время работы накапливается полезный инструментарий, которым он привык пользоваться. Естественно и у меня он тоже имеется. И вот решено было немного поделиться с сообществом. Возможно идеи не новые. Более того, допускаю, что реализованы они не самым оптимальным образом. Но ведь для этого сообщество и существует, чтобы делиться с ним, получая обратную связь.

Содержание

  • Управление видимостью, доступностью и просмотром реквизитов формы (добавлено 24.09.17, изменено 14.06.18)
  • Проверка изменений значений реквизитов формы (добавлено 24.09.17)
  • Подсистема «Помощник заполнения» (добавлено 20.07.18)
  • Интеграция с Confluence (анонс)
  • Тестирование прав доступа (анонс)

Управление видимостью, доступностью и просмотром реквизитов формы

Преамбула. Еще в бытность работы в 7.7, а далее и в первых конфигурациях на 8.х совершенно точно не нравились процедуры и функции вроде «УстановитьВидимость» или «УстановитьДоступность» и т.п. В них собирались все элементы, по различным условиям устанавливалась видимость. Как правило в них условия выставлялись по бизнес-логике редактирования документа, например проверка по видам операций, различным условиям заполненности и т.д. В итоге один и тот же элемент мог встречаться несколько раз и конечные условия «почему он виден или доступен» приходилось вникать во всю логику. Но не сразу пришло понимание, как должно быть, как будет удобно. Были различные варианты. Но вот некоторое время назад, мы совместно с нашей командой остановились на представленном ниже варианте.

Существует основная процедура «УстановитьУсловноеОформление» (неудачное имя для метода, понимаю, но увы уже много кода «наделано» руки не дойдут изменить его везде). В качестве параметров метода выступает: ЭтотОбъект — т.е. сама управляемая форма в которой метод вызывается и ИменаРеквизитов — список имен (не обязательно) через «,» для которых необходимо выполнить настройку видимости, доступности, просмотра или других свойств. При этом, есть возможность как создать произвольный набор элементов, так и не передавать список вовсе. В таком случае работать будет следующим образом:

  • НаборЭлементов — любое произвольное имя для набора элементов формы.
    Например: при изменении вида операции надо изменить видимость множества элементов формы. Для этого можно передать список имен этих элементов, но согласитесь, вызов метода может быть из нескольких мест, а потом найти и поправить все не факт что получится верно. Поэтому создается имя для набора, например: РеквизитыВидОперации. Далее в методе «УстановитьУсловноеОформлениеРеквизита» создается проверка условия и вызов метода для каждого из элементов входящих в набор. Таким образом, достаточно вызвать УстановитьУсловноеОформление(ЭтотОбъект, «РеквизитыВидОперации») и все зависимые элементы будут настроены. НО (повторюсь): можно указать и весь список элементов по отдельности.
  • Пустое имя реквизита — в таком случае настроены будут все элементы формы
&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, знач ИмяРеквизита)

Если НЕ Обработано.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат;
КонецЕсли;
Обработано.Добавить(ИмяРеквизита);

Элементы    = Форма.Элементы;
Объект        = Форма.Объект;

#Область Наборы

Если ИмяРеквизита = "Реквизиты" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, "Реквизит1");
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, "Реквизит2");
КонецЕсли;

#КонецОбласти

#Область Элементы

Если ИмяРеквизита = "Ответственный" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"Ответственный", "ТолькоПросмотр", ЗначениеЗаполнено(Объект.Ответственный));
КонецЕсли;

#КонецОбласти

#Область ТабЧасть_Имя

Если ИмяРеквизита = "ИмяТабличнойЧастиОтветственный" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"ИмяТабличнойЧастиОтветственный", "ТолькоПросмотр", ЗначениеЗаполнено(Объект.Ответственный));
КонецЕсли;

#КонецОбласти

#Область Команды

Если ИмяРеквизита = "КомандаЗаполнить" ИЛИ ПустаяСтрока(ИмяРеквизита) Тогда
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Элементы,
"ТаблицаФормыЗаполнить", "Видимость", НЕ Объект.Проведен);
КонецЕсли;

#КонецОбласти

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

&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьУсловноеОформление(Форма, знач ИменаРеквизитов = "")

Если ТипЗнч(ИменаРеквизитов) = Тип("Строка") Тогда
Если ПустаяСтрока(ИменаРеквизитов) Тогда
МассивИмен = Новый Массив;
МассивИмен.Добавить("");
Иначе
МассивИмен = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИменаРеквизитов, ",");
КонецЕсли;
ИначеЕсли ТипЗнч(ИменаРеквизитов) = Тип("Массив") ИЛИ ТипЗнч(ИменаРеквизитов) = Тип("ФиксированныйМассив") Тогда
МассивИмен = ИменаРеквизитов;
Иначе
Возврат;
КонецЕсли;

//Форма.ТолькоПросмотр = (Форма.СостоянияЗаблокировано.Найти(Форма.СведенияОЗаявкеСостояние) <> Неопределено);

Обработано = Новый Массив;
Для Каждого ИмяРеквизита Из МассивИмен Цикл
УстановитьУсловноеОформлениеРеквизита(Форма, Обработано, СокрЛП(ИмяРеквизита));
КонецЦикла;

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

// как использовать
УстановитьУсловноеОформление(ЭтотОбъект, "ИмяРеквизита");

Преимущества: по каждому элементу формы можно определить логику его настройки, при этом не вникая во все зависимости.
Недостатки: большое количество кода, если настраиваемых элементов формы много.
Итог: по последним наблюдениям, ошибок с настройкой вида форм стало значительно меньше. Программист, не владеющий достаточно логикой работы формы, тем не менее способен внести изменения согласно заданию аналитической службы. При этом, даже не программист способен понять каким образом выполнена настройка отдельно взятого элемента формы.

Проверка изменений значений реквизитов формы

Преамбула. Регулярно при изменении значений реквизитов формы необходимо выполнять те или иные действия. Часто приходится с клиента вызывать сервер. В таком случае, необходимо минимизировать вызовы. Да и вообще иногда надо проверить какое значение имел реквизит, чтобы выдать предупреждение о выборе некорретного значения и вернуть старое значение. Обычно для таких целей создают реквизиты формы куда записывают текущее значение и «ПриИзменении» проверяют выбранное значение и текущее, выполняют обработку или возвращают старое значение. Меня лично это крайне напрягает, более того когда надо проверку повесть на множество реквизитов, тогда набор реквизитов формы становится невыносим большим. А чем больше реквизитов, тем больше вероятность ошибки в будущем.

В итоге нами был реализован ряд методов, которые располагаются в форме + методы для общих модулей. При инициализации формы программа проверяет наличие служебного реквизита, создает его и хранит в нем текущие значения реквизитов, указанных пользователем. При изменении в форме, вызывается небольшой набор кода: проверка выбранного значения и возврат если значение не изменилось; обработка каких либо действий; вызов повторного копирования данных формы.

В примере приведен только код для формы, все общие модули в прикрепленном файле.

// Описание использования
//
//    1. Разместить команды из процедуры ИнициализацияФормы в соответствующую по смыслу процедуру формы (или вызвать метод из ПриСозданииНаСервере, ПриЧтенииНаСервере)
//    2. Добавить все сохраняемые реквизиты в процедуре СнятьКопиюОбъекта
//    3. Назначить обработчики ПриИзменении на сохраняемые реквизиты (см. ИмяРеквизитаПриИзменении)
//

&НаСервере
Процедура ИнициализацияФормы()

РаботаСФормами.СоздатьРеквизитХраненияКопииДанныхФормы(ЭтаФорма);

// прочие обработки
<?>

СнятьКопиюОбъекта(ЭтаФорма);

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

&НаКлиенте
Процедура ИмяРеквизитаПриИзменении(Элемент)
Если СравнитьСКопиейОбъекта(ЭтаФорма, "Объект.ИмяРеквизита") Тогда
Возврат;
КонецЕсли;

// прочие обработки

СнятьКопиюОбъекта(ЭтаФорма);
КонецПроцедуры

#Область СлужебныеПроцедурыИФункции_КопияДанныхФормы

&НаКлиентеНаСервереБезКонтекста
Процедура СнятьКопиюОбъекта(Форма)
МассивРеквизитов = Новый Массив;
МассивРеквизитов.Добавить("Объект.Дата");
МассивРеквизитов.Добавить("Объект.Организация");
МассивРеквизитов.Добавить("ИмяРеквизита");

РаботаСФормамиКлиентСервер.СкопироватьДанныеФормы(Форма, МассивРеквизитов);
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция СравнитьСКопиейОбъекта(Форма, ИмяРеквизита)
Возврат РаботаСФормамиКлиентСервер.СравнитьСКопиейДанныхФормы(Форма, ИмяРеквизита);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЗначениеИзКопииОбъекта(Форма, ИмяРеквизита)
Возврат РаботаСФормамиКлиентСервер.ЗначениеИзКопииДанныхФормы(Форма, ИмяРеквизита);
КонецФункции

#КонецОбласти

Преимущества: нет необходимости создавать множество реквизитов в форме для хранения старых данных; возможность хранить копии значений не только реквизитов «Объекта» (основного реквизита), но и реквизитов формы; возможность расширения механизма под нужды программиста.
Недостатки: отсутствие возможности хранить значения реквизитов таб. частей; дублирование кода в форме.
Итог: легко проверить изменился ли реквизит; легко вернуть значение назад.

Послесловие

На самом деле оригинального и сверхумного ничего в представленном коде нет, да и быть не может. Что придумал один человек, второй всегда повторит. Я с удовольствием выслушаю критику и внесу изменения. Надеюсь, код подкажется полезным кому-либо. И кстати, может уже кто-то трудится над созданием репозитория с «полезным» кодом? Используйте на здоровье, модифицируйте и т.д.
Версионирование данных инструментов на текущий момент не ведется. Пока не вижу смысла. Жизнь покажет.
На картинке изображен детский набор инструментов «Fisher-Price Disney’s Handy Manny Talking Tool Box». Вдруг кому интересно )))).

Содержание:

1.     Добавление реквизитов на 1С управляемые формы

2.     Добавить элементы на форму

3.     Установка событий элементам формы

При адаптации типовых конфигураций 1С часто приходится изменять в 1С 8 управляемые формы. Такие адаптации сложно потом поддерживать при обновлении. Такие изменения приходится вносить вручную заново, перепроверять корректность изменений в каждом обновлении. И если таких изменений множество, то каждое обновление может представлять серьезные трудозатраты. Есть несколько решений, которые позволяют упростить поддержку и обновление измененных систем 1С. Одно из них – это программное изменение форм.

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

Чтобы упростить разработку изменений формы, можно воспользоваться небольшой хитростью. Все изменения можно сначала внести на форму через конфигурирование и отладить доработку формы. После преобразовать программные изменения в код.

Изменения, которые нужны в форме изначально, стоит вносить в процедуре «ПриСозданииНаСервере». Для внесения изменений лучше сделать отдельную процедуру (например, «ДополнитьФормуПрограммно») и вызывать ее в штатной процедуре «ПриСозданииНаСервере», тогда изменение типовой формы 1С будет выглядеть одной строчкой:

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

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

1.          Добавление реквизитов на 1С управляемые формы

Если в ходе разработки изменилась типовая структура объекта, то добавлять новые реквизиты на форму нет необходимости. Эти реквизиты будут доступны по пути «Объект.НовыйРеквизит».

Но иногда нужно добавить реквизит формы. Например, «Статус документа», который будет заполняться из специального регистра при открытии формы. Добавить новые реквизиты можно, открыв в 1С табличный документ, управляемая форма изменяется через команду ИзменитьРеквизиты(«ДобавляемыеРеквизиты», «УдаляемыеРеквизиты»).

«ДобавляемыеРеквизиты» и «УдаляемыеРеквизиты» – это массивы с элементами типа «РеквизитФормы». Тут все просто – «Добавляемые» добавляются, «Удаляемые» – удаляются.

Функция РеквизитФормы («ИмяРеквизита», «ТипРеквизита», «Путь», «Заголовок») создает объект типа «РеквизитФормы».

Тут важно понимать, что «ИмяРеквизита» содержит имя без точек. То есть имя без пути реквизита. Если нужно добавить реквизит, например, табличной части объекта, то уже в реквизите «Путь» указать путь к ТЧ реквизита – «Объект.Товары». «ТипРеквизита» задается через объект «ОписаниеТипов».

В примере ниже я добавил два реквизита «ЭтоСборка» для табличной части «Товары» у объекта и «СтатусОбработки» на форму документа. 

2.          Добавить элементы на форму

После программного добавления реквизитов на форму нужно добавить элементы на форму или изменить свойства текущих.

Для добавления новых элементов на форму есть два метода:

­-Элементы.Добавить(«ИмяЭлемента», «ТипЭлемента», «Родитель»).

-Элементы.Вставить(«ИмяЭлемента», «ТипЭлемента», «Родитель», «Элемент»).

«ИмяЭлемента» должно быть уникальным в рамках элементов формы. Лучше добавить какой-то префикс, чтобы не возникло пересечений с типовыми элементами формы.

«ТипЭлемента» имеет не так уж много вариантов. Это «ПолеФормы», «ГруппаФормы», «ДекорацияФормы», «КнопкаФормы» и «ТаблицаФормы». Все остальные свойства назначаются через «Вид» создаваемого элемента. Например, поле с типом булево лучше сделать «флажком», установив вид элементу «ВидПоляФормы.ПолеФлажка».

В свойстве «Родитель» нужно указать группу или таблицу формы, в которую будет входить новый элемент. Также можно добавить элемент непосредственно на управляемую форму без подчинения другим элементам.

Для функции вставить дополнительно указывается «Элемент», перед которым будет вставлен новый создаваемый элемент формы.

На примере ниже я добавил статус обработку в форму шапки и поле флажка в табличную часть товары перед единицей измерения. 

3.          Установка событий элементам формы

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

Для установки событий элементам нужно использовать процедуру УстановитьДействие («ИмяСобытия», «Действие»).

«ИмяСобытия» — имя события, которое нужно отработать. Например, «ПриИзменении», «Очистка», «ОбработкаВыбора» и т.п.

«Действие» — процедура отработки события. Самое главное процедура должна содержать параметры необходимые для выполняемого события. Например, процедура «ПриИзменении» должна иметь параметр «Элемент».

Также программно можно задавать прочие доступные свойства новых элементов формы. Например, установить видимость кнопки очистки:

НовыйЭлемент.КнопкаОчистки = Истина;

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

Код для копирования:

&НаСервере

Процедура КЛ_ДополнитьФормуПрограммно()

МассивРеквизитовФормы = Новый Массив;

//Новый реквизит Товары.КЛ_ЭтоСборка

НовыйРеквизитФормы = Новый РеквизитФормы(«КЛ_ЭтоСборка»,

           Новый ОписаниеТипов(«Булево»)

           ,»Объект.Товары»

           ,»Это сборка»);

МассивРеквизитовФормы.Добавить(НовыйРеквизитФормы);

//Новый реквизит КЛ_СтатусОбработки

НовыйРеквизитФормы = Новый РеквизитФормы(«КЛ_СтатусОбработки»,

           Новый ОписаниеТипов(«ПеречислениеСсылка.СтатусыДокументовРеализации»)

           ,

           ,»Статус обработки»);

МассивРеквизитовФормы.Добавить(НовыйРеквизитФормы);

ИзменитьРеквизиты(МассивРеквизитовФормы);

НовыйЭлемент = Элементы.Добавить(«КЛ_СтатусОбработки», Тип(«ПолеФормы»), Элементы.ГруппаШапкаЛевая);

НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;

НовыйЭлемент.КнопкаОчистки = Истина;

НовыйЭлемент.УстановитьДействие(«ПриИзменении»,»КЛ_ПриИзмененииСтатусаОбработки»);

НовыйЭлемент = Элементы.Вставить(«КЛ_ЭтоСборка», Тип(«ПолеФормы»),Элементы.Товары,Элементы.ТоварыКоличество);

НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;

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

Специалист компании ООО «Кодерлайн»

Кирилл Карцев.

Понравилась статья? Поделить с друзьями:
  • Албо альфа банк бизнес онлайн телефон поддержки
  • 1с специалист решение задач по бизнес процессам
  • Ак барс банк офисы в казани адреса время работы
  • Алброс судоходная компания вакансии плавсостава
  • 2 боткинский проезд 5 к 28 как проехать в метро