Как писать, отлаживать и сопровождать код на встроенном языке 1С 8.3

· 10 мин

Содержание

Работа с кодом в 1С идёт в модулях конфигурации. Открыть их можно в Конфигураторе (Конфигурация → Открыть конфигурацию), в 1C:Enterprise Development Tools (EDT) или в VS Code с расширением для языка BSL. Отлаживать код при этом удобнее всего в Конфигураторе или EDT: там есть точки останова, пошаговое выполнение и замер производительности.

Частое заблуждение новичков: «код в 1С пишут только в Конфигураторе, а всё остальное — игрушки». На деле Конфигуратор остаётся основным инструментом для правок в рабочей базе, но командные проекты давно живут в EDT и Git, а VS Code берут ради статического анализа и быстрой навигации по выгруженным исходникам. Всё сказанное ниже относится к платформе 8.3 и подходит для любых конфигураций на ней.

Где писать код: Конфигуратор, EDT или VS Code

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

СредаКогда подходитОграничения
КонфигураторПравки в одной базе, отладка, обновление типовых, работа с хранилищемСлабый поиск и рефакторинг, нет встроенного Git
EDT (на основе Eclipse)Командная разработка, Git, ветки, проверки кода на летуТребовательна к памяти, проект живёт в файлах, а не в базе
VS Code + BSL Language ServerЧтение и анализ выгруженных исходников, проверка по стандартамНет визуальных редакторов форм и макетов, отладка не основная задача

Настройка рабочего места под Конфигуратор

  1. Заведите отдельную копию базы для разработки. В рабочей базе код не пишут: ошибка в модуле проведения остановит работу бухгалтерии.
  2. Откройте конфигурацию: Конфигурация → Открыть конфигурацию.
  3. Проверьте, что конфигурация доступна для изменения. У типовой на поддержке объекты закрыты замками — правки лучше вносить через расширение (о нём ниже).
  4. Держите под рукой Синтаксис-помощник: Справка → Синтаксис-помощник. Там описан каждый метод платформы с параметрами и контекстом выполнения.

Как подключить VS Code к коду базы

VS Code не открывает базу 1С напрямую. Сначала конфигурацию выгружают в файлы: в Конфигураторе Конфигурация → Выгрузить конфигурацию в файлы или из командной строки:

"C:\Program Files\1cv8\<версия>\bin\1cv8.exe" DESIGNER /F "D:\Bases\Dev" /N "Администратор" /P "пароль" /DumpConfigToFiles "D:\src\cf"

Обратная операция — ключ /LoadConfigFromFiles с тем же каталогом. Дальше в VS Code ставят расширение для языка 1С от сообщества 1c-syntax. Оно подтягивает BSL Language Server: подсветку, переход к определению и сотни диагностик по стандартам.

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

Модули конфигурации и где на самом деле выполняется код

Код в 1С 8.3 всегда принадлежит какому-то модулю. От типа модуля зависит, когда он вызывается и какие данные ему доступны.

  • 📦 Модуль объекта — обработчики записи и проведения конкретного документа или элемента справочника: ПередЗаписью, ОбработкаПроведения, ОбработкаЗаполнения.
  • 🗂 Модуль менеджера — код, который не привязан к одному объекту: печать, выборки, служебные функции объекта.
  • 🖼 Модуль формы — реакция на действия пользователя: нажатия, изменения полей, открытие формы.
  • 🧰 Общие модули — библиотека процедур для всей конфигурации. Флажки в свойствах (Сервер, Клиент (управляемое приложение), Вызов сервера, Привилегированный, Глобальный) определяют, откуда модуль можно вызвать.
  • 🚪 Модуль сеанса, модуль управляемого приложения, модуль внешнего соединения — код при старте сеанса и при запуске клиента.

Директивы компиляции: клиент и сервер

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

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

Типичная связка в модуле формы документа выглядит так:

&НаКлиенте
Процедура Заполнить(Команда)
	ЗаполнитьНаСервере();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьНаСервере()
	Объект.Комментарий = "Заполнено " + Формат(ТекущаяДатаСеанса(), "ДФ=dd.MM.yyyy");
КонецПроцедуры

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

