1с получить реквизит внешней обработки

Обновлено: 04.07.2024

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Просто вставил в конец модуля "Сообщить" и оно вызывается при каждом вызове сервера.

В общем, ощущение что всю систему проектировал какой-то криворукий гоблин.

Я просто очень долго пытался понять, почему реквизиты обработки теряются при каждом вызове, а потом оказалось, что теряется вообще всё.

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

А также, получается, что при каждом вызове всё гоняется туда-обратно.

(1) Укуренных инопланетян я видел, они на такое не способны.
А это, как говорится, многоруккий шивва нижними руками, которые аккурат из того места растут, из которого не надо.

P.S. была хорошая идея, как можно всё сделать, и оказалось, что тут, в принципе, ничего сделать нельзя, так как для каждого вызова компиллять модуль .

Хотя, видимо, писал специалист по php, так как там всё именно так и работает.

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

Просто, когда у одной обработки две формы и обе открыты, то в каждой форме свой набор реквизитов обработки и они между собой никак не связаны.

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

(8) Я прекрасно знал, что объекты хранятся только на клиенте.
Но для меня новым оказалось, что серверная часть модуля формы перекомпилляется при каждом вызове сервера, а также что при открытии одной формы обработки из другой данные реквизитов обработки не передаются - ведь команда открытия выполняется сначала на клиенте из формы, в которой эти реквизиты заполнены.
[Я прекрасно знал, что объекты хранятся только на клиенте.] — о как! А для меня это откровение.
РеквизитФормыВЗначение(), ДанныеФормыВЗначение() зачем-то ведь придуманы, а?
(10) А где им ещё быть - данные хранятся в базе, когда что-то из базы открывается, сервер приложений считывает данные, готовит форму и отправляет всё это на клиента, после чего у него "случается амнезия" и он всё забывает.
(11) Попробуй эти функции вызвать без контекста ?
А контекст - это то, что приехало к серверному вызову с клиента - и все наши данные именно в контексте.
Проблема-то в чем? Вызвать другую форму этого же экземпляра обработки?
(15) Проблема в том, что при заполнении реквизитов объекта (не формы) в одной форме обработки другая форма видит старые значения (так как они внутри её контекста живут).
(16) то, что Сообщить вызывается 2 раза, ведь не означает, что компилируется 2 раза.
На сервере экземпляр обработки получается через Обр=РеквизитФормыВЗначение("Объект") и в этот момент компилляется модуль обработки.

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

(21) Правильно, для обслуживания нашего вызова создаётся объект "Обработка", который после выполнения нашего вызова будет разрушен.

(22) Он уже собран. Считай, что выполняется конструктор объекта.
Почитай где-нибудб про immutable-объекты и прими как данность, что они в 1С есть.
(23) Очень сложно проверить, что происходит на самом деле, так как выполнение части модуля ниже всех функций можно организовать и без повторной компиляции самого модуля, но, так как модуль нигде не хранится, то можно предположить, что он компилляется ещё раз.

(24) Получается, что объектов вообще нет - есть только имитация их существования.

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

(26) Я полагаю, что компилируется он в момент открытия. И больше файл не перечитывается. После чего "класс" обработки занимает свое место в памяти "виртуальной машины 1С" и выполняется в нужный момент.
И потом, если при каждом обращении к объекту, как ты говоришь в (23) вызывается конструктор - это же не говорит, что объект неизменяемый, а как раз подтверждает тот факт, что его создают только тогда, когда он нужен.
(0) Да может просто тупо так сделали просто ради того, чтобы было.
(28) На этот вопрос очень сложно ответить, так как кеш, скорей всего, хранит не скомпилированный модуль, а данные для его компилляции - так проще - кешировать то, что получается с сервера базы данных.
(27) Да нет же. Два контекста не могут сделать один объект. Или наоборот, один объект не может принадлежать двум контекстам.
(29) а я и не говорю, что он неизменяемый. Я говорю, что к нему надо относиться как будто он неизменяемый. Еще и стейтлесс.

(32) Ну да, есть объекты, называемые "Контекст" и он у каждой формы свой.

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

