Установить модифицированность объекта 1с

Обновлено: 05.07.2024

Одним из требований для прохождения аудита расширения в модели сервиса является программная модификация управляемых форм без заимствования самой формы в расширение.

Мы рассмотрим основные составляющие этой задачи: добавление реквизитов, добавление элементов формы и назначение обработчиков событий элементов формы.

Добавление реквизитов

Для добавления реквизитов используется метод объекта ФормаКлиентскогоПриложения

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

Переменная ДобавляемыеРеквизиты является массивом объектов типа РеквизитФормы .

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

Процедуру ИзменитьРеквизиты логично вызывать из обработчика ПриСозданииНаСервере , но т.к. мы не заимствуем форму в расширение, то следует найти другую точку входа. Для конфигураций УТ 11, КА 2 и ERP 2 существует типовой механизм упрощенного изменения конфигураций. Нас интересует модуль МодификацияКонфигурацииПереопределяемый , в состав которого входит процедура

Данную процедуру можно заимствовать в расширение, добавить проверку имени формы и вставить код изменения реквизитов:

Для остальных конфигураций придется переопределять другие процедуры. Например

Использование той или иной процедуры следует проверить в модуле редактируемой формы.

Изменение элементов формы

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

Для добавления нового элемента формы требуется передать в функцию Добавить данной коллекции имя элемента, его тип и родителя (при необходимости). Например:

По аналогии с добавлением реквизитов, данный код можно выполнять в функциях МодификацияКонфигурацииПереопределяемый.ПриСозданииНаСервере (УТ, КА, ERP) , ПодключаемыеКоманды.ПриСозданииНаСервере или ВерсионированиеОбъектов.ПриСозданииНаСервере .

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

Обработка событий формы

Выполнить код по событию элемента формы можно двумя способами:

  • Создать команду, указать для этой команды имя обработчика события и назначить эту команду элементу формы
  • Выполнить метод УстановитьДействие элемента формы, чтобы указать имя обработчика события в модуле формы

Оба метода предполагают наличие в модуле формы процедуры с сигнатурой, соответствующей обработчику события. Для первого способа в модуле формы должна быть клиентская процедура, принимающая единственный аргумент - Команда. Для второго - всё зависит от события, для которого выполняется обработчик. Так, например, для события ПриИзменении элемента формы с типом ПолеВвода будет требоваться процедура, принимающая единственный аргумент - ЭлементФормы . А для события ПередНачаломДобавления таблицы формы - целых 6 аргументов ( ЭлементФормы , Отказ , Копирование , Родитель , ЭтоГруппа , Параметр ). Поэтому для некоторых событий попросту невозможно подобрать соответствующие клиентские методы в модуле формы и заимствования формы в расширение не избежать.

Для самых простых случаев (команда или событие без параметров) можно использовать следующие комбинации обработчиков и переопределяемых процедур:

  • обработчик Подключаемый_ВыполнитьПереопределяемуюКоманду с переопределением процедуры МодификацияКонфигурацииКлиентПереопределяемый.ВыполнитьПереопределяемуюКоманду для УТ, КА и ERP;
  • обработчик Подключаемый_ВыполнитьКоманду с переопределением процедуры ПодключаемыеКомандыКлиент.ВыполнитьКоманду

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

Либо вариант с использованием команд:

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

Полезные советы

Работа с динамическими списками

Довольно частой задачей является модификация в расширении текста запроса динамического списка. Многие разработчики просто копируют текст запроса из конфигуратора, редактируют его и заменяют стандартный в свойстве ТекстЗапроса объекта Динамический список .

Для небольших изменений гораздо лучше воспользоваться объектом СхемаЗапроса , появившемся в версии платформы 8.3.5. Он позволит всегда иметь актуальный текст запроса, если он поменяется при обновлении конфигурации.

Переопределение открываемой формы

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

Для этого следует реализовать новую форму (не заимствовать её, а написать с нуля) и в модуле менеджера переопределить процедуру ОбработкаПолученияФормы .

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

Признак модифицированности у формы

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

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

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

  • Измененный объект, являющийся значением основного реквизита формы, был успешно записан.
  • При открытии формы после события ПередОткрытием() формы, но перед событием ПриОткрытии() .

