«Чтобы оставаться на месте, нужно бежать со всех ног. А чтобы куда‑то попасть, надо бежать как минимум вдвое быстрее» — Льюис Кэрролл

Пролог. День, когда опять что‑то сломалось

Это было очередное утро после вечернего обновления релиза. В рабочей базе уже несколько часов валилась какая‑то ошибка. Пользователи писали в поддержку, поддержка — нам. В чем оказалась причина? Всего одна строчка кода — мы потеряли ее во время ручного переноса из дева в релизное хранилище.

Далее последовал примерно следующий диалог:

Руководство: «А откуда ошибка? Разве мы вчера всё не протестировали?».
Мы: «Протестировали, но ошибку довнесли позже».
Руководство: «А как нам этого избежать в будущем? Может автотесты какие добавить или ИИ привлечь? Что нужно сделать?».
Мы: (короткое молчание) «Пока точно не знаем, подумаем..».

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

В тот вечер в поисковиках у команды начали появляться следующие запросы: «Как перейти с конфигуратора 1С на EDT», “Git для 1С”, «ИИ в 1С‑разработке» и пр. И пока мы даже не задумывались, что запущен самый сложный, дорогой и одновременно очень нужный проект в нашей команде.

Часть 1. Наше бытие и ловушка комфорта

Мы — довольно большая компания. То, как мы работаем с 1С, должно быть многим будет знакомо. Есть два хранилища — dev и release. Разработчик делает правки, потом вручную, через «сравнение и объединение», переносит их в релизную базу. Получается, наш merge — это частый копипаст из окна в окно, либо сравнение/объединение, и постоянный риск забыть что‑то или перенести не так и не туда.

Code review? Формально он есть. Но найти и посмотреть изменения разработчика в Конфигураторе — довольно муторное занятие. Даже настроен SonarQube, но полностью ему на откуп проверку кода не отдаем, он как дополнительный информатор. На практике ревью сводилось к фразе «Ты посмотрел задачу? Сейчас гляну».

Про CI/CD слышали, что‑то даже есть. Настроен скрипт, который периодически выгружает хранилище в Git. Без веток задач, только теги на них в коммитах. По сути Git используется просто как архив, а не как основной инструмент, и использовать его для развертывания систем не можем.

И знаете, что здесь самое опасное? Все к такой работе привыкли и всех всё устраивало. Зачем что‑то менять, если «и так работает». Да и времени особо на нововведения нет, поток новых задач идет постоянно.

«Если ты не идёшь вперёд, ты откатываешься назад. В стоячей воде неизбежно начинается гниение» — Лао Цзы

Казалось, мы стоим в этой самой воде и она начинает понемногу пахнуть.

Часть 2. Новые надежды и встреча с реальностью

После исследования чужого опыта и погружения в тему, твердо решили: движемся в сторону перехода на EDT. Он хранит конфигурацию в отдельных файлах на диске, а это открывает дверь к Git с отдельными ветками задач, Merge‑requestами и полноценным code‑review. Есть какие‑то альтернативные варианты по синхронизации конфигуратора с Git, но скорее всего это было бы промежуточным переходом, надо сразу ставить разработку на правильные рельсы.

Мы представляли, что наши разработчики, как в Google: пишут код, делают коммиты, еще и ИИ используют на каждом шагу. Наши надежды были наивными и прекрасными. Реальность же оказалась жёстче.

Первая стена — не бюджетное железо

Конфигуратор работает на любом «калькуляторе», а EDT — это тяжелая IDE на Eclipse. На обычном ноутбуке с 8–16 ГБ ОЗУ она грузится и подключает базу неприлично долго. Работать на «стандартном железе» было бы невозможно.

«Гладкая дорога никогда не делает умелого водителя» — Латинская пословица

Мы собрали основные требования: 32 ГБ ОЗУ, быстрый SSD, современный производительный процессор. Для всей команды надо закупить хорошие рабочие станции, а лучше ноутбуки. А ведь это заранее незапланированный бюджет.

Вторая стена — сторонние разработчики

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

Решение ещё ищем, и то что сейчас прорабатываем — не такое красивое: синхронизация через файлы *.cf. Те, кто в EDT, работают в Git. Для внешних разработчиков выгружаем cf‑файл с изменениями. Схема сложная, но кажется позволяет начать двигаться вперед.

Третья стена — человеческий фактор

Люди боятся нового и не хотят ничего менять, это не новость.

«Зачем мне EDT? У меня куча задач и в Конфигураторе я всё успеваю» — высказались некоторые разработчики. «Это всё сложно, долго и не работает» — вторили им другие.

