Hi Audrey,
The subquery method is not costing you much more than any other method might. As far as dcount(), I used dcount() as an easy example, you could use another query with the subquery as source, or some other method, but early on I had a similar aversion to the domain functions, and I did some perf tests using queries, recordsets, etc, using all sorts of optimized settings (table-type with seek, etc, snapshot, etc) and the domain functions were faster them the majority of methods, and slower than only the most highly optimized table-type recordsets. Also they're a hell of a lot less coding and you can't use table-type on anything but a local jet table, unless you do even more coding and open the remote db, etc.
Anyway, as far as using a subquery or whatever--think about it--if the report is to know the grouping levels and figure out the number of them on the first page, it has to walk through the entire report's secondary recordsource somehow. There is no magic way that it's going to know this at the opening of the report. Whether it's some internal Access function or whatever, that secondary data's got to be visited.
To explain the 'secondary' recordsource--Access reports are all 'subqueries' internally, in that the Group levels are based on an internal GroupBY query over whatever source table/query you have as the report's source. And that recordset has not been visited until you page through the report, or use your own subquery.
You can reference certain totals in report at the first page, but only if they're core sql functions on the base recordsource, like Sum() and Avg(). Say you have a field in the report header that references a 'grand total' field in the report footer--you'll get the right answer, but Access is running the Sum() over that field and has walked through only the source table/query.
--Jim