Обработка заполнения реквизитов документов

Вывод результата запроса на форму УП в таблицу значений (аналог СоздатьКолонки() для УП) 2
при разработке на обычных формах было удобно выводить результат запроса используя метод СоздатьКолоки(): Процедура ПоискНажатие(Элемент)
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| ДокументоОборот.Этап,
| ДокументоОборот.Отдел,
| Докуме


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


Как отобразить дерево значений на управляемой форме 0
Создадим новую внешнюю обработку. Добавляем управляемую форму и создаем обработчик ПриСозданииНаСервере(). Никаких реквизитов и элементов “вручную” не добавляем, будем делать это программно. НаСервере
Процедура ПриСозданииНаСервере(Отказ, Станда


Как передать таблицу значений с сервера на клиент? 5
Многие спрашиваю, как передать тз с сервера на клиент — ниже несколько вариантов как это можно реализовать: Через ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр НаКлиенте
Процедура ПолучитьТаблицу НаСервер(Команд а)
ТЗВСтроке = ПолучитьТЗНаС


Комиссионная торговля 0
Добрый день. УТ11 (11.4.13.46) Наша организация принимает товар на комиссию. В отчете комитенту цена комитента — ставится последняя, а нужно по фактическому поступлению. Подскажите пожалуйста, может кто то сталкивался с подобной проблемой. Спасибо.


Посмотреть все результаты поиска похожих

Частая задача — сделать так, чтобы форма нового объекта открывалась не «пустая», а уже заполненная некоторыми начальными данными. Для самых простых случаев можно использовать свойство ЗначениеЗаполнения, которое есть у реквизитов объектов конфигурации. В более сложных случаях можно использовать свойство ЗаполнятьИзДанныхЗаполнения. Если ни тот, ни другой способы не подходят, на встроенном языке можно описать собственный алгоритм начального заполнения данных нового объекта.

Свойство ЗначениеЗаполнения

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

У реквизитов объектов конфигурации существует свойство ЗначениеЗаполнения. Реквизит Склад имеет тип ссылки на справочник Склады, а в справочнике Склады существует предопределенный элемент ГлавныйСклад. Тогда прямо в конфигураторе можно указать, что в новых документах реквизит Склад будет сразу же заполнен ссылкой на ГлавныйСклад:

Cвойство ЗаполнятьИзДанныхЗаполнения

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

Теперь будет происходить следующее. В режиме 1С:Предприятие пользователь отобрал список накладных по некоторому поставщику и некоторому складу. При вводе новой накладной с помощью команды «Создать» списка, поля Поставщик и Склад будут заполнены именно теми значениями, по которым отобран список накладных:

Собственный алгоритм заполнения реквизитов

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

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
                
     Если ДанныеЗаполнения = Неопределено Тогда 
          // «Простой» ввод нового объекта
                               
     ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("СправочникСсылка.Поставщики") Тогда 
          // Новый объект вводится на основании другого объекта. 
          // В этом случае в данные заполнения передается ссылка на объект, являющийся основанием.
          // В данном случае обрабатывается ввод на основании элемента справочника Поставщики.
                               
     ИначеЕсли ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
          // Новый объект вводится командой из отобранного списка.
          // В данных заполнения будет структура, содержащая значения отбора:
          // «Поставщик» — СсылкаНаПоставщика
          // «Склад» — СсылкаНаСклад
                               
     КонецЕсли;
                               
КонецПроцедуры

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

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

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

  • Реквизит заполнен — сразу будет вызван обработчик события ПриСозданииНаСервере.
  • Реквизит не заполнен — платформа попытается заполнить его из ДанныеЗаполнения. После этого снова проверит, заполнен реквизит или нет:
    • Реквизит заполнен — сразу будет вызван обработчик события ПриСозданииНаСервере.
    • Реквизит не заполнен — платформа попытается заполнить его из ЗначениеЗаполнения. После этого будет вызван обработчик события ПриСозданииНаСервере.

Поиск:
1С:Предприятие • Документ • Заполнять из данных заполнения • Значение заполнения • Обработка заполнения

1. Постановка задачи

В этой статье рассмотрим процесс написания простейшей внешней обработки заполнения табличной части в 1С 8 для конфигураций, использующих обычное приложение. Для примера возьмем такую задачу: “В конфигурации 1С:Бухгалтерия 2.0 создать внешнюю обработку заполнения табличной части Товары документа Реализация товаров и услуг, данные для заполнения взять из табличной части Товары документа Поступление товаров и услуг”. Таким образом нам необходимо заполнить товары реализации на основании товаров поступления, такая задача довольно часто встречается в реальной практике программиста 1С.

2. Создание внешней обработки

Зайдем в 1С 8 в режиме Конфигуратор. При помощи меню Файл -> Новый или пиктограммы Новый документ создадим новую внешнюю обработку.

Пиктограмма Новый документ в 1С 8

В поле Имя укажем: “ПростейшееЗаполнениеТабличнойЧасти” и сохраним внешнюю обработку на жесткий диск используя меню Файл -> Сохранить или пиктограмму Сохранить или сочетание клавиш Ctrl + S.

Наша команда предоставляет услуги по консультированию, настройке и внедрению 1С.

Связаться с нами можно по телефону +7 499 350 29 00.

Услуги и цены можно увидеть по ссылке.

Будем рады помочь Вам!

Пиктограмма Сохранить в 1С 8

Выделив ветку Реквизиты в дереве метаданных обработки и нажав кнопку Добавить(кнопка с зеленым плюсом) создадим новый реквизит внешней обработки — ДокументПоступления, выберем для него тип ДокументСсылка.ПоступлениеТоваровУслуг, этот реквизит нужен нам для выбора документа Поступление товаров и услуг, на основании которого будет заполняться реализация.

Создание реквизита внешней обработки

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

Конструктор формы обработки

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

Конструктор формы обработки. Добавление реквизитов на форму

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

Выбор действия для кнопки формы

3. Программирование

Приступим к программированию обработки заполнения табличной части. Перейдем в Модуль объекта внешней обработки(на нижней панели обработки кнопка Действия -> Открыть модуль объекта).

Переход в модуль объекта внешней обработки

В нем нам необходимо создать экспортную процедуру Инициализировать.

Процедура Инициализировать(Объект, ИмяТабличнойЧасти = Неопределено, ТабличноеПолеОбъекта = Неопределено) Экспорт
КонецПроцедуры

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

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

ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];

