При работе с Excel через COM скорость обмена данными оставляет желать лучшего. Авторы форума AxForum.RU
POS (
http://www.axforum.ru/forums/member.php?s=...nfo&userid=2317) и
DSV (
http://www.axforum.ru/forums/member.php?s=...nfo&userid=1527) предложили способ, позволяющий значительно ускорить вывод больших объемов данных в Excel.
Предлагаемое решение представляет собой метод класса
ComExcelDocument_RU:
<div class='XPPtop'>X++</div><div class='XPP'>[color=:blue]public[/color] [color=:blue]void[/color] insertText(BookMark _bookMark, TextBuffer _text, [color=:blue]int[/color] _workSheet = 1)
{
COM XLSWorkSheet, XLSrange;
TextBuffer tempBuffer; [color=:green]// To store clipboard contents
[/color] ;
[color=:green]// Initializing XLSWorkSheet object
[/color] XLSWorkSheet = this.getWorkSheet(_workSheet);
[color=:blue]if[/color] (!XLSWorkSheet)
[color=:blue]throw[/color] error([color=:red]"@DIS6043"[/color]);
[color=:green]// Initializing XLSRange object
[/color] XLSrange = this.findRange(_bookMark);
[color=:blue]if[/color] (!XLSrange)
[color=:blue]throw[/color] error([color=:red]"@SYS27391"[/color]);
XLSrange.[color=:blue]select[/color]();
[color=:green]// Storing clipboard contents
[/color] tempBuffer = [color=:blue]new[/color] TextBuffer();
tempBuffer.fromClipboard();
[color=:green]// Preparing text to be inserted
[/color] _text.toClipboard();
[color=:green]// Inserting text from clipboard
[/color] XLSWorkSheet.pasteSpecial(1); [color=:green]// 1 - "Text only" mode
[/color]
[color=:green]// Restoring clipboard contents
[/color] tempBuffer.toClipboard();
}</div>
Этот метод вставляет через буфер обмена содержимое текстового буфера
_text в ячейку с именем
_bookMark. То, что вставка происходит через буфер обмена, значительно ускоряет работу, так как и Axapta и Excel работают с буфером на приличной скорости.
Использование "Специальной вставки" (Paste special) и режима "Только текст" (Text only) позволяет побороть проблемы, возникающие в операционных системах линейки NT, связанные с некорректным выводом русских символов при вставке из буфера обмена.
В заключение небольшой пример использования метода:
<div class='XPPtop'>X++</div><div class='XPP'>[color=:blue]static[/color] [color=:blue]void[/color] Job1(Args _args)
{
ComExcelDocument_RU excelDocument = [color=:blue]new[/color] ComExcelDocument_RU();
TextBuffer text = [color=:blue]new[/color] TextBuffer();
[color=:blue]int[/color] chr;
[color=:green]// Initializing Excel
[/color] excelDocument.InitApplication();
[color=:green]// Creating new Excel document
[/color] excelDocument.newDocument();
[color=:green]// Preparing data for insertion
[/color] [color=:blue]for[/color] (chr = char2num([color=:red]'A'[/color], 1);
chr <= char2num([color=:red]'я'[/color], 1);
chr++) {
[color=:blue]if[/color] (chr [color=:blue]==[/color] char2num([color=:red]'a'[/color], 1) [color=:blue]||[/color]
chr [color=:blue]==[/color] char2num([color=:red]'А'[/color], 1))
text.appendText([color=:red]'\n'[/color]);
text.appendText(num2char(chr) + num2char(9));
[color=:blue]if[/color] (chr [color=:blue]==[/color] char2num([color=:red]'Z'[/color], 1) [color=:blue]||[/color]
chr [color=:blue]==[/color] char2num([color=:red]'z'[/color], 1) [color=:blue]||[/color]
chr [color=:blue]==[/color] char2num([color=:red]'Я'[/color], 1))
text.appendText([color=:red]'\n'[/color]);
}
[color=:green]// Inserting data into Excel
[/color] excelDocument.insertText([color=:red]"C4"[/color], text);
}</div>
В этом Job формируется текстовый буфер, заполненый символами от A до я со знаками табуляции в качестве разделителей. Затем сформированный буфер вставляется в Excel.