И люди боятся не самой EDT, а неизвестности. Угрозы своей компетентности. Новых привычек, манипуляций и дополнительной рутины, по началу возможно отнимающих еще больше времени.

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

«Трудности — это не преграды на пути, они и есть путь» — Райан Холидей

Главный вывод этой части: EDT при серьезной разработке в 1С — это уже не дань моде, а необходимость. Но этот путь требует мощных компьютеров, терпения и готовности от всех меняться.

Часть 3. Следующий уровень в работе

Здесь еще раз проговорим, зачем нам все это? Когда мы освоим EDT и Git, перед нами откроются горизонты, о которых мы раньше даже не мечтали:

Настоящий code review

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

В нашем светлом будущем нас ждет merge‑request. Каждая ветка‑задача проходит ревью. Мы сразу видим строки, которые изменились, всё в одном месте.

А ещё можно начать использовать Git‑хуки. Подключить скрипты, которые автоматически проверяют код перед коммитом или пушем, с помощью различных сервисов, в том числе на основе ИИ.

Автоматизация тестирования с Vanessa Automation

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

Сейчас активно развиваем Vanessa Automation — полноценный фреймворк для автоматизированного тестирования в 1С. А тут еще в последних версиях у нее появилась поддержка ИИ и MCP‑серверов, что кажется может дать огромную выгоду в генерацию тестовых данных. Vanessa сможет сама подготовить данные для теста: создать документы, заполнить справочники. ИИ поможет написать и сами тесты.

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

Сборка и выпуск приложения

И конечно основное преимущество — это единое окно внесения изменений в релиз и его последующая автоматическая сборка. Никаких больше тебе ручных, муторных и не внимательных переносов из хранилища в хранилище.

Часть 4. ИИ — не игрушка, а пропуск в будущее

Еще в начале нашего пути по освоению EDT мы знали: ИИ сейчас — практически везде. Коллеги из других команд уже активно используют его для написания тестов, рефакторинга и пр. К тому же наша компания активно продвигает его использование на всех уровнях и помогает в освоении.

И после этого задаешься вопросом: «Почему у нас этого нет?». Ответ обычно таков: потому что Конфигуратор, а совместное использование ИИ с ним трудно совместимо. Решим проблему с Конфигуратором — решим проблему с полноценным внедрением и использованием ИИ.

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

Проблема: ИИ слепой

ИИ вполне себе знает синтаксис 1С и даже может написать красивый код. Но он не знает про ваш справочник «Номенклатура» или «Товары», не знает реквизиты ваших документов и тому подобное. Пытается что‑то «правдоподобно угадать» и как результат — генерирует мёртвый код. Ему нужен ваш контекст!

Решение: MCP (Model Context Protocol) — “USB‑порт” для нейросети. Стандарт, который позволяет ИИ подключиться к вашей конфигурации и «увидеть» её. Сейчас активно тестируем некоторые из них, благо подобные инструменты для 1С начали активно появляться. Будем тестировать их как в отдельных средах так и внутри EDT, посмотрим что понравится больше. О конечных результатах пока говорить рано, и кажется это отдельная тема для новой статьи.

Здесь можно еще отметить отдельный вопрос поддержания актуальности этого контекста, возможность разворачивания его в виде RAG или других индексируемых сущностей. Но и эти моменты здесь уже широко раскрыть не успеем.

Выбор ИИ

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

Yandex Code Assist — “Универсальный солдат”

Ассистент Яндекса на базе модели Qwen. Работа строится через Visual Studio, то есть сбоку от EDT, конечно это не плюс. Зато обладает множеством дополнительных настроек (MCP, навыки, плагины и пр.), что может повышать качество работы и результата. Говорит по‑русски — это тоже важно. Без дополнительных знаний в языке 1С еще многое додумывает.

Результат: Код пишет качественно. Учитывает много нюансов. На вопросы отвечает полнее и зависаний практически нет.

Вердикт: Неплох, особенно для отдельных небольших алгоритмов или задач.

1С:Напарник — «Домашний питомец»

Раз есть EDT, значит есть и официальный ИИ‑помощник от 1С, который пока бесплатен. Сразу видно: он знает платформу, код пишет хорошо, а комментарии к нему еще лучше.

Результат: простейший алгоритм пишет быстро и качественно. Даже более сложную задачу, с учетом структуры данных, может сделать. Но не понравилось, что на некоторых сложных вопросах может уйти в бесконечный анализ и зависнуть, как так? А один раз даже умудрился так отредактировать модуль, что сломал его и сам попросил восстановить его из бекапа.

