Встроенный язык программирования в 1С:Предприятии
Содержание
Встроенный язык 1С — это язык программирования, на котором описывают поведение прикладного решения: что происходит при проведении документа, какие кнопки появляются на форме, как считается цена в табличной части. Он работает только внутри платформы 1С:Предприятие и без неё не запускается: у языка нет отдельного компилятора и внешней среды выполнения, он живёт в коде конфигурации.
Язык высокоуровневый, с динамической типизацией и сборкой мусора — программисту не нужно вручную выделять память или заранее объявлять тип каждой переменной. Синтаксис намеренно простой: его осваивают бухгалтеры-автоматизаторы и внедренцы, а не только профессиональные разработчики. При этом в одной связке со встроенным языком работает отдельный язык запросов — на нём пишут выборки данных из базы.
Ниже — из чего состоит язык, как выглядит код, какие бывают типы данных и модули, как код обращается к базе и чем его отлаживают.
Что такое встроенный язык и где он выполняется
Встроенный язык (в документации — «встроенный язык 1С:Предприятия», в обиходе часто «1С-код») — это процедурный язык, которым наполняют модули объектов конфигурации. Код не существует сам по себе в виде .exe или скрипта на диске: он хранится внутри конфигурации и выполняется платформой.
Ключевая особенность архитектуры — разделение на клиент и сервер. В клиент-серверном варианте один и тот же модуль формы содержит код, который выполняется:
- 🖥️ на клиенте — реакция на действия пользователя, работа с формой, интерактивные диалоги;
- ⚙️ на сервере — обращение к базе данных, чтение и запись объектов, тяжёлые вычисления.
Код не имеет прямого доступа к файлам операционной системы в произвольном месте и к памяти — он работает через объекты платформы. Это осознанное ограничение: прикладной программист думает категориями предметной области (документ, справочник, регистр), а не файлами и указателями.
Запрос к базе и чтение объектов возможны только на сервере. Если попытаться прочитать данные в клиентской процедуре, платформа выдаст ошибку компиляции ещё до запуска.
Как выглядит код: синтаксис и ключевые слова
Первое, что бросается в глаза, — двуязычный синтаксис. Ключевые слова существуют в русском и английском вариантах, и они равноправны: Если и If, Процедура и Procedure компилируются одинаково. На практике почти вся русскоязычная разработка ведётся на русском синтаксисе.
Базовые правила:
- каждый оператор заканчивается точкой с запятой
;; - регистр ключевых слов не важен:
Если,ЕСЛИиесли— одно и то же; - комментарий начинается с двойной косой черты
//и идёт до конца строки; - процедура не возвращает значение, функция — возвращает через
Возврат.
Простой пример функции, которая считает сумму с НДС:
Функция СуммаСНДС(Сумма, СтавкаПроцентов = 20) Экспорт
Если Сумма <= 0 Тогда
Возврат 0;
КонецЕсли;
Налог = Сумма * СтавкаПроцентов / 100;
Возврат Сумма + Налог;
КонецФункции
Здесь видны основные конструкции: условие Если … Тогда … КонецЕсли, значение параметра по умолчанию (СтавкаПроцентов = 20), слово Экспорт (о нём ниже) и возврат результата.
Управляющие конструкции языка:
| Конструкция | Назначение |
|---|---|
Если … Тогда … ИначеЕсли … Иначе … КонецЕсли | ветвление |
Для Сч = 1 По N Цикл … КонецЦикла | цикл со счётчиком |
Для Каждого Элемент Из Коллекция Цикл … КонецЦикла | обход коллекции |
Пока Условие Цикл … КонецЦикла | цикл с условием |
Попытка … Исключение … КонецПопытки | перехват ошибок |
Отдельного оператора switch/case в языке нет — его заменяет цепочка ИначеЕсли. Внутри циклов работают Прервать (выйти из цикла) и Продолжить (перейти к следующей итерации).
Типы данных и переменные
Типизация динамическая: тип принадлежит значению, а не переменной. Одна и та же переменная может сначала хранить число, потом строку. Объявлять переменную оператором Перем не обязательно — она появляется при первом присваивании.
Типы делятся на несколько групп.
Примитивные типы:
Число— целое и дробное, высокая точность (подходит для денег);Строка— текст в Unicode;Дата— дата и время одним значением;Булево—Истина/Ложь;Неопределено— «значение не задано» (им инициализируются необъявленные реквизиты);Null— отсутствие значения в результате запроса;Тип— сам тип как значение (через функциюТип()).
Ссылочные типы — ссылки на объекты базы: ссылка на элемент справочника, на документ, на значение перечисления. Именно через ссылки код адресует данные: Документ.Ссылка, Номенклатура, Контрагент.
Универсальные коллекции — то, без чего не обходится ни один модуль:
| Коллекция | Когда применяют |
|---|---|
Массив | упорядоченный список значений |
Структура | набор «ключ → значение», ключ — идентификатор |
Соответствие | «ключ → значение», ключом может быть любой тип |
СписокЗначений | список с пометками и представлением для форм |
ТаблицаЗначений | таблица с колонками, аналог временной таблицы в памяти |
ДеревоЗначений | иерархическая таблица |
Тип значения проверяют функцией ТипЗнч(), а сравнивают с эталоном через Тип("СправочникСсылка.Номенклатура"). Для пустой ссылки есть метод объекта или проверка Значение.Пустая().
Деньги считайте только в Число. Платформа хранит его с фиксированной точностью, поэтому копейки не «уплывают», как бывает с плавающей точкой в других языках.
Модули, директивы компиляции и область видимости
Код не пишут в одном файле — он распределён по модулям, привязанным к объектам конфигурации. Основные виды:
- Общие модули — процедуры и функции, доступные из любой точки; сюда выносят повторно используемую логику.
- Модуль формы — обработчики событий конкретной формы (открытие, нажатие кнопки, изменение поля).
- Модуль объекта (документа, справочника) — поведение самого объекта: обработка проведения, проверка заполнения, запись.
- Модуль менеджера — методы, относящиеся к виду объекта в целом, а не к одному экземпляру.
- Модуль сеанса — выполняется при старте сеанса, задаёт параметры сеанса.
Внутри модуля видимостью управляет слово Экспорт. Процедура или функция без него видна только внутри своего модуля; с Экспорт — доступна снаружи. Так разграничивают «внутреннюю кухню» модуля и его публичный интерфейс.
Где именно выполнится код, задают директивы компиляции — строки со знаком & перед процедурой:
| Директива | Где выполняется |
|---|---|
&НаКлиенте | на клиенте, с доступом к данным формы |
&НаСервере | на сервере, с доступом к данным формы |
&НаСервереБезКонтекста | на сервере, быстрее, но без данных формы |
&НаКлиентеНаСервереБезКонтекста | и там, и там (например, проверки) |
Процедуры без контекста выполняются быстрее и меньше нагружают сеть, поэтому серверную логику стараются писать именно так, передавая данные параметрами.
Для структурирования больших модулей служат области — #Область ИмяОбласти … #КонецОбласти. Они сворачиваются в редакторе и не влияют на выполнение. Есть и инструкции препроцессора #Если Клиент Тогда … #КонецЕсли — ими включают фрагмент кода только для нужной среды выполнения.
Глобальный контекст: функции, доступные из любого модуля
Часть функций языка не принадлежит какому-то объекту — их вызывают напрямую из любого модуля. Это глобальный контекст: встроенные функции для работы со строками, числами, датами и для взаимодействия с пользователем.
Самые ходовые группы:
- 🔤 строковые:
СтрДлина(),СтрНайти(),СтрЗаменить(),СтрРазделить(),ВРег()/НРег()(верхний и нижний регистр),СокрЛП()(убрать пробелы по краям); - 🔢 числа и формат:
Цел(),Окр()(округление),Формат()— универсальное форматирование числа и даты в строку; - 📅 даты:
ТекущаяДата()(серверная дата),НачалоДня(),КонецМесяца(),ДобавитьМесяц(); - 💬 сообщения:
Сообщить()и объектСообщениеПользователю— вывод текста пользователю.
Склеивать число со строкой напрямую нельзя — нужно явное преобразование. Правильно так:
Количество = 5;
Текст = СтрШаблон("Отобрано позиций: %1", Количество);
Сообщить(Текст);
Функция СтрШаблон() подставляет значения вместо %1, %2 и сама приводит их к строке — это надёжнее, чем конкатенация через +, и читается лучше.
Полный перечень функций глобального контекста есть в синтакс-помощнике в ветке «Глобальный контекст». Там же указано, где функция доступна — на клиенте, на сервере или везде.
Язык запросов: как код забирает данные из базы
Встроенный язык умеет перебирать объекты в цикле, но читать из базы «поштучно» в цикле — медленно. Для выборок есть отдельный язык запросов — декларативный, похожий на SQL, но со своими возможностями (обращение к реквизитам через точку, виртуальные таблицы итогов, иерархия).
Работает он через объект Запрос:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Товары.Номенклатура КАК Номенклатура,
| СУММА(Товары.Количество) КАК Количество
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК Товары
|ГДЕ
| Товары.Ссылка.Дата МЕЖДУ &Начало И &Конец
|СГРУППИРОВАТЬ ПО
| Товары.Номенклатура";
Запрос.УстановитьПараметр("Начало", НачалоПериода);
Запрос.УстановитьПараметр("Конец", КонецПериода);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Номенклатура);
КонецЦикла;
Ключевые слова запроса тоже двуязычные: ВЫБРАТЬ/SELECT, ИЗ/FROM, ГДЕ/WHERE. Параметры (&Начало) подставляют методом УстановитьПараметр — это защищает от ошибок и ускоряет повторные запросы.
Важные правила работы с запросами:
- запрос выполняется только на сервере — в клиентском коде объект
Запроснедоступен; - вертикальная черта
|в начале строк — это не часть языка, а приём переноса многострочного текста запроса; - составлять текст удобно в конструкторе запроса (правая кнопка в модуле → «Конструктор запроса»), а не вручную.
Правило практика: получить данные одним запросом и дальше работать с результатом в памяти — почти всегда быстрее, чем обходить справочник или документы объектами в цикле.
Отладка и инструменты разработчика
Пишут и правят код в двух средах: классический Конфигуратор и современная 1С:EDT (на базе Eclipse). Для платформы версии 8.3 обе поддерживают один и тот же язык; различается оболочка и удобство.
Базовый набор для отладки — в Конфигураторе:
- Точка останова (клавиша
F9на строке) — выполнение прерывается на этой строке. - Пошаговое выполнение — «шаг с заходом» в вызываемую процедуру и «шаг с обходом» без захода внутрь.
- Табло — окно, куда добавляют выражения и смотрят их значения во время остановки.
- Вычислить выражение — посчитать любое выражение в текущем контексте, развернуть структуру или таблицу значений.
- Замер производительности — показывает, какие строки кода выполнялись дольше всего.
Чтобы отладка заработала, в клиенте и на сервере должна быть разрешена отладка (параметры запуска / свойства информационной базы), иначе точки останова не сработают.
Помимо отладчика, разработчику помогают:
- 🔎 Синтакс-помощник — встроенный справочник по всем объектам, методам и свойствам языка; открывается из Конфигуратора и подсказывает сигнатуры.
- 💬 Проверка модуля — ищет синтаксические ошибки без запуска (пункт меню проверки в редакторе модуля).
- 📋 Контекстная подсказка — список доступных методов объекта по нажатию точки после переменной.
- 🧩 Расширения конфигурации — способ дописать код к типовому решению, не снимая его с поддержки; появились в платформе версии 8.3.6.
Перед замером производительности или отладкой на рабочей базе помните: пошаговая остановка «подвешивает» серверный вызов. На продуктивной базе с пользователями такие эксперименты лучше не проводить — используйте копию.
Частые вопросы
Язык 1С — это один язык или два?
Нужно ли знать английский, чтобы программировать в 1С?
Если, Процедура, ВЫБРАТЬ), и на английском. Русскоязычная разработка почти всегда ведётся на русском синтаксисе, английский вариант равноправен, но применяется редко.Чем встроенный язык отличается от C# или Python?
Можно ли выполнить любой код и на клиенте, и на сервере?
&НаКлиенте и &НаСервере.