Флаг модифицированности сбрасывается после события ПередОткрытием() формы, но перед событием ПриОткрытии() , так как при открытии формы нового объекта или уже записанного пользователь ожидает, что состояние данных не являются измененными. Если для нового объекта нужно дополнительная его инициализация перед редактированием в форме, то ее можно произвести в обработчике события формы ПередОткрытием() . В этом случае признак модифицированности не будет взведен у формы, как того и ожидает пользователь. Если же нужно внести исправления в объект при открытии формы, которые должны отразиться на признаке модифицированности, то это следует произвести в обработчике события формы ПриОткрытии() .

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

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

Если конфигурация типовая, то, наверное, самый простой способ решения такой задачи – создать внешнюю обработку вида "Заполнение объекта".

Заполнение формы объекта с помощью внешней обработки

Строка с соответствующим параметром в модуле обработки:

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

  • ВызовСерверногоМетода – обработчик команды располагается в модуле обработки;
  • ВызовКлиентскогоМетода – обработчик команды располагается в модуле формы обработки;
  • ЗаполнениеФормы – обработчик команды располагается в модуле обработки и позволяет работать с данными формы. Также позволяет вызвать серверную процедуру из модуля формы объекта. При этом можно заполнить форму не записывая объект.

Возможность заполнить форму не записывая объект – это то, что нужно. Ведь пользователь скорее всего ожидает, что по нажатию кнопки форма заполнится, а записываться будет позднее, после проверки результата заполнения. Поэтому выбираем тип команды – ЗаполнениеФормы.

В конечном итоге код в модуле обработки будет выглядеть примерно так:

В общем счёте задача решена. Однако, у такого способа есть небольшой недостаток – команда на форме размещается в определённом месте, а не там, где мы хотим её разместить. К примеру, на форме уже есть группа команд, включающая в себя команды заполнения, и мы хотели бы видеть новую команду в этой группе, но при подключении обработки команда на форме будет расположена отдельно от группы.

В связи с этим можно реализовать другой способ: добавить команду непосредственно в форму объекта – либо в основной конфигурации, либо в расширении – а обработчик команды организовать в модуле формы.

Заполнение формы объекта посредством обработчика команды в модуле формы

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

Над серверной процедурой нужно подумать. В ней у нас будет объект формы с типом "ДанныеФормыСтуктура". Что-либо менять или заполнять в этом объекте не получится, возникнет ошибка "Объект недоступен для изменения".

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

Будет лучше, если данные добавятся без записи, и мы можем это сделать с помощью метода РеквизитФормыВЗначение . Этот метод преобразует реквизит формы в объект прикладного типа, и вот этот объект прикладного типа мы можем заполнить, а затем, уже заполненный, преобразовать обратно с помощью метода ЗначениеВРеквизитФормы . Выглядеть это будет примерно так:

При открытии формы уже в ПриСозданииНаСервере объект модифицирован. Где до этого он может модифицироваться?

там в УФ с формами вообще все плохо в плане последовательности событий для привыкших к обычным

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

Сверил программно каждый реквизит с БД - никаких изменений, а Модифицированность = истина

а если поменяли на тоже самое? я давным давно любил автоименования элементов в ПриОткрытии загонять типа ФИО = Ф+" "+И" "+О

А ничего страшного, что Модифицированность есть только у , которых в УФ не наблюдается, если их только самому не создавать?

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

У Объекта не бывает модифицированности, в отличие от Формы Объекта У него есть только новизна, т.е. записан он в базу или нет.

а что такое модифицированность объекта в базе данных? про время модификации = времени записи ничего не говорю

Так как я не знаю, что такое "объект в базе данных", то ничего ответить не могу. Объект - он в памяти живет, а не в БД.

да согласен, неправильно выразился в если считать что объект это то что считано в память из бд то да есть модифицированность СправочникОбъект.<Имя справочника> (CatalogObject.<Имя справочника>) Модифицированность (Modified) Синтаксис: Модифицированность Возвращаемое значение: Тип: Булево. Истина - объект изменен; Ложь - в противном случае. Описание: Определяет, был ли изменен объект после считывания из базы данных. Доступность: Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер). Примечание: Метод не позволяет определить, был ли изменен объект другими пользователями.

Читайте также: