Методика обновления формы объекта данных при изменении объекта

03.04.23

Разработка - Инструментарий разработчика

В формах объектов данных часто встречаются элементы, косвенно связанные с объектом. Логику обновления этих элементов при изменении объекта обычно вызывают из обработчиков ПриСозданнииНаСервере и ПриОткрытии, забывая про наличие других способов изменения объекта. В статье предложена методика для обычных и управляемых форм, учитывающая все способы.

Скачать файлы

Наименование Файл Версия Размер
Методика обновления формы объекта данных при изменении данных 8.3
.dt 88,76Kb
2
.dt 88,76Kb 2 Скачать

Актуально для платформы 1С 8.2-8.3.17 (выше не проверял)

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

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

Также пусть в объекте есть реквизит типа ХранилищеЗначения, тип которого мы также хотим отображать в форме. Добавляем в форму реквизит ТипЗначенияВХранилище типа Строка и отображаем его в одноименное нередактируемое поле.

  

В каких же ситуациях нам потребуется обновлять эти косвенно связанные с объектом реквизиты?

Разумеется это нужно вызывать в событии ПриИзменении поля Наименование. А вот дальше многие ограничиваются только вызовом в ПриСозданииНаСервере[упр] и ПриОткрытии[обыч]. Тем самым они не учитывют

  1. Возможность выполнения пользователем команды "Перечитать" формы.
       
    В управляемой форме она всегда вызывает событие ПриЧтенииНаСервере.
    В обычной форме она вызывает событие ПриИзмененииДанных только в модифицированном состоянии формы. В немодифицированном состоянии команда делает ничего.
  2. Возможность изменения объекта в событии ПередЗаписью объекта.
    Форма отправляет на запись одно состояние объекта, а после выполнения записи получает другое.

 

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

Случай 1

Объект данных, отображаемый в форме, мог быть изменен в БД с момента его загрузки в форму. Типичные способы таких изменений

  1. в другой форме в этом же клиентском приложении
  2. этим же пользователем в другом клиентском приложении в этой же базе
  3. другим пользователем
  4. фоновым процессом

Тогда при попытке начать изменение любого поля формы, напрямую связанного с данными (флаг "Изменяет данные"), пользователь увидит предупреждение "Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)!"

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

Случай 2

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

 

В каких событиях обновлять форму?

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

Управляемая форма
  1. ПриСозданииНаСервере - вызываем в конце тела обработчика, но имеем доступ только к объекту в реквизите формы
  2. ПриЧтенииНаСервере - имеем доступ ко всем данным объекта
  3. ПослеЗаписиНаСервере - имеем доступ ко всем данным объекта и вызываем потому, что объект мог измениться в событии ПередЗаписью объекта
Обычная форма
  1. ПриИзмененииДанных - событие вызывается и для нового и для существующего объекта
  2. ПослеЗаписи - вызываем потому,  что объект мог измениться в событии ПередЗаписью объекта

 

Управляемая форма

В управляемой форме при открытии существующего объекта выполняются два обработчика: сначала ПриЧтенииНаСервере и затем ПриСозданииНаСервере. Поэтому процедура ПриСозданииПриЧтенииНаСервере будет вызываться 2 раза подряд и нужно не задублировать выполнение логики обновления формы. Элементы формы могут зависеть как от данных объекта, доступных через реквизит формы, так и от недоступных через него (реквизиты типа ХранилищеЗначений), которые доступны только одном из них (ПриЧтенииНаСервере). Поэтому в процедуре ПриСозданииПриЧтенииНаСервере надо предусмотреть оба вызова таким образом, чтобы при создании формы существующего объекта при ее вызове из ПриЧтенииНаСервере выполнилась только логика работы с хранилищами значений, а при последующем вызове из ПриСозданииНаСервере выполнилась только логика, зависящая от остальных данных объекта. При этом ее вызов из уже открытой формы (из ПриЧтенииНаСервере и ПослеЗаписиНаСервере) должен выполнять все действия. Для этого создадим в общем модуле функцию ЭтоВызовПослеОткрытияФормы, где будем проверять наличие параметра ТолькоПросмотр у формы. Тогда процедура ПриСозданииПриЧтенииНаСервере будет выглядеть так

