|
04.05.2010, 17:23 | #1 |
Участник
|
Вывод в Excel через Array
Доброго времени суток.
Задача: Создать отчет в Excel с табличной частью из шаблона Решение: Есть в отчете табличная область, например, A19:CG35 (N столбцов и M строк). Я заполняю массив Array N x M раз. X++: protected boolean fillData() { . . . ; reportRows = 0; . . . while select returnLine where returnLine.JournalId == returnTable.JournalId { inventTable = InventTable::find(returnLine.ItemId); custInvoiceJour = CustInvoiceJour::findFrominvoiceId(returnLine.InvoiceId); custInvoiceTrans = CustInvoiceTrans::findRecId(returnLine.CustInvoiceTransRecId); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", returnLine.ItemId)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", inventTable.ItemName)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", inventTable.ItemArticle)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", custInvoiceJour.InvoiceExternalId)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", custInvoiceJour.InvoiceDate)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", custInvoiceTrans.Qty)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", custInvoiceTrans.SalesPrice)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", custInvoiceTrans.amountDiscAmountInclTax())); tableRows.value(tableRows.lastIndex() + 1, ""); tableRows.value(tableRows.lastIndex() + 1, ""); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", returnLine.QtyDocument)); tableRows.value(tableRows.lastIndex() + 1, strfmt("%1", returnLine.SummDoc)); tableRows.value(tableRows.lastIndex() + 1, ""); tableRows.value(tableRows.lastIndex() + 1, ""); tableRows.value(tableRows.lastIndex() + 1, ""); reportRows++; } return (reportRows > 0) ? true : false; } return false; } X++: protected void fillTable() { Bookmark bookmark; ; bookmark = strfmt("%1%2:%3%4", #FirstTableCol, this.firstTableRow(), #LastTableCol, this.firstTableRow() + this.numOfRows() - 1); this.insertValue(bookmark, ExcelReportFromTemplate::array2variant(tableRows), 1); } Microsoft Business Solution Axapta 3.0 Build #1951.3730/514-193 SP3/OP023071 |
|
04.05.2010, 18:14 | #2 |
Moderator
|
Код статики ExcelReportFromTemplate::array2variant - в студию!
Хотя я более, чем уверен, что это из-за того, что нельзя передавать двумерные вариантные массивы. Это ограничение Аксапты. Вероятно, придётся в методе fillTable вводить цикл и вставлять букмарками, адреса которых лежат в пределах одной строки Excel, а не сразу всем прямоугольным диапазоном как сейчас. |
|
04.05.2010, 23:26 | #3 |
Участник
|
Помнится, вот здесь был пример импорта из двумерного массива (SafeArray), возможно, по аналогии можно реализовать и экспорт, хотя мне лично больше нравится экспорт в Excel табличных частей отчетов через ADO
|
|
05.05.2010, 08:43 | #4 |
Участник
|
Ты вчерась просил ковер? Ну так я его припер!
ExcelReportFromTemplate::array2variant
X++: static ComVariant array2variant(Array _array) { Integer idx; array arr = new array (types::class); ; if (_array) { for (idx=1; idx <= _array.lastIndex(); idx++) { arr.value(idx, ExcelReportFromTemplate::createVariantFromValue(_array.value(idx))); } return ComVariant::createFromArray(arr); } return ComVariant::createNoValue(); } X++: private static ComVariant createVariantFromValue(anytype _value) { str value; ; switch (typeof(_value)) { case Types::String : case Types::RString : case Types::VarString : return ComVariant::createFromStr(_value); case Types::Enum : return ComVariant::createFromStr(enum2Value(_value)); case Types::Integer : return ComVariant::createFromInt(_value); case Types::Real : return ComVariant::createFromReal(_value); case Types::Date : case Types::DateTime : return ComVariant::createFromDate(_value); case Types::Real : return ComVariant::createFromReal(_value); } return ComVariant::createNoValue(); } Последний раз редактировалось Roman N. Krivov; 05.05.2010 в 08:46. |
|
05.05.2010, 08:45 | #5 |
Участник
|
Цитата:
Сообщение от gl00mie
Помнится, вот здесь был пример импорта из двумерного массива (SafeArray), возможно, по аналогии можно реализовать и экспорт, хотя мне лично больше нравится экспорт в Excel табличных частей отчетов через ADO
|
|
05.05.2010, 08:49 | #6 |
Участник
|
Есть еще вариант сохранить Excel'евский шаблон как XML файл, его редактировать и открывать как уже готовый. Вот только как выделить оттуда табличную часть и добавить нужное количество строк с разбивкой по страницам - данная задача без конкретного решения.
|
|
05.05.2010, 10:36 | #7 |
Участник
|
Цитата:
Вариант с ADO - это, по сути, тот же массив, но выполненный другими средствами. Просто вместо массива заполняется RecordSet. Разный объект-получатель. Поэтому совершенно без разницы, что заполнять Если Вы не в курсе, как это делается, то в среде Axapta создается объект RecordSet и наполняется, а потом заполненный RecordSet просто передается в Excel. Технология совершенно такая же, как и при использовании массивов, но нет проблем с неадекватностью форматов хранения. Цитата:
Если уж Вы перебираете варианты, то есть еще вариант вставки через буфер обмена. Его основной недостаток - слабая управляемость этого самого буфера обмена и возможность его разрушения/изменения в процессе вставки. |
|
|
За это сообщение автора поблагодарили: Gustav (2). |
05.05.2010, 10:39 | #8 |
Moderator
|
Roman N. Krivov, спасибо за демонстрацию кода. Примерно это я и ожидал увидеть.
Цитата:
Цитата:
Цитата:
Заготовьте в шаблоне табличную часть с 2-мя строками в диапазоне A19:CG20. Поименуйте этот диапазон в шаблоне, например, как "TablePart" и далее в своем коде обращайтесь к нему через этот "букмарк", т.е. Range("TablePart") вместо Range("A19:CG20"). Далее вставляйте перед второй строкой нужное кол-во строк. Допустим, надо вам всего 17 строк. 2 уже есть, значит надо вставить еще 15 перед исходной 2-й. После их вставки ваш Range("TablePart") автоматически будет ссылаться уже на Range("A19:CG35"). |
|
05.05.2010, 11:13 | #9 |
Участник
|
Цитата:
Уверен. Там одномерный массив вставлялся целиком. Нет, именно XML (Таблица XML) Вот как раз с данной проблемой и столкнулся. У меня число преобразуется в дату. В качестве типа поля в ADORecordSet использую #adDouble X++: #define.adDouble ( 5) Последний раз редактировалось Roman N. Krivov; 05.05.2010 в 11:15. |
|
05.05.2010, 12:30 | #10 |
Участник
|
Цитата:
Сообщение от gl00mie
Помнится, вот здесь был пример импорта из двумерного массива (SafeArray), возможно, по аналогии можно реализовать и экспорт, хотя мне лично больше нравится экспорт в Excel табличных частей отчетов через ADO
__________________
Axapta v.3.0 sp5 kr2 |
|
Теги |
ado, array, excel, recordset |
|
|