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