Процедура ПриСозданииПриЧтенииНаСервере(ТекущийОбъект = Неопределено)
	
	Если ТекущийОбъект <> Неопределено Тогда
		// Здесь выполняем только те действия, которые невозможно выполнить на основании объекта в реквизите формы
		
		// Пример
		ЭтаФорма.ТипЗначенияВХранилище = ТипЗнч(ТекущийОбъект.Реквизит1.Получить());
		
		Если Не ФормыСервер.ЭтоВызовПослеОткрытияФормы(ЭтаФорма) Тогда 
			Возврат;
		КонецЕсли; 
	КонецЕсли; 

        // Здесь выполняем только те действия, которые возможно выполнить на основании объекта в реквизите формы
	
        // Пример
	ЭтаФорма.ДлинаСтроки = СтрДлина(Объект.Наименование);
	Сообщить("В форму загружен объект данных");
	
КонецПроцедуры

/////////////////////////
// Общий модуль ФормыСервер

Функция ЭтоВызовПослеОткрытияФормы(ЭтаФорма) Экспорт
	
	Возврат Не ЭтаФорма.Параметры.Свойство("ТолькоПросмотр");

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

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

Пример модуля управляемой формы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	// Инициализация формы
	// ...
	
	ПриСозданииПриЧтенииНаСервере();
	
КонецПроцедуры

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
	
	ПриСозданииПриЧтенииНаСервере(ТекущийОбъект);
	
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	
	ПриСозданииПриЧтенииНаСервере(ТекущийОбъект);
	
КонецПроцедуры

&НаСервере
Процедура ПриСозданииПриЧтенииНаСервере(ТекущийОбъект = Неопределено)
	
	Если ТекущийОбъект <> Неопределено Тогда
		// Здесь выполняем только те действия, которые невозможно выполнить на основании объекта в реквизите формы 
		
		// Пример
		ЭтаФорма.ТипЗначенияВХранилище = ТипЗнч(ТекущийОбъект.Реквизит1.Получить());
		
		Если Не ФормыСервер.ЭтоВызовПослеОткрытияФормы(ЭтаФорма) Тогда 
			Возврат;
		КонецЕсли; 
	КонецЕсли; 

        // Здесь выполняем только те действия, которые возможно выполнить на основании объекта в реквизите формы
	НастроитьЭлементыФормы(ЭтаФорма);
	
	// Пример
	Сообщить("В форму загружен объект данных");
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура НастроитьЭлементыФормы(ЭтаФорма)

	Объект = ЭтаФорма.Объект;
	Элементы = ЭтаФорма.Элементы;
	
	// Пример
	ЭтаФорма.ДлинаСтроки = СтрДлина(Объект.Наименование);
	
КонецПроцедуры // НастроитьЭлементыФормы()

&НаКлиенте
Процедура НаименованиеПриИзменении(Элемент)
	
	НастроитьЭлементыФормы(ЭтаФорма);
	
КонецПроцедуры


/////////////////////////
// Общий модуль ФормыСервер

Функция ЭтоВызовПослеОткрытияФормы(ЭтаФорма) Экспорт
	
	Возврат Не ЭтаФорма.Параметры.Свойство("ТолькоПросмотр");

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

 

Обычная форма

В обычной форме благодаря наличию события ПриИзмененииДанных логику обновления формы можно помещать прямо в его обработчик. Здесь также стоит вынести всю легкую логику в процедуру НастроитьЭлементыФормы по аналогии с управляемой формой.

Пример модуля обычной формы

Процедура ПриИзмененииДанных()
	
	// Пример
	ЭтаФорма.ТипЗначенияВХранилище = ТипЗнч(ЭтотОбъект.Реквизит1.Получить());
	
	НастроитьЭлементыФормы();
	
	// Пример
	Сообщить("В форму загружен объект данных");
	
КонецПроцедуры

Процедура ПослеЗаписи()
	
	ПриИзмененииДанных();
	
КонецПроцедуры


Процедура НастроитьЭлементыФормы()
	
	// Пример
	ЭтаФорма.ДлинаСтроки = СтрДлина(ЭтотОбъект.Наименование);
	
КонецПроцедуры

Процедура НаименованиеПриИзменении(Элемент)
	
	НастроитьЭлементыФормы();
	
КонецПроцедуры

Применяю данную методику уже много лет.

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

ПриСозданииПриЧтенииНаСервере ПриЧтенииНаСервере ПриИзмененииДанных

См. также

Infostart Toolkit: Инструменты разработчика 1С 8.3 на управляемых формах

Инструментарий разработчика Роли и права Запросы СКД Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Конфигурации 1cv8 Платные (руб)

Набор инструментов программиста и специалиста 1С для всех конфигураций на управляемых формах. В состав входят инструменты: Консоль запросов, Консоль СКД, Консоль кода, Редактор объекта, Анализ прав доступа, Метаданные, Поиск ссылок, Сравнение объектов, Все функции, Подписки на события и др. Редактор запросов и кода с раскраской и контекстной подсказкой. Доработанный конструктор запросов тонкого клиента. Продукт хорошо оптимизирован и обладает самым широким функционалом среди всех инструментов, представленных на рынке.

