Как исправить ошибку «Найдено более одной записи» при вызове метода «ЭтотУзел» в 1С

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

При обновлении конфигураций на платформе 1С:Предприятие 8.3 (особенно это касается релизов веток 8.3.8–8.3.10) программисты и администраторы часто сталкиваются с критической ошибкой. В процессе выполнения обработчиков обновления информационной базы система выдает сообщение: Ошибка при вызове метода контекста (ЭтотУзел): Найдено более одной записи. Чаще всего это происходит в общем модуле ОбменСообщениямиВнутренний или при работе с планами обмена в распределенных информационных базах (РИБ).

В этой статье мы подробно разберем, почему возникает эта коллизия, как продиагностировать проблему и какими способами можно вернуть базу в работоспособное состояние.

Выясняем причину возникновения ошибки

Для начала проанализируем ситуацию с технической точки зрения. В любом плане обмена в 1С существует так называемый «Предопределенный узел» — это запись, которая представляет текущую информационную базу. В программном коде к ней обращаются через метод ПланыОбмена.ИмяПланаОбмена.ЭтотУзел(). Логика платформы подразумевает, что такой узел в таблице может быть только один.

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

  1. Сбой при реструктуризации: Во время обновления метаданных платформа некорректно создала или пометила записи в таблице плана обмена.
  2. Дублирование предопределенных элементов: В базе физически появилось две записи, у которых установлен признак ЭтотУзел.
  3. «Битые» ссылки в кэше: Информация о предопределенном узле застряла в кэше сервера или локального ПК, из-за чего метод ЭтотУзел() получает противоречивые данные.
  4. Проблемы РИБ: При некорректном обмене или «отвязке» подчиненного узла от главного механизмы синхронизации могут создать лишний служебный узел.

Способ 1: Тестирование и исправление (ТиИ)

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

Выполним следующие шаги:

  1. Создадим резервную копию базы данных (обязательно!).
  2. Запустим базу в режиме Конфигуратор.
  3. Перейдем в меню Администрирование — Тестирование и исправление.
  4. Установим флажки на пунктах:
    • Реиндексация таблиц информационной базы;
    • Проверка логической целостности;
    • Проверка ссылочной целостности;
    • Пересчет итогов (опционально, но рекомендуется).
  5. В поле «При наличии ссылок на несуществующие объекты» выберем «Очищать ссылки».
  6. Нажмем «Выполнить».

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

Способ 2: Обновление платформы

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

Способ 3: Программное удаление дублей узлов

Если автоматическое тестирование не помогло, нам придется вмешаться в структуру данных программно. Основная сложность здесь заключается в том, что платформа блокирует изменение предопределенных узлов в обычном режиме. Чтобы обойти это ограничение, мы будем использовать свойство ОбменДанными.Загрузка = Истина.

Рассмотрим пример кода, который поможет найти лишний узел и удалить его. Предположим, ошибка возникает в плане обмена ОбменСообщениями или ПоМагазину. Создадим внешнюю обработку и в модуле пропишем следующий алгоритм:


Процедура ИсправитьДублиПлановОбмена() Экспорт
    // Выберем все узлы конкретного плана обмена, где ЭтотУзел = Истина
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Т.Ссылка КАК Ссылка,
        |   Т.Наименование КАК Наименование,
        |   Т.Код КАК Код
        |ИЗ
        |   ПланОбмена.ОбменСообщениями КАК Т
        |ГДЕ
        |   Т.ЭтотУзел = ИСТИНА";
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    // Если найдено больше одной записи, нужно оставить только одну
    Если Выборка.Количество() > 1 Тогда
        Пока Выборка.Следующий() Цикл
            // Логика: оставляем узел с заполненным наименованием/кодом,
            // а пустые или некорректные дубли удаляем.
            Если ПустаяСтрока(Выборка.Наименование) Или Выборка.Код = "000" Тогда
                ОбъектУзла = Выборка.Ссылка.ПолучитьОбъект();
                
                // Включаем режим загрузки, чтобы обойти проверки платформы
                ОбъектУзла.ОбменДанными.Загрузка = Истина;
                
                Попытка
                    ОбъектУзла.Удалить();
                    Сообщить("Удален лишний узел: " + Выборка.Ссылка);
                Исключение
                    // Если удаление невозможно, попробуем хотя бы снять признак ЭтотУзел
                    ОбъектУзла.ЭтотУзел = Ложь;
                    ОбъектУзла.Записать();
                    Сообщить("Не удалось удалить, снят признак 'ЭтотУзел': " + Выборка.Ссылка);
                КонецПопытки;
            КонецЕсли;
        КонецЦикла;
    Иначе
        Сообщить("Дублей не обнаружено.");
    КонецЕсли;
КонецПроцедуры

Важный момент: Если вы не уверены, какой именно узел является «лишним», посмотрите на его Наименование и Код. Обычно «правильный» узел заполнен данными вашей организации или магазина, а «фантомный» дубль может быть пустым или содержать дефолтные значения.

Способ 4: Очистка серверного и локального кэша

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

Для клиент-серверного варианта:

  1. Остановим службу 1C:Enterprise Server.
  2. Перейдем в папку с данными сервера (обычно это C:\Program Files\1cv8\srvinfo).
  3. Найдем папку вашей информационной базы (её GUID можно подсмотреть в консоли администрирования).
  4. Удалим содержимое папок snccntx и config (не трогайте файлы лицензий!).
  5. Запустим службу сервера.

Для локального пользователя:

Просто удалим базу из списка в окне запуска 1С и добавим её заново. Это принудительно создаст новую папку локального кэша в каталоге %AppData%\1C\1cv8.

Способ 5: Использование консоли запросов для диагностики

Прежде чем что-то удалять, проанализируем ситуацию через консоль запросов. Это поможет точно определить имя плана обмена, в котором произошел сбой. Выполним запрос:


ВЫБРАТЬ
    "ОбменСообщениями" КАК ИмяПлана,
    Ссылка,
    ЭтотУзел,
    ПометкаУдаления
ИЗ
    ПланОбмена.ОбменСообщениями
ГДЕ
    ЭтотУзел = ИСТИНА

Если в результате вы видите две и более строки — вы нашли виновника. Повторите этот запрос для всех подозрительных планов обмена (СинхронизацияДанныхЧерезУниверсальныйФормат, ПоМагазину, Полный и т.д.), если ошибка не указывает конкретное имя.

Дополнительные рекомендации

Если проблема возникла в РИБ, проанализируйте статус главного узла. Иногда помогает временное «отключение» базы от распределенной сети командой:

ПланыОбмена.УстановитьГлавныйУзел(Неопределено);

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

Подведем итог: ошибка «Найдено более одной записи» в методе ЭтотУзел — это результат коллизии в данных. Сочетание Тестирования и исправления с программным методом ОбменДанными.Загрузка = Истина позволяет решить проблему без потери данных и продолжить обновление конфигурации.

← На главную