Каждый серверный вызов с клиента — это обращение по сети. Если в обработчике три подряд вызова &НаСервере, объедините их в один &НаСервереБезКонтекста и передайте нужные значения параметрами.

Длинные модули делят на области: #Область ПрограммныйИнтерфейс … #КонецОбласти. Области сворачиваются в редакторе и не влияют на выполнение. Для кода, который должен компилироваться только на сервере, используют инструкции препроцессора: #Если Сервер Тогда … #КонецЕсли.

Встроенный язык 1С: синтаксис и работа с объектами

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

Ссылка и объект — главное различие

Через ссылку данные только читают. Чтобы изменить и записать элемент, нужен объект:

// Создание нового элемента справочника
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Тестовый товар";
НовыйЭлемент.Записать();

// Изменение существующего: от ссылки к объекту
ТоварОбъект = НовыйЭлемент.Ссылка.ПолучитьОбъект();
ТоварОбъект.Наименование = "Тестовый товар (изменён)";
ТоварОбъект.Записать();

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

Данные читают запросом

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

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

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
	Сообщить(Выборка.Наименование);
КонецЦикла;

Для быстрых экспериментов не трогайте конфигурацию вовсе. Создайте внешнюю обработку (Файл → Новый → Внешняя обработка), напишите код в её модуле и откройте файл в режиме 1С:Предприятие. Конфигурация при этом не меняется.

Проверьте себя
Процедура в модуле формы должна прочитать остаток товара из регистра и вернуть число. Форма ей не нужна. Какую директиву поставить?
Где нельзя открыть окно с вопросом пользователю?
Что нужно добавить к объявлению процедуры общего модуля, чтобы её видели другие модули?

Отладка кода в 1С и поиск медленных мест

Отладчик встроен в Конфигуратор. Базовый набор клавиш:

  • ▶️ F5 — запустить 1С:Предприятие в режиме отладки;
  • 🔴 F9 — поставить или снять точку останова на строке;
  • ⤵️ F11 — шагнуть внутрь процедуры, F10 — выполнить строку целиком, Shift+F11 — выйти из текущей процедуры;
  • 🔍 Shift+F9 — вычислить выражение: значение переменной, результат запроса, содержимое таблицы;
  • ✅ Ctrl+F7 — проверить синтаксис текущего модуля без запуска.

Когда точка останова не срабатывает

Самый частый вопрос. Причины обычно такие:

  1. Код выполняется на сервере, а база клиент-серверная, и сервер 1С запущен без отладки. Служба агента сервера должна работать с ключом -debug.
  2. Конфигурация изменена, но не обновлена: Конфигурация → Обновить конфигурацию базы данных (F7). Отладчик сверяет строки с тем, что реально выполняется.
  3. Строка не выполняется вообще: условие выше не пускает выполнение, или обработчик не привязан к событию формы.

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

Остановка по ошибке

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

Замер производительности

Если проведение документа идёт 20 секунд, не гадайте. Запустите Отладка → Замер производительности, повторите медленное действие и остановите замер. Платформа покажет по каждой строке число выполнений и долю времени.

Обычная картина: одна строка с запросом внутри цикла выполнилась 3 000 раз и заняла 80% времени. Её выносят из цикла: один запрос по всем строкам сразу вместо 3 000 мелких.

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

Обработка ошибок и исключений в коде 1С

Ошибки перехватывают конструкцией Попытка … Исключение … КонецПопытки. Главное правило: не глушить исключение молча. Пустой блок Исключение превращает понятную ошибку в «документ почему-то не провёлся».

