Почему при отладке в 1С выборка запроса автоматически переключается на следующую строку самостоятельно

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Каждый начинающий разработчик в среде 1С:Предприятие рано или поздно сталкивается с необъяснимым поведением платформы во время отладки кода. Одной из таких загадочных ситуаций является "самопроизвольный" переход выборки запроса на следующую строку. Вы только что получили выборку, остановились на точке останова перед циклом, но при просмотре значений переменных обнаруживаете, что указатель выборки уже сдвинулся вперед, а данные начали обрабатываться в обход написанного вами алгоритма.

В этой статье мы подробно разберем, почему возникает этот эффект, как устроен механизм вычисления выражений в отладчике 1С, к каким еще скрытым побочным эффектам он может привести и как правильно и безопасно анализировать данные в процессе разработки.

Суть проблемы: почему выборка «бежит» впереди кода

Рассмотрим классическую ситуацию. Разработчик пишет код для обработки результатов запроса:


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    // Здесь должна происходить обработка данных
    Сотрудник = Выборка.Сотрудник;
КонецЦикла;

При запуске отладки и остановке на строке Выборка = Запрос.Выполнить().Выбрать(); программист хочет заранее посмотреть, какие данные лежат внутри выборки. Он открывает окно Табло (сочетание клавиш Ctrl + Alt + W) или использует окно Вычислить выражение (Shift + F9) и вводит туда команду: Выборка.Следующий() или пытается напрямую прочитать свойства выборки, которые еще не доступны, так как метод позиционирования не был вызван.

После этого начинается «мистика»: при пошаговом переходе (клавиша F10) строки в выборке начинают переключаться сами по себе, даже если выполнение кода еще не дошло до строки Пока Выборка.Следующий() Цикл. В итоге реальный цикл пропускает часть записей или вовсе не выполняется, так как выборка уже была полностью прочитана в процессе обхода по шагам.

Выясняем причину: побочные эффекты отладчика 1С

Для того чтобы понять, почему так происходит, проанализируем внутренние механизмы работы конфигуратора 1С:

  1. Реальное выполнение кода в контексте сеанса: Когда мы пишем выражение в окне «Табло» или «Вычислить выражение», платформа 1С не просто анализирует статический снимок памяти. Она действительно выполняет этот код на стороне сервера или клиента (в зависимости от того, где установлена точка останова) в режиме реального времени.
  2. Автоматическое обновление значений в Табло: Окно «Табло» перевычисляет все добавленные в него строки на каждом шаге отладки. Если вы добавили туда вызов метода Выборка.Следующий(), то при каждом нажатии клавиш F10 (Шагнуть через) или F11 (Шагнуть в) отладчик неявно выполняет этот метод, чтобы обновить значение в таблице отображения.
  3. Сдвиг указателя выборки: Метод Следующий() у объекта РезультатЗапросаВыборка является функцией с побочным эффектом. Он не просто возвращает булево значение (Истина/Ложь), но и физически сдвигает указатель текущей строки выборки на одну позицию вперед. Поскольку отладчик выполняет эту команду за кулисами для обновления интерфейса «Табло», выборка незаметно для разработчика продвигается к концу.

Таким образом, пока вы пошагово анализируете код, отладчик самостоятельно прогоняет выборку до самого конца, из-за чего основной алгоритм программы лишается данных для обработки.

Как решить проблему и вернуть управление выборкой

Решение этой проблемы предельно простое, но крайне важное для понимания:

  1. Очистите окно «Табло»: Немедленно удалите любые выражения, содержащие вызовы методов, изменяющих состояние объектов (такие как Следующий(), Прочитать(), Записать(), ПолучитьОбъект()), из окон «Табло» и «Быстрый просмотр».
  2. Используйте безопасный просмотр данных: Если вам необходимо проанализировать, что вернул запрос, не сдвигая указатель выборки, воспользуйтесь выгрузкой результата в таблицу значений. Для этого в окне Вычислить выражение (Shift + F9) введите:
    Запрос.Выполнить().Выгрузить()
    Полученную таблицу значений можно безопасно открыть в визуальном режиме просмотра, развернуть колонки и изучить все строки. При этом состояние исходной выборки никак не изменится.

Другие опасные ловушки отладчика: Менеджер временных таблиц

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

Если в вашем коде используется МенеджерВременныхТаблиц, и вы решили выполнить запрос целиком в окне «Вычислить выражение» до того, как код выполнится в программе, вы рискуете получить ошибку времени выполнения: «Таблица с таким именем уже существует».

Это происходит потому, что при первом (ручном) вычислении запроса в отладчике временная таблица уже была создана и помещена в менеджер в текущем сеансе. Когда программа доходит до реального шага выполнения этого же запроса, платформа пытается создать таблицу повторно с тем же именем в рамках того же менеджера, что приводит к аварийному завершению работы системы.

Как правильно смотреть временные таблицы в отладчике:

Начиная с современных версий платформы 1С v8.3, нет необходимости повторно выполнять запросы для просмотра содержимого временных таблиц. Если запрос уже выполнился в коде, вы можете обратиться напрямую к менеджеру временных таблиц. Введите в «Вычислить выражение» следующую конструкцию:


Запрос.МенеджерВременныхТаблиц.Таблицы.Найти("ИмяВашейВременнойТаблицы").ПолучитьДанные().Выгрузить()

Этот метод абсолютно безопасен. Он не перезапускает создание таблиц, не дублирует данные и позволяет увидеть точное содержимое промежуточных таблиц в памяти СУБД на текущий момент отладки.

Деструктивные действия и транзакции при отладке

Проанализируем еще два критически важных аспекта, о которых должен знать каждый разработчик при работе с отладчиком:

1. Изменение данных в БД прямо из отладчика

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


НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Тестовый товар из отладки";
НовыйЭлемент.Записать();

Этот элемент действительно будет записан в вашу базу данных. Если вы проводите отладку на «живой» рабочей базе (что само по себе является плохой практикой), такие действия могут засорить систему мусорными данными или нарушить бизнес-логику.

2. Блокировки данных внутри транзакций

Когда вы останавливаетесь на точке останова внутри транзакции (например, в процедуре ОбработкаПроведения документа), СУБД накладывает и удерживает блокировки на изменяемые таблицы базы данных.

Пока вы стоите на точке останова и неторопливо анализируете переменные или выполняете тяжелые сопутствующие запросы в табло, все остальные пользователи системы будут заблокированы при попытке обратиться к тем же таблицам. Это может привести к ошибкам превышения времени ожидания блокировки у пользователей (Lock Timeout) или к возникновению взаимных блокировок (Deadlocks).

Золотое правило разработчика: Никогда не задерживайтесь надолго на точках останова внутри транзакций на работающих базах данных и минимизируйте использование сложных вычислений в табло в этот момент.

Резюме и лучшие практики отладки запросов

Для того чтобы процесс отладки приносил только пользу и не вызывал появление седых волос, придерживайтесь следующих простых правил:

Понимание физики процессов, происходящих под капотом платформы 1С:Предприятие, убережет вас от ложных выводов о «багах платформы» и поможет писать чистый, предсказуемый и производительный код.

← На главную