1с скопировать элемент формы программно

Обновлено: 08.07.2024

Введение в управляемая форма 1С реквизиты элементы команды

Рекомендуется модифицировать управляемые формы типового решения 1С программно для удобного будущего обновления и исключения конфликтов, а также для удобной работы с изменениями и надежности при использовании механизма расширений.
В некоторых типовых конфигурациях 1С (ЕРП 2, УТ 11) используется механизм упрощенного изменения конфигурации. Статьи о типовом механизме можно найти в разделе полезных ссылок. Данный механизм используется в БСП, и его необходимо знать при модификации типовых конфигураций.
При добавлении элементов на форму программно можно отредактировать практически любое свойство из панель свойств, которое можно установить вручную в конфигураторе.
Также все описанные в текущем разделе процедуры и функции находятся во внешней обработке УпрФормы.

Программное переопределение обработчиков событий формы и элементов формы

В теле модуля формы:

А в новой процедуре нужно добавить вызов основной, если такая процедура есть.

Аналогично можно поступить и с обработчиками элементов формы:

Программное создание групп формы.

Доступные виды групп формы:


Программное добавление команды на форму.

Удалить команду можно при помощи метода коллекции формы команд: Команды.Удалить(<Команда>). Удалять можно только те команды, которые были созданы программно.

Программное создание декораций форм.

Программное добавление реквизита на форму.

Добавлять новые реквизиты в управляемую форму и удалять необходимо с помощью метода ИзменитьРеквизиты(), куда в параметры передается массив добавляемых реквизитов и массив удаляемых. Удалять при этом можно только те реквизиты, которые были созданы программно.

Вывод реквизитов на форму.

Вызов процедур при создании на сервере 1С

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

Некоторые советы при программном редактировании формы


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

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

Поместить форму во временное хранилище и передать через клиента адрес тоже не получится, потому что она не сериализуется. Единственный выход - сериализовать форму самостоятельно.

Можно предположить, что форму все-таки можно получить из метаданных на сервере и там же обработать, но в синтаксис-помощнике на это написано:

ОбъектМетаданных: Форма (MetadataObject: Form)

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

В форме-приемнике нужно будет прописать процедуру заполнения по переданному описанию:

В обработке для копирования остается только выполнить код:

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

Obj - это объект, который будет хранить копию объекта источника в форме приемника. Использовать объект приемника не получится, т.к. он будет с другим типом (вероятно, ВнешняяОбработкаОбъект).

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

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

С добавлением элементов в структуру тоже есть некоторые нюансы, которые следует учесть:

Во-первых, элементы формы не помещаются во временное хранилище, поэтому их тоже придется сериализовать самостоятельно.

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

В-третьих, в зависимости от типов и видов элементов меняется набор имеющихся свойств.

Для добавления свойства в структуру используется отдельная процедура. Свойств у элементов очень много, и если копировать их через "ОписаниеЭлемента.Вставить()" то имя свойства придется указывать дважды. Процедура просто сокращает объем текста.

И вызывается она как то так:

В зависимости от типа элемента меняется его набор свойств.

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

Заполнение описания в зависимости от типов элементов можно посмотреть в коде в конце статьи. Интеллектуальной нагрузки оно не содержит, только долгую кропотливую работу.

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

Заполнение свойств выделено в отдельную процедуру с той же целью - уменьшить количество текста.

И вызывается она так:

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

И уже в процедуре заполнения делается ветвление в зависимости от типа элемента:

Как и при заполнении описания, заполнение свойств элементов в зависимости от типа интереса не представляет и можно найти в полной версии кода (тремя абзацами ниже).

Для демонстрации кода я сделал две простые обработки. Их краткое описание:

Заполнение из внешней формы. Подключаемая к подсистеме дополнительных отчетов и обработок БСП обработка заполнения. В документах, указанных в списке назначений появляется кнопка "Заполнение->Заполнение из внешней формы (С)". При нажатии на кнопку открывается копия формы со всеми данными, но отключенными событиями. При нажатии на кнопку "Перенести в документ" введенные данные копируются в первоначальную форму. ВАЖНО. Для работы обработки в форме документа должна быть процедура с_ПолучитьОписаниеФормы(), которую можно найти в модуле объекта обработки.

Копирование форм. Демонстрирует работу описанного в статье подхода. Имеет форму источник и форму приемник. Весь код находится в них, изменять конфигурацию не нужно.

.
Неожиданно для нас
Он устроил мастер класс.

Звдание: Впишите недостающую строку.

Если ничего не хочется делать - можно взять эту функцию из конвертации данных

(3) это явно интереснее очередного задротства фиксина.

тут юзеры по одному элементу копируют и такого воротят, что же начнется когда папками копировать будут?
(4) Смысл этой функции рассскажи?
вот первый идиотский вариант:
записать элемент в процедуре ПриКопировании и скопировать подчиненные элементы. Работает криво.
вот второй идиотский вариант:
создать подчиненные элементы, используя сцылку нового. Не работает вообще.

