Для выборок произвольных записей одним запросом есть класс RecordRefrenceList_RU. Появился, кажется, в RU3. Никаких особеннойстей новых
версий не использует и все это можно вполне "даунгрейтить" до 3.0.
Под произвольными имеется в виду то, что у выбираемых записей нет ничего общего - это просто список их кодов. Типичный пример - пользователь наставил в некоторой форме отбора сотню галок и хочет отмеченные записи как то обработать
Класс реализует универсальный join с постоянно/временной (постоянной в терминах БД, временной по сути) таблицей. RecId желаемых записей надо засунуть в этот класс, а затем использовать его в Query или select. Соответственно чтобы все работало нормально на фильтруемой таблице должен быть индекс по RecId
Для того чтобы работало с select надо метод getParmId() изменить на с private на public
Пример
X++:
static void refList_Tutorial(Args _args)
{
RecordReferenceList_RU refList = RecordReferenceList_RU::construct();
RecordReference_RU ref;
InventTable inventTable;
int i;
Query query;
QueryBuildDataSource qbds;
QueryRun queryRun;
;
setprefix("RecordReferenceList_RU");
while select inventTable
{
refList.addRecord(inventTable);
i++;
if (i > 10)
{
break;
}
}
refList.flush();
info("Query");
query = new Query();
qbds = query.addDataSource(tablenum(InventTable));
refList.join(qbds);
queryRun = new QueryRun(query);
while (queryRun.next())
{
info(queryRun.get(tablenum(InventTable)).caption());
}
info("Select");
while select inventTable
join ref
where ref.RefRecId == inventTable.RecId
&& ref.ParmId == refList.getParmId()
{
info(inventTable.caption());
}
refList.cleanup();
}
Записи вставаляются в таблицу в методе flush(), стираются в cleanup(). Соотвественно cleanup() надо не забывать вызывать, а если все работает без транзакции, то и предусматривать нормальное место для вызова cleanup() в блоках try|catch. Для очистки мусора в RecordReference_RU, который может там остаться из-за аварийных завершений работы при использовании без
транзакции, есть периодическая операция RecordReferenceCleanUp_RU (Основное/Пер операции/Очистка/Очистка ссылок на записи)
Достоинства и недостатки данного метода очевидны
+ Произвольные фильтры без ограничений на к-во выбранных записей
+ Нормальный join средствами сервера БД. Даже с учетом того что тут что то куда записывается работает (в общем случае - таблички с парой сотен записей не в счет)
быстрее чем join с временной таблицей
- Доп накладные расходы на запись/очистку.
Понятно что не стоит такое использовать если алгоритм, задействующий данный функционал, выполняется 100 раз в минуту или надо отобрать пару-тройку записей
В остальных случаях вполне годится
Еще раз - это тема про выборку одним запросом. Выборка в вызовом find() или select в цикле это то же вариант решения той же задачи, но здесь речь не о нем