При выполнении процедуры в параметре Объект будет содержаться объект документа, который мы заполняем, а в параметре ИмяТабличнойЧасти строка с именем табличной части, которую мы заполняем. Таким образом эта строчка кода получает табличную часть заполняемого документа по ее имени.

Нам необходимо что бы пользователь выбрал документ Поступление товаров и услуг, поэтому напишем код открытия формы выбора документа. Для начала получим эту форму в переменную, используя метод внешней обработки ПолучитьФорму(<Форма>, <Владелец>, <КлючУникальности>). Нам достаточно заполнить только первый параметр этого метода, передав туда строку с именем нашей формы.

ФормаВыбораПоступления = ПолучитьФорму("Форма");

Теперь откроем полученную форму, используя модальное открытие(пока форма открыта все остальные окна 1С недоступны), потому что при таком способе открытия дальнейший наш код в процедуре Инициализировать выполняться не будет, пока пользователь не закроет форму.

ФормаВыбораПоступления.ОткрытьМодально();

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

Если НЕ ЗначениеЗаполнено(ДокументПоступления) Тогда
    Сообщить("Не выбран документ поступления");
Возврат;
КонецЕсли;

Для проверки заполненности реквизита здесь используется функция глобального контекста ЗначениеЗаполнено(<Значение>), она проверяет отличатся ли значение переданное в параметре от значения по умолчанию того же типа. Процедура Сообщить выводит указанный текст в окно сообщений 1С 8. Ключевое слово Возврат прерывает выполнение процедуры.

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

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

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

Запрос.УстановитьПараметр("ДокументПоступления",ДокументПоступления);

Напишем текст запроса, будем делать это при помощи Конструктора запроса. Писать текст запроса вручную не рекомендуется, это не эффективно и отнимает кучу времени. Для начала напишем строку:

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

Поставим курсор между символами кавычек, нажмем правую кнопку мыши и выберем пунк Конструктор запроса…. После этого появится предложение создать новый запрос, нажмем кнопку “ОК”. Откроется окно конструктора, в левой его части расположены все доступные таблицы базы данных, нам необходим документ ПоступлениеТоваровУслуг. Найдем его и раскроем при помощи символа “+”, выберем табличную часть Товары и перетащим ее во вторую часть экрана конструктора, которая называется Таблицы(Также переместить нужную таблицу можно при помощи кнопки “>”).

Выбор табличной части в запросе 1С

Теперь раскроем по “+” выбранную нами таблицу(ПоступлениеТоваровУслугТовары) и перетащим необходимые для нашего заполнения табчасти поля в третью часть экрана конструктора, которая так и называется — Поля. Все доступные поля выбирать не будем, ограничимся таким набором: Номенклатура, Количество, Цена, Сумма, СтавкаНДС, СуммаНДС.

Выбор полей таблицы в конструкторе запроса 1С

Так как нам нужны данные только одного документа поступления(который мы выбрали перед началом заполнения), то в на закладке “Условия” наложим условие на ссылку документа при помощи переданного нами параметра.

 Создание условия в запросе 1С

Создание текста запроса в конструкторе на этом завершено, нажмем кнопку “ОК”. В итоге у нас получился следующий текст запроса:

Запрос.Текст = "ВЫБРАТЬ
|   ПоступлениеТоваровУслугТовары.Номенклатура,
|   ПоступлениеТоваровУслугТовары.Количество,
|   ПоступлениеТоваровУслугТовары.СтавкаНДС,
|   ПоступлениеТоваровУслугТовары.Сумма,
|   ПоступлениеТоваровУслугТовары.СуммаНДС,
|   ПоступлениеТоваровУслугТовары.Цена
|ИЗ
|   Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
|ГДЕ
|   ПоступлениеТоваровУслугТовары.Ссылка = &ДокументПоступления";

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

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

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

ТабличнаяЧасть.Очистить();

При помощи цикла Для каждого обойдем таблицу значений с результатами запроса.

Для Каждого ЭлементРезультата из Результат Цикл
КонецЦикла;

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