(8) Конфигурация КД сделана на подчиненных справочниках, есть возможность копировать правила с подчиненными и заменять влядельца (есть правила для одной конвертации - такие же будут для другой)

что вы на человека наезжаете? Гений хочет с общественностью поделиться опытом и знаниями, а вы все опохабите.
(13) по кнопочке Ф9! При чем здесь конвертация?
(16) я хочу проверить, есть ли тут не дятлы?
(17) жалко на мисте плюсиков нет. на инфостарте он их любит клянчить.
(13) как скопировать с подчиненными я знаю, там нюанс в другом - когда вызывается ПриКопировании, ссылки еще нет.
что-то у меня никаких идей.
скажем чтобы просто в справочнике можно было интерактивно скопировать несколько элементов а не один, то можно для списка поставить множественное выделение, ну и само собой обработку.
А чтобы скопировать с подчиненными справочниками? Ну просто аккуратно перебрать каждый и создать новые подчинив их скопированному
(18) подменить F9 несложно, главное, чтобы была функция, умеющая правильно копировать. В КД она есть. Я для себя ее брал. Возможно можно написать и более оптимально. Поскольку код функции от 1С известен - можно сравнить, что лучше. У меня обычно не хватает времени. Она точно работает.
(11) Врядли, скорее всего через УстановитьСсылкуНового и в транзакции.
(21) а далее, далее, ПриКопировании у объекта нет ссылки. Допустим юзверь нажал Ф9, потом отказался, а элементы уже созданы. Мозгами шевели, умник, при чем здесь приКопировании
(23) Писать не просят, просят идею. А я скажу, да блин, у меня так и сделано. Или - не чувак, у меня круче. Ибо круче чем у меня быть не может однозначно. У меня идеально сделано.

(25)
Не по ссылке нового.
Вот в 1це пишу, кстати.
В справочнике пимВалюты поставил обработчики:

<pre>
На выходе имею:

Что за бред, почему ссылка нового не поддерживается?

А если при копировании сохранять объект копирования и признак копирования, а подчиненные уже ПослеЗаписи() фигачить?
2(26) Можно все в транзакцию завернуть.. ну так, в порядке бреда.
В подписке ссылка уже есть, т.к. ПриЗаписи в объекте уже отработано
чё то я не догоняю, как соотносится тема и "Писать не просят, просят идею. ". Кто кого просит?

(32) Не гони, в ПриКопировании элемента еще нет.
(34) Не, там тоже объекта еще нет. К тому же это на уровне формы, а я на уровне объекта сделал.
(31) В порядке бреда если только.

У меня красивое решение. ДУМАЙТЕ, ДЯТЛЫ!

(37) вот загнул? А оно нам надо, в пятницу. под вечер - ДУМАТЬ!

Сказал бы в среду, до обеда, можно было бы и подумать, а так - есть что сказать - ГОВОРИ. нет, дык нефиг народ баломутить.

>>> У меня красивое решение. ДУМАЙТЕ, ДЯТЛЫ!
епт, это уже комплексы видать. )))
(39) Ну комплексы не комплексы, а до 38 го поста дошли, решения еще не придумали. Кто вы после этого? ;-)

может я чего не понимаю.

вот из БП кусок. форма элемента спр. Валюты

Фиксин, опять изобрел велосипед с квадратными колесами, после употребления очередной дозы мухоморов
предупреждаю, по аккуратней в выражениях, а то тебя и опустить могут
осталось только применить это к нашему случаю - и вуаля.
Но копировать нужно только при копировании, а не вдругих случаях! ;-)
(48) Какой нафиг горячо.
Выдрал код из рабочей базы 3 летней давности

(49) В коде (43) есть изюминка - Записать(); в процедуре ПриЗаписи()

Зачем можешь объяснить?

смотрб в отладчике в модуле объекта ПередЗаписью - пустота.
смотрю в ПриЗаписи - есть ссылка.

У меня какой-то другой отладчик?

(54) может в программу Мастер-Класс входит перекомпиляция ядра, но Гений считает что люди к этому не готовы?
(56) ты при создании элемента копированием сразу его записываешь?
(58) из (0) следовало несколько другое, имхо:
<нужно чтобы когда пользователь создавал элемент справочника А копированием (F9), при этом копировались все подчиненные элементы>
При копировании юзверем соответственно откроется форма элемента справочника в которой будет доступно ПараметрОбъектКопирования. Остальное можно запхнуть в процедуру ПослеЗаписи(). Какие еще извращения требуются?
+61 при редактировании в диалоге соответственно. Извращаться придется только при редактивовании в списке.
Хотя в списке есть процедура ПередНачаломДобавления(Отказ>, <Копирование>, <Родитель>, <Группа>) - в которой можно отследить факт копирования. Остается только выяснить - можно ли здесь отловить объект копирования и ссылку на добавляемый элемент справочника. Но с этим нет времени возиться.
Короче при копировании элемента всяко будет работа с формами - как- то здесь все это упущено вместе с событиями форм.

особенно в гениТальном решении мне понравился блок:

