На чём пишут в 1С: встроенный язык платформы 1С:Предприятие

· 9 мин

Содержание

В 1С не пишут на Java, C# или Python. У платформы 1С:Предприятие 8.3 свой встроенный язык программирования, и он работает только внутри платформы. Отдельного названия у него нет: его зовут «встроенный язык 1С», «язык 1С» или просто «1С-ка».

Частое заблуждение: «язык запросов — это и есть SQL». Нет. В 1С два языка: встроенный язык для логики и язык запросов для выборки данных. Второй похож на SQL, но устроен иначе, и об этом ниже.

Как устроен синтаксис и из чего состоит код

Язык процедурный, с элементами объектной модели. Код лежит в модулях: модуль формы, модуль объекта, модуль менеджера, общие модули, модуль управляемого приложения. В каждом модуле — переменные, процедуры и функции.

Ключевые слова существуют в двух вариантах, русском и английском, и их можно смешивать. Регистр не важен.

Русский вариантАнглийский вариант
Процедура / КонецПроцедурыProcedure / EndProcedure
Если … Тогда … КонецЕслиIf … Then … EndIf
Для Каждого … Из … ЦиклFor Each … In … Do
Попытка … ИсключениеTry … Except

На практике пишут по-русски: так читается проще, и именно так устроены типовые конфигурации.

Основные конструкции

  • 🔹 Условие: Если Сумма > 0 Тогда … ИначеЕсли … Иначе … КонецЕсли;
  • 🔹 Цикл по коллекции: Для Каждого Строка Из Таблица Цикл … КонецЦикла;
  • 🔹 Цикл с условием: Пока Выборка.Следующий() Цикл … КонецЦикла;
  • 🔹 Счётный цикл: Для Индекс = 0 По Массив.ВГраница() Цикл … КонецЦикла;
  • 🔹 Комментарий: две косые черты // до конца строки.
  • 🔹 Конец оператора: точка с запятой.

Короткий пример функции:

Функция СуммаСНДС(Сумма, СтавкаНДС)
    Возврат Окр(Сумма * (1 + СтавкаНДС / 100), 2);
КонецФункции

Вызов СуммаСНДС(1000, 20) вернёт 1200.

Переменную не нужно объявлять. Она появляется при первом присваивании. Объявление Перем нужно для переменных модуля и там, где важна область видимости.

Синтаксис напоминает Бейсик и Паскаль: блоки закрываются словами, а не скобками. Для тех, кто пришёл из C-подобных языков, это главное отличие на первых днях.

Какие типы данных есть и как устроена объектная модель

Типизация динамическая: переменная может сначала хранить число, потом строку. Тип определяется значением.

Примитивные типы

  • 🔢 Число — для реквизитов разрядность и точность задаются в метаданных;
  • 🔤 Строка — для переменных длина не ограничена, у реквизитов её задают в метаданных;
  • 📅 Дата — дата и время вместе, пустая дата равна 01.01.0001;
  • ☑️ Булево — Истина или Ложь;
  • ❔ Неопределено и Null — «значения нет», но это разные вещи: Null приходит из базы, например при левом соединении.

Проверить тип можно так: ТипЗнч(Значение) = Тип("Число").

Коллекции

ТипДля чего
Массивсписок значений по индексу с нуля
Структуранабор «ключ — значение», ключи — идентификаторы
Соответствието же, но ключом может быть любое значение
СписокЗначенийзначения с представлением, используется в формах
ТаблицаЗначенийтаблица с колонками, аналог временной таблицы в памяти
ДеревоЗначенийиерархическая таблица

Объекты базы данных

Данные конфигурации тоже доступны как объекты языка. Справочники, документы, регистры — это менеджеры: Справочники.Номенклатура, Документы.РеализацияТоваровУслуг, РегистрыСведений.КурсыВалют.

Здесь важно различать два понятия:

  • 🔗 Ссылка (СправочникСсылка.Номенклатура) — лёгкий указатель на запись. Через неё читают реквизиты, но не меняют.
  • 📝 Объект (СправочникОбъект.Номенклатура) — содержимое записи в памяти. Его получают через Ссылка.ПолучитьОбъект() или создают через СоздатьЭлемент(), меняют и вызывают Записать().
