Показать сообщение отдельно
Старый 29.09.2005, 15:27   #1  
petergunn is offline
petergunn
Участник
 
118 / 274 (10) ++++++
Регистрация: 30.08.2005
Адрес: Tyumen
Thumbs down ComWordDocument_RU - медленная работа
Axapta 3.0 SP3

Возможно для большинства поситителей этого форума такой проблемы уже давно не существует, но поиск ( может плохо искал ? ) ответов на этот вопрос не дал. Так что излагаю то что удалось найти.

Суть топика скорее сводится к медленной работе метода ComWordDocument_RU.InsertFieldValue(). Небольшие манипуляции с профайлером кода показывают что основное время тратится на вызов ComWordDocument_RU.FindField.
Посмотрим на код этого метода:
PHP код:
protected COM FindField(MSOfficeBookMark_RU _bookMark)
{
    
COM fieldsFieldFieldTmp;
    
int i;
    ;

    try
    {
        if (
m_comDocument)
        {
            
Fields =  m_comDocument.FormFields();

            if (
substr(m_comApplication.version(), ,1) >= '9'// Word 2000 and later
            
{
                
field fields.item(_bookMark);
            }
            else
            {
                 for (
i=i<= fields.count() ; i+=1)
                 {
                      
fieldTmp fields.item(i);

                      if (
fieldTmp.name() == _bookMark)
                      {
                            
field fieldTmp;
                            break;
                      }
                 }

                 if (! 
field)
                 {
                      
info(StrFmt("@DIS12564"_bookMark));
                 }

            }

        }
        else
        {
            
info(StrFmt("@DIS6408"this.GetApplicationName()));
        }
    }

    catch(
exception::error)
    {
        
info(StrFmt("@DIS12564"_bookMark));
    }

    return 
field;

а вот это уже интересно:

PHP код:
            if (substr(m_comApplication.version(), ,1) >= '9'// Word 2000 and later
            
{
                
field fields.item(_bookMark);
            }
            else
            {
                 for (
i=i<= fields.count() ; i+=1)
                 {
                      
fieldTmp fields.item(i);

                      if (
fieldTmp.name() == _bookMark)
                      {
                            
field fieldTmp;
                            break;
                      }
                 }

                 if (! 
field)
                 {
                      
info(StrFmt("@DIS12564"_bookMark));
                 }

            } 
Судя по комментарию ( DIS-слой ) для Word2000 и более поздних выбор поля должен происходить с использованием быстрой конструкции fields.item(_bookMark). На деле же из-за коряво написанного условия определения версии приложения
PHP код:
            if (substr(m_comApplication.version(), ,1) >= '9'// Word 2000 and later 
поиск поля заваливается в цикл с последовательным перебором полей документа.
Кому не лень, может загрузить Word и посмотреть major номер версии приложения - для Word2002 это будет что-то типа "10.2627.2625", соответсвенно проверка
if( substr( '10.2627.2625', 1, 1 ) >= '9' ) еще долго не вернет TRUE и будет обрекать счастливых обладателей последних версий продуктов от Microsoft на длительное ожидание

Небольшая модификация условия: ( в потомке или непосредственно в ComWordDocument_RU - кому как нравится )
PHP код:
 if( str2intm_comApplication.version() ) >= // Word 2000 and later 
приводит к заметному оживлению вывода в Word при условии что он не древнее Word2000.

Ну вот пожалуй и все что удалось накопать.