Скрипт для 1С с нуля: от первой строки кода до запуска в базе
Содержание
Скрипт для 1С — это код на встроенном языке, который чаще всего оформляют как внешнюю обработку
с расширением .epf. Писать его удобно в Конфигураторе, а запускать — в режиме «1С:Предприятие» через главное меню Файл → Открыть. Отдельный интерпретатор ставить не нужно: язык встроен в саму платформу.
Отдельный скрипт пишут, когда разовую задачу не хочется решать правкой типовой конфигурации: разослать уведомления, пересчитать поле в сотнях документов, выгрузить данные в файл, найти «битые» ссылки. Ниже — встроенный язык, обращение к данным, сборка обработки, отладка и приёмы ускорения. Примеры даны для платформы 8.3 с интерфейсом «Такси».
Что такое скрипт в 1С и где его писать
В 1С нет отдельного скриптового языка вроде Python или JavaScript. Весь код пишется на встроенном языке 1С — том же, на котором работает типовая конфигурация. У языка два варианта написания операторов: русский (Если, Цикл) и английский (If, For). Смешивать их в одном модуле нельзя, но результат одинаков. В примерах — русский синтаксис, он распространён шире.
Есть два места, где код выполняется:
- 🔧 Конфигуратор — здесь код пишут и отлаживают. Открывается отдельным ярлыком или из окна запуска кнопкой
Конфигуратор. - ▶️ Режим «1С:Предприятие» — здесь код работает с живой базой: читает справочники, проводит документы.
Разовый скрипт почти никогда не встраивают в основную конфигурацию — это потребовало бы снятия с поддержки и мешало бы обновлениям. Вместо этого делают внешнюю обработку: отдельный файл .epf, который открывается в предприятии и запускается кнопкой. Она не меняет структуру базы и переносится между базами копированием файла.
Для отчётов, которые только читают данные и ничего не пишут, вместо обработки удобнее внешний отчёт (.erf) — он устроен так же, но заточен под вывод в табличный документ.
Основы встроенного языка: переменные, условия, циклы
Типизация в 1С нестрогая: тип переменной определяется присвоенным значением, объявлять его заранее не требуется. Переменные модуля объявляют через Перем, но внутри процедуры можно сразу присваивать.
Количество = 0;
Имя = "Иванов";
Дата = ТекущаяДата();
Ветвление — Если … Тогда … Иначе … КонецЕсли:
Если Остаток <= 0 Тогда
Сообщить("Нет на складе");
ИначеЕсли Остаток < 10 Тогда
Сообщить("Заканчивается");
Иначе
Сообщить("Достаточно");
КонецЕсли;
Циклов три. Для … По считает по счётчику, Пока крутится по условию, Для Каждого … Из обходит коллекцию — массив, выборку, таблицу значений:
Для Каждого Строка Из Документ.Товары Цикл
Сумма = Сумма + Строка.Сумма;
КонецЦикла;
Повторяющуюся логику выносят в процедуры (ничего не возвращают) и функции (возвращают значение через Возврат). Экспортные процедуры, помеченные ключевым словом Экспорт, видны из других модулей.
Горстка встроенных функций нужна почти в каждом скрипте:
ЗначениеЗаполнено(Значение)— проверка, что ссылка или поле не пустые;СтрШаблон("Код %1 от %2", Код, Дата)— безопасная сборка строки с подстановками;Строка(Значение),Число(Строка),Дата(2026,1,1)— приведение типов;ТипЗнч(Значение)— какого типа переменная (пригодится, когда поле составного типа);ТекущаяДата()на сервере иТекущаяДатаСеанса()для даты с учётом часового пояса.
Ключевой момент для 1С — директивы компиляции. Каждая процедура в модуле формы помечается, где она выполняется:
&НаКлиенте— на компьютере пользователя; отсюда нельзя напрямую читать базу;&НаСервере— на сервере; здесь доступны справочники, документы, запросы;&НаСервереБезКонтекста— то же, но без передачи данных формы (работает быстрее).
Нажатие кнопки обрабатывается на клиенте, а за данными клиент вызывает серверную процедуру. Это разделение — главное, что сбивает новичков.
Вывод через Сообщить() на сервере не появляется мгновенно: сообщения копятся и показываются пользователю после возврата на клиент. Если в серверной процедуре «ничего не выводится» — скорее всего, код просто ещё не завершился.
Как обратиться к справочникам, документам и запросам
К данным есть два подхода. Объектная модель — обращение через менеджеры: Справочники.Номенклатура, Документы.РеализацияТоваровУслуг. Так удобно получить или записать один конкретный объект:
Товар = Справочники.Номенклатура.НайтиПоНаименованию("Бумага А4");
Если ЗначениеЗаполнено(Товар) Тогда
Объект = Товар.ПолучитьОбъект();
Объект.Комментарий = "Проверено";
Объект.Записать();
КонецЕсли;
НайтиПоНаименованию возвращает ссылку (или пустую, если не нашлось — её проверяют через ЗначениеЗаполнено). Чтобы изменить реквизит, из ссылки получают объект методом ПолучитьОбъект() и вызывают Записать().
Запрос — второй подход, и для чтения множества записей он единственно верный. Язык запросов похож на SQL, но на русском:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование + " / " + Выборка.Артикул);
КонецЦикла;
Вертикальная черта | — перенос строки внутри текста запроса, без неё строки склеятся. Выполнить() возвращает результат, Выбрать() — курсор, по которому идут методом Следующий(). К полям обращаются по псевдониму из части КАК.
Если значение подставляется из переменной, его передают параметром, а не вклеивают в текст:
Запрос.Текст = Запрос.Текст + " И Номенклатура.ВидНоменклатуры = &Вид";
Запрос.УстановитьПараметр("Вид", ВыбранныйВид);
Собираем и запускаем внешнюю обработку
Чтобы код стало можно запустить кнопкой, его упаковывают во внешнюю обработку. Порядок такой:
- В Конфигураторе:
Файл → Новый → Внешняя обработка. Задайте имя латиницей без пробелов, напримерПересчётЦен. - В дереве обработки откройте ветку
Формы, добавьте управляемую форму. Мастер предложит её создать — согласитесь. - На форму перетащите команду и свяжите с ней кнопку, либо добавьте кнопку в командную панель формы.
- В модуле формы напишите обработчик. Клиентская процедура только запускает серверную:
&НаКлиенте
Процедура ЗапуститьОбработку(Команда)
ВыполнитьНаСервере();
Сообщить("Готово");
КонецПроцедуры
&НаСервере
Процедура ВыполнитьНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Номенклатура.Ссылка КАК Ссылка
|ИЗ Справочник.Номенклатура КАК Номенклатура
|ГДЕ Номенклатура.Цена = 0";
Выборка = Запрос.Выполнить().Выбрать();
Счётчик = 0;
Пока Выборка.Следующий() Цикл
Объект = Выборка.Ссылка.ПолучитьОбъект();
Объект.Цена = 100;
Объект.Записать();
Счётчик = Счётчик + 1;
КонецЦикла;
Сообщить("Обновлено позиций: " + Строка(Счётчик));
КонецПроцедуры
- Сохраните файл:
Файл → Сохранить, тип — внешняя обработка.epf. - Запустите в режиме «1С:Предприятие»: главное меню (кнопка слева вверху) →
Файл → Открыть, выберите.epf. Откроется форма, нажмите кнопку.
Обратите внимание: число приклеено к строке через Строка(Счётчик) — складывать строку напрямую с числом нельзя, платформа выдаст ошибку преобразования типа.
Прежде чем запускать обработку, которая что-то записывает, в рабочей базе — проверьте её на копии. Массовая перезапись объектов необратима, а движения документов могут задвоиться.
Открытие внешних обработок управляется правами. Если пункт Файл → Открыть не даёт выбрать .epf или появляется запрет, значит, у роли пользователя снято право «Интерактивное открытие внешних обработок», а в клиент-серверной базе может быть включён профиль безопасности — это настраивает администратор.
Отладка кода и разбор ошибок выполнения
Отладка идёт в Конфигураторе. Поставьте точку останова на нужной строке клавишей F9, запустите под отладчиком клавишей F5 — выполнение прервётся на этой строке. Дальше шаг за шагом: F10 — по строкам, F11 — с заходом в процедуры. Значения переменных смотрят, наведя курсор, или через окно Отладка → Табло.
Чтобы отладка сработала, она должна быть разрешена. В Конфигураторе это Сервис → Параметры → Запуск 1С:Предприятия, вкладка Дополнительные, флажок разрешения отладки. Для серверной базы отладку по протоколу включает администратор при запуске агента сервера.
Когда выполнение остановилось на точке, не обязательно добавлять Сообщить ради проверки одного значения. Выделите выражение и нажмите Shift+F9 — окно Вычислить выражение покажет его результат прямо сейчас, со всеми свойствами объекта. Так же удобно проверить, что вернёт метод, прежде чем вставлять его в код.
Ещё один приём для разовой проверки логики — консоль запросов и консоль кода: это готовые внешние обработки (их легко найти в свободном доступе), в которых можно выполнить текст запроса или произвольный код без сборки собственной формы. Для быстрой проверки гипотезы это быстрее, чем каждый раз собирать .epf.
Ошибки в коде ловят конструкцией Попытка … Исключение … КонецПопытки. Внутри Исключение разбирают, что случилось:
Попытка
Объект = Выборка.Ссылка.ПолучитьОбъект();
Объект.Записать();
Исключение
Сообщить(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
ИнформацияОбОшибке() возвращает структуру с описанием, а ПодробноеПредставлениеОшибки() разворачивает её в читаемый текст со стеком вызовов.
Частые сообщения и что за ними стоит:
Как ускорить скрипт и не положить базу
Пока обработка перебирает десяток строк, скорость не важна. На тысячах записей разница между «секунда» и «полчаса» решается несколькими приёмами.
Не получайте объект в цикле без нужды. ПолучитьОбъект() читает всю запись и блокирует её. Если нужно только прочитать реквизит — возьмите его прямо в запросе, а объект получайте, лишь когда собираетесь записать.
Не выполняйте запрос внутри цикла. Запрос в теле цикла по тысяче элементов — это тысяча обращений к базе. Соберите нужные данные одним запросом с соединением (СОЕДИНЕНИЕ), а в цикле только обрабатывайте результат.
Фильтруйте в запросе, а не в коде. Условие в части ГДЕ отсеет лишнее на стороне СУБД. Выбирать всё, а потом в цикле проверять Если … Продолжить — значит гонять через сеть данные, которые тут же выбрасываются.
Для промежуточных наборов — временные таблицы. Если результат одного запроса используется в следующем, поместите его во временную таблицу через ПОМЕСТИТЬ и соединяйтесь с ней, а не читайте базу повторно.
Тяжёлую запись оборачивайте в транзакцию. НачатьТранзакцию() … ЗафиксироватьТранзакцию() вокруг массовой записи ускоряет работу и защищает от частично применённых изменений. В блоке Исключение вызывайте ОтменитьТранзакцию().
Массовую обработку запускайте, когда в базе мало пользователей. Долгая транзакция держит блокировки, и остальные упираются в ожидание. Для сотен тысяч записей делите работу на порции по несколько тысяч.
Частые ошибки, из-за которых скрипт не работает
Это не про синтаксис, а про логику, на которой спотыкаются чаще всего:
- 🧭 Код в клиентской процедуре лезет в базу. Обращение к справочнику или запрос из
&НаКлиентевызовет ошибку компиляции. Перенесите эту часть в&НаСервере. - 📝 Изменили реквизит у ссылки, а не у объекта.
Ссылка.Комментарий = "..."ничего не сохранит. Менять можно только то, что получено черезПолучитьОбъект(), и только послеЗаписать(). - 🔁 Записали объект без проведения.
Записать()для документа сохраняет его, но движения по регистрам не формирует. Чтобы провести, нуженЗаписать(Режим)с режимом проведения. - 🙈 Ждёте
Сообщить()из серверного кода по ходу выполнения. Сообщения появятся только после возврата на клиент — это не зависший скрипт.
Частые вопросы
Нужно ли снимать конфигурацию с поддержки, чтобы писать скрипты?
Можно ли запустить скрипт без Конфигуратора?
.epf можно в режиме «1С:Предприятие» через Файл → Открыть, если у пользователя есть право открывать внешние обработки.В чём разница между внешней обработкой и внешним отчётом?
.epf) может и читать, и менять данные. Отчёт (.erf) предназначен для вывода информации в табличный документ и обычно ничего не записывает. Для разовых правок данных берут обработку.