(31) при чем тут кеш? Речь про устройство "исполнителя 1С". Я не думаю, что оно принципиально отличается от JVM или другой VM.
(34) во, ты уже начал понимать, почему у форм не может быть состояния на сервере
(35) Он реально отличается - хотя бы тем, что их два - на клиенте и на сервере, и тот, который на сервере умеет забывать всё сразу после окончания обработки вызова.
(37) Я прекрасно знал, что у форм нет состояния на сервере, так как сервер вообще не знает, что происходит с формой.
Но для меня очень удивительным оказалось, что две формы на клиенте не могут иметь общих данных.
(36) Ну это ты про Параметры сеанса - так они и в базе данных могут хранится.
(38) Можно считать, что ВМ на сервере и клиенте различные. Это не принципиально. В случае с веб исполнитель вообще javascript браузера.
(39) так если у них нет состояния, как у них могут быть какие-то общие данные?
Просто у Microsoft в его реализации COM-объектов объекты прекрасно живут на разных машинах и обмениваются данными, независимо от расположения, и всё работает.
(42) Их вообще просто нет.
Объект на сервере собирается по данным, переданным с клиента, а они живут в контексте формы.
(44) Ну, сеансы в php тоже обычно хранятся в файликах, и несколько процессов прекрасно их между собой делят - тут создатели 1С подсмотрели готовое решение.
(46) Сессии в php (и не только в php) могут храниться разными способами. Можно не пользовался встроенными и реализавать свой.
В общем случае сессия - это некий persistent-объект, в котором что-то хранится, и id которого передается при каждом вызове (обычно в куках, но необязательно).

Странно все это. Ну да УФ при вызове &НаСервере, каждый раз все что делалось на Клиенте переносит на сервер.

Таки хочется спросить, у ТС: Пиши с этим учетом, забудь про Толстый клиент и что все держалось в форме.
Коль тебе на сервер надо перекидывать какую либо Таблицу значений из реквизитов формы.
То трансформируй её в Структуру и обращайся к процедуре формы "БезКонтекста".
Старайся меньше использовать обращений к процедурам "НаСервере" :)

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

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

(50) просто вдруг выясняется что управляемые формы не для таких задач
для таких задач придется юзать регламентое задание и выполнять всё только на сервере - а в УФ только настройки этого задания менять и логи просматривать

(51) Если бы к данным регламентного задания можно было иметь доступ в момент его исполнения - тогда да.
А так - как ни крути - ничего хорошего не выйдет.

Потому как, если что-то обрабатывается, то пользователю придётся показывать результат, а это форма.

(52) что мешает писать логи в РС регламентному заданию?
а твоей обработке читать этот РС и показывать состояние хода выполнения?

(53) Если я что-то сохраняю в базе, то ничего не мешает и просто вызывать функции "НаСервереБезКонтекста" и работать с этими сохранёнными данными.
К сожалению, не всё можно просто и удобно сохранить в данных.
Например, любой объект (то есть не ссылку, а сам объект с данными) сохранить не получится - его придётся каждый раз создавать заново.

То, что объект может прекрасно жить в памяти модуля, исполняющего фоновое задание, не значит, что его можно увидеть пользователю.

Просто, некоторые простые вещи, которые во многих системах реализуются "из коробки" в 1С требуют очень больших танцев с бубном, и отрицательно сказываются на производительности.

(54) ты просто ещё не вкурил новую философия от 1С - тебе надо раздуплиться - это бывает сложно
Конечно задача которая в толстом клиенте решается просто теперь может потребовать разработку нового алгоритма, что раздражает и хочется сказать "УФ=УГ" - но наверное стоит присмотреться к новой философии 1С, тем более эта философия совсем не нова.
Из всего вышесказанного становится понятна рекомендация 1С не делать сильно нагруженных УФ.
(4) Это да. Для меня тоже в своё время стало открытием, что реквизиты отчетов/обработок в УФ превратились в атавизм, т.к. не являются частью сериализуемого контекста.
Честно говоря, я совсем не уверен, что выбрав stateless-модель, 1С пошла по правильному пути. Хотя, учитывая сколько боков даже в этой модели у них вылазит, может и правильно.
(58) stateful в кластере и в вебе чревато еще большими косяками
(59) Ну как бы да, с одной стороны. С другой - профит тоже есть. И потом - какой, нафиг, stateless, если состояние таки на сервере хранится? Контекст сеанса, данные форм на сервере таки удерживаются и синхронизируются с клиентом. Чего уж тут мелочиться? Можно было бы и объекты удерживать.

(58) Они сериализуемы, только вручную - то есть как раз реквизиты-то и живут в контексте, а вот самого объекта там нет, когда мы его создаём, то мы создаём его копию по данным контекста, и если данные в контекст вернуть, то всё будет прекрасно.

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

(59) В нормальном кластере можно держать данные клиента на сервере, пока не порвётся соединение, просто тогда каждая часть кластера знает, каких клиентов она обслуживает и гонять весь набор данных от клиента к серверу и обратно можно только в момент перехода на другой участок кластера.
А когда при каждом вызове никто не знает, кто будет исполнять серверный код - это создание проблем на пустом месте.

