Спасибо Евгению Глазову (EVGL) за исходный совет. Спасибо
Максиму Горбунову за дополнения и
wamr за активное участие в обсуждении.
Обсуждение этого вопроса:
как подсчитать количество записей возвращаемых Query
В обсуждении этого вопроса, Максим горбунов отметил, что в текущей версии (Axapta 2.5 SP3, Axapta 2.5 SP6 CIS, Axapta 3.0 SP2) метод SysQuery::countTotal делает быстрый запрос только для простого query, который содержит только одну таблицу. Если в запросе содержится несколько связанных таблиц, то стандартный метод считает медленным и тупым сканированием записей.
Максим Горбунов предложил модификацию метода SysQuery::countTotal. Модификация Максима корректно и быстро считает количество записей в запросе с несколькими связанными таблицами и с группировками.
wamr отметил, что класс SysQuery содержит метод countLoops(). По сути, результат выполнения этого метода эквивалентен SQL-запросу
[sql]select count(distinct myfield) from myTable[/sql]
Метод countLoops()полезен когда надо вывести Progress bar. wamr предложил модификацию, которая позволяет для любого запроса считать количество группировок. В результате после этой модификации progress bar по запросам всегда будет работать правильно.
<div class='XPPtop'>X++</div><div class='XPP'>SysOperationProgress progress = [color=:blue]new[/color] SysOperationProgress();
progress.setTotal(SysQuery::countLoops(qr));
[color=:blue]while[/color]( qr.[color=:blue]next[/color]() ){
[color=:green]/* ...do somthing... */[/color]
progress.incCount();
}</div>
Обе модифицикации затрагивают только один метод - SysQuery::countPrim().
Обратите внимание, что методы работают во всех случаях, когда запрос имеет смысл. Однако существуют запросы, когда модифицированные версии могут вызывать ошибку SQL-запроса (Exception::Error). При тестировании обнаружены запросы в которых одновременно используется связь NoExistsJoin и группировки по подчиненным таблицам. Поэтому, для неочевидных запросов используйте обрамление try/catch для работы с исключениями.
Обратите также внимание, что countTotal() и countPrim() работают на сервере приложений, если у вас используется трехуровневая Аксапта. Это особенно важно, если у вас запрос с большим количеством возвращаемых группировок. SysQuery::countLoops генерирует существенно меньший трафик между клиентом и сервером, нежели "ручной" запрос с клиента.