На чём пишут в 1С: встроенный язык платформы и его особенности
Содержание
В 1С:Предприятии 8.3 используется собственный встроенный язык 1С — предметно-ориентированный язык платформы с русскоязычным синтаксисом и английскими синонимами ключевых слов. К нему в пару идёт отдельный язык запросов 1С, похожий на SQL. Других языков программирования для прикладного кода платформа не предлагает: всё, от проведения документа до печатной формы, пишется на этих двух.
Язык не универсальный, как Python или C#. Его сила в другом: он работает поверх готовых объектов учёта — справочников, документов, регистров. Программист описывает не таблицы и классы, а бизнес-логику. Ниже — как устроен язык, чем он отличается от мировых аналогов и чем на нём пишут.
Как устроен встроенный язык 1С
Код на встроенном языке живёт в модулях. Модуль привязан к месту в конфигурации, и это определяет, когда и где он выполняется.
| Модуль | Где находится | Для чего |
|---|---|---|
| Модуль объекта | у справочника, документа и т. п. | события записи, проведения, заполнения |
| Модуль менеджера | у объекта метаданных | процедуры, не привязанные к конкретному экземпляру |
| Модуль формы | у каждой формы | обработчики кнопок, полей, событий формы |
| Общий модуль | ветка «Общие модули» | библиотека процедур для всей конфигурации |
| Модуль сеанса | корень конфигурации | установка параметров сеанса при входе |
| Модуль приложения | корень конфигурации | события запуска и завершения клиента |
| Модуль набора записей | у регистра | контроль и дополнение движений |
Ключевые свойства языка:
- 🧩 Динамическая типизация. Тип переменной не объявляется, он определяется значением. Одна переменная может хранить сначала число, потом строку.
- ⚙️ Исполнение на платформе. Модуль при загрузке компилируется во внутренний код и выполняется виртуальной машиной платформы. Отдельного исполняемого файла нет.
- 🏗️ Нет пользовательских классов. Объявить свой класс с наследованием нельзя. Вместо этого есть объекты метаданных, которые разработчик создаёт в дереве конфигурации.
- 🌐 Двуязычность.
ПроцедураиProcedure,ЕслииIf— одно и то же. В типовых конфигурациях принято писать по-русски. - 🔒 Песочница платформы. Прямого доступа к памяти и указателей нет. Работа с файлами, сетью и ОС идёт через объекты платформы.
Компилятор платформы проверяет синтаксис модуля целиком. Ошибка в одной процедуре общего модуля делает недоступным весь модуль, поэтому проверку модулей в Конфигураторе стоит запускать перед каждым обновлением базы.
Синтаксис языка 1С: основные конструкции
По виду язык ближе всего к Visual Basic и Паскалю: блоки закрываются словами, а не фигурными скобками, оператор заканчивается точкой с запятой.
| Конструкция | Русский вариант | Английский вариант |
|---|---|---|
| Процедура | Процедура … КонецПроцедуры | Procedure … EndProcedure |
| Функция | Функция … Возврат … КонецФункции | Function … Return … EndFunction |
| Условие | Если … Тогда … ИначеЕсли … Иначе … КонецЕсли | If … Then … ElsIf … Else … EndIf |
| Цикл по счётчику | Для Сч = 1 По 10 Цикл … КонецЦикла | For … To … Do … EndDo |
| Цикл по коллекции | Для Каждого Эл Из Массив Цикл | For Each … In … Do |
| Цикл с условием | Пока … Цикл … КонецЦикла | While … Do … EndDo |
| Исключения | Попытка … Исключение … КонецПопытки | Try … Except … EndTry |
Небольшой пример — функция, которая считает сумму с НДС и возвращает строку:
Функция СуммаСНДСТекстом(Сумма, СтавкаПроцент = 20) Экспорт
Если Сумма <= 0 Тогда
ВызватьИсключение "Сумма должна быть больше нуля";
КонецЕсли;
СуммаНДС = Окр(Сумма * СтавкаПроцент / 100, 2);
Итог = Сумма + СуммаНДС;
Возврат СтрШаблон("Сумма %1, НДС %2, итого %3",
Формат(Сумма, "ЧДЦ=2"), Формат(СуммаНДС, "ЧДЦ=2"), Формат(Итог, "ЧДЦ=2"));
КонецФункции
Для суммы 1000 функция вернёт: Сумма 1000,00, НДС 200,00, итого 1200,00.
Что ещё бросается в глаза человеку из другого языка:
- 📝 Комментарий — только однострочный, через
//. - 🟰 Знак
=служит и присваиванием, и сравнением. «Не равно» пишется как<>. - 🔣 Логические операторы — словами:
И,ИЛИ,НЕ. - ❓ Тернарный оператор выглядит как
?(Условие, ЗначениеДа, ЗначениеНет). - 📅 Литерал даты — в одинарных кавычках:
'20261007'. - 📤 Слово
Экспортпосле заголовка делает процедуру видимой из других модулей. - 🧵 Многострочная строка продолжается символом
|в начале следующей строки.
Примитивные типы и коллекции
Примитивных типов немного: Число, Строка, Дата, Булево, а также особые значения Неопределено и NULL. NULL чаще всего приходит из запроса, когда при соединении не нашлось записи.
Коллекции дают всё нужное для обработки данных в памяти:
Массив— упорядоченный список значений;Структура— пары «ключ — значение» с ключами-строками;Соответствие— словарь, где ключом может быть любое значение, в том числе ссылка;СписокЗначений— список с представлениями и пометками, удобен для выбора в форме;ТаблицаЗначений— таблица в памяти с колонками, сортировкой, отбором и свёрткой;ДеревоЗначений— иерархическая таблица.
Асинхронный код
В современных версиях платформы 8.3 появились ключевые слова Асинх и Ждать. Они позволяют писать вызовы диалогов и вопросов пользователю в линейном стиле, без цепочек ОписаниеОповещения. В старом коде типовых конфигураций по-прежнему много обработчиков оповещений — это нормально, оба стиля работают.
Язык запросов и работа с базой данных
Читать данные из базы в 1С принято запросами. Язык запросов похож на SQL, но работает не с физическими таблицами СУБД, а с объектами конфигурации.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.Ссылка КАК Контрагент,
| Контрагенты.ИНН КАК ИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| НЕ Контрагенты.ПометкаУдаления
| И Контрагенты.ИНН = &ИНН";
Запрос.УстановитьПараметр("ИНН", "7700000000");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(СтрШаблон("%1, ИНН %2", Выборка.Контрагент, Выборка.ИНН));
КонецЦикла;
Чем язык запросов 1С отличается от обычного SQL:
- Только чтение. Конструкций
INSERT,UPDATE,DELETEнет. Запись идёт через объекты встроенного языка, чтобы сработали события и проверки. - Виртуальные таблицы регистров.
Остатки,Обороты,ОстаткиИОбороты,СрезПоследнихвозвращают готовые итоги на дату без ручной агрегации. - Разыменование через точку.
Документ.Контрагент.ИНН— платформа сама построит соединение с таблицей справочника. - Временные таблицы и пакеты.
ПОМЕСТИТЬ ВТ_Остаткисохраняет результат для следующего запроса в том же пакете. - Независимость от СУБД. Один и тот же текст запроса платформа транслирует в SQL для файловой базы, Microsoft SQL Server, PostgreSQL и других поддерживаемых СУБД.
Текст запроса можно не писать руками: в Конфигураторе и EDT есть конструктор запроса, который собирает его по таблицам и полям мышью.
Разыменование составного типа через точку — частая причина медленных отчётов. Если поле может ссылаться на пять разных справочников, платформа соединит все пять таблиц. Для таких полей используют ВЫРАЗИТЬ(Поле КАК Справочник.Контрагенты).
Метаданные и объектная модель
Главное отличие 1С от «обычного» программирования: структура данных не описывается кодом. Разработчик создаёт в дереве конфигурации объекты метаданных, а платформа сама строит таблицы в базе, формы по умолчанию и программные объекты для работы с ними.
| Объект метаданных | Что хранит | Программные объекты |
|---|---|---|
| Справочник | списки: контрагенты, товары, сотрудники | СправочникСсылка, СправочникОбъект, СправочникМенеджер |
| Документ | факты хозяйственной жизни | ДокументСсылка, ДокументОбъект, проведение |
| Регистр сведений | значения во времени: курсы, цены | набор записей, срез последних |
| Регистр накопления | остатки и обороты | движения, виртуальные таблицы |
| Регистр бухгалтерии | проводки по плану счетов | Дт/Кт, остатки по субконто |
| Перечисление | фиксированный набор значений | Перечисления.ВидыОпераций.Поступление |
У каждого объекта есть три лица, и путать их нельзя:
- Ссылка — лёгкий указатель на запись в базе, хранится в реквизитах других объектов. По ссылке можно прочитать поле, но не изменить его.
- Объект — полная копия записи в памяти. Получается через
Ссылка.ПолучитьОбъект(), после изменения сохраняется методомЗаписать(). - Менеджер — точка доступа к виду объектов в целом:
Справочники.Номенклатура.НайтиПоКоду("00-001"),Документы.РеализацияТоваровУслуг.СоздатьДокумент().
Встроенный язык знает про метаданные «из коробки». Добавили в справочник реквизит КодПоставщика — и в коде сразу доступно Товар.КодПоставщика, а в запросе — поле с тем же именем.
Клиент, сервер и директивы компиляции
В клиент-серверном варианте 1С код выполняется в двух местах: на компьютере пользователя и в рабочем процессе сервера 1С. От того, где выполняется строка, зависит, какие объекты ей доступны.
- 🖥️ Клиент показывает форму, реагирует на нажатия, задаёт вопросы пользователю. Прямого доступа к базе у него нет.
- 🗄️ Сервер читает и пишет данные, выполняет запросы, проводит документы.
Место выполнения процедуры в модуле формы задают директивы компиляции:
| Директива | Где выполняется | Что доступно |
|---|---|---|
&НаКлиенте | на клиенте | данные формы, интерактивные действия |
&НаСервере | на сервере | данные формы и база; форма передаётся на сервер и обратно |
&НаСервереБезКонтекста | на сервере | только база и параметры; форма не передаётся |
&НаКлиентеНаСервереБезКонтекста | и там, и там | только общие для обоих контекстов вещи |
Типичная связка в модуле формы:
&НаКлиенте
Процедура ЗаполнитьОстатки(Команда)
Количество = ПолучитьОстатокНаСервере(Объект.Номенклатура, Объект.Склад);
Объект.Остаток = Количество;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьОстатокНаСервере(Номенклатура, Склад)
// запрос к виртуальной таблице остатков регистра накопления
// возвращает число
КонецФункции
Каждый переход с клиента на сервер — это сетевой вызов. Десять вызовов в цикле на медленном канале заметны пользователю. Поэтому опытные разработчики собирают всё нужное за один серверный вызов.
В общих модулях и модулях объектов место выполнения задают не директивы, а свойства модуля (флажки «Клиент», «Сервер», «Вызов сервера») и инструкции препроцессора вида #Если Сервер Тогда … #КонецЕсли.
Инструменты разработки и отладки
| Инструмент | Для чего |
|---|---|
| Конфигуратор | классическая среда: дерево метаданных, редактор модулей, конструкторы, отладчик, обновление базы |
| 1С:EDT (Enterprise Development Tools) | современная среда на базе Eclipse: проверки кода на лету, рефакторинг, работа с Git |
| Синтакс-помощник | встроенный справочник по всем объектам и методам платформы, открывается из Конфигуратора |
| Консоль запросов | обработка для отладки текста запроса на живых данных |
| Замер производительности | показывает, сколько времени заняла каждая строка кода |
Отладчик умеет то, что ждёшь от любой IDE: точки останова (в том числе с условием), пошаговое выполнение, табло для наблюдения за переменными, вычисление выражений на лету, стек вызовов. В клиент-серверном варианте отлаживать можно и серверный код — для этого отладку нужно разрешить на сервере.
Расширения конфигурации
— ещё один важный инструмент практика. Они позволяют изменить поведение типовой конфигурации, не снимая её с поддержки. В модуле расширения процедуры помечают аннотациями &Перед, &После, &Вместо — и код выполняется до, после или вместо типового обработчика. Это главный способ доработать БП или ЗУП так, чтобы обновления ставились без ручного сравнения.
Вокруг языка сложилась и сторонняя экосистема:
- OneScript — независимый открытый интерпретатор языка 1С для скриптов автоматизации без платформы;
- BSL Language Server — проверка кода и подсветка в VS Code и других редакторах;
- Vanessa Automation и YAxUnit — сценарное и модульное тестирование.
Язык 1С в сравнении с Python, Java и C#
| Критерий | Встроенный язык 1С | Python / Java / C# |
|---|---|---|
| Назначение | учётные системы на платформе 1С | любые задачи |
| Модель данных | объекты метаданных, таблицы строит платформа | классы и ORM, схему БД проектирует разработчик |
| ООП | нет своих классов и наследования | полноценное ООП |
| Типизация | динамическая | Python — динамическая, Java/C# — статическая |
| Работа с БД | встроенный язык запросов, независимый от СУБД | SQL или ORM-библиотеки |
| Интерфейс | формы описываются декларативно, платформа рисует их на любом клиенте | отдельные фреймворки |
| Порог входа в учётные задачи | низкий: проводки, остатки, печать уже есть | высокий: всё строится с нуля |
Минусы языка тоже стоит назвать честно. Нет своих классов и модулей-пакетов с изоляцией, мало средств функционального стиля, код жёстко привязан к платформе. Перенести обработку из 1С в другой стек можно только переписав её.
Зато для учёта это сильно экономит время. Документ с проведением по двум регистрам, формой и печатью опытный разработчик собирает за день. На универсальном языке ту же задачу пришлось бы начинать с проектирования схемы базы.
Что с перспективами:
- 📈 Язык развивается вместе с платформой: асинхронность, HTTP-сервисы, работа с JSON, расширения конфигурации появились именно в версиях 8.3.
- 🔌 Интеграции решаются изнутри: HTTP-сервисы и веб-сервисы, обмен через JSON и XML, COM-соединение, внешние компоненты на C++.
- 💼 Спрос на разработчиков держится за счёт огромной базы внедрений: почти каждая российская компания работает хотя бы с одной конфигурацией 1С.
Частые ошибки начинающих разработчиков
- 🔁 Запрос в цикле. Перебирают 5000 строк документа и для каждой выполняют запрос. Правильно — один запрос по всем строкам сразу, через временную таблицу.
- 📦
&НаСерверетам, где хватит&НаСервереБезКонтекста. Вся форма со всеми таблицами гоняется по сети туда и обратно. - ✏️ Изменение через ссылку.
Товар.Наименование = "Новое"для ссылки не сработает: нужно получить объект, изменить и записать. - 🧮 Склейка числа со строкой.
"Итого: " + 1500дастИтого: 1 500с неразрывным пробелом — для выгрузок используйтеФормат(Число, "ЧГ=0"). - 🛠️ Правка типовой конфигурации напрямую. После снятия с поддержки каждое обновление превращается в ручное сравнение и объединение. Доработки — в расширение.
- 🔇 Пустой блок
Исключение. Ошибка проглатывается, данные остаются в непонятном состоянии. Минимум — записать в журнал регистрации черезЗаписьЖурналаРегистрации.
Частые вопросы
Можно ли писать код 1С на английском?
Procedure, If, Query. В одном модуле можно смешивать оба варианта, но в типовых конфигурациях код русскоязычный.Это компилируемый или интерпретируемый язык?
Нужно ли знать SQL, чтобы писать запросы в 1С?
ВЫБРАТЬ … ИЗ … ГДЕ … СГРУППИРОВАТЬ ПО та же, что в SQL. Новыми придётся освоить виртуальные таблицы регистров и разыменование через точку.