На чём пишут в 1С: встроенный язык платформы 1С:Предприятие
Содержание
В 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.
Пример целиком, от текста до обхода результата:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Шаблон
|УПОРЯДОЧИТЬ ПО
| Наименование";
Запрос.УстановитьПараметр("Шаблон", "Кабель%");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование + " (" + Выборка.Артикул + ")");
КонецЦикла;
Параметры (&Шаблон) задают через УстановитьПараметр, а не склеивают в текст. Так запрос быстрее и безопаснее.
Для сложных выборок есть временные таблицы (ПОМЕСТИТЬ), пакетные запросы с несколькими ; и конструктор запроса в Конфигураторе: он собирает текст мышкой.
В отчётах поверх запросов работает система компоновки данных (СКД). Она строит печатную и экранную форму из запроса и настроек, почти без кода.
Ошибки и отладка: Попытка, Исключение и отладчик
Обработка исключений
Структура простая: Попытка — Исключение — КонецПопытки.
Попытка
Документ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Сообщить("Не удалось провести: " + ОписаниеОшибки());
КонецПопытки;
Функция ОписаниеОшибки() возвращает текст последней ошибки. Для подробной информации (модуль, строка) есть ИнформацияОбОшибке(). Свою ошибку создают так: ВызватьИсключение "Не заполнен контрагент";.
Пустой блок Исключение — плохая практика. Ошибка исчезнет, а причину потом придётся искать вслепую. Минимум — запишите её в журнал регистрации через ЗаписьЖурналаРегистрации.
Внутри транзакции блок Попытка нужно сочетать с НачатьТранзакцию(), ЗафиксироватьТранзакцию() и ОтменитьТранзакцию(), иначе данные останутся в неопределённом состоянии.
Отладка
Отладчик встроен в Конфигуратор. Базовый порядок такой:
- Откройте базу в Конфигураторе и найдите нужную строку кода.
- Поставьте точку останова — клавиша
F9в этой строке. - Запустите отладку из меню
Отладка → Начать отладку(клавишаF5). - Повторите действие в запущенной программе. Выполнение остановится на точке.
- Проходите код по шагам (
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С
Порядок, который работает у большинства новичков:
- Поставьте учебную версию платформы и откройте любую типовую конфигурацию в Конфигураторе.
- Прочитайте код небольшого общего модуля или модуля менеджера справочника.
- Напишите обработку, которая выводит список справочника запросом.
- Научитесь пользоваться отладчиком раньше, чем писать сложную логику.
- Только потом переходите к расширениям, СКД и интеграциям.