Попытка
	ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
	ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
	ЗаписьЖурналаРегистрации("Загрузка документов",
		УровеньЖурналаРегистрации.Ошибка, , ДокументОбъект.Ссылка, ТекстОшибки);
	Сообщить("Не удалось провести документ: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Функции ПодробноеПредставлениеОшибки и КраткоеПредставлениеОшибки доступны в платформе с номером не ниже 8.3.17. На старых платформах используйте ОписаниеОшибки().

Шаблон работы с транзакцией

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

НачатьТранзакцию();
Попытка
	// изменения данных
	ЗафиксироватьТранзакцию();
Исключение
	ОтменитьТранзакцию();
	ВызватьИсключение;
КонецПопытки;

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

Собственную ошибку для пользователя генерируют так: ВызватьИсключение "Не заполнен склад в строке 3";. Текст сразу объясняет, что исправить.

Как менять код типовой конфигурации и не терять обновления

Правка модулей типовой конфигурации напрямую снимает её с поддержки. Каждое следующее обновление превращается в ручное сравнение и объединение.

Современный путь — расширение конфигурации (доступно с платформы 8.3.6). В расширение заимствуют нужный объект и перехватывают его процедуры аннотациями:

  • &Перед("ИмяПроцедуры") — ваш код выполняется до типового;
  • &После("ИмяПроцедуры") — после типового;
  • &Вместо("ИмяПроцедуры") — вместо типового, с возможностью вызвать исходный через ПродолжитьВызов();
  • &ИзменениеИКонтроль("ИмяПроцедуры") — точечная вставка и удаление строк внутри типовой процедуры (платформа не ниже 8.3.16).

Открыть расширения в Конфигураторе: Конфигурация → Расширения конфигурации. После добавления расширения базу нужно обновить так же, как основную конфигурацию.

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

Стандарты разработки и привычки, которые отличают аккуратный код

Фирма 1С публикует систему стандартов и методик разработки конфигураций. BSL Language Server и проверки EDT во многом построены на ней. Самые полезные правила для повседневной работы:

  • 🧾 Никаких запросов в цикле. Собирайте данные одним запросом, передавая в него таблицу или массив параметром.
  • 🔗 Не читайте реквизиты ссылок через точку в серверном коде. Нужно одно-два поля — получите их запросом.
  • 📡 Минимум клиент-серверных вызовов. Один вызов &НаСервереБезКонтекста дешевле трёх вызовов &НаСервере.
  • 🧩 Понятные имена. СуммаСНДС, а не С1. Процедура делает одно действие и называется глаголом.
  • 📝 Комментарий к экспортной процедуре. Что делает, какие параметры, что возвращает. Конфигуратор и EDT показывают его в подсказке.
  • 🗂 Области в модулях. ПрограммныйИнтерфейс, СлужебныеПроцедурыИФункции, ОбработчикиСобытий — по ним коллега находит нужное за секунды.
  • 🔒 Не обходите права через Привилегированный без необходимости. Привилегированный модуль выполняется без проверки прав пользователя.

Групповая разработка

Если над конфигурацией работают двое и больше, нужен общий источник правды. Варианты:

СпособКак устроенКому подходит
Хранилище конфигурацииОбъекты захватываются на изменение, помещаются обратно с комментариемНебольшие команды, работа в Конфигураторе
EDT + GitИсходники в файлах, ветки, слияние, ревью кодаКоманды от 3 человек, длинные доработки
Выгрузка в файлы + GitКонфигуратор остаётся основной средой, Git хранит историюПереходный вариант
Перед переносом доработки в рабочую базу
Выполнено: 0 / 6

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

Можно ли полностью отлаживать код 1С в VS Code?
VS Code используют в первую очередь для чтения, навигации и статического анализа выгруженных исходников. Пошаговую отладку с точками останова надёжнее вести в Конфигураторе или EDT.
Как быстро найти, где в типовой конфигурации выполняется нужное действие?
Включите Отладка → Остановка по ошибке, если действие заканчивается ошибкой. В остальных случаях помогает глобальный поиск по тексту модулей в Конфигураторе: ищите по тексту сообщения, которое видит пользователь.
Нужно ли знать английский синтаксис встроенного языка?
Нет. Каждый оператор и метод имеет русское и английское имя, они взаимозаменяемы. Английский вариант встречается в открытых библиотеках сообщества и в инструментах автоматизации.
Что выбрать для новой команды: хранилище или Git?
Хранилище проще запустить, но оно не даёт веток и ревью. Для команды, которая ведёт несколько доработок параллельно, удобнее EDT с Git.
Почему код в модуле формы не видит процедуру общего модуля?
Проверьте флажок Экспорт у процедуры и флажки общего модуля. Серверный модуль без признака Вызов сервера нельзя вызвать из клиентского кода напрямую.