Не забываем, также, что когда мы помещаем OLE-объект в хранилище значения, а потом это хранилище кладём в базу, то сам объект остаётся жить только в том исполнителе, где он был создан, и, если следующий участок нашего кода будет исполняться на другом участке, то объект будет разрушен, а, скорей всего, мы получим нестыковку "Заглушки" и основного объекта, что иногда кончается крахом всей подсистемы OLE и аварйным завершением процесса его вызвавшего.

(62) [тогда каждая часть кластера знает, каких клиентов она обслуживает] — а теперь представим ситуацию, когда эта часть кластера падает. И что должно произойти?
Про OLE-объекты вообще лучше забыть и не использовать этот атавизм.

Короче, как я и сказал в (50) объекта "Обработка" просто вообще нет. Когда мы выполняем РеквизитФормыВЗначение("Объект") у нас создаётся объект "Обработка" по тем данным, которые были сохранены в форме (а там живут его реквизиты).
Можно считать, что вызывается конструктор с параметрами.
Теперь мы можем работать с нашим объектом.
Потом, когда мы закончиили работу, мы его должны сохранить в реквизит, чтобы данные реквизитов ему соответствовали.
То есть выполняем ЗначениеВРеквизитФормы.

В следующий раз, когда мы снова создаём объект, он создаётся в том состоянии, в котором мы его сохранили в реквизит.

В общем - как сериализация в php - прочитал, поработал - не забудь сохранить.

(63) Если часть кластера упала, то клиенты должны переходить на другую часть, собственно именно тогда и переходить, а не каждый раз.
(66) А что делать с данными клиента, которые "держал" этот кусок кластера?

(64) Это не атавизм, это целая идеология программирования.
И от них никуда не денешься, так как эта реализация обеспечивает передачу данных между исполнителями независимо от среды. А по сути, это всего-лишь некоторая удобная надстройка над механизмом удалённого исполнения.

И потом, сами интерфейсы COM-объектов это всего лишь набор некоторых стандартных таблиц функций, которые система умеет передавать.

(67) Загрузить с клиента.
Никто же не говорит, что данные хранятся только на сервере - они должны быть и на сервере и на клиенте, только не надо все данные каждый раз передавать туда и обратно.
А смена исполнителя - это как раз тот момент, когда можно передать данные с клиента на сервер.
При этом, конечно, потеряются данные последнего исполнения, если на них упал участок, но, насколько я понимаю, если в 1С участок падает на исполнении, то клиент закрывается с ошибкой, так что ничего нового они не изобрели.
(68) Это атавизм хотя бы по той причине, что с кроссплатформенностью у COM всё плохо. Да и сама Microsoft почти похоронила эту технологию.
(70) ajax не предусматривает stateful бекенда. А даже наоборот, потенциально позволяет разбить бекенд на кучу относительно независимых микросервисов.
(70) Почему на первом? 1С упирает на то, что они стараются гонять не все данные, а только изменения. Правда, типа не всегда это возможно. Контекст формы кастомизируется как угодно.
(71) Ок. Какие альтернативы для доступа к внешним библиотекам из скриптовых языков?
(76) Ручным плугом пахать тоже вполне успешно получается.

(74) Ну, выходят потоками - просто для передачи потока данных как-то нужно договариваться, что там передаётся, как раз COM-подсистема и являлась тем звеном, которое скрывало от пользователя механизм договорённости.
В глубине COM-механизма лежат или WM_COPYDATA или тот же TCP-тунель, а внутри одного процесса допустимы и прямые вызовы.
Главной отличительной особенностью от всего остального является механизм разделения объектов, когда сам объект остаётся на месте, а передаётся только его интерфейс, который как раз и есть stateless.

(73) Обратно, может быть, и летят только изменения, а вот туда, всё, что есть, так как сервер-то не знает, что ему будет нужно, особенно, если модуль будет собираться уже после прихода данных.

Ситуация: есть обработка внешняя, в ней 5 реквизитов. есть 2 формы, 1 - основная, 2 - просто форма. Из 1 формы вызывается вторая на которой и вынесены эти реквизиты. После заполнения реквизита и закрытии второй формы они не сохраняются. На сколько я понимаю получается что необходимо вручную сохранять реквизиты у объекта через реквизит формы в значение и обратно, хотя для любого объекта конфигурации такой необходимости нет. Может кто пояснит ситуацию. По сути то обе формы принадлежат одному объекту, а элементы формы по есть ссылки на реквизиты этого объекта.

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