Номенклатура = Справочники.Номенклатура.НайтиПоКоду("00000012");
Если Не Номенклатура.Пустая() Тогда
    Объект = Номенклатура.ПолучитьОбъект();
    Объект.Наименование = "Новое наименование";
    Объект.Записать();
КонецЕсли;

Читать реквизиты через Ссылка.Реквизит удобно, но каждое такое обращение — запрос к базе. В цикле на тысячи строк это тормозит; лучше собрать данные одним запросом.

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

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

ДирективаГде работаетЧто доступно
&НаКлиентена клиентеэлементы формы, диалоги; нет прямого доступа к базе
&НаСерверена сервере, с контекстом формыреквизиты формы и база
&НаСервереБезКонтекстана сервере, без формытолько переданные параметры; вызов быстрее
&НаКлиентеНаСервереБезКонтекстав обоих местахкод без обращения к форме и базе

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

&НаКлиенте
Процедура ПересчитатьНажатие(Команда)
    Результат = РассчитатьНаСервере(Объект.Сумма);
    Объект.СуммаСНДС = Результат;
КонецПроцедуры

&НаСервереБезКонтекста
Функция РассчитатьНаСервере(Сумма)
    Возврат Окр(Сумма * 1.2, 2);
КонецФункции

Каждый серверный вызов — это сетевой обмен. Чем меньше вызовов, тем быстрее форма, особенно по веб-клиенту и через плохой канал.

Переданные между клиентом и сервером параметры копируются. Поэтому большие таблицы туда-обратно гонять не стоит: передавайте адрес во временном хранилище или собирайте данные на сервере.

Язык запросов: чем он отличается от SQL

Запросы пишут на отдельном языке. Он выглядит как SQL: ВЫБРАТЬ, ИЗ, ГДЕ, СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО, ОБЪЕДИНИТЬ ВСЕ. Но работает не с таблицами СУБД, а с метаданными конфигурации.

Что отличает его от обычного SQL:

  • 📌 в запросе указывают объекты конфигурации: Справочник.Номенклатура, РегистрНакопления.ТоварыНаСкладах.Остатки, а не имена таблиц СУБД;
  • 📌 есть виртуальные таблицы регистров (остатки, обороты) с параметрами периода и отбора;
  • 📌 поля-ссылки разыменовываются через точку: Номенклатура.Родитель.Наименование, платформа сама строит соединения;
  • 📌 запрос только читает. Операторов INSERT, UPDATE, DELETE нет: данные меняют средствами встроенного языка;
  • 📌 запрос не зависит от СУБД: он работает одинаково на файловой базе, PostgreSQL и MS SQL Server.

Пример целиком, от текста до обхода результата:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Номенклатура.Наименование КАК Наименование,
    |   Номенклатура.Артикул КАК Артикул
    |ИЗ
    |   Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |   Номенклатура.Наименование ПОДОБНО &Шаблон
    |УПОРЯДОЧИТЬ ПО
    |   Наименование";
Запрос.УстановитьПараметр("Шаблон", "Кабель%");

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

Параметры (&Шаблон) задают через УстановитьПараметр, а не склеивают в текст. Так запрос быстрее и безопаснее.

Для сложных выборок есть временные таблицы (ПОМЕСТИТЬ), пакетные запросы с несколькими ; и конструктор запроса в Конфигураторе: он собирает текст мышкой.

В отчётах поверх запросов работает система компоновки данных (СКД). Она строит печатную и экранную форму из запроса и настроек, почти без кода.

Ошибки и отладка: Попытка, Исключение и отладчик

Обработка исключений

Структура простая: Попытка — Исключение — КонецПопытки.

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

Функция ОписаниеОшибки() возвращает текст последней ошибки. Для подробной информации (модуль, строка) есть ИнформацияОбОшибке(). Свою ошибку создают так: ВызватьИсключение "Не заполнен контрагент";.

Пустой блок Исключение — плохая практика. Ошибка исчезнет, а причину потом придётся искать вслепую. Минимум — запишите её в журнал регистрации через ЗаписьЖурналаРегистрации.

