Как программно изменить булево значение в справочнике 1С и исправить ошибку Метод объекта не обнаружен

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

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

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

Разбор типовой ошибки Метод объекта не обнаружен (ПолучитьОбъект)

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


Процедура КнопкаВыполнитьНажатие(Кнопка) 
    Запрос = Новый Запрос; 
    Запрос.Текст = "ВЫБРАТЬ 
                   | ХранилищеДополнительнойИнформации.Ссылка 
                   |ИЗ 
                   | Справочник.ХранилищеДополнительнойИнформации КАК ХранилищеДополнительнойИнформации"; 
    Результат = Запрос.Выполнить(); 
    Выб = Результат.Выбрать(); 
    Пока Выб.Следующий() Цикл 
        ВыбО = Выб.Ссылка.ПолучитьОбьект(); // Здесь возникает ошибка
        ВыбО.юНужноВыгрузитьНаСайт = Ложь; 
        ВыбО.Записать(); 
    КонецЦикла; 
КонецПроцедуры

Основная причина здесь кроется в синтаксической опечатке. В языке 1С название метода пишется через твердый знак: ПолучитьОбъект. Использование мягкого знака (ПолучитьОбьект) делает вызов некорректным, так как платформа ищет метод именно с таким написанием и, не находя его у объекта типа СправочникСсылка, прерывает работу программы.

Важный совет: Для исключения подобных ошибок всегда используйте механизм контекстной подсказки (Ctrl + Пробел) или копируйте названия методов из Синтакс-помощника. Это гарантирует правильное написание имен методов и свойств.

Почему данные в базе изменились, а на форме остались прежними?

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

Дело в том, что 1С активно использует кэширование данных на стороне клиента. Когда мы программно меняем объект в базе данных, открытые формы списков или динамические списки не всегда мгновенно узнают об этих изменениях. Чтобы данные обновились в интерфейсе, необходимо выполнить одно из следующих действий:

  1. Нажать кнопку Обновить (F5) непосредственно в форме списка.
  2. Программно вызвать метод ОповеститьОбИзменении. Это наиболее профессиональный подход. После завершения цикла обработки добавьте строку: ОповеститьОбИзменении(Тип("СправочникСсылка.ХранилищеДополнительнойИнформации"));. Это заставит все открытые формы данного справочника перечитать данные из базы.
  3. Если вы используете управляемые формы, можно вызвать метод ОбновитьОтображениеДанных(), хотя оповещение по типу ссылки является более универсальным.

Оптимизация процесса записи данных

Если справочник, который вы обрабатываете (например, ХранилищеДополнительнойИнформации), содержит тысячи или десятки тысяч записей, стандартный метод Записать() внутри цикла может работать крайне медленно. Рассмотрим, как ускорить выполнение задачи.

Использование режима Загрузка:

При записи объекта 1С выполняет множество проверок: срабатывают модули объекта, подписки на события, проверяются условия в процедурах ПередЗаписью и ПриЗаписи. Если вам нужно просто технически поменять одно значение без запуска всей бизнес-логики, используйте свойство ОбменДанными.Загрузка.


ВыбО = Выб.Ссылка.ПолучитьОбъект();
ВыбО.ОбменДанными.Загрузка = Истина; // Отключает проверки и подписки
ВыбО.юНужноВыгрузитьНаСайт = Ложь;
ВыбО.Записать();

Использование транзакций:

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


НачатьТранзакцию();
Пока Выб.Следующий() Цикл
    // Код изменения и записи объекта
КонецЦикла;
ЗафиксироватьТранзакцию();

Специфика работы со справочником ХранилищеДополнительнойИнформации

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

Метод ПолучитьОбъект() считывает из базы данных все поля объекта. Если в элементе справочника хранится большая картинка в реквизите типа ХранилищеЗначения, она будет загружена в оперативную память сервера (rphost) при каждом вызове метода. При массовой обработке тысяч таких элементов это может привести к резкому росту потребления памяти и замедлению работы всей системы.

Рекомендации для работы с тяжелыми объектами:

Итоговый правильный алгоритм работы

Подведем итог и составим эталонный код для решения нашей задачи с учетом всех исправлений и оптимизаций:


Процедура КнопкаВыполнитьНажатие(Кнопка)
    Запрос = Новый Запрос;
    // Выбираем только ссылки, чтобы не тянуть лишние данные в память
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Хранилище.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.ХранилищеДополнительнойИнформации КАК Хранилище
        |ГДЕ
        |   Хранилище.юНужноВыгрузитьНаСайт = ИСТИНА"; // Меняем только те, что еще не Ложь

    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();
    
    НачатьТранзакцию();
    Попытка
        Пока Выборка.Следующий() Цикл
            // Используем правильное написание метода
            ОбъектСпр = Выборка.Ссылка.ПолучитьОбъект();
            
            Если ОбъектСпр <> Неопределено Тогда
                ОбъектСпр.юНужноВыгрузитьНаСайт = Ложь;
                // Оптимизируем запись
                ОбъектСпр.ОбменДанными.Загрузка = Истина;
                ОбъектСпр.Записать();
            КонецЕсли;
        КонецЦикла;
        
        ЗафиксироватьТранзакцию();
        
        // Оповещаем систему об изменениях для обновления списков
        ОповеститьОбИзменении(Тип("СправочникСсылка.ХранилищеДополнительнойИнформации"));
        Сообщить("Обработка завершена успешно!");
        
    Исключение
        ОтменитьТранзакцию();
        Сообщить("Произошла ошибка при записи: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

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

Таким образом, решение задачи по смене булевого значения требует не только внимательности к орфографии (ПолучитьОбъект), но и понимания механизмов взаимодействия клиента и сервера, а также способов оптимизации нагрузки на базу данных.

← На главную