Программирование на встроенном языке 1С с нуля

· 9 мин

Содержание

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

Дальше начинается настоящая работа: обращение к справочникам и документам, запросы к базе, обработка событий, отладка, интеграция по HTTP. Ниже — как это устроено по порядку: от первой строки до модуля с обменом данными и ограничением прав.

Где именно хранится код: модули и инструменты

Весь код живёт в модулях — их несколько видов, и у каждого своя зона ответственности:

  • 📦 Модуль объекта (справочника, документа) — логика конкретной записи: обработчики ПередЗаписью, ПриПроведении, ОбработкаПроведения.
  • 🖥 Модуль формы — поведение при открытии формы, нажатии кнопок, изменении полей.
  • 🔧 Общий модуль — переиспользуемые процедуры и функции, доступные из любого места.
  • 🗂 Модуль менеджера — методы, относящиеся не к одной записи, а ко всему объекту (например, печатные формы).
  • ▶️ Модуль приложения и модуль сеанса — запуск и завершение программы, инициализация параметров сеанса.

Открыть редактор кода можно двумя инструментами:

  1. Конфигуратор — классический инструмент, входит в поставку платформы. Запускается из окна запуска 1С кнопкой Конфигуратор. Дерево конфигурации — слева, двойной щелчок по объекту и переход на вкладку модуля открывает редактор.
  2. 1С:EDT — среда на базе Eclipse для командной разработки, с подсветкой, рефакторингом и Git. Ставится отдельно.

Для первых шагов хватает Конфигуратора. EDT имеет смысл осваивать, когда над проектом работает команда и нужен контроль версий.

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

Первые строки: синтаксис встроенного языка

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

Простейшая процедура, которая выводит сообщение:

Процедура ПоказатьПривет()
    Сообщить("Первый код в 1С работает");
КонецПроцедуры

Функция с возвратом значения:

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

Что стоит запомнить с самого начала:

  • Каждая команда заканчивается точкой с запятой ;.
  • Комментарий — две косых черты //.
  • Переменные не типизированы: в одну и ту же переменную можно положить число, строку, ссылку.
  • Параметры по умолчанию задаются через = в объявлении (как Ставка = 20 выше).

Без условий и циклов не обойтись почти ни в одной процедуре. Условие — конструкция Если … Тогда … Иначе … КонецЕсли, цикл по коллекции — Для Каждого … Из … Цикл … КонецЦикла:

Итого = 0;
Для Каждого Строка Из Товары Цикл
    Если Строка.Количество > 0 Тогда
        Итого = Итого + Строка.Сумма;
    КонецЕсли;
КонецЦикла;

Есть и счётный цикл Для Сч = 1 По 10 Цикл, и цикл Пока Условие Цикл. Прервать цикл досрочно — Прервать, перейти к следующей итерации — Продолжить.

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

Попытка
    Ответ = Соединение.Получить(Запрос);
Исключение
    ЗаписьЖурналаРегистрации("Обмен", УровеньЖурналаРегистрации.Ошибка, , ,
        ИнформацияОбОшибке().Описание);
КонецПопытки;

Текст ошибки берётся из ИнформацияОбОшибке().Описание. Не оставляйте блок Исключение пустым — «проглоченная» ошибка потом превращается в неуловимый баг.

В формах действует контекст исполнения — директивы компиляции. Они указывают, где выполняется код: на клиенте (у пользователя) или на сервере (где база):

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

&НаСервереБезКонтекста
Функция ПосчитатьНаСервере()
    Возврат СуммаСНДС(1000);
КонецФункции

Обращаться к базе данных (запросы, запись объектов) можно только на сервере. Код под &НаКлиенте базу не видит. Это частая причина ошибки «Обращение к процедуре как к функции» и падений у новичков.

Работа со справочниками, документами и регистрами

Главное, ради чего пишется код в 1С, — это чтение и изменение данных. Обращение идёт через менеджеры объектов и ссылки.

Создать и записать элемент справочника:

НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = "ООО Ромашка";
НовыйКонтрагент.ИНН = "7701234567";
НовыйКонтрагент.Записать();

Прочитать реквизит по ссылке — через точку от ссылочной переменной: Контрагент.ИНН. Если нужен только один реквизит, не поднимайте весь объект, используйте запрос.

Запрос — основной способ получать данные пачками. Текст пишется на языке запросов, близком к SQL:

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

Вертикальная черта | в начале строк — продолжение текстовой строки, так принято оформлять многострочные запросы.

Обработчик события документа — где обычно формируются движения по регистрам. Пишется в модуле объекта документа:

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    Движения.ОстаткиТоваров.Записывать = Истина;
    Строка = Движения.ОстаткиТоваров.Добавить();
    Строка.Период = Дата;
    Строка.Товар = Товар;
    Строка.Количество = Количество;
КонецПроцедуры
ЗадачаГде писать код
Проверка перед записью элементаМодуль объекта, ПередЗаписью
Движения по регистрамМодуль документа, ОбработкаПроведения
Реакция на кнопку формыМодуль формы, под &НаКлиенте
Общий расчёт для многих местОбщий модуль

Отладка: как найти, почему код не работает

Отладчик встроен в Конфигуратор и в EDT. Он позволяет остановить выполнение в нужной точке и посмотреть значения переменных.