Вердикт: для чего‑то не сложного, разработки с нуля, шаблонов и комментариев — очень даже. Если нужно большее — кажется пока слабоват, но будем пробовать.

Claude Code — “Профессиональный наемник”

Сам по себе Claude Code — мощный агент. Хорошо анализирует конфигурацию и код, удачно предлагает и принимает решения. НО! Стоит больших денег( Непонятна его дальнейшая судьба в РФ и нашей компании в частности. Пока пользуемся им осторожно)

Результат: Код пишет красиво (правда, пока не идеально), с учётом нашей структуры и стандартов. Ещё и объясняет, почему сделал так, а не иначе. С каждым обновлением про 1С знает все больше.

Вердикт: для сложного рефакторинга легаси, тестирования и анализа — кажется лучший. Но дорогой, зараза.

Небольшой ИИ‑батл

Еще в начале работы удалось устроить короткое сравнение между всеми тремя. Задача была сделать одну и ту же, срочную и не сложную задачку. Промт звучал примерно так:

«Нужен пример кода для базы УХ: сначала запросом отобрать документы ВерсияСоглашенияКоммерческийДоговор с Номером ПОДОБНО „%‑%-%“; потом обойти эту выборку и изменить номер на „000071959“ увеличивая на единицу. Документы записывать в режиме загрузка. Добавить комментарии у процедуры и основных действий»

Вот что из этого получилось:

  • Yandex Code Assist

    • Написал работоспособную процедуру на 55 строк с обширным комментарием к процедуре.

    • Комментарии к основным действиям добавил где надо и не надо, визуально они заняли места больше самого кода.

    • Про режим загрузки ничего не понял и придумал такую конструкцию: «ДокументОбъект.Записать(РежимЗаписиДокумента.Загрузка)»

    • В конце выдал некие рекомендации, по мне — не особо полезные.

Пример кода
// Процедура выполняет изменение номеров документов "Версия соглашения коммерческий договор".
//
// Логика работы:
//   1. Запросом отбираются документы "ВерсияСоглашенияКоммерческийДоговор",
//      у которых номер документа содержит подстроку вида "ЧЧЧ-ЧЧЧ-ЧЧЧ" (маска "%-%-%").
//   2. Выборка обходится в цикле, и каждому документу присваивается новый номер,
//      начиная с базового значения "000071959" и увеличиваясь на единицу
//      для каждого следующего документа.
//   3. Документы записываются в режиме записи "Обмен данными.Загрузка",
//      что позволяет изменять номера без срабатывания проверок уникальности номера.
//
// ВАЖНО: процедура модифицирует данные в базе. Перед выполнением убедитесь в наличии
// резервной копии базы данных и в корректности выбранных документов.