НоваяСтрокаТЧ = ТабличнаяЧасть.Добавить();

Заполним созданную строку таб. части данными из строки результата запроса используя процедуру Глобального контекстаЗаполнитьЗначенияСвойств(<Приемник>, <Источник>).

ЗаполнитьЗначенияСвойств(НоваяСтрокаТЧ,ЭлементРезультата);

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

процедурой ЗаполнитьСчетаУчетаВСтрокеТабЧасти из модуля объекта документа Реализация товаров и услуг. Вызовем ее при помощи параметра Объект(следует заметить,

что мы можем вызывать только экспортные процедуры из модуля объекта документа).

Объект.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(НоваяСтрокаТЧ, ИмяТабличнойЧасти, Истина);

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

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

    ТабличнаяЧасть = Объект[ИмяТабличнойЧасти];

    ФормаВыбораПоступления = ПолучитьФорму("Форма");
    ФормаВыбораПоступления.ОткрытьМодально();

    Если НЕ ЗначениеЗаполнено(ДокументПоступления) Тогда
        Сообщить("Не выбран документ поступления");
        Возврат;
    КонецЕсли;

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("ДокументПоступления",ДокументПоступления);

    Запрос.Текст = "ВЫБРАТЬ
    |   ПоступлениеТоваровУслугТовары.Номенклатура,
    |   ПоступлениеТоваровУслугТовары.Количество,
    |   ПоступлениеТоваровУслугТовары.СтавкаНДС,
    |   ПоступлениеТоваровУслугТовары.Сумма,
    |   ПоступлениеТоваровУслугТовары.СуммаНДС,
    |   ПоступлениеТоваровУслугТовары.Цена
    |ИЗ
    |   Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
    |ГДЕ
    |   ПоступлениеТоваровУслугТовары.Ссылка = &ДокументПоступления";

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

    ТабличнаяЧасть.Очистить();

    Для Каждого ЭлементРезультата из Результат Цикл
        НоваяСтрокаТЧ = ТабличнаяЧасть.Добавить();

        ЗаполнитьЗначенияСвойств(НоваяСтрокаТЧ,ЭлементРезультата);

        Объект.ЗаполнитьСчетаУчетаВСтрокеТабЧасти(НоваяСтрокаТЧ, ИмяТабличнойЧасти, Истина);
    КонецЦикла;
КонецПроцедуры

В следующей части стать будет рассказано, как отладить обработку заполнения табличной части и как подключить ее к документу.

4. Отладка

Довольно часто требуется отлаживать код, который вы пишите. Для того что бы отладить обработку заполнения табличной части в 1С 8 создадим у нее реквизит СсылкаНаОбъект типа ДокументСсылка.РеализацияТоваровУслуг

Реквизит для отладки 1С 8

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

Форма отладки заполнения табличной части 1С 8

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

Процедура КнопкаВыполнитьНажатие(Кнопка)
    Инициализировать(СсылкаНаОбъект.ПолучитьОбъект(), "Товары");
КонецПроцедуры

Теперь необходимо сделать созданную форму основной формой обработки. Для этого выберем ее в поле “Форма обработки”.

Выбор основной формы обработки

Теперь вы можете ставить точку останова в нужном месте процедуры Инициализировать или процедуры КнопкаВыполнитьНажатие формы отладки, и запускать обработку заполнения табличной части в режиме отладки 1С:Предприятия.

5. Подключение к документу

После того как обработка заполнения написана и отлажена следует подключить ее к документу из которого она будет выполняться. Для этого зайдем в 1С 8 в режиме Предприятие, перейдем в меню Сервис -> Дополнительные отчеты и обработки -> Дополнительные внешние обработки табличных частей и добавим новый элемент справочника. При помощи кнопки Заменить файл внешней обработки добавим файл созданной нами обработки заполнения табличной части.

Добавление файла внешней обработки в 1С

Заполним принадлежность обработки, для этого воспользовавшись кнопкой Подбор выберем документ Реализация товаров и услуг

Выбор принадлежности внешней обработки

И укажем, что заполнение предназначено для табличной части Товары.

Выбор табличной части для заполнения

Нажимаем кнопку ОК и на этом все, обработка заполнения будет доступна в меню Заполнить табличной части Товары документа Реализация товаров и услуг. Скачать обработку использованную для этого примера вы можете по ссылке.

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

Прежде чем мы начнем разбирать вопросы программной работы с документами в 1С 8.3, хочу обратить Ваше внимание, что на управляемой форме в режиме тонкого клиента мы можем программно работать (создавать, записывать и проводить) с документами только в серверном контексте. То есть, ваша процедура или функция должна выполняться под директивами &НаСервере или &НаСервереБезКонтекста.

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

Создать документ 1С программно

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

Реквизиты документа в 1С 8.3

Для программного создания документов, я сделал обработку. У этой обработки , я разработал форму и создал команду управляемой формы, которую назвал  «Создать документ прихода», поместив её на форму обработки.

Форма обработки для создания документа

Для этой команды, я сделаю обработчики на клиенте и на сервере.

Создание обработчиков команды

В серверном обработчике мы и напишем код, который и будет создавать документ..

&НаСервере
Процедура СоздатьДокументПриходаНаСервере()

    ДокПриход = Документы.ПриходТовара.СоздатьДокумент();

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

