Показать сообщение отдельно
Старый 26.04.2007, 18:16   #167  
DocSerzh is offline
DocSerzh
Участник
 
51 / 22 (0) +++
Регистрация: 28.06.2004
Ускорение позиционирования по AxPath.
С разрешения Максима Белугина привожу часть переписки, чтобы четче осветить предложение :
DocSerzh
При позиционировании записи в "\Forms\Tabax\Methods\goMenuItemForm"
очень много времени занимает formRun.dataSource().findRecord(record).
Предлагается использовать formRun.args().lookupField() и formRun.args().lookupValue() для позиционирования.
belugin
У меня сомнения по поводу formRun.args().lookupField() и formRun.args().lookupValue().
Эти поля теоретически могут быть использованы кодом формы, и поэтому в каких-то случаях их изменение может нарушить работу чего-то ...
_____________________________________________________________

Провел исследование своих настроек и мозговой штурм. Приведу предлагаемый код - извините, что пояснения ниже.

Вариант 1
X++:
void goMenuItemForm(MenuItemType _itemType, MenuItemName _itemName, RecID _recID)
{
    Args args=new Args();
    FormRun formRun ;
    Common record;
    TableID tableID;

    // Dcs 04.04.2007 СБРFI-200703_02 KC
    FormDataSource      fds             ;
    // Dcs 04.04.2007 СБРFI-200703_02 KC
;
    args.menuItemType(_itemType);
    args.menuItemName(_itemName);
    formRun = new MenuFunction(_itemName, _itemType).create(args);
    formRun.run();
    if (_recID && formRun.dataSourceCount())
    {
        tableID = formRun.dataSource().cursor().TableId;

        //+ Dcs 04.04.2007 СБРFI-200703_02 KC
        // orig
        //  record = SysDictTable::newTableId(tableID).makeRecord();
        //  select firstOnly record
        //      where record.recID==_recID;
        //  formRun.dataSource().findRecord(record);

        if( ! formRun.args().lookupField() )
        {
            formRun.args().lookupField( fieldname2id( TableId, 'RecId') );

            formRun.args().lookupValue( int2str( _recId ) )              ;

            fds = formRun.dataSource().cursor().dataSource();

            fds.executeQuery();
        }
        else
        {
            record = SysDictTable::newTableId(tableID).makeRecord();

            select firstOnly record
                where record.recID==_recID;

            formRun.dataSource().findRecord(record);
        }
        //- Dcs 04.04.2007 СБРFI-200703_02 KC
    }
    formRun.detach();
}
Вариант 2
или c восстановлением lookupField ( в принципе, можно и целиком аргументы )

X++:
void goMenuItemForm(MenuItemType _itemType, MenuItemName _itemName, RecID _recID)
{
    Args args=new Args();
    FormRun formRun ;
    Common record;
    TableID tableID;

    // Dcs 04.04.2007 СБРFI-200703_02 KC
    fieldId             fldId           ;
    FormDataSource      fds             ;
    // Dcs 04.04.2007 СБРFI-200703_02 KC
;
    args.menuItemType(_itemType);
    args.menuItemName(_itemName);
    formRun = new MenuFunction(_itemName, _itemType).create(args);
    formRun.run();
    if (_recID && formRun.dataSourceCount())
    {
        tableID = formRun.dataSource().cursor().TableId;

        //+ Dcs 04.04.2007 СБРFI-200703_02 KC
        // orig
        //  record = SysDictTable::newTableId(tableID).makeRecord();
        //  select firstOnly record
        //      where record.recID==_recID;
        //  formRun.dataSource().findRecord(record);

        fldId = formRun.args().lookupField()                         ;

        formRun.args().lookupField( fieldname2id( TableId, 'RecId') );

        formRun.args().lookupValue( int2str( _recId ) )              ;

        fds = formRun.dataSource().cursor().dataSource();

        fds.executeQuery();

        formRun.args().lookupField( fldId )             ;

        //- Dcs 04.04.2007 СБРFI-200703_02 KC
    }
    formRun.detach();
}
Пояснения :
Рассуждаем логически . После formRun.run(); все, что могло сломаться в форме - уже сломалось и без нашего вмешательства. Если args были заданы до run() и есть в коде упоминание на lookup методы и их анализ - можно восстанавливать args после позиционирования по lookupField.
В предложенных вариантах :
1 - Если в обработчике menuItem были заданы args - позиционируемся по findRecord.В противном случае - по lookupField
2 - Позиционируеся по lookupField. Восстанавливаем lookupField после позиционирования (или все аргументы...)

Узкое место - анализ lookupField в executeQuery...

Перелопатил свою appl - не нашел таких критичесикх мест... В принципе,они отсекаются вариантом 1.

Преимущества
Позиционирование в SalesTable из конца в начало по lookupField идет меньше секунды, по findRecord - 25 ....

С радостью приму критику, отмету заблуждения.

Извините, если немного сумбурно.
За это сообщение автора поблагодарили: belugin (8).