хотя ситуацию с родителем надо конечно обрабатывать отдельно
(0) Да это фигня. Я вот очень удивился когда выяснил что в снеговике так же как и в клюшках нельзя делать групповые операции с элементами справочников, списков и т.д. Например мы выбираем мышью при нажатом Ctrl ряд объектов и они все охренительно выделены (вот прогресс!), потом я могу одним движением (. ) руки всех их пометить на удаление, перести в другую группу и т.д. Этого до сих пор почему то нет. Подумай над тем как это сделать, а потом устрой тут мастер-класс. :)
(66)наверно я что-то не понял, при множественном выделении работает множественная пометка на удаление и перенос в другую группу штатными методами
(66) э-э-э, как только ставим режим выделения "Множественный" - так сразу это работает
я лично записывал элемент, а потом если пользователь отказ делал при выборе - удалял его.
(69)при копировании подчиненного иерархического справочника необходимо менять ссылки на родителя в подчиненных эмлементах чтобы не получилось, что у родителя и дочернего элемента владельцы разные
(67)(68) У меня не работает. Что я делаю не так?
(Запуская конфу. )
Иногда создается впечатление, что под ником Гений 1С пишут все кому не лень.
(61) отрабатывать события на уровне формы - это не наш метод. К тому же если пользователь щелкнет записать дважды в одной форме, нужно чтобы во второй раз подчиненные элементы не скопировались.
(72) перетаскивать в группу можно если разрешить драг и дроп, тогда писать ничего не надо. НАсчет групповой пометки на удаление не знаю - а что, сложно кнопку с обработчиком повесить? Для каждого Эл из ВыделенныеЭлементы и т.п.

(75)да, опечатка, но это не дает тебе право меня оскорблять

По ходу Фиксин наконец-то открыл для себя методы ПолучитьСсылку() и УстановитьСсылкуНового() :))
(77) Ну почему же. Повод дает. Про метод Скопировать() я забыл, чесгря.

открыл карточку фиксина на инфостаре и офигел рейтинг за 800. и 4 страници ссылок на его опусы (большенство по 5-10 плюсов) то есть ни кому нафиг не нужны. Наверно если писать статьи копированием из синтаксиса помошника можно больше заработать!

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

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

В управляемой форме можно программно добавить, изменить и удалить:

  • реквизиты;
  • локальные команды;
  • элементы.

Все указанные операции возможны только на сервере.

Программное изменение формы имеет ограничения:

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

Изменение команд формы

Для управления составом команд у объекта УправляемаяФорма есть коллекция Команды . У коллекции есть несколько методов:

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

Обработчик команды должен располагаться в форме и иметь директиву компиляции &НаКлиенте .

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

Чтение состава реквизитов формы выполняется функцией ПолучитьРеквизиты (< Путь >) , возвращающей массив типа РеквизитФормы . Параметр функции указывает путь к родительскому реквизиту (в виде строки). Если параметр опущен или указана пустая строка, возвращаются реквизиты верхнего уровня.

Изменение реквизитов выполняется методом ИзменитьРеквизиты (< ДобавляемыеРеквизиты >, < УдаляемыеРеквизиты >) объекта УправляемаяФорма . В параметр ДобавляемыеРеквизиты передается массив с элементами типа РеквизитФормы . В параметр УдаляемыеРеквизиты передается массив строк, описывающих пути к удаляемым реквизитам.

Внимание!

Процесс изменения состава реквизитов является достаточно ресурсоемким. Фактически выполняется пересоздание формы. В связи с этим работа с реквизитами формы выполняется в пакетном режиме.

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

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

Для управления составом элементов у объекта УправляемаяФорма есть коллекция Элементы . У коллекции есть несколько методов:

Переместить (< Элемент >, < Родитель >, < МестоРасположения >)

Коллекция Элементы доступна как на клиенте, так и на сервере. Изменять коллекцию (методы Вставить () , Добавить () , Переместить () и Удалить () ) можно только на сервере. Искать и получать количество элементов (методы Найти () и Количество () ) можно как на клиенте, так и на сервере. Элементами коллекции могут быть:

  • ГруппаФормы;
  • ТаблицаФормы;
  • ПолеФормы;
  • КнопкаФормы.

Элементам формы можно программно назначить обработчики событий. Для этих целей предназначен метод УстановитьДействие (< ИмяСобытия >, < Действие >) .

Рассмотрим несколько наиболее распространенных на практике примеров работы с командами, реквизитами и элементами формы.

Добавление команды и связанной с ней кнопки:

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

Назначение элементу формы обработчика события:

Внимание!

Процедурам, которые устанавливаются в качестве обработчиков событий из кода с помощью метода УстановитьДействие () , рекомендуется задавать префикс Подключаемый_.

Внимание!

Остались вопросы?
Спросите в комментариях к статье.

2 комментария

Ваш текст:
В параметры ДобавляемыеРеквизиты и УдаляемыеРеквизиты передаются массивы с элементами типа РеквизитФормы.
Верный текст:
(необязательный)
Тип: Массив.
Массив, содержащий СТРОКИ, описывающие ПУТИ к удаляемым реквизитам.

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