Выборки
Для осуществления выборок из ссылочных коллекций реализован класс "Селектор". Селектор позволяет:
- формировать выборки из ссылочных коллекций с учетом сложных отборов, в том числе по полям на неограниченной глубине и по полям табличных частей;
- формировать выборки с учетом сортировок по полям на неограниченной глубине;
- формировать выборки, содержащие контекстные данные самих объектов, а также объктов, на которые ссылаются внутренние поля.
Создать селектор можно:
- вызвав метод "СоздатьСелектор()" объекта "БромКлиент";
- вызвав метод "СоздатьСелектор()" модуля менеджера соответствующей коллекции.
Формирование выборки происходит:
- при вызове метода "Выполнить()" селектора;
- при получении итератора селектора "getIterator()".
Селектор может формировать выборки для следующих коллекций:
- Справочники;
- Документы;
- Перечисления;
- Планы видов характеристик;
- Планы счетов;
- Планы видов расчета;
- Бизнес-процессы;
- Задачи.
// Выборка всех элементов справочника "Номенклатура"
$текСелектор = $клиент->СоздатьСелектор();
$текСелектор->УстановитьКоллекцию("Справочник.Номенклатура");
$текСелектор->АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов::ТолькоСтандартныеРеквизиты();
foreach ($текСелектор as $текСсылка) {
echo("Наименование: {$текСсылка->Наименование}; Код: {$текСсылка->Код} <br/>");
}
// Добавляем отбор и дозапрашиваем данные производителя
$текСелектор->ДобавитьОтбор("ЭтоГруппа", false);
$текСелектор->ДобавитьСортировку("Наименование");
$текСелектор->ДобавитьПоля("Производитель, Производитель.ИНН");
foreach ($текСелектор as $текСсылка) {
echo("
Наименование: {$текСсылка->Наименование};
Код: {$текСсылка->Код};
Производитель: {$текСсылка->Производитель};
ИНН: {$текСсылка->Производитель->ИНН} <br/>
");
}
// Сохраняем результат выборки в массив для последующего использования
$результат = $текСелектор->ВыгрузитьРезультат();
// Выборка из справочника "Номенклатура" в стиле языка запросов
$текСелектор = $клиент->СоздатьСелектор();
$текСелектор->
Выбрать("Наименование, Код, Производитель, Производитель.ИНН")->
Первые(20)->
Из("Справочник.Номенклатура")->
Где("ЭтоГруппа", false)->
Где("Родитель.Наименование", "Мебель")->
Упорядочить("Наименование");
foreach ($текСелектор as $текСсылка) {
echo("
Наименование: {$текСсылка->Наименование};
Код: {$текСсылка->Код};
Производитель: {$текСсылка->Производитель};
ИНН: {$текСсылка->Производитель->ИНН} <br/>
");
}
// Сохраняем результат выборки в массив для последующего использования
$результат = $текСелектор->ВыгрузитьРезультат();
// Выборка номенклатуры из группы "Мебель"
$группаМебель = $клиент->Справочники->Номенклатура->НайтиПоНаименованию("Мебель");
$текСелектор = $клиент->Справочники->Номенклатура->СоздатьСелектор();
$текСелектор->
Выбрать("Наименование, Код, Производитель, Производитель.ИНН")->
Где("ЭтоГруппа", false)->
Где("Ссылка", $группаМебель, ВидСравнения::ВИерархии())->
Упорядочить("Производитель")->
Упорядочить("Наименование", НаправлениеСортирвки::Убывание());
foreach ($текСелектор as $текСсылка) {
echo("
Наименование: {$текСсылка->Наименование};
Код: {$текСсылка->Код};
Производитель: {$текСсылка->Производитель};
ИНН: {$текСсылка->Производитель->ИНН} <br/>
");
}
// Сохраняем результат выборки в массив для последующего использования
$результат = $текСелектор->ВыгрузитьРезультат();
// Выборка заказов с определенной даты, в которых есть товары из раздела "Мебель"
$группаМебель = $клиент->Справочники->Номенклатура->НайтиПоНаименованию("Мебель");
$текСелектор = $клиент->Документы->ЗаказКлиента->СоздатьСелектор();
$текСелектор.
Выбрать("Дата, Номер, Контрагент")->
Где("Проведен", true)->
Где("Дата", new DateTime(2019, 1, 1), ВидСравнения::БольшеИлиРавно())->
Где("Товары.Номенклатура", $группаМебель, ВидСравнения::ВИерархии())->
Упорядочить("Контрагент")->
Упорядочить("Дата", НаправлениеСортирвки::Убывание());
foreach ($текСелектор as $текСсылка) {
echo("Дата: {$текСсылка->Дата}; Номер: {$текСсылка->Номер}; Контрагент: {$текСсылка->Контрагент} <br/>");
}
// Сохраняем результат выборки в массив для последующего использования
$результат = $текСелектор->ВыгрузитьРезультат();
Установка отборов
Установить отбор селектора можно:
- вызвав метод "ДобавитьОтбор()" селектора;
- вызвав метод "Где()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать:
- Ключ поля (путь к данным поля), например "Ссылка", "Артикул", "Производитель.ИНН", "Родитель.Наименование". Допускается указывать путь к данным реквизитов табличных частей, например "Товары.Количество", "ДополнительныеРеквизиты.Свойство.Наименование" и тд...
- Значене сравнения сериализуемого типа. Тип значения должен соответствовать реквизиту;
- Вид сравнения (опционально, по умолчанию "Равно"). Вид сравнения может быть:
- Равно;
- НеРавно;
- Больше;
- БольшеИлиРавно;
- Меньше;
- МеньшеИлиРавно;
- Содержит;
- НеСодержит;
- ВСписке;
- НеВСписке;
- ВИерархии;
- НеВИерархии.
Для видов сравнения "ВСписке" и "НеВСписке" в качестве значения необходимо передавать массив значений (array или Массив). Для видов сравнения "ВИерархии" и "НеВИерархии" можно передавать как одно значение (ссылку), так и массив значений (массив ссылок).
// Пример отборов для справочника
$текСелектор->ДобавитьОтбор("Артикул", "Т-0001");
$текСелектор->ДобавитьОтбор("Вес", 15, ВидСравнения::БольшеИлиРавно());
$текСелектор->ДобавитьОтбор("Ссылка", $группаМебель, ВидСравнения::НеВИерархии());
$текСелектор->ДобавитьОтбор(
"Производитель.Родитель",
Массив::ИзМассива(array($ссылка1, $ссылка2, $ссылка3)),
ВидСравнения::ВСписке()
);
// Пример отборов для документа
$текСелектор->
Где("Дата", new Дата("2019-01-01"), ВидСравнения::БольшеИлиРавно())->
Где("Товары.Номенклатура", array($ссылка1, $ссылка2, $ссылка3), ВидСравнения::ВСписке())->
Где("Проведен", true, ВидСравнения::Равно())->
Где("ДокументОснование", $клиент->Документы->ЗаказКлиента->ПустаяСсылка(), ВидСравнения::НеРавно());
Сортировка выборок
Указать сортировку выборки можно:
- вызвав метод "ДобавитьСортировку()" селектора;
- вызвав метод "Упорядочить()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать:
- Ключ поля (путь к данным поля), например "Наименование", "Артикул", "Производитель.Код", "Родитель.Наименование" и тд..;
- Направление сортировки (опционально, по умолчанию "Возрастание").
$текСелектор->ДобавитьСортировку("Наименование");
$текСелектор->ДобавитьСортировку("Производитель.Наименование", НаправлениеСортирвки::Убывание());
$текСелектор->
Упорядочить("Дата", НаправлениеСортирвки::Убывание())->
Упорядочить("Контрагент");
Загрузка контекстных данных
Сам по себе селектор является коллекцией ссылок, реализующей интерфейсы "IteratorAggregate", "ArrayAccess", "Countable". В некоторых случаях возникает необходимость получения доступа к контекстным данным объектов (к данным реквизитов и табличных частей), на которые эти ссылки указывают. Доступ к данным может быть получен путем обращения к динамическим полям ссылки, например "текСсылка.Артикул", однако при таком обращении будет отправлен запрос серверу с последующей загрузкой полного набора контекстных данных. Чтобы избежать множественных запросов к серверу и избыточной загрузки данных, в классе селектора предусмотрена возможность указания полей объекта, которые должны быть загружены единовременно вместе с формированием выборки.
Указать дополнительные поля выборки можно:
- вызвав метод "ДобавитьПоля()" селектора;
- вызвав метод "Выбрать()" селектора (метод является синонимом).
В качестве параметров метода необходимо указать список полей, данные которых необходимо загрузить. Могут быть указаны как поля самого объекта выборки, так и подчиненные поля, например "Производитель.Родитель.Наименование", "Контрагент.ИНН" и тд...
// Неоптимальный вариант работы с данными
$текСелектор = $клиент->Справочники->Номенклатура->СоздатьСелектор();
foreach ($текСелектор as $текСсылка) {
echo("Наименование: {$текСсылка->Наименование}; Производитель: {$текСсылка->Производитель} <br/>");
// В каждой итерации будет происходить два запроса на сервер:
// - запрос на получение ВСЕХ контекстных данных ссылки "текСсылка", включая данные табличных частей;
// - запрос на получение ВСЕХ контекстных данных ссылки "Производитель" для формирования представления ссылки.
// Это медленно и крайне неэффективно!
}
// Оптимальный вариант работы с данными
$текСелектор = $клиент->Справочники->Номенклатура->СоздатьСелектор();
$текСелектор->ДобавитьПоля("Наименование, Производитель");
foreach ($текСелектор as $текСсылка) {
echo("Наименование: {$текСсылка->Наименование}; Производитель: {$текСсылка->Производитель} <br/>");
// Дополнительных запросов на сервер происходить не будет,
// т.к. необходимые данные уже загружены с сервера и помещены в контекст
}
$текСелектор = $клиент->Справочники->Номенклатура->СоздатьСелектор();
// Запрашиваем данные, которые понадобятся для дальнейшей работы
$текСелектор->
Выбрать("Наименование, Родитель.Код, Производитель.Родитель.Наименование")->
Выбрать("ПометкаУдаления, ДополнительныеРеквизиты");
foreach ($текСелектор as $текСсылка) {
// TODO
}
В классе селектора также предусмотрено свойство "АвтозагрузкаПолей", которое позволяет указать, какие именно данные необходимо загружать вместе с выборкой, без указания конкретных имен полей.
// Будут загружены данные только стандартных реквизитов
$текСелектор->АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов::ТолькоСтандартныеРеквизиты();
// Будут загружены данные всех реквизитов объекта (без табличных частей)
$текСелектор->АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов::ТолькоРеквизиты();
// Будут загружены все данные объекта (реквизиты и табличные части)
$текСелектор->АвтозагрузкаПолей = АвтозагрузкаПолейОбъектов::ВсеПоля();
Подробная информация по работе со ссылками и контекстными данными ссылок представлена в разделе "Работа со ссылками".
Ограничение размера выборки
Ограничить количество выбираемых элементов можно:
- установив свойство "Лимит";
- вызвав метод "Первые()".
$текСелектор->Лимит = 10;
$текСелектор->Первые(10);