Встроенный язык 1С глазами программиста из другого стека
Содержание
Язык программирования 1С больше всего похож на смесь Pascal и Visual Basic с русскими ключевыми словами: блоки Если … Тогда … КонецЕсли, точка с запятой между операторами, динамическая типизация, как в VBA. Язык запросов 1С почти дословно повторяет SQL, но умеет ходить по ссылкам через точку. А по общей логике работы с бизнес-объектами 1С ближе к фреймворку с ORM, чем к «чистому» языку общего назначения.
Сходство с другими языками помогает быстро начать читать код. Но писать хорошо мешает: многие привычки из Python, Java или C# в 1С либо не работают, либо бьют по производительности. Разберём, где аналогии верны, а где обманчивы.
На что похож язык 1С в целом: короткая карта сходств
У платформы 1С:Предприятие 8.3 два языка, и сравнивать их нужно по отдельности:
- 🧩 встроенный язык — процедуры, функции, циклы, условия, работа с объектами;
- 🗄️ язык запросов — чтение данных из базы, аналог SELECT в SQL.
Поверх них лежит то, чего нет в обычных языках, — метаданные конфигурации. Справочники, документы, регистры описываются в дереве Конфигуратора, а не в коде. Код только реагирует на события этих объектов.
| С чем сравнивают | Что действительно похоже | Где аналогия ломается |
|---|---|---|
| Pascal | блоки с явным концом, ; между операторами, Процедура/Функция | нет объявления типов, нет begin/end |
| Visual Basic / VBA | динамические типы, = и для присваивания, и для сравнения, объекты «хоста» | нет классов, нет Dim … As |
| SQL | ВЫБРАТЬ … ИЗ … ГДЕ … СГРУППИРОВАТЬ ПО | только чтение, разыменование через точку, виртуальные таблицы |
| ORM (Hibernate, Entity Framework) | объекты базы как сущности, Записать() вместо INSERT | схема задаётся метаданными, не кодом |
| Python | динамика, коллекции «из коробки» | нет отступов как синтаксиса, нет пакетов и pip |
| JavaScript | клиент и сервер, асинхронные вызовы | клиент и сервер пишутся в одном модуле |
Если вы пришли из VBA или Delphi, первые недели в 1С пройдут легче всего. Из Python и JavaScript — сложнее: мешает привычка к функциональному стилю и большим библиотекам.
Синтаксис 1С: родство с Pascal и Visual Basic
Внешне код на 1С узнаётся сразу: русские слова, длинные идентификаторы, явные концы блоков. Каждый блок закрывается своим словом: КонецЕсли, КонецЦикла, КонецПроцедуры, КонецФункции, КонецПопытки.
Функция СуммаСоСкидкой(Знач Сумма, ПроцентСкидки = 0) Экспорт
Если ПроцентСкидки < 0 Или ПроцентСкидки > 100 Тогда
ВызватьИсключение "Неверный процент скидки";
ИначеЕсли ПроцентСкидки = 0 Тогда
Возврат Сумма;
КонецЕсли;
Возврат Окр(Сумма * (100 - ПроцентСкидки) / 100, 2);
КонецФункции
Что пришло из Pascal
- 📌
;разделяет операторы, а передКонецЕслиеё можно не ставить — как передendв Pascal; - 📌 деление на процедуры (без возврата) и функции (с
Возврат); - 📌 цикл со счётчиком
Для Сч = 1 По 10 Циклс включёнными обеими границами — какfor i := 1 to 10; - 📌
<>для «не равно», логическиеИ,Или,Несловами.
Что пришло из Visual Basic
- 📌 типы не объявляются: переменная получает тип при присваивании,
Перемнужен только для явного объявления; - 📌 один знак
=для присваивания и для сравнения — смысл зависит от позиции; - 📌 регистр не важен:
КонецЕслииконецесли— одно и то же; - 📌 параметры по умолчанию передаются по ссылке, по значению — только с
Знач.
Последний пункт часто ловит разработчиков из Python и Java. Если функция меняет параметр без Знач, изменится и переменная в вызывающем коде.
Двуязычный синтаксис
У каждого ключевого слова есть английский эквивалент: Если — If, Тогда — Then, КонецЕсли — EndIf. Код на английском синтаксисе выглядит почти как VB:
If Amount > 0 Then
Result = Amount * 2;
EndIf;
Платформа понимает оба варианта, но в типовых конфигурациях и на практике пишут по-русски. Смешивать стили в одном модуле не стоит — код читается хуже.
Язык запросов 1С: SQL с разыменованием через точку
Язык запросов — та часть, где сходство с SQL почти полное. Кто писал SELECT, прочитает запрос 1С без подготовки:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Продажи.Номенклатура КАК Номенклатура,
| Продажи.Номенклатура.Родитель.Наименование КАК Группа,
| СУММА(Продажи.Количество) КАК Количество
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Продажи
|ГДЕ
| Продажи.Ссылка.Дата МЕЖДУ &Начало И &Конец
|СГРУППИРОВАТЬ ПО
| Продажи.Номенклатура,
| Продажи.Номенклатура.Родитель.Наименование";
Запрос.УстановитьПараметр("Начало", НачалоМесяца(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("Конец", КонецМесяца(ТекущаяДатаСеанса()));
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// обработка строки
КонецЦикла;
Чем запрос 1С отличается от SQL
| Возможность | SQL | Язык запросов 1С |
|---|---|---|
| Чтение данных | SELECT | ВЫБРАТЬ |
| Изменение данных | INSERT, UPDATE, DELETE | нет: запись идёт через объекты |
| Связь с другой таблицей | явный JOIN | можно через точку: Номенклатура.Родитель.Наименование |
| Остатки и обороты | агрегаты по таблице движений | готовые виртуальные таблицы .Остатки(), .Обороты() |
| Временные таблицы | CREATE TEMP TABLE / #temp | ПОМЕСТИТЬ ИмяТаблицы в пакете запросов |
| Итоги по иерархии | ROLLUP, CTE | ИТОГИ ПО … ИЕРАРХИЯ |
| Параметры | @p, ?, :p | &Имя и УстановитьПараметр |
Разыменование через точку — главная особенность. Платформа сама строит левое соединение со справочником. Это удобно, но каждая точка — ещё один JOIN. Цепочка из пяти точек по составному типу превращается в тяжёлый запрос к СУБД.
Запрос 1С выполняется не напрямую: платформа транслирует его в SQL для конкретной СУБД (MS SQL, PostgreSQL, файловая база). Обращаться к таблицам СУБД напрямую, в обход платформы, лицензионное соглашение 1С не разрешает, а прямая запись к тому же ломает целостность данных.
Почему здесь пригодится опыт ORM
Запись в базу в 1С похожа на Entity Framework или Hibernate. Вы не пишете INSERT — вы создаёте объект и вызываете Записать():
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Бумага А4";
НовыйЭлемент.Записать();
Отличие от ORM: схему данных не описывают классами в коде. Её задают в метаданных, а платформа сама создаёт таблицы и поля в СУБД.
Объектная модель и события: ООП без классов
В 1С нельзя объявить свой класс, наследоваться или переопределить метод. Роль классов играют объекты метаданных: справочник «Номенклатура», документ «Реализация», регистр накопления. У каждого есть модули, где пишется поведение.
| Модуль | Аналог в ООП | Что в нём пишут |
|---|---|---|
| Модуль объекта | методы экземпляра | обработчики ПередЗаписью, ОбработкаПроведения |
| Модуль менеджера | статические методы класса | функции для работы со всеми объектами вида |
| Общий модуль | утилитарный класс / пакет | общие процедуры, вызываемые из разных мест |
| Модуль формы | контроллер UI | обработчики формы и её элементов |
Событийная архитектура
Большая часть кода в 1С — обработчики событий. Платформа сама вызывает нужную процедуру в нужный момент:
Процедура ПередЗаписью(Отказ)
Если Не ЗначениеЗаполнено(Контрагент) Тогда
Сообщить("Не указан контрагент");
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Параметр Отказ = Истина отменяет запись. Это похоже на event.preventDefault() в JavaScript или на отмену в триггере базы данных. Для документов есть ОбработкаПроведения — здесь формируются движения по регистрам.
Чтобы вмешаться в событие чужого объекта, не правя его модуль, используют подписки на события. По сути это паттерн «наблюдатель»: одна процедура в общем модуле срабатывает при записи сразу нескольких видов документов.
Ссылка и объект — два разных понятия
- 🔗 Ссылка — неизменяемый идентификатор записи, как первичный ключ. Её передают, сравнивают, хранят в реквизитах.
- 📦 Объект — загруженная в память запись, которую можно менять. Получают через
Ссылка.ПолучитьОбъект().
Новички часто пытаются изменить реквизит через ссылку. Так не выйдет: ссылка только читает данные.
Язык 1С против Python и JavaScript
С Python и JavaScript у 1С общая динамическая типизация, но устройство разработки совсем другое.
Сравнение с Python
| Python | 1С | Комментарий |
|---|---|---|
list | Массив | индексы с 0 |
dict | Соответствие | ключ — любое значение |
dict с ключами-строками | Структура | ключи — только корректные идентификаторы |
| pandas DataFrame | ТаблицаЗначений | есть Свернуть(), Итог(), Сортировать() |
try / except | Попытка / Исключение | нет типов исключений, только текст и информация об ошибке |
eval() | Вычислить(), Выполнить() | работают, но в рабочем коде их избегают |
x if c else y | ?(c, x, y) | тернарная функция |
Чего в 1С нет по сравнению с Python:
- ❌ отступов как части синтаксиса — блоки закрываются словами;
- ❌ генераторов списков, лямбд, декораторов;
- ❌ сокращённых операторов
+=,++— пишутСумма = Сумма + 1; - ❌ пакетного менеджера и внешних библиотек «из интернета»: всё нужное — в платформе или в библиотеках конфигураций вроде БСП;
- ❌ многострочных комментариев — только
//в начале каждой строки.
Сравнение с JavaScript
Ближе всего JavaScript к 1С в клиент-серверной части. Управляемая форма работает как фронтенд: часть кода выполняется у пользователя, часть — на сервере. Разница в том, что в 1С оба куска лежат в одном модуле формы и размечаются директивами:
&НаКлиенте
Процедура Рассчитать(Команда)
РассчитатьНаСервере();
КонецПроцедуры
&НаСервере
Процедура РассчитатьНаСервере()
Объект.Сумма = Объект.Количество * Объект.Цена;
КонецПроцедуры
Асинхронность тоже знакома JS-разработчику. Сначала в 1С появились колбэки через ОписаниеОповещения — аналог передачи функции обратного вызова. С платформы 8.3.18 добавили Асинх и Ждать — это прямой аналог async/await.
Уникальные конструкции языка 1С
Есть вещи, аналогов которым в популярных языках почти нет.
- 🧭 Директивы компиляции
&НаКлиенте,&НаСервере,&НаСервереБезКонтекста. Последняя вызывает сервер без передачи данных формы — вызов быстрее. - 🧱 Инструкции препроцессора
#Если Сервер Тогда … #КонецЕслии#Область … #КонецОбласти— последние только группируют код, как#regionв C#. - 📅 Литерал даты в одинарных кавычках:
'20240115'или'20240115103000'с временем. - 📝 Многострочные строки через вертикальную черту
|в начале каждой строки — так оформляют тексты запросов. - 🔢 Два «пустых» значения:
Неопределено(значение не задано) иNULL(пришло из запроса при отсутствии связанной записи). Это разные вещи, и путать их — частая ошибка. - 📊 Регистры — накопления, сведений, бухгалтерии. Это готовые структуры для остатков, оборотов и проводок, а не просто таблицы.
- 🔐 Транзакции через
НачатьТранзакцию(),ЗафиксироватьТранзакцию(),ОтменитьТранзакцию()прямо во встроенном языке.
Ещё одна деталь, на которой спотыкаются: массивы нумеруются с 0, а позиции в строках — с 1. СтрНайти("Привет", "П") вернёт 1, а при отсутствии подстроки — 0.
Переход на 1С из других языков: что ломает привычки
Освоить синтаксис можно за пару недель. Дольше уходит на то, чтобы перестроить мышление под платформу.
Мышление «сначала метаданные»
В обычном проекте вы пишете класс, а потом ORM создаёт таблицу. В 1С наоборот: сначала добавляете реквизит или табличную часть в дереве конфигурации, потом пишете код. Многие задачи решаются вообще без кода — настройкой формы, отчётом на системе компоновки данных (СКД), правами в ролях.
Ошибки, которые чаще допускают «пришельцы»
- Запрос в цикле. Привычка «для каждого элемента — сходить в базу» в 1С даёт тысячи обращений к СУБД. Правильно — один запрос с параметром-списком через
В (&Список). - Разыменование ссылки в коде. Строка
Документ.Контрагент.ИННвнутри цикла читает объект контрагента из базы. Нужные поля лучше сразу получить в запросе. - Путаница контекстов. На клиенте нельзя прочитать реквизит ссылки и обратиться к базе. Код из серверной процедуры не переносится на клиент «как есть».
- Свой велосипед вместо БСП. В типовых конфигурациях уже есть общие модули Библиотеки стандартных подсистем: работа со строками, датами, файлами, печатью. Писать своё — терять время и совместимость.
- Правка типовой конфигурации напрямую. Вместо этого используют расширения — так легче обновлять типовую.
Инструменты: чего не хватает и чем заменить
| Привычный инструмент | В 1С |
|---|---|
| VS Code, IntelliJ | Конфигуратор или 1C:Enterprise Development Tools (EDT, на базе Eclipse) |
| Git | хранилище конфигурации; EDT работает с Git напрямую |
| Отладчик IDE | встроенный отладчик Конфигуратора и EDT |
| Модульные тесты | фреймворки сообщества, встроенного аналога pytest нет |
| Профайлер | замер производительности в Конфигураторе |
Если вы сильны в SQL, начните со СКД и запросов. Это самый быстрый путь к пользе: отчёты нужны в каждой компании, а опыт SQL переносится почти целиком.
Частые вопросы
Можно ли писать на 1С на английском?
If, EndIf, SELECT, FROM. Платформа понимает оба варианта, но типовые конфигурации написаны по-русски.Язык 1С объектно-ориентированный?
Можно ли подключить к 1С библиотеку на Python или C#?
Есть ли в языке 1С строгая типизация?
ТипЗнч(Значение) = Тип("Число").