← Назад к вопросам

Можем ли мы получить доступ к реквизитам если в регистр сведений получаем срез последних?

2.0 Middle🔥 131 комментариев
#Запросы и оптимизация#Регистры

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Доступ к реквизитам при срезе последних в регистре сведений

Этот вопрос проверяет понимание того, что именно содержит срез последних и какие данные из него доступны. Прямой ответ: ДА, мы можем получить доступ к реквизитам.

Краткий ответ: ДА

Срез последних содержит ВСЕ данные:

  • Измерения ✅
  • Ресурсы ✅
  • Реквизиты ✅

Детальное объяснение

Структура регистра сведений:

Регистр Сведений "ПараметрыТовара"
    Измерения:                      // По каким параметрам
        Товар (ссылка)              // = какой товар
        Период (дата)               // = на какую дату
    
    Ресурсы:                        // Что храним
        Цена (число)                // текущая цена
        Скидка (число)              // текущая скидка
    
    Реквизиты:                      // Дополнительная информация
        Валюта (ссылка)             // в какой валюте
        РассчитаноАвтоматически     // флаг
        КомментарийПоЦене (строка)  // комментарий

Пример 1: Простой срез последних

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

Пример 2: Срез последних с условиями

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

Пример 3: Со встроенным запросом

Процедура ПолучитьЦеныЧерезЗапрос(ТоварМассив)
    
    Запрос = Новый Запрос;
    
    // Можно даже через запрос получить и реквизиты!
    Запрос.Текст = "ВЫБРАТЬ
        |    ПараметрыТовара.Товар,
        |    ПараметрыТовара.Цена,
        |    ПараметрыТовара.Скидка,
        |    ПараметрыТовара.Валюта,              // ✅ Реквизит!
        |    ПараметрыТовара.РассчитаноАвтоматически, // ✅ Реквизит!
        |    ПараметрыТовара.КомментарийПоЦене    // ✅ Реквизит!
        |ИЗ
        |    РегистрСведений.ПараметрыТовара КАК ПараметрыТовара
        |ГДЕ
        |    ПараметрыТовара.Товар В (&ТоварМассив)";
    
    Запрос.УстановитьПараметр("ТоварМассив", ТоварМассив);
    
    Результат = Запрос.Выполнить().Выгрузить();
    
    Возврат Результат;
    
КонецПроцедуры

Различие между Срезом последних и другими способами

Способ 1: СрезПоследних

// ✅ Последние значения по измерениям
// ✅ Включены реквизиты
// ✅ Быстро
// ❌ Только последние записи

СрезПоследних = РегистрыСведений.ПараметрыТовара.СрезПоследних(Новый Массив());

Способ 2: Прямой запрос

// ✅ Гибкость
// ✅ Включены реквизиты
// ✅ Любые условия
// ❌ Чуть медленнее

Запрос.Текст = "ВЫБРАТЬ * ИЗ РегистрСведений.ПараметрыТовара";

Способ 3: Выбрать()

// ✅ Навигация по результатам
// ✅ Включены реквизиты
// ❌ Нельзя использовать срез последних

Выборка = РегистрыСведений.ПараметрыТовара.Выбрать();

Важные детали

Деталь 1: Реквизиты НЕ являются измерениями

// ❌ НЕПРАВИЛЬНО
ТаблицаИзмерений = Новая ТаблицаЗначений;
ТаблицаИзмерений.Колонки.Добавить("Товар");     // ✅ Измерение
ТаблицаИзмерений.Колонки.Добавить("Валюта");    // ❌ Реквизит! Не работает

// ✅ ПРАВИЛЬНО
ТаблицаИзмерений = Новая ТаблицаЗначений;
ТаблицаИзмерений.Колонки.Добавить("Товар");     // ✅ Только измерения!

СрезПоследних = РегистрыСведений.ПараметрыТовара.СрезПоследних(
    ТаблицаИзмерений);

// Но Валюта будет в результате как реквизит!
Для Каждого Строка Из СрезПоследних Цикл
    Сообщить(Строка.Валюта); // ✅ Доступна!