13000 руб.

02.09.2020    119974    656    389    

701

Infostart PrintWizard

Пакетная печать Печатные формы Инструментарий разработчика Платформа 1С v8.3 Запросы 1С:Зарплата и кадры бюджетного учреждения 1С:Конвертация данных 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Платные (руб)

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

18000 руб.

06.10.2023    7020    20    6    

37

Infostart УДиФ: Управление данными и формами

Инструменты администратора БД Инструментарий разработчика Роли и права Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

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

10000 руб.

10.11.2023    3256    10    1    

31

SALE! 30%

PowerTools

Инструментарий разработчика Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

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

3600 2520 руб.

14.01.2013    177361    1071    0    

846

Многопоточность. Универсальный «Менеджер потоков» 2.1

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

Восстановление партий или взаиморасчетов, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

5000 руб.

07.02.2018    99208    239    97    

296

[ЕХТ] Фреймворк для Расширений 1С

Инструментарий разработчика Платформа 1С v8.3 Управляемые формы Платные (руб)

"Фреймворк для Расширений 1С" это универсальное и многофункциональное решение, упрощающее разработку и поддержку создаваемых Расширений. Поставляется в виде комплекта из нескольких Расширений с открытым исходным кодом. Работает в любых Конфигурациях в режиме Управляемого приложения с режимом совместимости 8.3.12 и выше без необходимости внесения изменений в Конфигурацию.

3000 руб.

27.08.2019    17922    6    8    

38

1С HTML Шаблоны / HTML Templates

Инструментарий разработчика Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

Быстрая и удобная обработка для работы с шаблонами HTML. Позволяет легко и быстро формировать код HTML.

2040 руб.

27.12.2017    27951    3    10    

14

Выполнение произвольного кода или запроса с параметрами через Web-сервис (замена COM-подключений)

Инструментарий разработчика Обмен между базами 1C Платформа 1С v8.3 Платные (руб)

В процессе работы в 1С часто возникает потребность получить данные из другой базы.  Обычно это делается через COM-соединение, и время выполнения запроса при этом оставляет желать лучшего. В данной публикации представлено универсальное решение, позволяющее практически моментально выполнить произвольный код или запрос с параметрами в другой информационной базе через Web-сервис.

2400 руб.

24.09.2019    23494    15    15    

31
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. MVK80 09.03.20 12:18 Сейчас в теме
(0), а зачем использовать ЭтаФорма. в управляемых формах?
2. tormozit 7133 09.03.20 12:48 Сейчас в теме
(1) Затем, что методика приведена для версий платформы 8.2-8.3.17. Свойство ЭтаФорма совместимо со всеми указанными версиями платформы.
8. Алексей Воробьев 291 10.03.20 07:33 Сейчас в теме
(1) Стараюсь всегда использовать ЭтаФорма в программном коде при обращении к реквизитам формы и даже к элементам формы (ЭтаФорма.Элементы...). Не уверен, насколько это правильно с точки зрения стандартов разработки, но как по мне - это повышает читабельность кода в плане визуального разделения реквизитов формы и обычных переменных...
user1835472; idjumatov; kild; +3 Ответить
10. tormozit 7133 10.03.20 10:37 Сейчас в теме
(8) Да. Имя "ЭтотОбъект" имеет бОльшую двусмысленность, чем "ЭтаФорма". Тем более что в обычных формах обычно присутствовало свойство ЭтотОбъект и имело другой смысл.
12. sa1m0nn 28 14.03.20 10:49 Сейчас в теме
(1)
Если реквизиты формы добавлены программно (а в типовых формах на внедрении это отличный прием на длительную поддержку), то прямое обращение к программносозданному реквизиту без ЭтаФорма не даст модулю формы скомпилироваться.
13. MVK80 14.03.20 13:41 Сейчас в теме
(12), это понятно. Только надо использовать ЭтотОбъект вместо ЭтаФорма, если вы не делаете продукт как Сергей с поддержкой платформы от 8.2 Но где вы увидели в данной статье программно добавленные реквизиты?