&НаКлиенте
Процедура СоздатьДокументПрихода(Команда)
    СоздатьДокументПриходаНаСервере();
КонецПроцедуры

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

Следующим шагом, я присвою дату этому документу, для простоты, это будет текущая дата.

ДокПриход = Документы.ПриходТовара.СоздатьДокумент();
ДокПриход.Дата = ТекущаяДата();

Номер я присваивать не буду, потому что у объекта моего документа включено свойство Автонумерация.

Свойство автонумерация документа

В принципе, этого вполне достаточно, чтобы наш документ существовал. Но создав его при помощи функции СоздатьДокумент, мы не записали его непосредственно в базу. После выполнения кода выше, ни какого документа в базе не появится!

Записать документ 1С программно

Для того, чтобы документ 1С появился в базе, его необходимо записать.  Делается это при помощи метода документа-объекта Записать. Этот метод позволяет и записать, и провести документ. Он имеет два параметра, которые я разберу ниже. Но, метод Записать также можно использовать и без параметров, тогда он будет просто записывать документ. Что мы и сделаем.

ДокПриход = Документы.ПриходТовара.СоздатьДокумент();
ДокПриход.Дата = ТекущаяДата();
ДокПриход.Записать();

Все теперь документ появится в базе.

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

Создание пустого документа

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

Заполнить документ 1С программно

У нашего документа два реквизита «шапки» – Склад и Комментарий. Создадим на форме обработки реквизит управляемой формы Склад с соответствующим типом, для последующей записи его в шапку документа, а реквизит комментарий заполним в ручную.

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

Присвоим реквизитам созданного объекта-документа нужные значения, просто обратившись через точку к этим реквизитам.

ДокПриход = Документы.ПриходТовара.СоздатьДокумент();
ДокПриход.Дата = ТекущаяДата();
ДокПриход.Склад = Склад;
ДокПриход.Комментарий = "#Документ создан автоматически обработкой"
ДокПриход.Записать();

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

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

ДокПриход = Документы.ПриходТовара.СоздатьДокумент();
ДокПриход.Дата = ТекущаяДата();
ДокПриход.Склад = Склад;
ДокПриход.Комментарий = "#Документ создан автоматически обработкой";
Для Каждого стрТЗ Из ТЗ Цикл
    НовСтрТЧДокумента = ДокПриход.СписокТоваров.Добавить();
    НовСтрТЧДокумента.Номенклатура = стрТЗ.Номенклатура;
    НовСтрТЧДокумента.Количество   = стрТЗ.Количество;
    НовСтрТЧДокумента.Цена         = стрТЗ.Цена;
    НовСтрТЧДокумента.Сумма = НовСтрТЧДокумента.Количество*НовСтрТЧДокумента.Цена;
КонецЦикла;
ДокПриход.Записать();

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

Для Каждого стрТЗ Из ТЗ Цикл
    НовСтрТЧДокумента = ДокПриход.СписокТоваров.Добавить();
    ЗаполнитьЗначенияСвойств(НовСтрТЧДокумента,стрТЗ);
    НовСтрТЧДокумента.Сумма = НовСтрТЧДокумента.Количество*НовСтрТЧДокумента.Цена;
КонецЦикла;


Всё! Мы можем смело создать документ, который будет заполнен.

Создание и заполнение документа 1С

Создание и заполнение документа 1С

Провести документ 1С программно

Все документы, которые мы создавали ранее были не проведены. Если мы хотим, чтобы документ был записан проведенным, то необходимо записывать его немного по-другому. Если раньше мы использовали метод Записать объекта документа без параметров, то теперь необходимо применять параметры этого метода. Данный метод имеет следующий синтаксис.

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

Оба параметра это системные перечисления. Первый параметр это перечисление РежимЗаписиДокумента, которое может принимать следующие значения:

РежимЗаписиДокумента.Запись
РежимЗаписиДокумента.Проведение
РежимЗаписиДокумента.ОтменаПроведения

Т.е. мы можем записать документ, провести документ и отменить проведение документа.

Во втором параметр РежимПроведения необходимо указывать системное перечисление РежимПроведениеДокумента, которое может принимать следующие значения:

РежимПроведенияДокумента.Неоперативный
РежимПроведенияДокумента.Оперативный

Т.е. мы можем провести документ как в оперативном режиме, так и в неоперативном. Если этот параметр не указан, то документ проводится в неоперативном режиме.

Изменим запись нашего документа: пусть он проводится в оперативном режиме.

ДокПриход.Записать(РежимЗаписиДокумента.Проведение,
                   РежимПроведенияДокумента.Оперативный);

Теперь документ будет сразу проведен при создании.

Изменить документ 1С программно

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

Обработка изменения документа

Как и в прошлый раз, я создам обработчик команды на сервере и на клиенте. И в серверном обработчике напишу код получения объекта из ссылки документа.

&НаСервере
Процедура ИзменитьДокументНаСервере()

    ДокОбъект = ДокументПрихода.ПолучитьОбъект();

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

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

Мы получили объект документа, используя метод ссылки на документ ПолучитьОбъект. Имейте в виду, что этот метод можно использовать или на сервере, или клиенте в режиме толстого клиента.  Переменная, которую мы создали будет иметь тип ДокументОбъект.ПриходТовара.