КонецЦикла;

Деталь 2: Реквизиты связаны с периодом

Реквизиты сохраняются вместе с записью, поэтому в срезе последних они соответствуют последней дате по каждому измерению.

// Пример данных в регистре:
// Товар = "Ноутбук", Период = 01.01.2024, Цена = 100000, Валюта = USD
// Товар = "Ноутбук", Период = 15.02.2024, Цена = 95000, Валюта = USD
// Товар = "Ноутбук", Период = 01.03.2024, Цена = 90000, Валюта = EUR

// СрезПоследних вернет только:
// Товар = "Ноутбук", Период = 01.03.2024, Цена = 90000, Валюта = EUR ✅

Практический пример из реальности

Задача: Получить текущие цены всех товаров с информацией о валюте и кто их установил

Регистр Сведений "ЦеныТоваров"
    Измерения:
        Товар
        Склад
    
    Ресурсы:
        Цена
    
    Реквизиты:
        Валюта
        УстановленноПользователем  // Кто установил
        ДатаУстановления           // Когда

// Решение:
Процедура ПолучитьТекущиеЦены()
    
    СрезПоследних = РегистрыСведений.ЦеныТоваров.СрезПоследних(
        Новый Массив());
    
    // Результат содержит:
    // - Товар (измерение)
    // - Склад (измерение)
    // - Цена (ресурс)
    // - Валюта (реквизит) ✅
    // - УстановленноПользователем (реквизит) ✅
    // - ДатаУстановления (реквизит) ✅
    
    Для Каждого Цена Из СрезПоследних Цикл
        Сообщить(Цена.Товар.Наименование + " (" + Цена.Склад.Наименование + ")");
        Сообщить("Цена: " + Цена.Цена + " " + Цена.Валюта.Код);
        Сообщить("Установил: " + Цена.УстановленноПользователем.ПолноеИмя);
        Сообщить("Дата: " + Цена.ДатаУстановления);
        Сообщить("");
    КонецЦикла;
    
КонецПроцедуры

Частые ошибки

Ошибка 1: Думаю, что реквизиты не включены

// ❌ НЕПРАВИЛЬНАЯ ЛОГИКА
Если СрезПоследних.Количество() > 0 Тогда
    ПервыеДанные = СрезПоследних[0];
    
    // "Реквизит Валюта не существует"
    Валюта = ПервыеДанные.Валюта; // ❌ Ошибка в логике
    
    // На самом деле Валюта ТАМ ЕСТЬ!
    Валюта = ПервыеДанные.Валюта; // ✅ Работает!
КонецЕсли;

Ошибка 2: Пытаюсь фильтровать по реквизиту в параметрах СрезПоследних

// ❌ НЕПРАВИЛЬНО
ТаблицаИзмерений = Новая ТаблицаЗначений;
ТаблицаИзмерений.Колонки.Добавить("Товар");
ТаблицаИзмерений.Колонки.Добавить("Валюта"); // ❌ Это реквизит!

СрезПоследних = РегистрыСведений.ПараметрыТовара.СрезПоследних(
    ТаблицаИзмерений); // Ошибка! Валюта не измерение

// ✅ ПРАВИЛЬНО
ТаблицаИзмерений = Новая ТаблицаЗначений;
ТаблицаИзмерений.Колонки.Добавить("Товар"); // Только измерения!

СрезПоследних = РегистрыСведений.ПараметрыТовара.СрезПоследних(
    ТаблицаИзмерений);

// Потом фильтрую по Валюте в коде
Для Каждого Строка Из СрезПоследних Цикл
    Если Строка.Валюта = МояВалюта Тогда
        // Обработка
    КонецЕсли;
КонецЦикла;

Итоговая таблица доступности

Тип данныхСрезПоследнихЗапросВыбрать()
Измерения
Ресурсы
Реквизиты

Вывод: ДА, при получении среза последних из регистра сведений мы имеем полный доступ ко ВСЕМ реквизитам. Это одно из преимуществ сведений — вся информация у нас в руках.