Создание обработок в 1С 8.3: от объекта до внешнего файла

· 9 мин

Содержание

Обработку в 1С 8.3 пишут двумя путями: как объект внутри конфигурации или как отдельный внешний файл с расширением .epf. И то и другое создаётся в Конфигураторе (или в 1С:EDT), код — на встроенном языке, интерфейс — на управляемой форме. Писать обработки в 1С имеет смысл тогда, когда нужно выполнить действие, а не хранить данные: пересчитать цены в номенклатуре, разово загрузить остатки из файла, собрать служебный отчёт по регистру.

Классический случай: бухгалтер просит «поправить во всех договорах одно поле», документов — тысячи, руками нереально. Отчёт тут не поможет (он только показывает), а обработка пройдёт по данным и запишет изменения.

Ниже — весь путь: от выбора типа объекта до упаковки готового .epf, с кодом под управляемое приложение 1С 8.3.

Внешняя или встроенная: выбираем тип и создаём объект

Первое решение — где будет жить обработка.

  • 🧩 Встроенная — объект в дереве конфигурации. Ставится вместе с обновлением, доступна через меню, но требует снятия конфигурации с поддержки или своего расширения.
  • 📦 Внешняя (.epf) — отдельный файл. Не трогает конфигурацию, легко передать, подключить и удалить. Для разовых задач и утилит — почти всегда выбор в её пользу.

Для доработок «на живой базе» удобнее внешняя обработка, помещённая в справочник Дополнительные обработки (есть в типовых на БСП): раздел Администрирование → Печатные формы, отчёты и обработки. Так она не ломает поддержку и подключается без Конфигуратора.

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

В Конфигураторе: Файл → Новый → Внешняя обработка. Откроется окно объекта — задайте имя (латиницей, без пробелов, например ПересчётЦен) и синоним (это русское название для пользователя).

Чтобы сразу работать с файлом, сохраните его: Файл → Сохранить → имя .epf. Дальше вся правка идёт в этом файле.

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

В дереве конфигурации найдите ветку Обработки, правой кнопкой — Добавить. Остальное идентично внешней: имя, синоним, формы, модуль. Разница только в способе поставки.

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

Форма обработки: реквизиты, команды и элементы

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

В окне объекта откройте вкладку Формы и нажмите «плюс». Мастер предложит тип — для обработки это форма обработки. Галку «назначить основной» оставьте включённой, иначе форма не откроется двойным кликом.

Форма управляемого приложения состоит из трёх связанных частей:

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

Пример: поле периода и кнопка запуска

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

Реквизиты формы живут только пока форма открыта. Если данные нужно сохранить между сеансами, пишите их в константу, регистр сведений или настройки хранилища — сама форма ничего не помнит.

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

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

ДирективаГде работаетДля чего
&НаКлиентетонкий клиентдиалоги, вопросы, открытие форм
&НаСервересервер, с контекстом формычтение/запись данных, запросы
&НаСервереБезКонтекстасервер, без формырасчёты, не трогающие форму
&НаКлиентеНаСервереБезКонтекстаобе стороныобщие функции без обращения к БД

Главное правило: база данных доступна только на сервере. Прочитать справочник, выполнить запрос, записать документ — всё это на сервере.

Типичная связка — команда формы вызывает клиентскую процедуру, та передаёт управление на сервер:

&НаКлиенте
Процедура Выполнить(Команда)
    КоличествоОбработанных = ВыполнитьНаСервере(ПериодОтбора.ДатаНачала, ПериодОтбора.ДатаОкончания);
    Сообщить("Обработано объектов: " + КоличествоОбработанных);
КонецПроцедуры

&НаСервере
Функция ВыполнитьНаСервере(ДатаС, ДатаПо)
    // здесь доступны запросы и запись данных
    Возврат ОбработатьДанные(ДатаС, ДатаПо);
КонецФункции

Серверный вызов — это «дорога» между клиентом и сервером. Чем их меньше, тем быстрее работает форма. Не вызывайте сервер в цикле: соберите параметры и сходите на сервер один раз.

Директиву &НаСервереБезКонтекста используйте, когда процедуре не нужны реквизиты формы — такой вызов легче, потому что не тащит на сервер всё содержимое формы.

Длительные операции в фоне

Если обработка перебирает тысячи объектов, прямой серверный вызов заморозит форму: пользователь увидит «зависший» интерфейс и может решить, что программа упала. Чтобы этого избежать, тяжёлую работу запускают в фоновом задании.

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

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

Запросы и работа с данными в обработке

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

Собирать текст запроса вручную не нужно: правой кнопкой в модуле — Конструктор запроса. Он покажет таблицы (справочники, документы, регистры), поможет собрать поля, условия и соединения.

Выполнение запроса в коде

&НаСервере
Функция ПолучитьНоменклатуру(ДатаС, ДатаПо)
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |   Товары.Ссылка КАК Ссылка,
        |   Товары.Наименование КАК Наименование
        |ИЗ
        |   Справочник.Номенклатура КАК Товары
        |ГДЕ
        |   НЕ Товары.ПометкаУдаления";
    
    Выборка = Запрос.Выполнить().Выбрать();
    
    Результат = Новый Массив;
    Пока Выборка.Следующий() Цикл
        Результат.Добавить(Выборка.Ссылка);
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Параметры в запрос передавайте через Запрос.УстановитьПараметр("ДатаС", ДатаС), а в тексте пишите &ДатаС. Никогда не вставляйте значения прямо в строку запроса — это и медленно, и небезопасно.