Внутри транзакции блок Попытка нужно сочетать с НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию(), иначе данные останутся в неопределённом состоянии.

Отладка

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

  1. Откройте базу в Конфигураторе и найдите нужную строку кода.
  2. Поставьте точку останова — клавиша F9 в этой строке.
  3. Запустите отладку из меню Отладка → Начать отладку (клавиша F5).
  4. Повторите действие в запущенной программе. Выполнение остановится на точке.
  5. Проходите код по шагам (F11 — с заходом в процедуру, F10 — без захода), а значения смотрите в окне Вычислить выражение и в таблице локальных переменных.

Для быстрой проверки используйте Сообщить(Значение): строка появится в окне сообщений. Для нагрузочных разборов в платформе есть замер производительности и технологический журнал.

Расширения и интеграция с внешними системами

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

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

  • ➕ &После — выполнить код после штатной процедуры;
  • ➖ &Перед — выполнить код до неё;
  • 🔁 &Вместо — заменить штатный код своим (с возможностью вызвать оригинал);
  • 🧩 новые объекты (справочники, обработки, отчёты) добавляют в расширение как обычные.

Расширение подключают из Конфигуратора: пункт Конфигурация → Расширения конфигурации.

Обмен с другими системами

Платформа умеет много без сторонних библиотек:

СпособЧто даёт
HTTP-сервисысвоё API: внешняя система вызывает 1С по адресу
HTTPСоединение, HTTPЗапрос1С сама обращается к REST-сервисам
Веб-сервисы (SOAP)обмен по WSDL, подключение через WSОпределения
JSON и XMLЧтениеJSON, ЗаписьJSON, ЧтениеXML, ЗаписьXML
COMуправление Excel, Word и другими программами на Windows
Внешние компонентыподключение библиотек на C++ для оборудования и особых задач
План обменаобмен данными между базами 1С и конфигурациями

Пример чтения JSON из ответа:

Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();

При Истина объекты превращаются в Соответствие, а не в Структуру: это удобно, когда ключи содержат пробелы или символы, недопустимые в идентификаторах.

COM-вызовы работают только там, где установлено нужное приложение. На сервере без Excel и в веб-клиенте такой код не запустится.

Где язык 1С упирается в пределы

Язык не заменяет всё. Тяжёлые вычисления на миллионах строк, машинное обучение, сложная работа с изображениями — это не его территория. Такие задачи выносят во внешний сервис и связывают с 1С через HTTP.

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

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

Как начать изучать язык 1С

Порядок, который работает у большинства новичков:

  1. Поставьте учебную версию платформы и откройте любую типовую конфигурацию в Конфигураторе.
  2. Прочитайте код небольшого общего модуля или модуля менеджера справочника.
  3. Напишите обработку, которая выводит список справочника запросом.
  4. Научитесь пользоваться отладчиком раньше, чем писать сложную логику.
  5. Только потом переходите к расширениям, СКД и интеграциям.
Проверьте себя
Что нужно, чтобы выполнить серверную процедуру формы с доступом к реквизитам формы?
Можно ли изменить запись справочника запросом на языке запросов?

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

Это язык программирования общего назначения?
Нет. Он создан для разработки прикладных решений на платформе 1С:Предприятие и вне её не применяется.
Нужно ли знать SQL, чтобы писать в 1С?
Не обязательно. Для работы достаточно языка запросов 1С. SQL пригодится для разбора производительности на уровне СУБД.
Можно ли писать на английском варианте ключевых слов?
Да. Русские и английские слова равноправны, их можно смешивать в одном модуле. Но в типовых конфигурациях принят русский вариант.
Чем 1С отличается от Python или JavaScript?
Язык привязан к объектам конфигурации и работает внутри платформы. Нет самостоятельных скриптов вне неё, нет пакетных менеджеров, а ядро — это метаданные, а не библиотеки.
Можно ли подключить внешний код на Python?
Напрямую нет. Обычно используют HTTP-сервисы, обмен файлами и внешние компоненты, а Python-программу запускают отдельно.
Где учить код, если я бухгалтер?
Начните с небольших отчётов на СКД и простых запросов. Они дают пользу сразу и не требуют глубокого знания модулей.