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

· 9 мин

Содержание

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

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

Ниже — из чего состоит язык, как выглядит код, какие бывают типы данных и модули, как код обращается к базе и чем его отлаживают.

Что такое встроенный язык и где он выполняется

Встроенный язык (в документации — «встроенный язык 1С:Предприятия», в обиходе часто «1С-код») — это процедурный язык, которым наполняют модули объектов конфигурации. Код не существует сам по себе в виде .exe или скрипта на диске: он хранится внутри конфигурации и выполняется платформой.

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

  • 🖥️ на клиенте — реакция на действия пользователя, работа с формой, интерактивные диалоги;
  • ⚙️ на сервере — обращение к базе данных, чтение и запись объектов, тяжёлые вычисления.

Код не имеет прямого доступа к файлам операционной системы в произвольном месте и к памяти — он работает через объекты платформы. Это осознанное ограничение: прикладной программист думает категориями предметной области (документ, справочник, регистр), а не файлами и указателями.

Запрос к базе и чтение объектов возможны только на сервере. Если попытаться прочитать данные в клиентской процедуре, платформа выдаст ошибку компиляции ещё до запуска.

Как выглядит код: синтаксис и ключевые слова

Первое, что бросается в глаза, — двуязычный синтаксис. Ключевые слова существуют в русском и английском вариантах, и они равноправны: Если и If, Процедура и Procedure компилируются одинаково. На практике почти вся русскоязычная разработка ведётся на русском синтаксисе.

Базовые правила:

  • каждый оператор заканчивается точкой с запятой ;;
  • регистр ключевых слов не важен: Если, ЕСЛИ и если — одно и то же;
  • комментарий начинается с двойной косой черты // и идёт до конца строки;
  • процедура не возвращает значение, функция — возвращает через Возврат.

Простой пример функции, которая считает сумму с НДС:

Функция СуммаСНДС(Сумма, СтавкаПроцентов = 20) Экспорт
    Если Сумма <= 0 Тогда
        Возврат 0;
    КонецЕсли;
    Налог = Сумма * СтавкаПроцентов / 100;
    Возврат Сумма + Налог;
КонецФункции

Здесь видны основные конструкции: условие Если … Тогда … КонецЕсли, значение параметра по умолчанию (СтавкаПроцентов = 20), слово Экспорт (о нём ниже) и возврат результата.

Управляющие конструкции языка:

КонструкцияНазначение
Если … Тогда … ИначеЕсли … Иначе … КонецЕсливетвление
Для Сч = 1 По N Цикл … КонецЦиклацикл со счётчиком
Для Каждого Элемент Из Коллекция Цикл … КонецЦиклаобход коллекции
Пока Условие Цикл … КонецЦиклацикл с условием
Попытка … Исключение … КонецПопыткиперехват ошибок

Отдельного оператора switch/case в языке нет — его заменяет цепочка ИначеЕсли. Внутри циклов работают Прервать (выйти из цикла) и Продолжить (перейти к следующей итерации).

Типы данных и переменные

Типизация динамическая: тип принадлежит значению, а не переменной. Одна и та же переменная может сначала хранить число, потом строку. Объявлять переменную оператором Перем не обязательно — она появляется при первом присваивании.

Типы делятся на несколько групп.

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

  • Число — целое и дробное, высокая точность (подходит для денег);
  • Строка — текст в Unicode;
  • Дата — дата и время одним значением;
  • Булево — Истина / Ложь;
  • Неопределено — «значение не задано» (им инициализируются необъявленные реквизиты);
  • Null — отсутствие значения в результате запроса;
  • Тип — сам тип как значение (через функцию Тип()).

Ссылочные типы — ссылки на объекты базы: ссылка на элемент справочника, на документ, на значение перечисления. Именно через ссылки код адресует данные: Документ.Ссылка, Номенклатура, Контрагент.

Универсальные коллекции — то, без чего не обходится ни один модуль:

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

Тип значения проверяют функцией ТипЗнч(), а сравнивают с эталоном через Тип("СправочникСсылка.Номенклатура"). Для пустой ссылки есть метод объекта или проверка Значение.Пустая().

Деньги считайте только в Число. Платформа хранит его с фиксированной точностью, поэтому копейки не «уплывают», как бывает с плавающей точкой в других языках.

Модули, директивы компиляции и область видимости

Код не пишут в одном файле — он распределён по модулям, привязанным к объектам конфигурации. Основные виды:

  1. Общие модули — процедуры и функции, доступные из любой точки; сюда выносят повторно используемую логику.
  2. Модуль формы — обработчики событий конкретной формы (открытие, нажатие кнопки, изменение поля).
  3. Модуль объекта (документа, справочника) — поведение самого объекта: обработка проведения, проверка заполнения, запись.
  4. Модуль менеджера — методы, относящиеся к виду объекта в целом, а не к одному экземпляру.
  5. Модуль сеанса — выполняется при старте сеанса, задаёт параметры сеанса.

Внутри модуля видимостью управляет слово Экспорт. Процедура или функция без него видна только внутри своего модуля; с Экспорт — доступна снаружи. Так разграничивают «внутреннюю кухню» модуля и его публичный интерфейс.

Где именно выполнится код, задают директивы компиляции — строки со знаком & перед процедурой:

ДирективаГде выполняется
&НаКлиентена клиенте, с доступом к данным формы
&НаСерверена сервере, с доступом к данным формы
&НаСервереБезКонтекстана сервере, быстрее, но без данных формы
&НаКлиентеНаСервереБезКонтекстаи там, и там (например, проверки)

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

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

