Чтение кода на встроенном языке 1С: с чего начать и как не утонуть в чужом модуле
Содержание
Чтение кода в 1С начинается не с первой строки модуля, а с ответа на три вопроса: где этот код лежит, на клиенте он выполняется или на сервере и кто его вызывает. Открыли процедуру ПриПроведении в модуле документа — значит, вы в серверном коде, который отрабатывает при записи с проведением. Эти три координаты важнее, чем понимание каждой строчки.
Встроенный язык 1С похож на обычные языки программирования только внешне. Переменные, циклы, условия и функции тут есть, но логика разбросана по десяткам модулей разного типа, один и тот же метод может жить в четырёх местах, а часть кода выполняется на машине пользователя и часть — на сервере. Ниже — как читать такой код, не теряя нить: от структуры модулей и навигации в Конфигураторе до отладки и разбора живого фрагмента.
Почему код в 1С читается не как обычная программа
Главная сложность — не русский синтаксис (Если … Тогда … КонецЕсли), к нему привыкаешь за день. Сложность в модели исполнения и в том, что код физически раздроблен.
Что мешает читать 1С-код линейно:
- 🧩 Код живёт в разных модулях. Логика справочника «Контрагенты» размазана по модулю объекта, модулю менеджера, модулю формы, общим модулям и, возможно, расширению конфигурации. Одного файла, где «всё про контрагента», не существует.
- 🖥️ Клиент и сервер вперемешку. Одна процедура формы выполняется в браузере пользователя, соседняя — на сервере. Переход между ними стоит сетевого вызова, и это меняет смысл кода.
- 🔁 Обработчики, а не главная функция. Точки входа тут нет. Платформа сама дёргает процедуры-обработчики событий:
ПередЗаписью,ОбработкаПроведения,ПриИзмененииРеквизита. Чтобы понять «что запускается», надо знать, какое событие сработало. - 🏷️ Одинаковые имена в разных местах. Процедура
ЗаполнитьДокумент()может быть и в модуле объекта, и в общем модуле, и в расширении. Пока не поймёте, из какого модуля идёт вызов, читаете не тот код.
Поэтому опытный специалист сначала строит карту: какой это модуль, какой контекст (клиент/сервер), кто вызывает. Понимание отдельных строк приходит потом и быстро.
Карта модулей: где какой код лежит
Прежде чем читать, определите тип модуля — он задаёт правила игры. Основные типы в 1С 8.3:
| Модуль | Что в нём | Контекст по умолчанию |
|---|---|---|
| Модуль формы | Обработчики событий формы и её элементов | Клиент (с серверными процедурами) |
| Модуль объекта | ПередЗаписью, ОбработкаПроведения, бизнес-логика документа/справочника | Сервер |
| Модуль менеджера | Методы уровня менеджера объекта, общие для всех экземпляров | Сервер |
| Общий модуль | Переиспользуемые процедуры и функции | Зависит от флагов модуля |
| Модуль приложения / сеанса | События запуска и завершения программы | Клиент / сервер |
У общего модуля смысл кода задают его флаги в свойствах: Клиент (управляемое приложение), Сервер, Вызов сервера, Внешнее соединение. Общий модуль с галкой только «Сервер» и «Вызов сервера» — это серверный код, который можно вызвать с клиента. Без этого знания половина кода читается неправильно.
Как быстро понять тип открытого модуля: посмотрите в дерево конфигурации слева — подсветится объект, которому модуль принадлежит. Либо загляните в заголовок окна: Конфигуратор пишет путь вроде Документы.РеализацияТоваровУслуг.МодульОбъекта.
Директивы компиляции: как отличить клиент от сервера
Перед каждой процедурой и функцией в управляемых формах стоит директива — это первое, что нужно читать:
&НаКлиенте
Процедура ЦенаПриИзменении(Элемент)
ПересчитатьСумму();
КонецПроцедуры
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗаполнитьРеквизитыПоУмолчанию();
КонецПроцедуры
Что означают директивы:
&НаКлиенте— код работает на машине пользователя. Отсюда нельзя напрямую обратиться к базе данных.&НаСервере— код работает на сервере, имеет доступ к базе, но при вызове туда-обратно передаётся весь контекст формы (это дорого по времени).&НаСервереБезКонтекста— серверный код без передачи данных формы. Быстрее; его в типовых конфигурациях большинство.&НаКлиентеНаСервереБезКонтекста— доступен и там, и там.
Читая код формы, всегда держите в голове, на какой стороне вы находитесь. Переход &НаКлиенте → &НаСервере — это сетевой вызов, и именно на этих границах чаще всего прячутся ошибки производительности.
Ещё один маркер — инструкции препроцессора. Конструкция #Если Сервер Тогда … #КонецЕсли в общем модуле означает, что кусок кода компилируется только на сервере. Не пропускайте эти блоки: один и тот же модуль может вести себя по-разному на клиенте и сервере.
С чего начать разбор незнакомого модуля
Не читайте модуль сверху вниз как книгу — это и есть главный антипаттерн. Двигайтесь от задачи.
- Сформулируйте вопрос. «Почему при проведении не заполняется счёт учёта?» — конкретная цель экономит часы. Чтение «вообще» бесполезно.
- Найдите точку входа. Для документа это обычно
ОбработкаПроведенияв модуле объекта. Для поведения формы — обработчик события нужного элемента в модуле формы. - Идите по вызовам вглубь. Встретили вызов
ЗаполнитьСчетаУчета()— перейдите к определению этой процедуры (клавишаF12на имени) и читайте её. Так вы разворачиваете только нужную ветку, а не весь модуль. - Отмечайте границы клиент/сервер. Каждый переход между контекстами — повод остановиться и понять, какие данные передаются.
- Сверяйтесь с именами. Разработчики 1С называют процедуры по-русски и по делу:
ПроверитьЗаполнение,СформироватьДвижения. Имя часто заменяет чтение тела.
Отдельная ветка — расширения конфигурации
. Если над процедурой в основной конфигурации «ничего не происходит», проверьте, нет ли расширения, которое её переопределяет или дополняет через &Вместо или &После. Это частая причина, почему код «не тот, что читаешь».
Навигация в Конфигураторе и EDT
Читать код мышкой и стрелками — медленно. Инструменты навигации ускоряют разбор в разы.
В Конфигураторе пригодятся:
- Переход к определению — поставьте курсор на имя процедуры и нажмите
F12. Откроется её тело, даже если оно в другом модуле. - Поиск ссылок на объект — контекстное меню на имени реквизита, справочника или процедуры. Показывает, где по всей конфигурации используется элемент. Незаменимо, чтобы понять, кто дёргает код.
- Глобальный поиск — меню
Правка → Глобальный поиск. Ищет строку по всем модулям конфигурации, а не только в открытом. - Синтакс-помощник — встроенный справочник по методам платформы. Поставьте курсор на метод вроде
НайтиПоКодуи вызовите контекстную подсказку, чтобы увидеть параметры. - Контекстная подсказка — сочетание
Ctrl + Пробелпоказывает доступные свойства и методы объекта. Заодно помогает понять, с каким типом вы работаете. - Группировка областями — код оформляют блоками
#Область … #КонецОбласти. Сверните все области, чтобы увидеть структуру модуля целиком, потом разворачивайте нужную.
В 1C:Enterprise Development Tools (EDT) — альтернативной среде на базе Eclipse — навигация богаче: переход к объявлению по F3, поиск использований, автоматическое построение структуры модуля, подсветка, рефакторинг. Для чтения больших объёмов чужого кода EDT ощутимо удобнее Конфигуратора, хотя типовые доработки чаще ведут именно в Конфигураторе.
Поиск ссылок и глобальный поиск работают только по конфигурации, открытой в среде. Если код пришёл расширением или внешней обработкой, подключите их, иначе часть вызовов окажется невидимой.
Отладка: чтение кода в движении
Статическое чтение показывает, что код делает в теории. Отладчик показывает, что он делает на самом деле и с какими данными. Это самый быстрый способ понять незнакомую логику.
Базовый сценарий разбора через отладку:
- Поставьте точку останова на интересующей строке — клавиша
F9или щелчок по левому полю редактора. - Запустите приложение в режиме отладки — меню
Отладка → Начать отладку(F5). - Выполните в программе действие, которое приводит к этому коду (например, проведите документ).
- Когда выполнение остановится, читайте табло и локальные переменные — там реальные значения.
- Шагайте по коду:
F10— выполнить строку, не заходя внутрь вызовов;F11— зайти в вызываемую процедуру;Shift + F11— выйти из текущей.
Два инструмента, которые экономят больше всего времени:
- Стек вызовов — показывает цепочку процедур, которая привела в текущую точку. Отвечает на вопрос «кто меня вызвал» лучше любого чтения.
- Вычислить выражение — позволяет прямо на паузе посчитать любое выражение в текущем контексте, например
Строка.Количество * Строка.Цена, и проверить гипотезу.
Важная тонкость клиент-серверной базы: отладку серверного кода надо разрешить. В файловой базе она работает сразу, а в клиент-серверном варианте нужно включить отладку
по протоколу (в параметрах информационной базы) и подключить предметы отладки через меню Отладка → Подключение. Без этого точки останова в серверных модулях просто не сработают.
Разбор реального фрагмента
Посмотрим на простую функцию и прочитаем её так, как это делает специалист:
Функция СуммаДокумента(ТабличнаяЧасть) Экспорт
Итог = 0;
Для Каждого Строка Из ТабличнаяЧасть Цикл
Итог = Итог + Строка.Количество * Строка.Цена;
КонецЦикла;
Возврат Итог;
КонецФункции
Как это читается по шагам:
Функция … Экспорт— это функция (возвращает значение), а ключевое словоЭкспортозначает, что её можно вызвать из других модулей. Значит, где-то есть вызов извне — стоит поискать ссылки.ТабличнаяЧасть— параметр. По имени понятно: внутрь передают табличную часть документа (например, «Товары»).Для Каждого Строка Из … Цикл— обход всех строк коллекции.Строкана каждой итерации — это текущая строка таблицы.Строка.Количество * Строка.Цена— обращение к колонкам табличной части по именам реквизитов. Тут же становится ясно, что у таблицы есть колонкиКоличествоиЦена.Возврат Итог— функция отдаёт накопленную сумму.
Вывод за тридцать секунд: функция считает сумму документа как количество × цену по всем строкам. Чтобы убедиться, что колонки называются именно так, достаточно открыть табличную часть документа в дереве конфигурации — читать всё тело не нужно.
Отдельно стоит язык запросов: если в коде встречается Запрос.Текст = "ВЫБРАТЬ …", это не процедурный код, а декларативный запрос к базе. Его читают по блокам ВЫБРАТЬ … ИЗ … ГДЕ …, а разбирать удобнее в конструкторе запросов (контекстное меню на тексте запроса).
Частые ошибки при чтении кода
На чём спотыкаются чаще всего:
- ❌ Путают клиент и сервер. Читают процедуру под
&НаКлиентеи ждут обращения к базе — а его там быть не может. Всегда смотрите директиву над процедурой. - ❌ Читают не тот модуль. Нашли процедуру с нужным именем в общем модуле, а вызывается одноимённая из модуля объекта. Сначала через стек вызовов или поиск ссылок убедитесь, что это тот самый код.
- ❌ Не замечают расширение. Код в основной конфигурации выглядит правильным, но поведение меняет расширение через
&Вместо. Проверяйте список расширений. - ❌ Пытаются понять всё сразу. Читают модуль целиком вместо того, чтобы идти по одной ветке вызовов от конкретной задачи.
- ❌ Игнорируют препроцессор. Пропускают блоки
#Если Сервер Тогда, не понимая, что часть кода на клиенте просто не компилируется. - ❌ Не пользуются F12 и поиском ссылок. Листают модули вручную вместо перехода к определению — теряют время на каждом вызове.
Если код совсем не поддаётся чтению глазами, не упорствуйте — ставьте точку останова и смотрите реальные данные. Пять минут в отладчике часто заменяют час чтения.
Частые вопросы
Нужно ли знать программирование, чтобы читать код 1С?
Где лучше читать код — в Конфигураторе или в EDT?
Как понять, кто вызывает процедуру?
Почему одна и та же процедура ведёт себя по-разному?
&Вместо или дополняет через &После. Либо вы читаете одноимённую процедуру из другого модуля. Проверьте и то, и другое.Можно ли отлаживать серверный код в клиент-серверной базе?
Отладка → Подключение. В файловой базе отладка доступна сразу.