Внешняя обработка 1С — это файл .epf со своими реквизитами, формой, кодом и макетами, который хранится вне конфигурации. Его открывают через «Файл → Открыть» или загружают в справочник дополнительных обработок, а типовая конфигурация при этом остаётся на поддержке. Ниже — полный путь на платформе 8.3: от пустого файла в конфигураторе до рабочего инструмента с формой, запросом, макетом и регистрацией в БСП. Пример — обработка, которая считает документы каждого вида за период. Она ничего не пишет в базу, так что её безопасно запускать и в рабочей.
Ограничения: внешняя обработка не добавляет в базу новые объекты метаданных, не подписывается на запись типовых документов и не меняет типовые формы — это задачи расширений. Внешний отчёт (.erf) устроен почти так же, но ему можно назначить основную схему компоновки данных — тогда форма и настройки строятся автоматически.
| Внешняя обработка | Расширение | Правка конфигурации | |
|---|---|---|---|
| Новые реквизиты, регистры | нет | да | да |
| Изменение типовых форм и модулей | нет | да | да |
| Обновление типовой | не мешает | обычно проходит, иногда требует правки расширения | сравнение и объединение при каждом обновлении |
ДокументСсылка.РеализацияТоваровУслуг) берутся из открытой конфигурации.СтатистикаДокументов и синоним «Статистика документов за период». Имя используется в коде, синоним пользователь видит в заголовке окна.Период типа СтандартныйПериод и табличную часть Результат с колонками ВидДокумента (Строка, 150), ИмяМетаданных (Строка, 80), Всего и Помечено (Число, 10, 0).Объект.Статистика..epf подставится само.Получится один файл внешней обработки 1С с реквизитами, модулями, формами и макетами. Базу он не меняет, пока код сам ничего не записывает.
Модуль внешней обработки 1С бывает двух видов: модуль объекта и модули форм. Модуль объекта открывается через контекстное меню корня обработки («Открыть модуль объекта»). Он исполняется там, где существует сам объект: на сервере, во внешнем соединении и в толстом клиенте обычного приложения. Сюда кладём всё, что обращается к данным.
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
// Заполняет табличную часть Результат: сколько документов каждого вида
// создано за Период и сколько из них помечено на удаление.
Процедура ЗаполнитьСтатистику() Экспорт
Результат.Очистить();
ШаблонТекста =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| КОЛИЧЕСТВО(*) КАК Всего,
| ЕСТЬNULL(СУММА(ВЫБОР
| КОГДА Т.ПометкаУдаления
| ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ), 0) КАК Помечено
|ИЗ
| #Таблица КАК Т
|ГДЕ
| Т.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(Период.ДатаНачала));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(Период.ДатаОкончания));
Для Каждого МетаДокумент Из Метаданные.Документы Цикл
// Без права чтения запрос упадет с ошибкой, такие виды пропускаем.
Если Не ПравоДоступа("Чтение", МетаДокумент) Тогда
Продолжить;
КонецЕсли;
Запрос.Текст = СтрЗаменить(ШаблонТекста, "#Таблица", "Документ." + МетаДокумент.Имя);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() И Выборка.Всего > 0 Тогда
НоваяСтрока = Результат.Добавить();
НоваяСтрока.ВидДокумента = МетаДокумент.Представление();
НоваяСтрока.ИмяМетаданных = МетаДокумент.Имя;
НоваяСтрока.Всего = Выборка.Всего;
НоваяСтрока.Помечено = Выборка.Помечено;
КонецЕсли;
КонецЦикла;
Результат.Сортировать("Всего Убыв");
КонецПроцедуры
// Выводит табличную часть Результат в табличный документ по макету «Статистика».
Функция СформироватьТабличныйДокумент() Экспорт
Макет = ПолучитьМакет("Статистика");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьИтого = Макет.ПолучитьОбласть("Итого");
ТабДок = Новый ТабличныйДокумент;
ОбластьШапка.Параметры.Период = ПредставлениеПериода(
НачалоДня(Период.ДатаНачала), КонецДня(Период.ДатаОкончания));
ТабДок.Вывести(ОбластьШапка);
Для Каждого СтрокаРезультата Из Результат Цикл
ОбластьСтрока.Параметры.Заполнить(СтрокаРезультата);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
ОбластьИтого.Параметры.Всего = Результат.Итог("Всего");
ОбластьИтого.Параметры.Помечено = Результат.Итог("Помечено");
ТабДок.Вывести(ОбластьИтого);
Возврат ТабДок;
КонецФункции
#КонецОбласти
#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение — модуль объекта не должен компилироваться на тонком клиенте. Ветка #Иначе даёт понятную ошибку, если объект попытаются создать не там.ВЫБРАТЬ РАЗРЕШЕННЫЕ — при ограничении доступа на уровне записей запрос без этого слова завершится ошибкой, а с ним посчитает только доступные пользователю документы.ПравоДоступа("Чтение", МетаДокумент) отсекает виды документов, которые пользователю не видны вообще.СтрЗаменить. Это имя из метаданных, а не пользовательский ввод, так что испортить текст запроса нечем.СГРУППИРОВАТЬ ПО возвращает строку и тогда, когда документов нет. Проверка Выборка.Всего > 0 отбрасывает пустые виды.ПолучитьМакет("Статистика") — метод объекта обработки. Макет разбирается на сервере, а на клиент уходит готовый табличный документ.Запросов будет столько, сколько видов документов в конфигурации (в ERP их сотни), так что на большой базе обработка думает заметное время.
Откройте макет «Статистика» и нарисуйте три блока строк:
ВидДокумента, Всего, Помечено;Всего, Помечено.Чтобы строки стали областью, выделите их по номерам слева и назначьте имя через меню «Таблица → Имена → Назначить имя». В свойствах ячейки со значением поставьте «Заполнение» = «Параметр» и впишите имя параметра — такое же, как у колонки табличной части. Тогда одна строка ОбластьСтрока.Параметры.Заполнить(СтрокаРезультата) разложит значения по ячейкам. Для смешанного текста, как в заголовке, выберите «Заполнение» = «Шаблон» и пишите параметр в квадратных скобках.
В форме перетащите реквизит Период и табличную часть Результат из дерева реквизитов в элементы, у таблицы включите «Только просмотр». На вкладке «Команды» создайте команды Сформировать и ПоказатьОтчет, назначьте им одноимённые действия и вынесите в командную панель. Обработчик ПриСозданииНаСервере привяжите в свойствах формы.
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// По умолчанию показываем текущий месяц.
Если Не ЗначениеЗаполнено(Объект.Период.ДатаОкончания) Тогда
Объект.Период.Вариант = ВариантСтандартногоПериода.ЭтотМесяц;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура Сформировать(Команда)
Если Не ЗначениеЗаполнено(Объект.Период.ДатаОкончания) Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Укажите период.'"));
Возврат;
КонецЕсли;
СформироватьНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ПоказатьОтчет(Команда)
Если Объект.Результат.Количество() = 0 Тогда
ПоказатьПредупреждение(, НСтр("ru = 'Сначала нажмите «Сформировать».'"));
Возврат;
КонецЕсли;
ТабДок = ТабличныйДокументНаСервере();
ТабДок.Показать(НСтр("ru = 'Документы за период'"));
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Процедура СформироватьНаСервере()
Обработка = РеквизитФормыВЗначение("Объект");
Обработка.ЗаполнитьСтатистику();
ЗначениеВРеквизитФормы(Обработка, "Объект");
КонецПроцедуры
&НаСервере
Функция ТабличныйДокументНаСервере()
Обработка = РеквизитФормыВЗначение("Объект");
Возврат Обработка.СформироватьТабличныйДокумент();
КонецФункции
#КонецОбласти
Главная связка здесь — РеквизитФормыВЗначение и ЗначениеВРеквизитФормы. На форме живёт не объект обработки, а данные формы: их можно передавать между клиентом и сервером, но методов модуля объекта у них нет. На сервере данные превращаются в объект ВнешняяОбработкаОбъект.СтатистикаДокументов, мы вызываем его экспортный метод и возвращаем результат на форму.
Каждый вызов процедуры &НаСервере — отдельное обращение к серверу с передачей данных формы. Поэтому серверную работу собирают в один вызов, а не вызывают сервер в цикле. Коду, которому данные формы не нужны, подходит &НаСервереБезКонтекста: такой вызов легче, но реквизиты формы в нём недоступны.
В режиме «1С:Предприятие» откройте файл через главное меню «Файл → Открыть» (Ctrl+O). Если у пользователя включена защита от опасных действий, платформа покажет предупреждение безопасности, его нужно подтвердить. Без права «Интерактивное открытие внешних обработок» открыть файл не получится вовсе — это право обычно есть только у администраторов.
Для отладки запустите базу из конфигуратора (F5), поставьте точку останова в модуле обработки, открытой в конфигураторе, и откройте в клиенте этот же файл. В клиент-серверном варианте серверный код остановится на точке, только если на сервере 1С разрешена отладка.
Открывать файл через меню неудобно и небезопасно. В конфигурациях на БСП (БП 3.0, УТ 11, КА 2, ERP 2, УНФ 3.0) обработку загружают в справочник «Дополнительные отчеты и обработки» и там указывают, в каком разделе показывать команду. Чтобы БСП приняла файл, в модуле объекта нужна экспортная функция СведенияОВнешнейОбработке(). Другие полезные подсистемы — в статье про БСП.
// Только для конфигураций на БСП. Добавьте в область ПрограммныйИнтерфейс
// модуля объекта (внутри #Если ... #КонецЕсли).
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.Информация = НСтр("ru = 'Количество документов каждого вида за период'");
Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = НСтр("ru = 'Статистика документов за период'");
Команда.Идентификатор = "ОткрытьСтатистику";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
Команда.ПоказыватьОповещение = Ложь;
Возврат ПараметрыРегистрации;
КонецФункции
В конфигурации без БСП эту функцию не добавляйте: общего модуля ДополнительныеОтчетыИОбработки там нет, и модуль объекта не скомпилируется. Поэтому в сводный листинг обработки она не включена.
Дальше: «Администрирование → Печатные формы, отчеты и обработки», включите флажок «Дополнительные отчеты и обработки», откройте одноимённый список и нажмите «Добавить из файла…». В карточке укажите разделы для размещения команды и оставьте публикацию «Используется». Пользователь найдёт команду в выбранном разделе, в списке «Дополнительные обработки». Названия пунктов немного различаются в разных конфигурациях и версиях БСП.
По умолчанию БСП подключает такие файлы в безопасном режиме. Запросы и чтение метаданных в нём работают, поэтому наш пример ничего не заметит. Работа с файлами на сервере, COM-объектами и внешними компонентами в безопасном режиме запрещена. Для таких операций актуальные версии БСП запрашивают отдельные разрешения, а не отключают безопасный режим целиком.
Если обработка меняет документы, запись идёт через обычный объект документа. Сработают обработчики ПередЗаписью, ПриЗаписи и подписки на события, и любой из них может отказать в записи. Поэтому ошибки ловим по каждому документу отдельно, чтобы один сбой не останавливал всю пачку. Массив ссылок обычно получают запросом в том же модуле объекта; о поиске конкретных документов — в статье как получить ссылку.
// Модуль объекта. Записывает комментарий в переданные документы.
// Реквизит Комментарий есть в большинстве документов типовых конфигураций.
Процедура УстановитьКомментарий(МассивДокументов, ТекстКомментария) Экспорт
Для Каждого СсылкаНаДокумент Из МассивДокументов Цикл
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Если ДокументОбъект = Неопределено Тогда
Продолжить; // документ уже удален
КонецЕсли;
Попытка
ДокументОбъект.Заблокировать();
ДокументОбъект.Комментарий = ТекстКомментария;
// Комментарий не влияет на движения, поэтому пишем без перепроведения.
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
Исключение
ТекстОшибки = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
Сообщить(НСтр("ru = 'Не удалось записать'") + " " + Строка(СсылкаНаДокумент)
+ ": " + ТекстОшибки);
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Проверку заполнения программная запись не запускает, её выполняет форма при интерактивной записи. Нужен контроль обязательных реквизитов — вызовите ДокументОбъект.ПроверитьЗаполнение() перед Записать и пропускайте документ, если метод вернул Ложь.
Групповую запись сначала прогоните на копии базы: отменить сотню записанных документов нечем, кроме резервной копии.
Объект.ЗаполнитьСтатистику() или ЭтотОбъект.ЗаполнитьСтатистику() в процедуре &НаКлиенте приводит к ошибке «Метод объекта не обнаружен (ЗаполнитьСтатистику)». В модуле формы ЭтотОбъект — это сама форма, а Объект — данные формы. Нужен серверный вызов с РеквизитФормыВЗначение.Новый Запрос в клиентской процедуре даёт «Тип не определен (Запрос)». Работа с базой — только на сервере.ЗначениеВРеквизитФормы. Ошибки нет, но таблица на форме пустая: изменения остались в серверной копии объекта.Объект в процедуре &НаСервереБезКонтекста. Модуль не скомпилируется: «Переменная не определена (Объект)».СведенияОВнешнейОбработке модуль объекта не компилируется: «Переменная не определена (ДополнительныеОтчетыИОбработки)», и обработка не открывается.Обработку пользователь запускает сам, в конфигурацию она не встраивается. Расширение добавляет реквизиты, меняет формы и перехватывает методы типовых модулей. Поменять поведение типового документа при записи обработкой не получится.
В мастере формы выберите тип «Обычная». Модуль такой формы исполняется в толстом клиенте, поэтому запросы можно писать прямо в нём, а директивы &НаКлиенте и &НаСервере не нужны. Макет и модуль объекта работают так же, как в примере выше. Если в мастере нет выбора типа формы, включите в конфигураторе «Сервис → Параметры → Общие → Редактирование конфигурации для режимов запуска: Управляемое приложение и обычное приложение».
На клиенте поместите файл во временное хранилище (НачатьПомещениеФайла), на сервере вызовите ВнешниеОбработки.Подключить: метод вернёт имя, по которому открывают форму "ВнешняяОбработка." + Имя + ".Форма". Третий параметр метода — безопасный режим; отключайте его только для файлов, которым доверяете.
Регламентное задание само по себе вызывает только метод общего модуля конфигурации. В БСП дополнительную обработку с командой вида «Вызов серверного метода» можно поставить на расписание в её карточке. Для этого в модуле объекта реализуют процедуру ВыполнитьКоманду.
Если обработка должна менять много документов, работать с файлами или внешними сервисами либо встраиваться в типовую через БСП, быстрее отдать её программисту: ошибка в групповой записи обходится дороже, чем сам код. Мы делаем отчёты и обработки 1С без снятия конфигурации с поддержки. Опишите задачу на странице «Разместить задачу» — оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.