К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как написать процедуру в 1С: пошаговое руководство

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

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

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

Где размещать процедуру: выбор модуля

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

Модуль формы подходит для логики интерфейса: обработчики кнопок, реакция на изменение полей. Модуль объекта — для бизнес-логики конкретного объекта: проведение, заполнение, проверка данных. Общий модуль — для кода, который вызывается из разных мест конфигурации.

Где разместить процедуру

Модуль формы

Обработчики событий элементов формы, команды. Ограничение: требует директив компиляции и разделения клиент/сервер.

Модуль объекта

Проведение, заполнение, проверка заполнения. Выполняется на сервере, недоступен с клиента напрямую.

Общий модуль

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

Модуль менеджера

Операции над коллекцией объектов: печать, получение данных без создания объекта.

Базовый синтаксис процедуры

Минимальная процедура состоит из ключевого слова «Процедура», имени, круглых скобок с параметрами, тела и завершающего «КонецПроцедуры». Имя должно начинаться с буквы и отражать действие: «ЗаполнитьТаблицуТоваров», «ПроверитьОстатки».

Процедура ЗаполнитьСкидку(ПроцентСкидки) Экспорт

Если ПроцентСкидки > 30 Тогда

ВызватьИсключение "Скидка не может превышать 30%";

КонецЕсли;

Для Каждого Строка Из Товары Цикл

Строка.Сумма = Строка.Сумма * (100 - ПроцентСкидки) / 100;

КонецЦикла;

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

Ключевое слово «Экспорт» делает процедуру доступной из других модулей. Без него процедура видна только внутри своего модуля — это правильный выбор для вспомогательных внутренних операций. Не помечайте Экспорт всё подряд: широкий интерфейс модуля усложняет сопровождение.

Параметры: по ссылке, по значению и со значением по умолчанию

По умолчанию параметры передаются по ссылке: процедура может изменить переданную переменную, и вызывающий код увидит изменение. Если процедура не должна менять аргумент, используйте ключевое слово «Знач» — тогда передаётся копия.

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

Процедура СформироватьОтчет(Знач Период, Организация = Неопределено, Сжать = Ложь)

// Период передан по значению — исходная переменная не изменится

// Организация и Сжать можно не указывать при вызове

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

// Вызов:

СформироватьОтчет(ТекущийПериод, , Истина);

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

Директивы компиляции в модулях форм

В модуле формы управляемого приложения каждая процедура должна иметь директиву компиляции: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста или &НаКлиентеНаСервереБезКонтекста. Без директивы код не скомпилируется.

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

&НаКлиенте

Процедура КомандаРассчитать(Команда)

РассчитатьНаСервере(Объект.Ссылка);

ОбновитьОтображениеДанных();

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

&НаСервереБезКонтекста

Процедура РассчитатьНаСервере(Ссылка)

// запрос к данным

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

Пошаговый порядок написания процедуры

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

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

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

Как проверить результат

Главный инструмент — отладчик конфигуратора. Поставьте точку останова внутри процедуры, запустите отладку и выполните действие, вызывающее процедуру. По F11 (шаг с заходом) и F10 (шаг через) пройдите код построчно, наблюдая значения переменных в табло (Shift+F9).

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

Контрольные точки

Как проверить результат

Синтаксис модуля
Норма

Проверка модуля завершается без ошибок и предупреждений

Тревожный признак

Ошибки компиляции, неопределённые переменные

Вызов процедуры
Норма

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

Тревожный признак

Процедура не вызывается или параметры равны Неопределено

Результат работы
Норма

Данные изменились как задумано, движения документа корректны

Тревожный признак

Данные не изменились или изменились лишние записи

Поведение при ошибке
Норма

Некорректный ввод вызывает понятное исключение

Тревожный признак

Тихое падение или запись мусора в базу

Типичные ошибки начинающих

Большинство проблем с процедурами у новичков однотипны. Знание этого списка сокращает отладку в разы.

Типичные ошибки
01
Вызов серверной процедуры без директивы &НаСервере — код не компилируется или падает в рантайме
02
Изменение параметра, переданного по ссылке, когда вызывающий код этого не ожидает — трудноуловимые побочные эффекты
03
Экспорт всех процедур подряд — модуль превращается в неуправляемый интерфейс
04
Игнорирование проверки на Неопределено — исключение в глубине кода вместо понятной ошибки на входе
05
Обращение к реквизитам формы из процедуры &НаСервереБезКонтекста — ошибка компиляции
06
Забытый КонецПроцедуры или лишний КонецЕсли — каскад синтаксических ошибок ниже по модулю

Процедура или функция?

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

Контекст сервера в тонком клиенте

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

Частые вопросы

Чем процедура отличается от функции в 1С?

Функция возвращает значение через оператор «Возврат» и может использоваться в выражениях: Итог = РассчитатьСумму(). Процедура только выполняет действия и вызывается отдельным оператором. Если результат не нужен — пишите процедуру, это точнее отражает намерение кода.

Как вызвать процедуру из другого общего модуля?

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

Почему процедура в модуле формы не видна на клиенте?

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

Можно ли передать в процедуру таблицу значений?

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

Что делать, если процедура работает в отладке, но не в рабочей базе?

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

Нужно ли писать комментарии к процедуре?

Да, особенно к экспортным. Стандарт разработки 1С рекомендует заголовок с описанием назначения, параметров и возвращаемого значения. Хороший комментарий отвечает на вопрос «зачем», а не пересказывает код — имя процедуры и параметров уже говорит «что».

Итог

Что важно запомнить

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