(6) а нельзя как-нибудь указать, что бы форма была привязана к первоначальному экземпляру?
И получается что в принципе механизм обработок такой, что новый экземпляр создается или это только для внешних?

(7)Так работает с любыми обработками.
Вряд ли вам нужны все данные/реквизиты объекта в отдельной форме.
Зачем все это тянуть с клиента на сервер и тд?

(8) Нет, все данные не нужны, причин было 2:
1) Это просто удобно, потому что одни данные в одной форме, другие в другой, при их большом количестве можно поиграться в различных окнах и при этом не заморачиваться с обменом данными между этими формами, так как все это реквизиты объекта.
2) Это динамическое обновление, опять же можно кодом реализовать, но более геморно, например при изменении реквизита в одной форме он изменяется и в другой.

Ну видимо придется писать оповещения((((

(9) Ну зато так работать должно быстрее, особенно если обработка "тяжелая". По идее))
Когда открываете вторую форму - открывайте ее в режиме блокировки владельца.
Чтобы сценарий был примерно следующий - открыл, изменил данные - нажал ок - они изменились в основной форме.
Нужна будет только одна процедура оповещения о закрытии формы.

если вторая форма создана как "произвольная форма". то у неё нет привязки к реквизитам обработки.
Надо руками

Нет, создана как "ФормаОбработки" и основной реквизит "Объект"

Этим кодом открывается вторая форма из основной:
ОткрытьФорму("ВнешняяОбработка.УниверсальныйИсполнительКода20.Форма.ФормаРеквизитов",, ЭтаФорма,, ВариантОткрытияОкна.ОтдельноеОкно);

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

Преподаватель 1С
Санкт-Петербург
зарплата от 100 000 руб. до 120 000 руб.
Временный (на проект)

Внешние обработки, печатные формы, обработки по заполнению табличных частей

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

Общее описание

Механизм предназначен для подключения (без изменения конфигурации):

  • Внешних обработок для произвольного выполнения
  • Внешних обработок в качестве дополнительных печатных форм объектов (справочников и документов)
  • Обработок для заполнения табличных частей объектов

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

Для реализации механизма ВПФО используется справочник "Внешние обработки".

Для справочника предусмотрены специализированные реквизиты*:

  • "Вид обработки" - описывает, какого вида данная ВПФО
    1. Произвольная обработка
    2. Обработка для заполнения табличных частей объектов
    3. Внешняя печатная форма
    • "Хранилище внешней обработки" - хранит двоичные данные подключаемой внешней обработки. При использовании двоичные данные сохраняются на диск во временный файл, и обращение к файлу производится программно как к внешней обработке.

    ПРИМЕЧАНИЕ
    Полный перечень реквизитов будет описан ниже, в разделе Техническая реализация механизма "Внешние обработки, печатные формы, обработки по заполнению табличных частей"

    Для удобства, формы списков ВПФО вызываются раздельно, с предустановленным отбором по реквизиту "Вид обработки", из подменю "Сервис".

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

    Для остальных пользователей назначаются права на чтение(использование) и запись(изменение) по каждому элементу справочника ВПФО.

    Преимущества использования механизма ВПФО перед механизмом платформы открытия внешних обработок:

    • Возможность использования механизма пользователями, НЕ имеющими права на интерактивное открытие внешних обработок
    • Ограничение доступа к использованию и изменению обработок на уровне записей (RLS), т.е. к каждой обработке отдельно
    • Целостность БД и неизменность функционала в зависимости от внешних факторов (переноса БД, сетевой работы пользователей, создания архивных копий БД и пр.)

    Описание видов справочника ВПФО и требования к подключаемым внешним обработкам

    Рассмотрим каждый вид ВПФО по отдельности.

    Произвольная обработка

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

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

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

    Обработка для заполнения ТЧ объектов

    Для обработок заполнения ТЧ необходимо указывать внешнюю обработку (файл на диске, с расширением epf), список объектов и их ТЧ, для которых необходимо использовать данную обработку.

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

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

    При нажатии на созданную перед открытием кнопку подменю "Заполнить" происходит сохранение соответствующей обработки на диск во временный файл, для сохраненной внешней обработки вызывается процедура:

    Инициализировать (Объект, ИмяТабличнойЧасти, ТабличноеПолеОбъекта)

    • Объект – ДокументОбъект, СправочникОбъект. Откуда был произведен вызов процедуры заполнения внешней обработки;
    • ИмяТабличнойЧасти – Строка. Имя табличной части, для которой вызвана обработка;
    • ТабличноеПолеОбъекта – Элемент формы: Табличное поле. Табличное поле формы, для которого вызвана обработка.

    Наличие экспортной процедуры "Инициализировать()" в модуле объекта обработки с видом "Заполнение табличных частей" обязательно. В теле данной процедуры должен располагаться программный код, заполняющий табличную часть в соответствии с назначением обработки.

    Обработка так же может иметь в своем составе макет "Параметры_Авторегистрации", используемый для автоматического заполнения принадлежности печатной формы в справочнике "Внешние обработки". Макет должен состоять из 2-х колонок – "полное имя объекта" и "имя табличной части".

    Пример макета Параметры_Авторегистрации:


    Внешняя печатная форма

    Для подключаемых внешних печатных форм указывается:

    • внешняя обработка
    • список объектов, для которых данная печатная форма используется

    Для каждого типа объекта дополнительно можно указать:

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

    Вызов диалога настройка условий отбора осуществляется при начале выбора значения в колонке "отбор":


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


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

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

    Для сохраненной внешней обработки:

    • заполняется реквизит "СсылкаНаОбъект" - тип "Любая ссылки", в который передается ссылка на объект, для которого необходимо выполнить печать;
    • вызывается функция "Печать()" (должна располагаться в модуле обработки с признаком "Экспорт") без параметров, возвращающая табличный документ.

    Наличие реквизита "СсылкаНаОбъект" и экспортной функции "Печать()" в модуле объекта обработки с видом "Внешняя печатная форма" обязательно.

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

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

    Пример макета Параметры_Авторегистрации:


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

    Техническая реализация механизма "Внешние обработки, печатные формы, обработки по заполнению табличных частей"

    В базе данных внешние обработки, печатные формы, обработки по заполнению табличных частей хранятся в справочнике "Внешние обработки". Справочник имеет следующую структуру:


    • ХранилищеВнешнейОбработки. Хранилище значения, хранятся двоичные данные обработки, определенной для всего элемента.
    • ВидОбработки. ПеречислениеСсылка. ВидыДополнительныхВнешнихОбработок, определяет вид ВПФО каждый вид (печатная форма, заполнение табличных частей, обработка) рассмотрен отдельно в разделе "Описание видов справочника ВПФО и требования к подключаемым внешним обработкам".
    • Комментарий. Строка неограниченной длинны.
    • КомментарийКФайлуИсточнику. Строка, неограниченной длинны, хранит параметры файла, дату создания и пр. Заполняется автоматически в момент интерактивного выбора файла внешней обработки. Пользователем не изменяется.

    ТабличнаяЧасть.Принадлежность. Хранит типы объектов, для которых задается ВПФО и прочие описанные ниже параметры. Табличная часть используется для элементов с видом обработки: "Печатная форма" или "Заполнение табличных частей".

    Реквизиты табличной части:

    • ПредставлениеОбъекта. Строка, неограниченной длинны, хранит строковое представление выбранного объекта, для отображения пользователю.
    • СсылкаОбъекта. СправочникСсылка, ДокументСсылка, содержит пустую ссылку на объект конфигурации. т.к. реквизит типа "Тип" для табличной части не может быть определен, то по пустой ссылке определяется тип объекта, для которого следует подключать внешнюю печатную форму или обработку по заполнению табличной части. Ссылку на пустое значение определенного типа удобно использовать в запросах.
    • ТабличнаяЧастьИмя**. Строка, 100. Содержит имя ТЧ объекта, для которого задается ВПФО.
    • ТабличнаяЧастьПредставление**. Строка, неограниченной длинны. Содержит синоним ТЧ объекта, используется для отображения пользователю представления табличной части объекта, для которого задается.
    • НастройкиПостроителяДляОтбора***. Хранилище значения, может содержать настройки построителя отчета, выгруженные из него отборы для выбранного объекта.
    • ХранилищеВнешнейОбработки***. ХранилищеЗначения, может содержит двоичные данные подключаемой внешней обработки., которая будет использоваться в первую очередь, вместо обработки расположенной в шапке.
    • ЗаменяемаяПечатнаяФорма***. Строка, 200. Имя печатной встроенной формы объекта, которую необходимо заменить подключаемой.
    • ИмяФайлаПечатнойФормы***. Строка, неограниченной длинны - имя файла подключенной печатной формы.
    • ПредставлениеОтбораПостроителя***. Строка, неограниченной длинны, хранит представление отбора построителя, используется для отображения представления отбора в табличной части формы элемента справочника "Внешние обработки".

    ** Используется только для элементов с видом обработки: "Заполнение табличных частей"
    *** Используется только для элементов с видом обработки: "печатная форма".

    Подключение дополнительных печатных форм к формам объектов конфигурации

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

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

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

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