Проверьте себя
Процедура помечена `&НаСервереБезКонтекста`. Что ей доступно?
Какое слово делает функцию общего модуля доступной из других модулей?
Чем считают сумму денег, чтобы не терять копейки?

Глобальный контекст: функции, доступные из любого модуля

Часть функций языка не принадлежит какому-то объекту — их вызывают напрямую из любого модуля. Это глобальный контекст: встроенные функции для работы со строками, числами, датами и для взаимодействия с пользователем.

Самые ходовые группы:

  • 🔤 строковые: СтрДлина(), СтрНайти(), СтрЗаменить(), СтрРазделить(), ВРег() / НРег() (верхний и нижний регистр), СокрЛП() (убрать пробелы по краям);
  • 🔢 числа и формат: Цел(), Окр() (округление), Формат() — универсальное форматирование числа и даты в строку;
  • 📅 даты: ТекущаяДата() (серверная дата), НачалоДня(), КонецМесяца(), ДобавитьМесяц();
  • 💬 сообщения: Сообщить() и объект СообщениеПользователю — вывод текста пользователю.

Склеивать число со строкой напрямую нельзя — нужно явное преобразование. Правильно так:

Количество = 5;
Текст = СтрШаблон("Отобрано позиций: %1", Количество);
Сообщить(Текст);

Функция СтрШаблон() подставляет значения вместо %1, %2 и сама приводит их к строке — это надёжнее, чем конкатенация через +, и читается лучше.

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

Язык запросов: как код забирает данные из базы

Встроенный язык умеет перебирать объекты в цикле, но читать из базы «поштучно» в цикле — медленно. Для выборок есть отдельный язык запросов — декларативный, похожий на SQL, но со своими возможностями (обращение к реквизитам через точку, виртуальные таблицы итогов, иерархия).

Работает он через объект Запрос:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Товары.Номенклатура КАК Номенклатура,
    |   СУММА(Товары.Количество) КАК Количество
    |ИЗ
    |   Документ.РеализацияТоваровУслуг.Товары КАК Товары
    |ГДЕ
    |   Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец
    |СГРУППИРОВАТЬ ПО
    |   Товары.Номенклатура";
Запрос.УстановитьПараметр("Начало", НачалоПериода);
Запрос.УстановитьПараметр("Конец", КонецПериода);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Номенклатура);
КонецЦикла;

Ключевые слова запроса тоже двуязычные: ВЫБРАТЬ/SELECT, ИЗ/FROM, ГДЕ/WHERE. Параметры (&Начало) подставляют методом УстановитьПараметр — это защищает от ошибок и ускоряет повторные запросы.

Важные правила работы с запросами:

  • запрос выполняется только на сервере — в клиентском коде объект Запрос недоступен;
  • вертикальная черта | в начале строк — это не часть языка, а приём переноса многострочного текста запроса;
  • составлять текст удобно в конструкторе запроса (правая кнопка в модуле → «Конструктор запроса»), а не вручную.

Правило практика: получить данные одним запросом и дальше работать с результатом в памяти — почти всегда быстрее, чем обходить справочник или документы объектами в цикле.

Отладка и инструменты разработчика

Пишут и правят код в двух средах: классический Конфигуратор и современная 1С:EDT (на базе Eclipse). Для платформы версии 8.3 обе поддерживают один и тот же язык; различается оболочка и удобство.

Базовый набор для отладки — в Конфигураторе:

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

Чтобы отладка заработала, в клиенте и на сервере должна быть разрешена отладка (параметры запуска / свойства информационной базы), иначе точки останова не сработают.

Помимо отладчика, разработчику помогают:

  • 🔎 Синтакс-помощник — встроенный справочник по всем объектам, методам и свойствам языка; открывается из Конфигуратора и подсказывает сигнатуры.
  • 💬 Проверка модуля — ищет синтаксические ошибки без запуска (пункт меню проверки в редакторе модуля).
  • 📋 Контекстная подсказка — список доступных методов объекта по нажатию точки после переменной.
  • 🧩 Расширения конфигурации — способ дописать код к типовому решению, не снимая его с поддержки; появились в платформе версии 8.3.6.

Перед замером производительности или отладкой на рабочей базе помните: пошаговая остановка «подвешивает» серверный вызов. На продуктивной базе с пользователями такие эксперименты лучше не проводить — используйте копию.

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

Язык 1С — это один язык или два?
Формально во встроенной разработке используют два разных языка: встроенный язык (им описывают алгоритмы и поведение) и язык запросов (им выбирают данные из базы). Они дополняют друг друга и работают вместе.
Нужно ли знать английский, чтобы программировать в 1С?
Нет. Ключевые слова есть и на русском (Если, Процедура, ВЫБРАТЬ), и на английском. Русскоязычная разработка почти всегда ведётся на русском синтаксисе, английский вариант равноправен, но применяется редко.
Чем встроенный язык отличается от C# или Python?
У него нет самостоятельной среды выполнения — код работает только внутри платформы 1С:Предприятие. Типизация динамическая, память управляется автоматически, а вместо файлов и сетевых сокетов программист оперирует объектами предметной области: документами, справочниками, регистрами.
Можно ли выполнить любой код и на клиенте, и на сервере?
Нет. Обращение к базе данных, чтение и запись объектов, выполнение запросов доступны только в серверном коде. Клиентский код отвечает за форму и взаимодействие с пользователем. Где выполнится процедура, задают директивы &НаКлиенте и &НаСервере.
Где посмотреть все методы и свойства объекта?
В синтакс-помощнике Конфигуратора — это полный встроенный справочник по языку. Плюс контекстная подсказка: поставьте точку после переменной, и редактор покажет доступные методы.