Похоже, нашел ошибку в классе LedgerBalanceDim, точнее, его методе balance. Как известно, данный класс используется для расчета оборотов по счетам ГК в разрезе финансовой аналитики за определенный период. Помимо прочих параметров при создании экземпляра класса можно указать, что необходимо использовать кеширование (параметр _cache в методе new). В этом случае, все результаты расчета сохраняются в контейнере и при повторной попытке рассчитать обороты по какому-либо счету, результат берется из данного контейнера, а не рассчитываются заново. Для кеширования используется несколько контейнеров, в частности, cacheAccount используется для хранения списка счетов, для которых был выполнен расчет, и cacheData, в котором, собственно, хранятся сами рассчитанные данные.
Вставка данных осуществляется следующим образом (строки 87 и 88 метода balance() в DAX 3.0 или 85 и 86 в DAX 4.0):
X++:
cacheAccount += accountNum;
cacheData = conIns(cacheData,1, balance.export());
Т.е. счет записывается в контейнер cacheAccount последним элементом, а данные для этого счета записываются в контейнер cacheData первым элементом.
Дальнейший поиск кешированных данных осуществляется следующим образом (строки с 24 по 29 метода balance() в DAX 3.0 или с 45 по 50 в DAX 4.0):
X++:
accountIdx = conFind(cacheAccount, accountNum);
if (accountIdx)
{
balance.import(conPeek(cacheData, accountIdx));
return balance;
}
Т.е. в контейнере cacheData поиск данных осуществляется по тому номеру, по которому в контейнере cacheAccount находится счет. Но поскольку вставка данных в эти два контейнера происходила в разном порядке, то выбираются неверные данные. Исправляется ошибка достаточно просто: необходимо изменить вставку данных в контейнер cacheData следующим образом:
X++:
cacheAccount += accountNum;
cacheData = conIns(cacheData,conLen(cacheData) + 1, balance.export());
Проблема была обнаружена в DAX 3.0 SP6 и DAX 4.0 SP2. Вопрос: это действительно ошибка или здесь есть какая-то хитрая логика?