PS. И скорей всего модуль скомпилируется, просто ваш реквизит не будет изменен, потому что то, что вы напишите без ЭтаФорма. или ЭтотОбъект. будет простой переменной, которой и присвоится значение. Сам давно использую программное изменение форм, но мой вопрос был не об этом, а о том, что в управляемых формах(если не оглядываться на режим совместимости) можно напрямую к реквизитам формы обращаться, если они интерактивно добавлены на форму, как, например, в этой статье.
3. par_62 09.03.20 16:34 Сейчас в теме
А что тут особенного? В литературе по 1с описаны события формы,описаны действия платформы для объектов при этих событиях.
По моему,вы зря потратили время на статью. Можно было просто дать ссылку на книгу или ресурс
4. tormozit 7133 09.03.20 16:55 Сейчас в теме
(3) Особенное здесь в том, что я описал простую и универсальную методику корректного обновления формы при изменении объекта. Если что то похожее уже публиковалось, то приведите ссылки. Поделитесь своим пример построения аналогичной логики.
RomanKod; mvxyz; +2 Ответить
5. kolya_tlt 85 09.03.20 21:36 Сейчас в теме
Когда же кнопку Перечитать упразднят... ее смысл конечному пользователю крайне сложно обьяснить.
6. tormozit 7133 09.03.20 21:57 Сейчас в теме
(5) Ее не упразднят. Она полезна в случаях

Случай 1.
Объект данных отображаемый в форме мог быть изменен в БД с момента его загрузки в форму. Типичные способы таких изменений
1. в другой форме в этом же клиентском приложении
2. этим же пользователем в другом клиентском приложении в этой же базе
3. другим пользователем
4. фоновым процессом
Тогда при попытке начать изменение любого поля формы, напрямую связанному с данными (флаг "Изменяет данные"), пользователь увидит предупреждение "Операция не может быть выполнена из-за несоответствия версии или отсутствия записи базы данных (возможно, запись была изменена или удалена)!" И тогда, чтобы получить возможность редактировать объект, нужно будет его перечитать либо переоткрыть форму.

Случай 2.
Пользователь изменил данные в форме и решил отменить сделанные изменения, но продолжить редактировать объект от его текущего состояния в БД.

Добавил эту информацию в статью.
Прикрепленные файлы:
Риник; IgorS; kolya_tlt; Алексей Воробьев; +4 Ответить
7. Алексей Воробьев 291 10.03.20 07:28 Сейчас в теме
(6) Да, все так. Но обычно для среднестатистического пользователя существование кнопки "Перечитать" и ее назначение - секрет.

Варианты "доведения до сведения": отразить в инструкции (а кто ее читает?), подсказать сообщением или предупреждением, что именно нужно нажать (а на каком событии?).
Ну и самый правильный вариант: повышать уровень среднестатистического пользователя :-)
11. ixijixi 1761 12.03.20 12:18 Сейчас в теме
(7) У меня юзеры удивляются, почему при нажатии кнопки "Перечитать" форма не заполняется "правильными" значениями) Например, почему химсостав блюда не рассчитывается по его спецификации
9. Cyberhawk 135 10.03.20 10:29 Сейчас в теме
ее вызов из уже открытой формы (из ПриЧтенииНаСервере и ПослеЗаписиНаСервере) должен выполнять все действия
В таком случае - если действия с формой включают программное добавление реквизитов и элементов управления на форму - придется в коде проверять, что реквизит / элемент уже не добавлен ранее.
14. AneJIbcuH 37 23.12.20 11:04 Сейчас в теме
Подскажите, пожалуйста, такой момент. Имеем обычную форму, на форме кнопка, которая выгружает данные на устройство (ТСД)
Далее приходят измененные данные (срабатывает фоновое задание, которое модифицирует объект).
Всё время форма не закрывалась. Как в этом случае перечитать данные (чтобы на форме обновились, не переоткрывая форму) ?
Как быть, если несколько форм открыли (несколько разных документов одного вида) и потом их скопом модифицировали, как все обновить, не переоткрывая каждый?
15. acsent 1198 25.08.21 15:19 Сейчас в теме
Зачем только то, что вызывается в ПриСоздании, но не в ПриЧтении пихать в процедуру ПриСозданииЧтении?
16. tormozit 7133 25.08.21 16:11 Сейчас в теме
(15) Не понял. Перефразируй.
17. tormozit 7133 30.08.22 12:20 Сейчас в теме
В целях ускорения можно отключать тяжелые операции чтения/обновления связанных данных при вызове этого обработчика из ПослеЗаписи, если есть четкое понимание, что данные там не могли измениться.
18. Fynjy2 30.01.24 15:37 Сейчас в теме
ПриСозданииПриЧтенииНаСервере

ПриЧтенииСозданииНаСервере
19. Fynjy2 30.01.24 15:40 Сейчас в теме
ПриЧтенииСозданииНаСервере()
Оставьте свое сообщение