К статье
Практический материал

Разработка и Конфигурация · 17 мин

Как работает язык 1С: устройство и принципы выполнения кода

Как устроен встроенный язык 1С: компиляция, контексты выполнения, работа с объектами и запросами, отличия тонкого и толстого клиента, типичные ошибки новичков.

Встроенный язык 1С — это не отдельный язык программирования в духе C++ или Python, а скриптовый язык, жёстко привязанный к платформе 1С:Предприятие. Код на нём выполняется не сам по себе, а внутри контекста прикладного решения: модуля формы, модуля объекта, общего модуля или обработчика события. Понимание этой связки — ключ к тому, чтобы писать рабочие доработки, а не наборы операторов, которые «почему-то не видят» нужные данные.

Язык 1С имеет русскоязычный синтаксис с возможностью использования английских синонимов ключевых слов. Конструкции вроде «Если... Тогда... КонецЕсли» и «Процедура... КонецПроцедуры» — это не упрощение «для бухгалтеров», а полноценный язык со строгой типизацией значений, объектной моделью доступа к данным и встроенным языком запросов. Платформа компилирует код во внутреннее представление и исполняет его либо на клиенте, либо на сервере — и место исполнения определяет, какие объекты и операции доступны.

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

Из чего состоит язык 1С и где живёт код

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

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

Структура модуля строго регламентирована: сначала идёт раздел описания переменных, затем процедуры и функции, в конце — раздел основной программы (исполняется при инициализации модуля). Процедуры и функции могут быть экспортными (видимыми из других модулей) или локальными. Это единственный способ организации кода — никаких классов и наследования в привычном ООП-смысле в языке нет.

Как платформа компилирует и выполняет код

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

Ключевая особенность — разделение исполнения между клиентом и сервером. В клиент-серверном режиме код с директивой компиляции «НаСервере» выполняется на сервере 1С:Предприятия, код «НаКлиенте» — на рабочем месте пользователя. Директивы «&НаКлиенте», «&НаСервере», «&НаСервереБезКонтекста» в модуле формы определяют, где будет исполнена каждая процедура. На сервере доступны запросы и запись объектов, на клиенте — элементы интерфейса и диалоги с пользователем.

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

Типы данных и работа со значениями

Язык 1С — язык со слабой динамической типизацией: переменные объявляются без указания типа, а тип определяется присвоенным значением. Базовые примитивы — Число, Строка, Дата, Булево, Неопределено и Null. Значение «Неопределено» означает отсутствие значения вообще, а Null обычно приходит из запросов при соединениях таблиц, где не нашлось соответствия. Смешивание этих двух значений — частый источник трудноуловимых ошибок в условиях.

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

Отдельная категория типов — ссылочные типы прикладных объектов: СправочникСсылка, ДокументСсылка, ПеречислениеСсылка и другие. Ссылка — это «указатель» на запись в базе, содержащий только идентификатор и минимум данных. Чтобы получить доступ ко всем реквизитам и менять объект, ссылку преобразуют в объект методом ПолучитьОбъект(). Это дорогая операция: она читает объект из базы целиком, поэтому в циклах её нужно использовать осознанно.

// Проверка типов и пустых значений

Если Не ЗначениеЗаполнено(Контрагент) Тогда

Сообщить("Контрагент не указан");

Возврат;

КонецЕсли;

Если ТипЗнч(Параметр) = Тип("СправочникСсылка.Номенклатура") Тогда

Наименование = Параметр.Наименование; // обращение через ссылку

КонецЕсли;

Как код обращается к данным: объекты против запросов

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

Второй способ — встроенный язык запросов. Синтаксически он напоминает SQL, но оперирует именами объектов метаданных и их реквизитов, а не физическими таблицами СУБД. Запрос выполняется на сервере (в клиент-серверном режиме — фактически средствами СУБД), поэтому выборка ста тысяч записей запросом на порядки быстрее, чем объектным перебором. Правило простое: чтение и анализ данных — через запрос, изменение отдельных объектов с бизнес-логикой — через объектную модель.

Объектный доступ или запрос

Объектная модель (ПолучитьОбъект, Записать)

Подходит для создания и изменения отдельных документов и элементов справочников с полной бизнес-логикой. Ограничение: медленно при массовой обработке, каждая запись — отдельное обращение к базе.

