Показать сообщение отдельно
Старый 16.04.2009, 15:21   #278  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,275 / 3476 (122) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Подсчет количества записей
Решил поделиться небольшой кнопкой подсчета количества записей в активном датасорсе (т.е. в том датасорсе, к которому привязано текущее выбранное поле)
Умеет считать количество записей во временной таблице и в таблице, в которой записи отфильтрованы по диналинкам. При подсчете код ориентируется на SysQuery::countTotal

X++:
void clicked()
{
    FormRun              formRun = element.currentFormRun();
    FormObjectSet        formObjectSet;
    FormDataSource       formDS;
    Counter              cnt;
    Common               copyCursor;
    Query                copyQuery;
    int                  i;
    QueryBuildDataSource qbds;
    ;
    if (!formRun)
    {
        return;
    }
    formObjectSet = formRun.objectSet();
    if (!formObjectSet)
    {
        return;
    }
    formDS = formObjectSet.cursor().dataSource();
    if (formRun.objectSet().cursor().isTmp())
    {
        copyCursor = new DictTable(formRun.objectSet().cursor().TableId).makeRecord();
        copyCursor.setTmp();
        copyCursor.setTmpData(formRun.objectSet().cursor());
        select firstonly firstfast recId from copyCursor;
        if (copyCursor)
        {
            cnt = SysQuery::countTotal(formDS.queryRun(), copyCursor);
        }
    }
    else
    {
        copyQuery = new Query(formDS.queryRun().query().pack(false));
        for (i = 1; i <= formDS.queryRun().query().dataSourceCount(); i++)
        {
            qbds = formDS.queryRun().query().dataSourceNo(i);
            if (qbds.dynalinkCount())
            {
                SysQuery::queryAddDynaCursorAsRangeAndValue(copyQuery, formDS.queryRun().query(), i);
            }
        }
        cnt = SysQuery::countTotal(new QueryRun(copyQuery));
    }
    info(strfmt("%1 записей", cnt));
}
Здесь мне пришлось немного поправить стандартный код, но его при желании можно откопировать в форму табакса:
Класс SysQuery:
X++:
private server static container countPrim(container _queryPack, Common _tmpBuffer = null) // Корректный подсчет кол-ва записей во временной таблице
{
    Query                   countQuery;
    QueryRun                countQueryRun;
    QueryBuildDataSource    qbds;
    QueryBuildFieldList     qbfl;
    Common                  common;
    Integer                 counter;
    Integer                 loops;
    ;
    countQueryRun   = new QueryRun(_queryPack);
    countQuery      = countQueryRun.query();
    qbds            = countQuery.dataSourceNo(1);
    qbds.update(false);
    qbds.sortClear();
    qbfl = qbds.fields();
    qbfl.dynamic(false);
    qbfl.clearFieldList();
    if (countQuery.dataSourceCount() == 1)
        qbds.addSelectionField(fieldnum(Common,RecId),SelectionField::Count);

    countQueryRun   = new QueryRun(countQuery);
    // Корректный подсчет кол-ва записей во временной таблице -->
    if (_tmpBuffer)
    {
        countQueryRun.setCursor(_tmpBuffer);
    }
    // Корректный подсчет кол-ва записей во временной таблице <--

    while (countQueryRun.next())
    {
        common  = countQueryRun.get(countQuery.dataSourceNo(1).table());
        counter += common.RecId;
        loops++;
    }

    return [counter,loops];
}
и

X++:
public client server static Integer countTotal(QueryRun _queryRun, Common _tmpBuffer = null)// Корректный подсчет кол-ва записей во временной таблице

{
    container c = SysQuery::countPrim(_queryRun.pack(false), _tmpBuffer);

    return conpeek(c,1);
}
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 16.04.2009 в 15:24.
За это сообщение автора поблагодарили: belugin (5), alex55 (1).