Как исправить ошибку «Значение не является значением объектного типа (Выбрать)» при открытии реализации в 1С?

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

При повседневной работе в 1C:Бухгалтерия пользователи нередко сталкиваются с ситуацией, когда документы по определенному контрагенту перестают открываться. Платформа аварийно прерывает операцию с системным сообщением: «Значение не является значением объектного типа (Выбрать)». При этом аналогичные документы других контрагентов функционируют в штатном режиме. Разберем по шагам, почему возникает данный сбой, как локализовать проблемное место в коде и какими инструментами восстановить целостность информационной базы.

Анализ причин возникновения ошибки

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

{ОбщийМодуль.УправлениеКонтактнойИнформациейБП.Модуль(423)}: Значение не является значением объектного типа (Выбрать)

Сбой происходит на строке вызова метода выборки данных:

Выборка = ИсторияАдреса.Выбрать;

Выясним причину такого поведения платформы. Метод Выбрать() применяется к результатам запроса или выборкам данных. Переменная ИсторияАдреса ожидает получить объектный тип, однако вместо него функция чтения реквизитов возвращает значение Неопределено. Это происходит в тех случаях, когда:

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

Диагностика проблемы с помощью отладчика

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

Если база работает в клиент-серверном режиме (SQL), убедимся, что служба сервера 1С запущена с параметром -debug, иначе точки останова в серверных общих модулях срабатывать не будут.

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


Функция ЗначенияРеквизитовОбъекта(Ссылка, Знач Реквизиты) Экспорт
    Если ТипЗнч(Реквизиты) = Тип("Строка") Тогда
        Если ПустаяСтрока(Реквизиты) Тогда
            Возврат Новый Структура;
        КонецЕсли;
        Реквизиты = СтрРазделить(Реквизиты, ",", Ложь);
    КонецЕсли;

    СтруктураРеквизитов = Новый Структура;
    Если ТипЗнч(Реквизиты) = Тип("Структура") Или ТипЗнч(Реквизиты) = Тип("ФиксированнаяСтруктура") Тогда
        СтруктураРеквизитов = Реквизиты;
    ИначеЕсли ТипЗнч(Реквизиты) = Тип("Массив") Или ТипЗнч(Реквизиты) = Тип("ФиксированныйМассив") Тогда
        Для Каждого Реквизит Из Реквизиты Цикл
            СтруктураРеквизитов.Вставить(СтрЗаменить(Реквизит, ".", ""), Реквизит);
        КонецЦикла;
    КонецЕсли;

    ТекстПолей = "";
    Для Каждого КлючИЗначение Из СтруктураРеквизитов Цикл
        ИмяПоля = ?(ЗначениеЗаполнено(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Значение), СокрЛП(КлючИЗначение.Ключ));
        Псевдоним = СокрЛП(КлючИЗначение.Ключ);
        ТекстПолей = ТекстПолей + ?(ПустаяСтрока(ТекстПолей), "", ",") + " | " + ИмяПоля + " КАК " + Псевдоним;
    КонецЦикла;

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Запрос.Текст = 
        "ВЫБРАТЬ |" + ТекстПолей + " |ИЗ | " + Ссылка.Метаданные.ПолноеИмя + " КАК ПсевдонимЗаданнойТаблицы |ГДЕ | ПсевдонимЗаданнойТаблицы.Ссылка = &Ссылка |";

    Выборка = Запрос.Выполнить().Выбрать();
    Выборка.Следующий();

    Результат = Новый Структура;
    Для Каждого КлючИЗначение Из СтруктураРеквизитов Цикл
        Результат.Вставить(КлючИЗначение.Ключ);
    КонецЦикла;
    ЗаполнитьЗначенияСвойств(Результат, Выборка);

    Возврат Результат;
КонецФункции

В момент остановки проанализируем значение параметра Ссылка. Если в параметре отображается <Объект не найден...>, то попытка обратиться к Ссылка.Метаданные возвращает ошибку или пустой результат, из-за чего модуль управления контактной информацией получает Неопределено вместо реальной выборки адреса.

Способ 1. Исправление через тестирование и исправление информационной базы

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

Выполним процедуру правильно:

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

Способ 2. Исправление с помощью группового изменения реквизитов

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

  1. Откроем раздел Администрирование -> Обслуживание -> Корректировка данных -> Групповое изменение реквизитов.
  2. В поле «Выбирать» укажем документ Реализация (акты, накладные).
  3. Нажмем Добавить условие отбора и отфильтруем список по проблемному контрагенту или конкретному номеру документа.
  4. В списке доступных реквизитов найдем поля, отвечающие за грузополучателя, грузоотправителя, банковские счета и договоры.
  5. Если в одном из полей отображается битая ссылка, зададим корректное значение (например, установим грузополучателя равным контрагенту) и нажмем Изменить реквизиты.

Способ 3. Программная очистка поврежденных ссылок

Если доступ к документу заблокирован, разберем, как программно прочитать и перезаписать проблемный объект с помощью внешней обработки или консоли кода без вызова клиентских процедур формы:


ДокументСсылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("НомерДокумента", ТекущаяДата());
ДокОбъект = ДокументСсылка.ПолучитьОбъект();

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

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

ДокОбъект.Записать(РежимЗаписиДокумента.Запись);

После устранения поврежденной ссылки структура реквизитов объекта восстанавливается, функция ЗначенияРеквизитовОбъекта возвращает корректные типы данных, и документ реализации открывается без ошибок.

← На главную