Язык запросов (ВЫБРАТЬ ... ИЗ)

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

Наборы записей регистров

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

Типовой сценарий выборки выглядит так: создаётся объект Запрос, задаётся текст, устанавливаются параметры, выполняется метод Выполнить(), результат выгружается в таблицу значений или обходится через Выборку. Параметры запроса всегда передаются через конструкцию «&ИмяПараметра» и метод УстановитьПараметр — конкатенация значений прямо в текст запроса считается плохой практикой и источником ошибок.

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

Контексты выполнения: клиент, сервер, тонкий и толстый клиент

Место исполнения кода определяется режимом запуска и директивами компиляции. В файловом режиме вся логика чаще всего выполняется на компьютере пользователя. В клиент-серверном режиме появляется трёхзвенная архитектура: клиентское приложение, сервер 1С:Предприятия и СУБД. Тонкий клиент и веб-клиент умеют исполнять только ограниченный набор операций — вся работа с базой уходит на сервер.

На тонком клиенте недоступны, например, прямая работа с файловой системой сервера, COM-объекты, некоторые операции с табличными документами. Если код, написанный и проверенный в толстом клиенте, перестаёт работать у пользователей на тонком клиенте — почти наверняка дело в недоступном в этом режиме методе. Проверяется это через синтакс-помощник: у каждого метода указана доступность по режимам (сервер, толстый клиент, тонкий клиент, веб-клиент).

Передача данных между клиентом и сервером требует сериализуемых типов. Можно передать примитивы, структуры, массивы, ссылки. Нельзя передать объект документа или набор записей — они существуют только в рамках серверного вызова. Если нужно отредактировать объект, типовой шаблон такой: клиент передаёт ссылку на сервер, серверная процедура получает объект, изменяет, записывает и возвращает клиенту результат (например, признак успеха или текст ошибки).

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

Событийная модель: обработчики и подписки

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

Порядок событий имеет практическое значение. Например, в ПередЗаписью объект ещё можно изменить или отказаться от записи через параметр Отказ, а в ПриЗаписи объект уже считается записываемым, и отказ приведёт к откату транзакции. Проверки заполнения логично размещать в ОбработкаПроверкиЗаполнения — тогда они корректно сработают и при интерактивной записи, и при программной.

Для сквозной логики, которая должна срабатывать у многих объектов (например, проставление ответственного во всех документах), используются подписки на события. Подписка привязывает обработчик из общего модуля к событию группы объектов. Это удобно, но опасно: ошибка в подписке на ПередЗаписью справочников сломает запись всех справочников сразу. Обработчики подписок должны быть максимально защищены проверками типа источника и попытками-исключениями.

Отладка и проверка работоспособности кода

Основной инструмент — встроенный отладчик конфигуратора. Отладка запускается через меню «Отладка — Начать отладку», точки останова ставятся кликом по полю слева от строки кода. Важно, что отлаживать можно и серверный код, и код на тонком клиенте — для этого в настройках отладки включается поиск предметов отладки на сервере и нужные виды клиентских приложений.

Когда отладчик недоступен (код выполняется в фоновом задании или на сервере без включённой отладки), используют журнал регистрации и вывод диагностических сообщений. Метод Сообщить() подходит для быстрой проверки, но в серверном коде его сообщения увидит только тот сеанс, который выполнял вызов. Для постоянной диагностики надёжнее ЗаписьЖурналаРегистрации с указанием уровня важности.

Проверка результата доработки — отдельный этап, который нельзя пропускать. Минимальный набор: прогнать сценарий на тестовой копии с данными, близкими к реальным; проверить поведение при пустых и некорректных входных данных; убедиться, что обработчики не срабатывают дважды (частая проблема при сочетании подписки и кода в модуле объекта); проверить права — код, работающий под администратором, может падать у рядового пользователя из-за нехватки прав на объекты.

Контрольные точки

Как проверить результат доработки

Запись и проведение документа после изменения модуля объекта
Норма

Документ записывается, движения по регистрам формируются как раньше или согласно новой логике

Тревожный признак

Ошибки при проведении, дублирующиеся или пропавшие движения

Работа под пользователем с ограниченными правами
Норма