Процедура ИзменитьНомераДоговоров() Экспорт

    // Формируем и выполняем запрос для отбора документов с номером, содержащим дефисы.
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ВерсияСоглашенияКоммерческийДоговор.Ссылка КАК Ссылка
    |ИЗ
    |    Документ.ВерсияСоглашенияКоммерческийДоговор КАК ВерсияСоглашенияКоммерческийДоговор
    |ГДЕ
    |    ВерсияСоглашенияКоммерческийДоговор.Номер ПОДОБНО ""%-%-%""";
    // Условие "%-%-%" отбирает документы, у которых номер состоит минимум
    // из трёх частей, разделённых дефисом (например, "123-456-789").

    Выборка = Запрос.Выполнить().Выбрать();

    // Начальное значение номера, с которого начинается перенумерация.
    БазовыйНомер = "000071959";

    // Обходим отобранные документы в цикле.
    Пока Выборка.Следующий() Цикл

        // Открываем объект документа для изменения его номера.
        ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();

        // Присваиваем документу новый номер.
        ДокументОбъект.Номер = БазовыйНомер;

        // Записываем документ в режиме "Обмен данными.Загрузка".
        // Такой режим записи позволяет изменить номер документа в обход
        // стандартных проверок уникальности и правил нумерации.
        ДокументОбъект.Записать(РежимЗаписиДокумента.Загрузка);

        // Увеличиваем базовый номер на единицу для следующего документа.
        // Число в строке прибавляется как целочисленное значение,
        // результат преобразуется обратно в строку.
        БазовыйНомер = Строка(Число(БазовыйНомер) + 1);

    КонецЦикла;

КонецПроцедуры
  • 1С‑Напарник

    • Написал работоспособную процедуру на 57 строк с адекватными комментариями к процедуре и основным действиям.

    • Оказался единственным, кто еще при рассуждении понял про «ДокументОбъект.ОбменДанными.Загрузка = Истина» и указал это в коде.

    • Выдал добротные и полезные рекомендации для запуска.

Пример кода
// Перенумерация документов "Версия соглашения (коммерческий договор)".
// Для всех документов с номером вида "<x>-<y>-<z>" устанавливает
// последовательные числовые номера, начиная с "000071959".
//
Процедура ПеренумероватьВерсииСоглашений() Экспорт

    // Начальное значение новой нумерации.
    НачальныйНомер = 71959;

    // Шаблон отбора: документы, в номере которых присутствуют дефисы.
    ШаблонНомера = "%-%-%";

    // Формируем запрос для отбора документов со "старыми" номерами.
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |    ВерсияСоглашенияКоммерческийДоговор.Ссылка КАК Ссылка
        |ИЗ
        |    Документ.ВерсияСоглашенияКоммерческийДоговор КАК ВерсияСоглашенияКоммерческийДоговор
        |ГДЕ
        |    ВерсияСоглашенияКоммерческийДоговор.Номер ПОДОБНО &ШаблонНомера
        |УПОРЯДОЧИТЬ ПО
        |    ВерсияСоглашенияКоммерческийДоговор.Дата,
        |    ВерсияСоглашенияКоммерческийДоговор.Ссылка";

    Запрос.УстановитьПараметр("ШаблонНомера", ШаблонНомера);

    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();

    // Счетчик новых номеров - увеличивается на единицу для каждого документа.
    ТекущийНомер = НачальныйНомер;

    Пока Выборка.Следующий() Цикл

        // Получаем объект документа для изменения реквизита Номер.
        ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
        Если ДокументОбъект = Неопределено Тогда
            // Документ мог быть удален другой транзакцией - пропускаем.
            Продолжить;
        КонецЕсли;

        // Присваиваем номер в формате 9-значного числа с лидирующими нулями.
        ДокументОбъект.Номер = Формат(ТекущийНомер, "ЧЦ=9; ЧВН=; ЧГ=0");

        // Записываем документ в режиме загрузки:
        //   - РежимЗаписиДокумента.Запись - простая запись без проведения;
        //   - ОбменДанными.Загрузка = Истина - отключает проверки заполнения
        //     и подписки на события, выполняемые при интерактивной записи.
        ДокументОбъект.ОбменДанными.Загрузка = Истина;
        ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);

        ТекущийНомер = ТекущийНомер + 1;

    КонецЦикла;

КонецПроцедуры
  • Claude Code

    • Написал аж две процедуры на 128 строк: основную + вспомогательную для ее клиентского вызова. Показалось, что кода даже слишком много для такой задачи.

    • Даже использовал блоки Попытка‑Исключение, а также Сообщить для вывода информации пользователю.

    • Все комментарии разумных размеров.

    • Тоже ничего не понял про загрузку и откуда‑то придумал метод «УстановитьРежимЗагрузкиДанных(Истина)».

Пример кода
// Процедура для обновления номеров документов ВерсияСоглашенияКоммерческийДоговор
// Находит документы с номерами по шаблону "%-%-%", изменяет их номера начиная с "000071959"
// и записывает в режиме загрузки для повышения производительности
Процедура ОбновитьНомераВерсийСоглашений() Экспорт

// Начальный номер для присвоения документам
НачальныйНомер = 71959;
ТекущийНомер = НачальныйНомер;

// Создаем запрос для отбора документов с номерами по шаблону "%-%-%"
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВерсияСоглашенияКоммерческийДоговор.Ссылка КАК Ссылка,
| ВерсияСоглашенияКоммерческийДоговор.Номер КАК СтарыйНомер,
| ВерсияСоглашенияКоммерческийДоговор.Дата КАК Дата
|ИЗ
| Документ.ВерсияСоглашенияКоммерческийДоговор КАК ВерсияСоглашенияКоммерческийДоговор
|ГДЕ
| ВерсияСоглашенияКоммерческийДоговор.Номер ПОДОБНО ""%-%-%""
|УПОРЯДОЧИТЬ ПО
| ВерсияСоглашенияКоммерческийДоговор.Дата,
| ВерсияСоглашенияКоммерческийДоговор.Номер";

// Выполняем запрос и получаем результат
РезультатЗапроса = Запрос.Выполнить();

// Проверяем, есть ли найденные документы
Если РезультатЗапроса.Пустой() Тогда
Сообщить("Документы с номерами по шаблону '%-%-%' не найдены.");
Возврат;
КонецЕсли;

// Получаем выборку документов для обработки
ВыборкаДокументов = РезультатЗапроса.Выбрать();

// Счетчики для отчета о выполнении
КоличествоОбработанных = 0;
КоличествоОшибок = 0;

// Включаем режим загрузки данных для повышения производительности
УстановитьРежимЗагрузкиДанных(Истина);

Попытка
// Обходим все найденные документы
Пока ВыборкаДокументов.Следующий() Цикл

Попытка
// Получаем объект документа для изменения
ДокументОбъект = ВыборкаДокументов.Ссылка.ПолучитьОбъект();

// Сохраняем старый номер для логирования
СтарыйНомер = ДокументОбъект.Номер;

// Формируем новый номер с ведущими нулями (9 знаков)
НовыйНомер = Формат(ТекущийНомер, "ЧЦ=9; ЧВН=");

// Присваиваем новый номер документу
ДокументОбъект.Номер = НовыйНомер;

// Записываем документ (в режиме загрузки)
ДокументОбъект.Записать();

// Выводим информацию о изменении
Сообщить(СтрШаблон("Документ %1: номер изменен с '%2' на '%3'",
ВыборкаДокументов.Ссылка,
СтарыйНомер,
НовыйНомер));

// Увеличиваем номер для следующего документа
ТекущийНомер = ТекущийНомер + 1;
КоличествоОбработанных = КоличествоОбработанных + 1;

Исключение
// Обрабатываем ошибки записи отдельных документов
КоличествоОшибок = КоличествоОшибок + 1;
ТекстОшибки = ОписаниеОшибки();
Сообщить(СтрШаблон("Ошибка при обработке документа %1: %2",
ВыборкаДокументов.Ссылка,
ТекстОшибки),
СтатусСообщения.Важное);

// Продолжаем обработку следующих документов
Продолжить;
КонецПопытки;

КонецЦикла;

Исключение
// Обрабатываем критические ошибки
ТекстОшибки = ОписаниеОшибки();
Сообщить("Критическая ошибка при выполнении процедуры: " + ТекстОшибки, СтатусСообщения.ОченьВажное);

// Обязательно отключаем режим загрузки данных
УстановитьРежимЗагрузкиДанных(Ложь);

КонецПопытки;

// Выводим итоговую информацию о выполнении процедуры
Сообщить("");
Сообщить("=== РЕЗУЛЬТАТЫ ВЫПОЛНЕНИЯ ===");
Сообщить(СтрШаблон("Обработано документов: %1", КоличествоОбработанных));
Сообщить(СтрШаблон("Ошибок при обработке: %1", КоличествоОшибок));
Сообщить(СтрШаблон("Следующий доступный номер: %1", Формат(ТекущийНомер, "ЧЦ=9; ЧВН=")));

КонецПроцедуры

// Вспомогательная процедура для запуска обновления с подтверждением
// Рекомендуется использовать эту процедуру для безопасного выполнения
Процедура ЗапуститьОбновлениеНомеровСПодтверждением() Экспорт

// Запрашиваем подтверждение у пользователя
Ответ = Вопрос("Выполнить обновление номеров документов ВерсияСоглашенияКоммерческийДоговор?" + Символы.ПС +
"Будут изменены все документы с номерами вида '%-%-%'" + Символы.ПС +
"Операция необратима!",
РежимДиалогаВопрос.ДаНет,
0,
КодВозвратаДиалога.Нет);

Если Ответ = КодВозвратаДиалога.Да Тогда
// Выполняем обновление только после подтверждения
ОбновитьНомераВерсийСоглашений();
Иначе
Сообщить("Операция отменена пользователем.");
КонецЕсли;

КонецПроцедуры

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

Эпилог. Есть только путь

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

Теперь у нас впереди освоение: полноценного Git‑инструментария, для проверки кода и развертывания приложений; полные автотесты с выявлением багов до релиза; ИИ, который не заменяет программиста, но реально помогает и ускоряет его работу.

«Идти вперёд — значит прорываться через стены, которые кажутся непреодолимыми, с верой, что за ними — свет» — Нельсон Мандела

«Есть только путь» — не просто громкая фраза, а правда. Да, путь труден. Да, он требует денег на железо, времени на настройку и смелости, чтобы сказать коллегам: «Мы это сделаем. Идёте с нами?». Но каждый пройденный километр этого тернистого пути даёт нам новый опыт. Опыт, который закаляет команду. Опыт, который подготовит нас к следующим вызовам. А они обязательно будут.

Мы движемся вперед. Медленно, с матами и перезагрузками. Но движемся — и это радует!