Изменим склад и проведем документ. В этот раз проведем в неоперативном режиме.

ДокОбъект = ДокументПрихода.ПолучитьОбъект();
ДокОбъект.Склад = Склад;
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение,
                   РежимПроведенияДокумента.Неоперативный);


Открыть документ 1С программно

Научимся открывать документ 1С программно. Для этого мы доработаем предыдущую обработку: после изменения документа откроем основную форму этого объекта для просмотра и возможного редактирования. Для открытия формы документа, мы будем использовать метод  ОткрытьФорму, в котором будем использовать параметр Ключ, где укажем ссылку на открываемый документ.

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

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

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

Обработка изменения документа

Более подробно и основательно разработка в 1С дается в моей книге: «Программировать в 1С за 11 шагов»

Изучайте программирование в 1С в месте с моей книги «Программировать в 1С за 11 шагов»

  1. Книга написана понятным и простым языком — для новичка.
  2. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  3. Научитесь понимать архитектуру 1С;
  4. Станете писать код на языке 1С;
  5. Освоите основные приемы программирования;
  6. Закрепите полученные знания при помощи задачника;

О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»

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

  1. Очень доступный и понятный язык изложения
  2. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  3. Поймете идеологию управляемого приложения 1С
  4. Узнаете, как разрабатывать управляемое приложение;
  5. Научитесь разрабатывать управляемые формы 1С;
  6. Сможете работать с основными и нужными элементами управляемых форм
  7. Программирование под управляемым приложением станет понятным

Промо-код на скидку в 15% — 48PVXHeYu

Вступайте в мои группы:

Вконтакте: https://vk.com/1c_prosto
Фейсбуке: https://www.facebook.com/groups/922972144448119/
ОК: http://ok.ru/group/52970839015518
Твиттер: https://twitter.com/signum2009

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

Создание простой обработки в 1С 8.3

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

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

  1. Открываем ИБ в режиме конфигуратора и с помощью меню «Файл»-«Новый» создаем внешнюю обработку;
    Рис.1 Выбор вида документа
    Рис.1 Выбор вида документа
  2. Добавляем форму обработки, нажимая на кнопку в виде лупы у одноименного поля, подтверждаем предлагаемые настройки кнопкой «Готово»;
    Рис.2 Конструктор формы обработки
    Рис.2 Конструктор формы обработки
  3. В разделе «Команды» добавляем новый объект, изменяем наименование и перетаскиваем его влево, в элементы формы. Видим, что появилась кнопка с нужным нам именем;
    Рис.3 Внешняя обработка Форма
    Рис.3 Внешняя обработка Форма
  4. Чтобы добавить алгоритм заполнения нового реквизита, нам нужно создать процедуру на клиенте, вызывающую выполнение кода на сервере. Для этого вызываем контекстное меню на созданной нами кнопке и выбираем пункт «Действие команды». Выбираем «Создать на клиенте и процедуру на сервере без контекста»;
    Рис.4 Создание процедуры на клиенте
    Рис.4 Создание процедуры на клиенте
  5. Перед нашими глазами откроется текст модуля формы с 2 процедурами. Алгоритм работы с документами реализовываем в той, которая исполняется на серверной стороне. Сам текст кода состоит из следующих частей:
    • С помощью запроса определяем, в строках ТЧ каких документов новый реквизит «Назначение» не заполнен;
    • В цикле получаем объект каждого документа, заполняем реквизит строк табличной части и записываем документ для сохранения изменений.
                 
&НаКлиенте
Процедура ЗаполнитьТЧ(Команда)
        	ЗаполнитьТЧНаСервере();
КонецПроцедуры
 