Сценарий выполняется без ошибок доступа

Тревожный признак

Сообщения о нарушении прав доступа к объектам

Поведение на тонком клиенте
Норма

Все функции доработки доступны и работают

Тревожный признак

Ошибки вида «Метод объекта не обнаружен» или недоступные операции

Массовая обработка данных
Норма

Обработка выполняется за приемлемое время, без тысяч отдельных серверных вызовов

Тревожный признак

Форма «зависает», в журнале видны длинные цепочки вызовов

Типичные ошибки начинающих разработчиков 1С

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

Типичные ошибки
01
Вызов ПолучитьОбъект() внутри цикла по тысячам ссылок — каждый вызов читает объект из базы, обработка выполняется часами вместо минут; для чтения данных нужен запрос
02
Серверные вызовы в цикле на клиенте — каждый вызов это сетевое обращение; данные нужно передавать на сервер пакетом одним вызовом
03
Изменение реквизитов через ссылку (Ссылка.Реквизит = ...) — ссылка доступна только для чтения; для изменения нужен ПолучитьОбъект() и Записать()
04
Игнорирование параметра Отказ в обработчиках — после установки Отказ = Истина код продолжает выполняться и пытается работать с несогласованными данными; после отказа нужен Возврат
05
Сравнение с Null как с пустым значением — Null из запроса не равен пустой строке и Неопределено; проверять нужно через «ЕСТЬ NULL» в запросе или функцию проверки в коде
06
Доработка типового модуля вместо расширения — при обновлении конфигурации изменения теряются; для типовых конфигураций на поддержке используются расширения

Отдельного упоминания заслуживает работа с типовыми конфигурациями. Прямая правка модулей типовой конфигурации снимает её с полной поддержки и превращает каждое обновление в ручное сравнение изменений. Механизм расширений конфигурации позволяет переопределять процедуры, добавлять свои объекты и формы, не трогая типовой код. Для большинства доработок «под себя» расширение — правильный и безопасный путь.

Маршрут решения

Как выбрать способ доработки

Нужно изменить поведение типовой конфигурации, которая обновляетсяИспользуйте расширение конфигурации с аннотациями &ИзменениеИКонтроль или &Вместо
Нужен разовый анализ или выгрузка данных без изменения учётаНапишите внешнюю обработку с запросом — конфигурация при этом не меняется вовсе
Нужна логика, общая для нескольких документов или справочниковСоздайте общий модуль и подписку на событие, с проверками типа источника
Нужно массово исправить данные в базеРаботайте на копии, используйте транзакции и обрабатывайте данные порциями, сначала проверив результат на малой выборке

Частые вопросы о языке 1С

Нужно ли знать другой язык программирования, чтобы освоить 1С?

Нет, язык 1С вполне подходит как первый язык: синтаксис простой, среда разработки единая, результат виден сразу в прикладной системе. Знание основ SQL поможет быстрее освоить язык запросов, а общее понимание алгоритмов (циклы, условия, коллекции) переносится из любого языка. Обратный перенос тоже работает: после 1С проще освоить Python или JavaScript, чем наоборот начинать с нуля.

Чем язык запросов 1С отличается от обычного SQL?

Запрос 1С оперирует именами объектов метаданных (Документ.РеализацияТоваровУслуг), а не физическими таблицами СУБД, и платформа сама преобразует его в SQL конкретной базы. Есть специфические конструкции: виртуальные таблицы регистров (Остатки, Обороты), разыменование ссылок через точку, иерархические итоги. Прямого доступа к возможностям СУБД вроде хранимых процедур из языка запросов нет.

Почему код работает в толстом клиенте, но падает в тонком?

Тонкий клиент поддерживает ограниченный набор методов платформы: недоступны многие операции с файлами, COM-объекты, часть функций работы с табличными документами. Откройте синтакс-помощник на проблемном методе и посмотрите колонку доступности по режимам. Решение — перенести такую логику в серверную процедуру, где ограничений тонкого клиента нет.

Можно ли выполнять код 1С вне платформы, как обычный скрипт?

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

Что быстрее: запрос или обход объектов в цикле?

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

Как безопасно тестировать доработки, если нет отдельного тестового сервера?

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

Итог

Что важно запомнить

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