Чтение и запись наборов записей

Если обработка правит регистры, работайте через набор записей, а не через отдельные строки:

Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(ТоварСсылка);
Набор.Прочитать();
// правим строки набора
Набор.Записать();

Для справочников и документов берите объект через .ПолучитьОбъект(), меняйте реквизиты и вызывайте .Записать(). Менять данные напрямую в выборке запроса нельзя — запрос только читает.

Временные таблицы для больших выборок

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

Для этого в конструкторе запроса на вкладке Пакет запросов первым шагом поместите выборку в ПОМЕСТИТЬ ВременнаяТаблица, а в коде передайте объект МенеджерВременныхТаблиц:

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

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

Транзакции: безопасная запись изменений

Когда обработка меняет много объектов в цикле, оберните запись в транзакцию. Тогда при сбое на середине не останется половины изменённых данных.

НачатьТранзакцию();
Попытка
    Для Каждого Ссылка Из МассивОбъектов Цикл
        Объект = Ссылка.ПолучитьОбъект();
        Объект.Комментарий = "Обработано";
        Объект.Записать();
    КонецЦикла;
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

Правила, которые экономят нервы:

  • 🔁 На каждый НачатьТранзакцию() — ровно один ЗафиксироватьТранзакцию() или ОтменитьТранзакцию(). Незакрытая транзакция повесит сеанс.
  • 🧯 В блоке Исключение сначала ОтменитьТранзакцию(), потом уже разбор ошибки. Иначе платформа ругнётся на незавершённую транзакцию.
  • 📏 Не держите в одной транзакции тысячи записей — это раздувает блокировки. Крупные массивы обрабатывайте порциями по несколько сотен объектов, фиксируя каждую порцию.

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

Вывод результата в табличный документ

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

Самый управляемый способ — макет:

  1. На вкладке Макеты объекта добавьте макет типа Табличный документ.
  2. Нарисуйте области: шапку, строку данных, подвал. Имена областям задайте в свойствах.
  3. В ячейки с данными впишите [ИмяПараметра] и пометьте ячейку как параметр.
  4. В коде заполните и выведите области.
&НаСервере
Функция СформироватьОтчёт(Данные)
    Макет = Обработки.ПересчётЦен.ПолучитьМакет("Макет");
    Таб = Новый ТабличныйДокумент;
    
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    Таб.Вывести(ОбластьШапка);
    
    ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
    Для Каждого Строка Из Данные Цикл
        ОбластьСтрока.Параметры.Наименование = Строка.Наименование;
        Таб.Вывести(ОбластьСтрока);
    КонецЦикла;
    
    Возврат Таб;
КонецФункции

Готовый табличный документ возвращайте на клиент и показывайте через поле формы типа ТабличныйДокумент либо откройте отдельно. Пользователь сможет распечатать его или выгрузить в Excel стандартными средствами 1С.

Для сложных отчётов с группировками и настройками удобнее не рисовать макет вручную, а взять систему компоновки данных (СКД). Но для «вывести, что обработали» ручного табличного документа достаточно.

Отладка, тестирование и упаковка внешней обработки

Перед передачей обработку надо проверить в отладчике и на тестовых данных.

Отладка

Запустите базу в режиме 1С:Предприятие из Конфигуратора клавишей F5 — отладка включится автоматически. Поставьте точку останова (F9) на нужной строке модуля: когда выполнение дойдёт до неё, оно остановится.

Что помогает на остановке:

  • 👁 Табло (Отладка → Табло) — показывает значения переменных. Выделите переменную и перетащите в табло.
  • ➡️ Шаг с заходом (F11) и шаг с обходом (F10) — проход по строкам.
  • 🧪 Вычисление выражения (Shift+F9) — посмотреть содержимое структуры, таблицы значений, выборки прямо на паузе.

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

Тестирование

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

Перед передачей внешней обработки
Выполнено: 0 / 6

Упаковка и подключение

Готовую внешнюю обработку сохраните как .epf (Файл → Сохранить). Передать можно просто файлом.

Подключение на стороне пользователя:

  • Разово: Файл → Открыть в режиме 1С:Предприятие (нужны права на открытие внешних обработок).
  • Постоянно: через справочник Дополнительные обработки — раздел Администрирование → Печатные формы, отчёты и обработки. Там обработка появится в списке и будет доступна без Конфигуратора.

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

Чем обработка отличается от отчёта?
Отчёт только читает и показывает данные, ничего не меняя. Обработка выполняет действие — может читать, считать и записывать изменения в базу. По технике они близки, отличается назначение.
Почему код в запросе не видит справочник, а на форме всё работает?
Запросы и обращение к базе возможны только на сервере. Если процедура помечена &НаКлиенте, базы она не видит. Перенесите работу с данными в процедуру &НаСервере.
Можно ли менять типовую конфигурацию обработкой, не снимая с поддержки?
Да. Внешняя обработка и расширение конфигурации не трогают основную конфигурацию и не мешают обновлениям. Прямую правку конфигурации лучше не делать.
Как передать результат с сервера на клиент?
Серверная функция возвращает значение (число, массив, табличный документ), клиентская процедура его принимает. Объекты вроде ДокументОбъект на клиент не передаются — передавайте ссылки или примитивные данные.
Обработка выдаёт «Транзакция не завершена» — в чём дело?
Где-то НачатьТранзакцию() не закрыт парным Зафиксировать/Отменить, чаще всего из-за ошибки в цикле. Оберните тело в Попытка…Исключение и в блоке исключения вызовите ОтменитьТранзакцию().