AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.06.2006, 14:18   #1  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2480 (88) +++++++++
Регистрация: 20.08.2005
Продолжим

Выгрузка в текстовый файл с последующей загрузкой в Excel

В кач-ве особенности - в книге Excel создается макрос для загрузки текстового файла с помощью функции OpenText. Затем этот макрос запускается и происходит открытие этого файла с учетом типов данных в столбцах.

Почему такой путь - для передачи типов данных в столбцах функция требует передачи в кач-ве одного из параметров массива массивов. К сожалению, не знаю как это организовать в Axapta без привлечения сторонних средств

Время полета - 20 с

PS Для того, что бы этот код выполнился, необходимо включить в Excel параметр "Доверять доступ к Visual Basic Project" в форме управления безопасностью макросов

Еще информация по этой теме
Axapta программирует Excel на VBA

X++:
static void ExportExcelTXT(Args _args)
{
    LedgerTrans ledgerTrans;
    LedgerTable ledgerTable;
    int timeFullStart, timeFullFinish, timeFullTotal;
    int cnt = 0;
    str Buf, s;
    ComExcelDocument_Ru excel;
    COM                 doc;
    COM                 app;
    TextBuffer          tb;

    COM Workbook;
    COM prj;
    COM comp;
    COM module;
    COM code;
    Array fields;

    #define.vbext_ct_StdModule(1)
    #define.fileName("d:\\temp\\demo.txt")

    void AddField(int fldNum, TableId tbl, FieldId fld)
    {
        DictField   dictField;
        Array field;
        #define.xlGeneralFormat(0x00000001)
        #define.xlTextFormat(0x00000002)
        #define.xlMDYFormat(0x00000003)
        #define.xlDMYFormat(0x00000004)
        #define.xlYMDFormat(0x00000005)
        #define.xlMYDFormat(0x00000006)
        #define.xlDYMFormat(0x00000007)
        #define.xlYDMFormat(0x00000008)
        #define.xlSkipColumn(0x00000009)
        ;
        if (!fields)
            fields = new Array(Types::Class);
        dictField = new dictField( tbl, fld );
        field = new Array(Types::Integer);
        field.value(1, fldNum);
        if (dictField)
        {
            switch (dictField.baseType())
            {
                case Types::Date:
                    field.value(2, #xlDMYFormat);
                    break;
                case Types::Enum, Types::String:
                    field.value(2, #xlTextFormat);
                    break;
                default:
                    field.value(2, #xlGeneralFormat);
            }
        }
        else
            field.value(2, #xlGeneralFormat);

        fields.value((fields.lastIndex()+1), field);
    }
    str getFields()
    {
        str ret = "";
        int i;
        Array field;
        ;
        if (!fields) return "";
        for (i=1; i<= fields.lastIndex(); i++)
        {
            field = fields.value(i);
            if (field)
                ret += (ret ? ", " : "") + strfmt("Array(%1,%2)", field.value(1), field.value(2));
        }
        if (ret)
            return "FieldInfo:=Array(" + ret + "), ";
        return "";
    }
    // засекаем время
    timeFullStart = timenow();

    excel = new ComExcelDocument_Ru();
    excel.newFile("", false);
    doc = excel.getComDocument();
    app = doc.application();

    buf = "RecId\tAccountNum\tAccountName\tAccountPlType\tBondBatchTrans_RU\tBondBatch_RU\tTransDate\tTxt\tAmountMST\tCrediting\n";

    cnt++;
    while select  ledgerTrans
            join  ledgerTable
            where ledgerTrans.AccountNum == ledgerTable.AccountNum
                && ledgerTrans.TransDate >= str2date('dd.mm.yy',123) && ledgerTrans.TransDate <= str2date('DD.MM.YY',123)
    {
            // 10 полей
        buf +=
            strfmt(
                "%1\t%2\t%3\t%4\t%5\t%6\t%7\t%8\t%9\t%10\n",
                ledgerTrans.RecId, ledgerTrans.AccountNum, ledgerTable.AccountName, ledgerTable.AccountPlType,
                ledgerTrans.BondBatchTrans_RU, ledgerTrans.BondBatch_RU,
                date2str(ledgerTrans.TransDate, 123, 2, 2, 2, 2, 4), ledgerTrans.Txt,
                strltrim(strrem(num2str(ledgerTrans.AmountMST, 10, 2, 2, 3), "+")), ledgerTrans.Crediting);

        cnt++;
        if (cnt >=65000) break;
    }
    tb = new TextBuffer();
    tb.setText(buf);
    tb.toFile(#fileName);

    Workbook = app.ActiveWorkbook();
    prj = Workbook.VBProject();
    comp = prj.VBComponents();
    comp.add(#vbext_ct_StdModule);
    module = comp.item(comp.count());
    code = module.CodeModule();

    addField( 1, ledgerTrans.TableId, fieldnum(ledgerTrans, RecId));
    addField( 2, ledgerTrans.TableId, fieldnum(ledgerTrans, AccountNum));
    addField( 3, ledgerTable.TableId, fieldnum(ledgerTable, AccountName));
    addField( 4, ledgerTable.TableId, fieldnum(ledgerTable, AccountPlType));
    addField( 5, ledgerTrans.TableId, fieldnum(ledgerTrans, BondBatchTrans_RU));
    addField( 6, ledgerTrans.TableId, fieldnum(ledgerTrans, BondBatch_RU));
    addField( 7, ledgerTrans.TableId, fieldnum(ledgerTrans, TransDate));
    addField( 8, ledgerTrans.TableId, fieldnum(ledgerTrans, Txt));
    addField( 9, ledgerTrans.TableId, fieldnum(ledgerTrans, AmountMST));
    addField(10, ledgerTrans.TableId, fieldnum(ledgerTrans, Crediting));

    s = strfmt( "sub OpenDemo()\n" +
                "    Workbooks.OpenText Filename:=\"%1\", Origin:=1251, StartRow:= 1, _\n" +
                "        DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, Tab:=True, _\n" +
                "        %2TrailingMinusNumbers:=True, _\n" +
                "        DecimalSeparator:=\",\", ThousandsSeparator:=\" \"\n" +
                "End Sub", #fileName, getFields());
    code.addFromString(s);

    app.Run(strfmt("%1.OpenDemo", module.name()));
    App.DisplayAlerts(false);
    Workbook.Close();
    App.DisplayAlerts(true);

    excel.visible(true);

    timeFullFinish = timenow();
    timeFullTotal = timeFullFinish - timeFullStart;
    info('Время выполнения, сек');
    info(int2str(timeFullTotal));
}
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 20.06.2006 в 14:25.
За это сообщение автора поблагодарили: Gustav (3).
Старый 20.06.2006, 16:34   #2  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от AndyD
Продолжим
Выгрузка в текстовый файл с последующей загрузкой в Excel...
Супер. Высший пилотаж. У меня на всё той же "эталонной" машине (AMD,2.5,4) трижды подряд получилось "время полета" = 14 сек для "эталонных" 50 тыс. записей, т.е. при "if (cnt > 50000) break". Типы полей - всё как надо. Полный зачОт!

P.S. Спасибо! Дал именно "троечку" - не "раскрутки маховика инфляции репутации ради", а "своей симпатии к круглым числам из-за". Поздравляю с достижением 150! (честно говоря, думал, появится еще один зеленый "кирпичик"...)

P.P.S. AndyD, ну и надо наконец закомментарить или удалить строку " && ledgerTrans.TransDate >= str2date('dd.mm.yy',123) && ledgerTrans.TransDate <= str2date('DD.MM.YY',123)", а то чел, не вдающийся в подробности всей ветки, запустит джоб и обнаружит пустой набор, а ошибку компиляции эта строка не дает.

Последний раз редактировалось Gustav; 20.06.2006 в 16:58.
Старый 21.06.2006, 13:29   #3  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от AndyD
Почему такой путь - для передачи типов данных в столбцах функция требует передачи в кач-ве одного из параметров массива массивов.
К сожалению, не знаю как это организовать в Axapta без привлечения сторонних средств
AndyD, есть мысль - использовать формулу массива, во всяком случае в Excel у меня получилось...

Итак, как я понимаю, проблема заключается в том, что в операторе VBA вида
PHP код:
...
Workbooks.OpenText Filename:="C:\demo.txt"Origin:=1251StartRow:=1_
DataType
:=xlDelimitedTextQualifier:=xlDoubleQuoteConsecutiveDelimiter _
:=FalseTab:=TrueSemicolon:=FalseComma:=FalseSpace:=False_
Other
:=FalseFieldInfo:=Array(Array(11), Array(22), Array(32), Array(42), _
Array(51), Array(61), Array(71), Array(81), Array(91), Array(101)), _
TrailingMinusNumbers
:=True
... 
присутствует неудобный для нас фрагмент:
PHP код:
...
FieldInfo:=Array(Array(11), Array(22), Array(32), Array(42), _
Array(51), Array(61), Array(71), Array(81), Array(91), Array(101)),
... 
По жизни это не что иное, как двумерный массив "Номер поля - Тип поля" (в данном контексте задачи):
Код:
Номер Тип
---------
    1   1
    2   2
    3   2
    4   2
    5   1
    6   1
    7   1
    8   1
    9   1
   10   1
Так вот, если перед вызовом Workbooks.OpenText... выполнить оператор VBA:
PHP код:
...
Worksheets("Sheet1").Range("A1:B10").FormulaArray "={1,1;2,2;3,2;4,2;5,1;6,1;7,1;8,1;9,1;10,1}"
... 
(запятые разделяют элементы в строке, точка с запятой - строки),
то потом можно заменить FieldInfo:=Array... на FieldInfo:=Worksheets("Sheet1").Range("A1:B10") и получится:
PHP код:
...
Workbooks.OpenText Filename:="C:\demo.txt"Origin:=1251StartRow:=1_
DataType
:=xlDelimitedTextQualifier:=xlDoubleQuoteConsecutiveDelimiter _
:=FalseTab:=TrueSemicolon:=FalseComma:=FalseSpace:=False_
Other
:=FalseFieldInfo:=Worksheets("Sheet1").Range("A1:B10"), _
TrailingMinusNumbers
:=True
... 
Соответственно, от функции VBA.Array избавляемся и получается, что всё можно сделать из Аксы, не вызывая код VBA.

Попробуете? Только прошу, ни в коем случае не убирайте предыдущую версию. Пусть она останется в ветке. А новую можно назвать типа "ExportExcelTXT_2"
За это сообщение автора поблагодарили: AndyD (4).
Теги
benchmark, download, excel, faq, xml, законченный пример, производительность, экспорт/импорт

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Axapta программирует Excel на VBA Gustav DAX: База знаний и проекты 10 13.03.2006 11:42
Использование OWC.Spreadsheet для ускорения экспорта/импорта в/из Excel. storer DAX: Программирование 24 28.03.2005 19:10
Передача данных из 1С в Axapta 3.0 через COM Connector isbist DAX: Программирование 10 03.12.2004 10:58
Особенности экспорта данных в Excel Roman-sp DAX: Функционал 18 01.03.2004 12:07
Введение в Аксапту Роман Кошелев DAX: Прочие вопросы 0 18.12.2001 14:00

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:49.