При работе в платформе 1С:Предприятие 7.7 периодически возникает необходимость обратиться к реквизитам документа, который находится выше по цепочке подчиненности. Рассмотрим ситуацию, когда реквизит Склад расположен не в текущем документе и не в его прямом документе-основании, а на два уровня выше — в так называемом документе-«дедушке».
Структура подчиненности документов выглядит следующим образом:
Склад)ДокОснование)ДокОснование)Для обращения к реквизиту исходного документа в 1С 7.7 используется последовательный переход по реквизитам основания: ДокОснование.ДокОснование.Склад.
Прямое обращение по цепочке без предварительной проверки может привести к ошибкам времени выполнения, если какой-либо из документов в цепочке не выбран или у него отсутствует нужный реквизит. Поэтому проанализируем, как корректно и безопасно извлечь значение склада перед выполнением основной логики обработки.
Разберем безопасный алгоритм получения реквизита:
Перем НужныйСклад;
НужныйСклад = ПолучитьПустоеЗначение("Справочник.Склады");
Если ДокОснование.Выбран() = 1 Тогда
ПромежДок = ДокОснование;
Если ПромежДок.ДокОснование.Выбран() = 1 Тогда
НужныйСклад = ПромежДок.ДокОснование.Склад;
КонецЕсли;
КонецЕсли;
Если НужныйСклад.Выбран() = 0 Тогда
Сообщить("Не удалось определить склад из документа-основания!");
Возврат;
КонецЕсли;
Рассмотрим итоговый вариант процедуры УбратьИзМинОст(). Помимо безопасного обращения к складу, учтем следующие важные технические нюансы:
Номенклатура, чтобы не передавать пустое значение в метод ИспользоватьВладельца().Записать() достаточно вызвать один раз — после установки всех реквизитов (включая изменение реквизита Набор2).Спр.ИспользоватьВладельца(Номенклатура) перед созданием нового элемента методом Спр.Новый() владелец подставляется автоматически, поэтому явное присвоение Спр.Владелец = Номенклатура не требуется.С учетом всех улучшений и проверок код процедуры принимает следующий вид:
Процедура УбратьИзМинОст()
Перем НужныйСклад;
// Получаем склад из документа-основания через один уровень
Если ДокОснование.Выбран() = 1 Тогда
Если ДокОснование.ДокОснование.Выбран() = 1 Тогда
НужныйСклад = ДокОснование.ДокОснование.Склад;
КонецЕсли;
КонецЕсли;
Если ПустоеЗначение(НужныйСклад) = 1 Тогда
Сообщить("Сначала надо выбрать документ-основание с указанным складом!");
Возврат;
ИлиЕсли НужныйСклад.Выбран() = 0 Тогда
Сообщить("Склад в документе-основании не выбран!");
Возврат;
КонецЕсли;
Спр = СоздатьОбъект("Справочник.СписокМинимальныхОстатков");
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
Если Номенклатура.Выбран() = 0 Тогда
Продолжить;
КонецЕсли;
Спр.ИспользоватьВладельца(Номенклатура);
Если Спр.НайтиПоРеквизиту("Склад", НужныйСклад, 0) = 0 Тогда
Спр.Новый();
Спр.Склад = НужныйСклад;
КонецЕсли;
Спр.Набор2 = Спр.Набор2 - Количество;
Спр.Записать();
КонецЦикла;
КонецПроцедуры
Обратите внимание: для корректной работы метода НайтиПоРеквизиту() у реквизита Склад в справочнике СписокМинимальныхОстатков в Конфигураторе должен быть установлен признак «Сортировка» или «Отбор по реквизиту».