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