&НаСервереБезКонтекста
Процедура ЗаполнитьТЧНаСервере()
        	Запрос = Новый Запрос;
        	Запрос.Текст =
                   	"ВЫБРАТЬ РАЗЛИЧНЫЕ
                   	|       	ПоступлениеТоваровУслугТовары.Ссылка КАК Ссылка,
                   	|       	ПоступлениеТоваровУслугТовары.Ссылка.Склад.Наименование КАК Назначение
                   	|ИЗ
                   	|       	Документ.ПоступлениеТоваровУслуг.Товары КАК ПоступлениеТоваровУслугТовары
                   	|ГДЕ
                   	|       	ПоступлениеТоваровУслугТовары.Назначение = """"";        	
        	ВыборкаРезультатаЗапроса = Запрос.Выполнить().Выбрать();
        	Пока ВыборкаРезультатаЗапроса.Следующий() Цикл
                   	ДокументОбъектДляИзменения =  ВыборкаРезультатаЗапроса.Ссылка.ПолучитьОбъект();
                   	Для каждого строки из ДокументОбъектДляИзменения.Товары цикл
                               	строки.Назначение = ВыборкаРезультатаЗапроса.Назначение;       	
                   	КонецЦикла;
                   	ДокументОбъектДляИзменения.Записать(РежимЗаписиДокумента.Проведение);
                   	Сообщить("Документ "+ДокументОбъектДляИзменения.ссылка+" успешно исправлен.");        	
        	КонецЦикла;
КонецПроцедуры
  1. Сохраняем внешнюю обработку на компьютере;
  2. Запускаем информационную базу в режиме предприятия и через меню «Файл»-«Открыть…» находим нашу сохраненную обработку. Открывается форма с кнопкой, для которой мы реализовали код. Активируем исполнение описанного выше алгоритма нажатием на кнопку и получаем сообщения об успешном исправлении.
Рис.5 Внешняя обработка
Рис.5 Внешняя обработка

У этого способа есть недостаток – обработка не сохраняется в конфигурации. То есть, если через некоторое время добавят новый реквизит, то снова придется ее найти, адаптировать и открыть через основное меню. Но такие ситуации достаточно редки, так как перед вводом системы в эксплуатацию идет тщательный аудит с составлением списка нужных реквизитов. Гораздо более распространены ситуации, когда пользователям необходимо в процессе работы править данные в строках, например, изменять количество.

Добавление в ИБ дополнительной обработки

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

  • ЗаполнениеОбъекта;
  • ДополнительнаяОбработка;
  • СозданиеСвязанныхОбъектов;
  • ПечатнаяФорма;
  • Отчет;
  • ДополнительныйОтчет.

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

Рис.6 Заполнение данных обработки
Рис.6 Заполнение данных обработки

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

  1. Вид – указывается 1 из вышеперечисленных вариантов;
  2. МасНазначений – массив, включающий в себя все объекты конфигурации, на которые предполагается добавить новый функционал;
  3. Наименование – как будет называться наша доработка в общем списке;
  4. БезопасныйРежим – ограничение определенных действий для обработки;
  5. Команды – список кнопок, которые появятся в объектах, перечисленных в МасНазначений.

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

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


&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) экспорт
Для каждого стр из ВладелецФормы.Объект.Товары цикл
        	стр.Количество = стр.Количество + 10;	
        	стр.КоличествоУпаковок = стр.КоличествоУпаковок + 10; 	
КонецЦикла;
КонецПроцедуры

После сохранения внешней обработки нам остается только подключить ее в базу 1С в режиме предприятия. Запускаем 1С, заходим в раздел «НСИ и администрирование», «Печатные формы, отчеты и обработки». Открываем форму «Дополнительные отчеты и обработки» и перед нами открывается список всех подключенных объектов.

Рис.7 НСИ и администрирование
Рис.7 НСИ и администрирование

Нажав «Добавить из файла…», выбираем сохраненный файл, и 1С при помощи процедуры «СведенияОВнешнейОбработке» подгружает всю информацию. Нам лишь остается сохранить данные и зайти в документы, чтобы проверить результат работы. Так как в коде описаны действия на стороне клиента, чтобы данные попали в базу, необходимо провести документ после изменения количества.

Рис.8 Проведение документа
Рис.8 Проведение документа

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

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

Обработчик события ОбработкаЗаполнения

Область применения: управляемое приложение, мобильное приложение, обычное приложение.

1. В случае если в силу каких-либо условий необходимо ограничивать ввод на основании по команде «Создать на основании», то такую проверку следует выполнять в обработчике ОбработкаЗаполнения модуля объекта (набора записей). Например, это могут быть проверки вида:

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

2. Для оповещения пользователя о причинах отказа, в обработчике ОбработкаЗаполнения следует использовать исключения:

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)

Если ТипЗнч(ДанныеЗаполнения) = Тип(«СправочникСсылка.Сотрудники») Тогда
Если ПолучитьЗначениеРеквизита(ДанныеЗаполнения, «ЭтоГруппа») = Истина Тогда
ВызватьИсключение «Ввод приказа о приеме на основании группы сотрудников невозможен!
|Выберите сотрудника. Для раскрытия группы используйте клавиши Ctrl и стрелку вниз»;
КонецЕсли;

// обработка заполнения объекта по данным заполнения

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

Методическая рекомендация (полезный совет)

3. Рекомендуется придерживаться следующей логической структуры обработчика ОбработкаЗаполнения (отдельные шаги могут быть пропущены):

3.1. Выполнение специального заполнения в зависимости от типа параметра ДанныеЗаполнения .

Например:

ТипДанныхЗаполнения = ТипЗнч(ДанныеЗаполнения);
Если ТипДанныхЗаполнения = Тип(«Структура») Тогда
ЗаполнитьДокументПоОтбору(ДанныеЗаполнения);
ИначеЕсли ТипДанныхЗаполнения = Тип(«ДокументСсылка.ЗаказКлиента») Тогда
ЗаполнитьДокументНаОснованииЗаказаКлиента(ДанныеЗаполнения);
// .

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

Например:

Если Не ЗначениеЗаполнено(Подразделение) Тогда
Подразделение = ЗначениеНастроекПовтИсп.ПодразделениеПоУмолчанию();
КонецЕсли;

Также при заполнении реквизитов значениями по умолчанию следует, по возможности, использовать свойство метаданных «Значение заполнения» . Значение, указанное в этом свойстве будет автоматически присваиваться реквизиту при выходе из обработчика ОбработкаЗаполнения , в случае если параметр СтандартнаяОбработка установлен в Истина , и реквизит не был заполнен в обработчике.

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

Обработказаполнения когда вызывается

У объекта, который вводится на основании другого объекта (например, документа) существует обработчик события — ОбработкаЗаполнения

Данные обработчик имеет следующие параметры

  • ДанныеЗаполнения
  • ТекстЗаполнения
  • СтандартнаяОбработка

Описание:

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

Как отменить действие ОбработкаЗаполнения

Часто возникает вопрос, как отменить действие этого обработчика. Или проще говоря отказаться от процедуры заполнения объекта на основании. Как мы видим из описания выше, параметра Отказ у обработчика нет. А отказ от стандартной обработки (СтандартнаяОбработка = Ложь) не отменяет действие.

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

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип(«СправочникСсылка.Сотрудники») Тогда
Если ПолучитьЗначениеРеквизита(ДанныеЗаполнения, «ЭтоГруппа») = Истина Тогда
ВызватьИсключение «Ввод приказа о приеме на основании группы сотрудников невозможен!
|Выберите сотрудника. Для раскрытия группы используйте клавиши Ctrl и стрелку вниз»;
Иначе
// обработка заполнения объекта по данным заполнения
КонецЕсли;
КонецЕсли;
КонецПроцедуры

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

Последовательности событий при проведении документа 1С. Шпаргалка + про формы + про расширения

ПоследовательностьСобытийДокументаОтменаПроведения_v1.1.png

ПередЗаписью(<Отказ>, <ПараметрыЗаписи>)
ОбработкаПроверкиЗаполненияНаСервере(<Отказ>, <ПроверяемыеРеквизиты>)
ОбработкаПроверкиЗаполнения(<Отказ>, <ПроверяемыеРеквизиты>)
ПередЗаписьюНаСервере(<Отказ>, <ТекущийОбъект>, <ПараметрыЗаписи>)
ПередЗаписью(<Отказ>, <ПараметрыЗаписи>)
ПриУстановкеНовогоНомера(<СтандартнаяОбработка>, <Префикс>)
ПриЗаписи(<Отказ>)
ОбработкаПроведения(<Отказ>, <РежимПроведения>) или
ОбработкаУдаленияПроведения(<Отказ>)
ПриЗаписиНаСервере(<Отказ>, <ТекущийОбъект>, <ПараметрыЗаписи>)
ПослеЗаписиНаСервере(<ТекущийОбъект>, <ПараметрыЗаписи>)
ПослеЗаписи(<ПараметрыЗаписи>)

ОбработкаПолученияФормы(<ВидФормы>, <Параметры>, <ВыбраннаяФорма>, <ДополнительнаяИнформация>, <СтандартнаяОбработка>)
<Активация модуля формы на сервере>
<Активация модуля объекта>
ПриЧтенииНаСервере(<ТекущийОбъект>) или
ПриКопировании(<ОбъектКопирования>) или
ОбработкаЗаполнения(<ДанныеЗаполнения>, <ТекстЗаполнения>, <СтандартнаяОбработка>)
ПриСозданииНаСервере(<Отказ>, <СтандартнаяОбработка>)
ПередЗагрузкойДанныхИзНастроекНаСервере(<Настройки>)
ПриЗагрузкеДанныхИзНастроекНаСервере(<Настройки>)
<Активация модуля формы на клиенте>
ПриОткрытии(<Отказ>)
ПриПовторномОткрытии()

Цвета: &НаКлиенте &НаСервере

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

Работа с расширенным программным модулем имеет существенные особенности, которые будут рассмотрены в данном разделе.

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

В расширяющем модуле имеется возможность:

  1. Создавать собственные методы и переменные (если это допускает расширяемый модуль).
  2. Назначать собственные обработчики на события, которые не обрабатываются в расширяемой конфигурации.
  3. Перехватывать любой метод расширяемого модуля (в том числе и методы обработчиков событий), при этом имеется возможность:
    • полностью заменить оригинальный метод собственным;
    • создать методы, которые будут вызваны перед или после расширяемого метода.

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

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

В общем случае, аннотированный метод из программного модуля расширения выглядит следующим образом:

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

Если расширяемый метод содержит какие-либо параметры, то:

  1. Все расширяющие методы обязаны иметь в точности такое же описание, как и расширяемый метод, с точностью до ключевых слов Знач в описаниях параметров методов.
  2. Значения параметров разделяются между всеми расширяющими методами из всех расширений и собственно расширяемым методом. Это значит, что если какой-либо расширяющий метод изменит значение параметра, все методы, которые получат управление после этого метода, получат измененное значение этого параметра.
  3. В расширяющем методе не имеет смысла указывать значения по умолчанию для параметров расширяемого метода. Значения по умолчанию будут определяться из описания расширяемого метода.

Также следует отметить, что если расширяется обработчик события, то расширяющий метод выполниться до того, как сработают подписки на «расширяемое» событие (см. здесь).

Исполнение до расширяемого метода (аннотация Перед)

Если метод аннотирован таким образом, это означает, что вначале будет выполнен метод расширения, а затем расширяемый метод.

Рис. 688. Схема исполнения «Перед»

Исполнение после расширяемого метода (аннотация После)

Если метод аннотирован таким образом, это означает, что вначале будет выполнен расширяемый метод, а затем метод расширения.

Рис. 689. Схема исполнения «После»

Обрамление расширяемого метода (аннотации Перед и После)

Если в расширяющем модуле созданы расширяющие методы, которые отмечены аннотациями Перед и После , то это означает, что вначале будет вызван метод, который отмечен аннотацией Перед , затем расширяемый метод и зачем метод расширения, отмеченный аннотацией После .

Рис. 690. Схема исполнения «Перед» и «После»

Замена метода (аннотация Вместо)

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

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

Рис. 691. Схема исполнения «Вместо»

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

Рис. 692. Схема исполнения «Вместо» совместно с ПродолжитьВызов()

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

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

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

При выполнении команды Добавить в расширение происходит следующее:

  • Если объект, из модуля которого добавляется метод, отсутствует в выбранном расширении этот объект автоматически добавляется в расширение.
  • Если расширяется метод из модуля, отличного от модуля формы:
    • Разработчику предлагается выбрать аннотацию для метода ( Перед , После или Вместо ). При этом полужирным шрифтом выделяются те расширения метода, которые уже существуют в расширении.
    • Если выбран существующий метод в расширении, то выполняется переход к этому методу. При этом возможна корректировка объявления метода, если оно стало отличаться от расширяемого метода.
    • Если выбран несуществующий способ расширения, то будет создан новый метод в расширении, который будет предваряться соответствующей аннотацией.
    • Для функций недоступны аннотации Перед и После
    • Для процедуры недоступно:
      • Аннотация Вместо , если уже существуют методы с аннотациями Перед или После
      • Аннотация Перед / После , если уже существует метод с аннотацией Вместо

      Следует учитывать, что если расширяемый метод обрамлен инструкциями препроцессора, то эти инструкции не будут перенесены в расширение.

      При проверке соответствия описания расширяемого метода и метода расширения проверяются следующие характеристики методов:

      • Количество параметров и признак передачи параметров «по значению» (ключевое слово Знач ).
      • Метод является процедурой или функцией. Если определение метода изменяется с процедуры на функцию, а до этого процедура была расширена с применением аннотаций Перед / После , то аннотация будет заменена на аннотацию Вместо
      • Если в модуле расширения присутствуют несколько методов с одинаковым именем, но которые обрамлены разными инструкциями препроцессора, то в расширении будет обновляться всегда первый из перечня таких методов.

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

      При разработке расширений следует исходить из следующих предположений:

      1. Расширение должно разрабатываться как автономный продукт, не опирающийся на наличие или отсутствие других расширений.
      2. Одновременно может быть подключено более одного расширения, которое расширяет один и тот же объект расширяемой конфигурации.
      3. Порядок исполнения программных модулей в результирующей конфигурации определяется порядком регистрации расширений в информационной базе расширяемой системы. Первым используется расширение, которое зарегистрировано последним.
      4. Необработанное исключение, возникающее в любом из расширений (или расширяемой конфигурации) прерывает исполнение всей цепочки методов расширений и распространяется в расширяемой конфигурации.

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

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

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

      Рис. 693. Схема взаимодействия. Пример 1

      При попытке вызвать метод Расширяемая() (в основной конфигурации), встроенный язык будет исполняться в следующем порядке:

      1. Будет вызван метод, отмеченный аннотацией Перед(«Расширяемая») из Расширения2
      2. Затем будет вызван метод, отмеченный аннотацией Перед(«Расширяемая») из Расширения1
      3. Затем будет вызван метод Расширяемая() из расширяемой конфигурации.
      4. Затем, в обратном порядке (относительно списка расширений, т. е. Расширение1 и Расширение2 ), будут вызваны методы, отмеченные аннотациями После(«Расширяемая»)

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

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

      Рис. 694. Схема взаимодействия. Пример 2

      Так произошло потом, что метод, отмеченный аннотацией Вместо , полностью заменяет собой расширяемый метод. Следует особо отметить, что если в этом примере поменять порядок регистрации расширений (первым будет Расширение2 , а последним Расширение1 ), то единственным выполнившимся методом будет метод из Расширения1

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

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

      Если прикладное решение работает в файловом варианте или в клиент-серверном варианте без профилей безопасности, то при подключении расширения:

      • В обычном режиме исполнения встроенного языка допустимо расширять как клиентские, так и серверные методы. Без ограничения места расположения методов.
      • В безопасном режиме исполнения встроенного языка будут расширяться только клиентские методы и серверные обработчики форм, которые установлены через панель свойств. К остальным серверным методам (аннотированные серверные методы модулей формы и серверные общие модули) расширение применяться не будет.

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

      ps: оригинальные изображения взяты из источников

      upd(ответ на комментарии Cyberhawk и Yashazz):

      «Отказ=Истина», выставленный в одной подписке, не мешает срабатывать другой (т.е. процесс не прерывается)

      утверждение верно для ОДНОГО события (в случае наличия нескольких подписок на одно и то же событие). Например, если есть 3 подписки на событие ПриЗаписи документа ПКО, то Отказ=Истина выставленный в одной из них не помешает срабатыванию других двух.

      Отказ для каждого события проверяется в двух местах
      1. После выполнения обработчика в модуле объекта/менеджера, включая все расширения.
      2. После обработки всех подписок, включая все их расширения.
      Т.е. если в п.1 выставили Отказ, то п.2 уже выполняться не будет. Думаю стоит это добавить в статью.

      (с) tormozit

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