Встроенный язык 1С глазами программиста из другого стека

· 10 мин

Содержание

Язык программирования 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

Python1СКомментарий
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С передаётся параметр без слова Знач?
Что вернёт СтрНайти("1С:Бухгалтерия", "1")?
Какой запрос язык запросов 1С выполнить не сможет?

Переход на 1С из других языков: что ломает привычки

Освоить синтаксис можно за пару недель. Дольше уходит на то, чтобы перестроить мышление под платформу.

Мышление «сначала метаданные»

В обычном проекте вы пишете класс, а потом ORM создаёт таблицу. В 1С наоборот: сначала добавляете реквизит или табличную часть в дереве конфигурации, потом пишете код. Многие задачи решаются вообще без кода — настройкой формы, отчётом на системе компоновки данных (СКД), правами в ролях.

Ошибки, которые чаще допускают «пришельцы»

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

Инструменты: чего не хватает и чем заменить

Привычный инструментВ 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#?
Напрямую нет. Внешний код подключают через внешние компоненты, COM-объекты в Windows или HTTP-сервисы, которые 1С вызывает или публикует сама.
Есть ли в языке 1С строгая типизация?
Нет, типизация динамическая. Но у реквизитов метаданных тип задан жёстко, и платформа приводит к нему значение при записи. Проверить тип в коде можно через ТипЗнч(Значение) = Тип("Число").
Сколько времени нужно программисту, чтобы перейти на 1С?
Синтаксис осваивают за 1-2 недели. На уверенную работу с типовыми конфигурациями, регистрами и СКД обычно уходит от нескольких месяцев практики.