v8: Прочтение списка строк табличного поля Ключевые слова: Прочитать, список, табличное, поле, отбор.
Элемент формы "Табличное поле" может отображать различные списки данных, например, список элементов справочника, список документов, список записей регистра сведений и т. д.
Ключевым в предыдущим предложении является слово "отображать", поскольку само табличное поле никаких данных не хранит, а всего лишь отображает пользователю порцию записей, столько, сколько уместится в окне элемента.
Для предотвращения эффекта торможения при быстром пролистывании списка записи читаются не только те, которые должны быть сейчас отображены в окне табличного поля, но и небольшое количество записей до и после этой порции.
Что, впрочем, нисколько не меняет суть дела, табличное поле принципиально не хранит в себе никаких записей, оно всего лишь их отображает.
При всем при этом зачастую возникает необходимость как-то получить список записей, отображаемых в табличном поле.
Оговорюсь, что речь обо всех записях табличного поля, которые будут показаны, если прокрутить список от начала до конца, а не только о тех записях, которые отображаются в окне табличного поля сейчас.
Поскольку у каждого табличного поля есть источник данных, указанный в свойстве "Данные", то в случае, когда в табличном поле не используется отбор, проблема решается очень просто, достаточно всего лишь работать не с табличнвм полем, а с тем самым источником данных, который указан в свойстве "Данные".
Сложности начинаются тогда, когда в табличном поле установлен отбор по каким-либо полям.
Для получения данных нужно использовать запрос.
Но вот хитрый момент, как написать запрос так, чтобы в него при выполнении попали только те записи, которые сейчас попадают в табличное поле?
То есть, говоря иначе, как в запрос включить те условия в раздел "ГДЕ" или в параметры виртуальной таблицы, которые используются в табличном поле?
Ниже приведен пример, позволяющий сделать запрос с отбором, аналогичным текущему отбору в табличном поле "СправочникСписок", отображающем какой-либо список, к примеру справочник "Контрагенты".
Запрос = Новый Запрос();
ТекстОтбора = "";
Для Каждого ЭлементНастройкиОтбора Из ЭлементыФормы.СправочникСписок.НастройкаОтбора Цикл
Если СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Использование Тогда
ВидСравненияЭлементаОтбора = СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ВидСравнения;
Если ВидСравненияЭлементаОтбора = ВидСравнения.Больше Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.БольшеИлиРавно Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВИерархии Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра)";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВСписке Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " В (&ЗначениеПараметра)";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ВСпискеПоИерархии Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра)";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Интервал Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра1";
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра2";
Запрос.УстановитьПараметр("ЗначениеПараметра1", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
Запрос.УстановитьПараметр("ЗначениеПараметра2", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяГраницы Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра1";
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра2";
Запрос.УстановитьПараметр("ЗначениеПараметра1", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
Запрос.УстановитьПараметр("ЗначениеПараметра2", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяНачало Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " >= &ЗначениеПараметра1";
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра2";
Запрос.УстановитьПараметр("ЗначениеПараметра1", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
Запрос.УстановитьПараметр("ЗначениеПараметра2", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.ИнтервалВключаяОкончание Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " > &ЗначениеПараметра1";
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра2";
Запрос.УстановитьПараметр("ЗначениеПараметра1", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеС);
Запрос.УстановитьПараметр("ЗначениеПараметра2", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].ЗначениеПо);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Меньше Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " < &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.МеньшеИлиРавно Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " <= &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВИерархии Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И (НЕ Контрагенты." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра))";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВСписке Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И (НЕ Контрагенты." + ЭлементНастройкиОтбора.Имя + " В (&ЗначениеПараметра))";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеВСпискеПоИерархии Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И (НЕ Контрагенты." + ЭлементНастройкиОтбора.Имя + " В ИЕРАРХИИ(&ЗначениеПараметра))";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеРавно Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " <> &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.НеСодержит Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И (НЕ Контрагенты." + ЭлементНастройкиОтбора.Имя + " ПОДОБНО &ЗначениеПараметра)";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Равно Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " = &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
ИначеЕсли ВидСравненияЭлементаОтбора = ВидСравнения.Содержит Тогда
ТекстОтбора = ТекстОтбора + Символы.ПС + " И Контрагенты." + ЭлементНастройкиОтбора.Имя + " ПОДОБНО &ЗначениеПараметра";
Запрос.УстановитьПараметр("ЗначениеПараметра", СправочникСписок.Отбор[ЭлементНастройкиОтбора.Имя].Значение);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ТекстОтбора <> "" Тогда
ТекстОтбора = "ГДЕ" + Символы.ПС + " " + Сред(ТекстОтбора, 4);
КонецЕсли;
ТекстЗапроса =
"ВЫБРАТЬ
| Контрагенты.Ссылка
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|" + ТекстОтбора;
Запрос.Текст = ТекстЗапроса;
Ну и напоследок, кому лень заморачиваться с вышеописанным вариантом, могут просто сделать так
ПостроительОтчета = Новый ПостроительОтчета;
ПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(СправочникСписок);
Вы спросите, как лучше?
Конечно же через построитель отчета, то есть вторым способом!
Вы спросите, почему я вам морочил голову первым вариантом и заставил разбираться в куче строк программного кода?
Ну, во-первых какие же вы программисты, если вы не понимаете сути работы программы?
А во-вторых люблю я это дело, головы морочить :))
TormozIT:
Задача достаточно нетривиальная, на самом деле. Описанный способ через источник данных построителя отчета имеет ряд серьезных недостатков. Например, он устанавливает типы не у всех доступных полей. Также в случае иерархического просмотра списка он вернет неполный порядок и отбор. И этим список недостатков не ограничивается...
Правильный же алгоритм построения запроса, который бы вадывал отображаемый список (тот же отбор и тот же порядок), занимает по крайней мере 300 строк кода. Привести его пока затруднительно, т.к. вместе с ним придется вытаскивать немаленькое дерево методов.
|