Порядок работы:

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

Если точки останова не срабатывают, проверьте в настройках информационной базы, что отладка разрешена, а в клиенте — что он подключён к отладчику (Сервис → Параметры → Запуск → Использовать отладку).

Для поиска «тормозов» есть замер производительности (Отладка → Замер производительности): он показывает, сколько миллисекунд заняла каждая строка. Так находят медленный запрос в цикле.

Простейший приём для быстрой диагностики — временно вставить Сообщить(СтрокаПеременной) и посмотреть, что реально лежит в переменной на этом шаге. После отладки такие строки убирают.

Чтобы код не тормозил: приёмы оптимизации

Производительность в 1С почти всегда упирается в работу с базой. Главные правила:

  • 🚫 Не делайте запрос внутри цикла. Если для каждой строки документа выполняется отдельный запрос, при тысяче строк будет тысяча обращений к базе. Соберите данные одним запросом заранее.
  • 📊 Получайте только нужные поля. Выборка всех реквизитов, когда нужен один, нагружает базу напрасно.
  • 🔗 Соединяйте таблицы в запросе, а не дочитывайте связанные данные через точку в цикле (это скрытые подзапросы).
  • 🧮 Считайте итоги средствами запроса (СУММ(…), СГРУППИРОВАТЬ ПО), а не складывайте вручную в цикле по выборке.
  • 📑 Для сложной логики используйте временные таблицы (ПоместитьВременнуюТаблицу) и пакетные запросы.

Запрос в цикле — причина номер один медленных обработок. Если провёденный документ или регулярная обработка «висит», первым делом ищите цикл, внутри которого создаётся Новый Запрос.

Проверьте себя
Где в 1С можно выполнять запрос к базе данных?
Что чаще всего делает обработку медленной?
Чем процедура отличается от функции?

Обмен с внешними системами: JSON, HTTP и REST

Код в 1С умеет ходить в интернет и обмениваться данными с чужими сервисами — это основа интеграций.

HTTP-запрос. Понадобятся объекты HTTPСоединение и HTTPЗапрос:

Соединение = Новый HTTPСоединение("api.example.com", 443, , , , , Новый ЗащищённоеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/v1/rates");
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();

Соединение.Получить(Запрос) — это GET; для POST есть Соединение.ОтправитьДляОбработки(Запрос). Порт 443 и ЗащищённоеСоединениеOpenSSL нужны для https.

Разбор JSON. Пришедший в ТекстОтвета JSON читают через ЧтениеJSON:

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

ПрочитатьJSON вернёт структуру или соответствие — дальше обращаетесь к полям по именам: Данные.Свойство, если это структура.

Запись JSON для отправки — обратная операция через ЗаписьJSON и ЗаписатьJSON:

Отправляемое = Новый Структура("Код, Сумма", "RUB", 1000);
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Отправляемое);
СтрокаJSON = Запись.Закрыть();

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

REST здесь — это стиль работы с таким API: разные адреса (/v1/rates, /v1/orders) и методы (GET, POST, PUT, DELETE) для разных действий. Для публикации своего REST-сервиса в 1С есть HTTP-сервисы — отдельные объекты конфигурации, в модулях которых пишутся обработчики входящих запросов.

Права доступа и защита кода

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

  • Если процедуре нужно прочитать данные, которые пользователю по роли недоступны, используйте привилегированный режим: УстановитьПривилегированныйРежим(Истина) в начале и УстановитьПривилегированныйРежим(Ложь) в конце. В нём проверка прав не выполняется.
  • Ограничение на уровне отдельных записей (например, «менеджер видит только своих контрагентов») настраивается через RLS — ограничение доступа на уровне записей, в свойствах роли.

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

Защита самого кода от просмотра и копирования делается не кодом, а средствами поставки: конфигурацию можно поставлять «на замок» (без возможности редактирования) и закрывать модули от просмотра при создании файла поставки .cf. Отдельные обработки защищают компиляцией в закрытый формат .epf с установленной защитой.

Проверить, что всё настроено, поможет короткий чек-лист:

Перед передачей кода в работу
Выполнено: 0 / 5

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

На каком языке пишут код в 1С?
На встроенном языке 1С. Ключевые слова есть и на русском (Процедура, Если, Цикл), и на английском — можно писать на любом, но в русскоязычных проектах принят русский.
Нужно ли знать другой язык программирования, чтобы начать?
Нет. Встроенный язык 1С самодостаточен и проще многих. Но понимание SQL сильно помогает с запросами, а знание HTTP и JSON — с интеграциями.
Чем отличается код на клиенте от кода на сервере?
Клиентский код (&НаКлиенте) работает у пользователя и не видит базу данных. Серверный (&НаСервере, &НаСервереБезКонтекста) имеет доступ к данным, но не может напрямую управлять формой на экране. Запросы — только на сервере.
Где писать общую функцию, чтобы вызывать её из разных мест?
В общем модуле. Поставьте флаги доступности (Клиент/Сервер) в свойствах модуля в зависимости от того, откуда будете вызывать.
Как отлаживать, если выполнение не останавливается на точке?
Проверьте, что в клиенте включён режим отладки и он подключён к процессу, а в настройках базы отладка разрешена. Для серверного кода отладка настраивается отдельно на сервере.