В практике начинающего разработчика 1С часто возникает ситуация, когда при попытке изменить данные в справочнике или документе система выдает ошибку «Метод объекта не обнаружен (ПолучитьОбъект)». Эта ошибка является фундаментальной и указывает на непонимание различий между ссылочными и объектными типами данных в платформе «1С:Предприятие 8». Рассмотрим подробнее, почему это происходит и как правильно реализовать задачу массовой установки ставки НДС в справочнике Номенклатура.
Проанализируем ситуацию. Ошибка возникает тогда, когда мы пытаемся вызвать метод ПолучитьОбъект() у того, что объектом или ссылкой не является, либо когда мы обращаемся к метаданным напрямую. В коде автора из примера были допущены следующие критические ошибки:
Перечисления.СтавкиНдс.ПолучитьОбъект() лишена смысла, так как перечисления — это объекты метаданных, значения которых задаются в Конфигураторе. Их нельзя программно изменять или «получать как объект» в режиме «Предприятие».Номенклатура.СтавкаНДС ошибочна, так как СтавкаНДС — это уже конкретное значение (ссылка на перечисление), а не ссылка на элемент справочника номенклатуры.ПолучитьОбъект().Для того чтобы корректно изменить ставку НДС во всей номенклатуре (или ее части), мы должны придерживаться строгого алгоритма: сформировать запрос, получить ссылку, преобразовать ее в объект, изменить реквизит и записать объект. Рассмотрим пошагово реализацию этой задачи на сервере.
Проанализируем исправленный код, который решает поставленную задачу:
&НаСервере
Процедура УстановитьСтавкуНДСНаСервере()
// 1. Создаем запрос для получения ссылок на элементы справочника
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа = ЛОЖЬ
| И Номенклатура.СтавкаНДС <> &СтавкаНДС"; // Выбираем только те, где ставка еще не совпадает
// СтавкаНДС в параметре — это значение из реквизита формы (выбор пользователя)
Запрос.УстановитьПараметр("СтавкаНДС", Объект.СтавкаНДС);
РезультатЗапроса = Запрос.Выполнить();
// 2. Начинаем обход выборки
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// 3. Получаем объект из ссылки для возможности редактирования
ОбъектНоменклатура = Выборка.Ссылка.ПолучитьОбъект();
// 4. Устанавливаем новое значение реквизита
ОбъектНоменклатура.СтавкаНДС = Объект.СтавкаНДС;
// 5. Записываем изменения в базу данных
Попытка
ОбъектНоменклатура.Записать();
Исключение
Сообщить("Не удалось записать объект: " + Выборка.Ссылка + " Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Сообщить("Обработка завершена успешно!");
КонецПроцедуры
При написании подобных обработок важно учитывать несколько профессиональных аспектов, которые сделают ваш код надежным и быстрым.
Исключение групп: В справочнике Номенклатура обычно используется иерархия. У папок (групп) может не быть реквизита СтавкаНДС или его изменение для групп не имеет смысла. Поэтому в запросе мы добавили условие ГДЕ Номенклатура.ЭтоГруппа = ЛОЖЬ.
Использование режима записи «Загрузка»: Если вы уверены в данных и не хотите, чтобы при записи срабатывали сложные проверки (например, проверка заполнения артикула или веса, которые могут заблокировать запись старых позиций), используйте свойство ОбменДанными.Загрузка. Рассмотрим пример:
ОбъектНоменклатура = Выборка.Ссылка.ПолучитьОбъект();
ОбъектНоменклатура.СтавкаНДС = Объект.СтавкаНДС;
// Отключаем проверки в модуле объекта для ускорения и обхода ошибок заполнения
ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
ОбъектНоменклатура.Записать();
Работа с транзакциями: Если справочник содержит десятки тысяч элементов, запись каждого объекта по отдельности может занять много времени. Однако запись всех объектов в одной транзакции может привести к блокировке всей таблицы для других пользователей. Оптимальным решением будет фиксация транзакции порциями по 500-1000 элементов.
Выясним причину, по которой иногда вообще не стоит писать свой код. В большинстве современных типовых конфигураций 1С (УТ 11, БП 3.0, ERP) уже встроена мощная обработка «Групповое изменение реквизитов».
Если ваша задача разовая, рассмотрите следующий путь:
Номенклатура.Ставка НДС, установите новое значение и нажмите Изменить реквизиты.Этот способ безопаснее, так как он использует отлаженные механизмы библиотеки стандартных подсистем (БСП) и позволяет избежать написания лишнего кода, в котором легко допустить ошибку ПолучитьОбъект().
Подводя итог, помните: метод ПолучитьОбъект() вызывается только у Ссылок. Перед вызовом всегда полезно убедиться, что ссылка не является пустой, используя метод Пустая(), чтобы избежать лишних ошибок в коде.