01.07.2009, 16:24 | #26 |
Участник
|
Недавно стал разбираться с возможностью использования данного функционала при формировании отчетов в Эксел. Столкнулся с проблемой, которая для остальных возможно не является таковой.
Ее суть: static void aaa_TestADO_2(Args _args) { // ---------------------------------------------------------------------------- // ADODB.Recordset в оперативной памяти без привязки к источнику данных // ---------------------------------------------------------------------------- // EmplTable emplTable; InventTrans inventTrans; InventTable inventTable; PurchLine purchLine; InventDim inventDim; Voucher voucher; AccountNum account; TransDate date1; // TransDate toDate; // TransDate nDate, date1; ItemID itemID; str itemName; InventQTY qty; InventTransRefID zakaz; ItemGroupID itemGroupID; SysDim podraz; InventLocationID locationID; COM rstAxa; // ADO: Recordset COM flds, fld; // ADO: Fields, Field COM xlApp; // Excel.Application COM wbks, wbk; // Workbooks, Workbook COM wkss, wks; // Worksheets, Worksheet COM rng, cell, rngCR; // все Range COM font; // Range.Font COM entCol; // Range.EntireColumn COM actWin; // Excel.Application.ActiveWindow int i, iMax; // ============================================================================ // СНАЧАЛА ВЛОЖЕННАЯ ФУНКЦИЯ // ---------------------------------------------------------------------------- // функция для задания типа поля нашего Recordset-а в оперативной памяти // в данном демо-джобе используется для наглядности // для простоты используем всего 3 типа данных: число, строка и дата int adoTypeToExcel(str _type) { switch (_type) { // используются значения констант перечисления DateTypeEnum из топика TypeProperty (ADO) // (см. справку по ADO в файле ADO210.CHM - можно поискать на своем компе) case 'num' : return 5; // adDouble case 'str' : return 8; // adBSTR case 'date': return 133; // adDBDate case 'memo': return 203; // adLongVarChar } return 8; } // ============================================================================ // ТЕПЕРЬ ОСНОВНОЙ ПРОЦЕСС // Recordset создается в оперативной памяти - без Connection! rstAxa = new COM('ADODB.Recordset'); // формируем структуру нашего Recordset-а в "мозгах" flds = rstAxa.Fields(); flds.Append('Zakaz' , adoTypeToExcel('str' )); flds.Append('Voucher' , adoTypeToExcel('str' )); flds.Append('Цех' , adoTypeToExcel('str' )); flds.Append('НомГруппа', adoTypeToExcel('str' )); flds.Append('Номенклатура' , adoTypeToExcel('str' )); flds.Append('Наименование' , adoTypeToExcel('str' )); flds.Append('Склад' , adoTypeToExcel('str' )); // flds.Append('BirthDate' , adoTypeToExcel('date')); flds.Append('Кол-во' , adoTypeToExcel('num' )); flds.Append('Сумма' , adoTypeToExcel('num' )); // и наконец открываем его rstAxa.Open(); // ---------------------------------------------------------------------------- while select * from inventTrans // where ((inventTrans.DateFinancial >= fromDate && inventTrans.DateFinancial <= toDate) where ((inventTrans.DateFinancial >= 01\01\2009 && inventTrans.DateFinancial <= 31\05\2009) && inventTrans.TransType == 3) // && inventTrans.StatusReceipt == 1) join inventTable where (inventTrans.ItemId == inventTable.ItemId && inventTable.dataAreaId == "ssm") join purchLine where (inventTrans.ItemId == purchLine.ItemId && inventTrans.InventTransId == purchLine.InventTransId) join InventDim where (inventTrans.inventDimId == inventDim.inventDimId) { itemID = inventTrans.ItemId; itemName = inventTrans.itemName(); zakaz = inventTrans.TransRefId; qty = inventTrans.Qty; // amount0 = inventtrans.CostAmountPhysical; amount0 = inventTrans.CostAmountPosted; itemGroupID = inventTable.ItemGroupId; podraz = purchLine.Dimension[2]; voucher = inventTrans.Voucher; locationID = inventDim.InventLocationId; // бежим по таблице "......." Axapta // и добавляем записи (выбранные поля) в Recordset в оперативной памяти rstAxa.AddNew(); // fld = flds.Item('Zakaz' ); fld.Value(inventTrans.TransRefId ); // fld = flds.Item('Voucher' ); fld.Value(inventTrans.Voucher ); fld = flds.Item('Цех' ); fld.Value(purchLine.Dimension[2] ); fld = flds.Item('НомГруппа' ); fld.Value(inventTable.ItemGroupId); fld = flds.Item('Номенклатура' ); fld.Value(inventTrans.ItemId ); fld = flds.Item('Наименование' ); fld.Value(itemName); fld = flds.Item('Склад' ); fld.Value(inventDim.InventLocationId ); // fld = flds.Item('BirthDate' ); fld.Value(emplTable.BirthDate ); fld = flds.Item('Кол-во' ); fld.Value(inventTrans.Qty ); fld = flds.Item('Сумма' ); fld.Value(inventTrans.CostAmountPosted ); rstAxa.Update(); } // к этому моменту в оперативной памяти сформирована НАША таблица "Список сотрудников" // ---------------------------------------------------------------------------- // перед выгрузкой в Excel встанем на первую запись НАШЕЙ ТАБЛИЦЫ В ПАМЯТИ // и изменим имя сотрудника, дату его рождения и ID // НЕ БОЙТЕСЬ!!! Аксаптовская таблица EmplTable при этом НЕ ЗАТРАГИВАЕТСЯ!!! )) // rstAxa.MoveFirst(); // fld = flds.Item('Name' ); fld.Value('Самый молодой cотрудник с очень длинным именем'); // fld = flds.Item('BirthDate'); fld.Value(1\3\2006); // 1-е марта 2006 года // fld = flds.Item('EmplId' ); fld.Value('000333'); // потом обратите внимание, что в Excel ведущие нули у 000333 сохранятся! // rstAxa.Update(); // ---------------------------------------------------------------------------- // готовим новую рабочую книгу Excel для приема данных из Axapta: xlApp = new COM('Excel.Application'); xlApp.Visible(true); wbks = xlApp.Workbooks(); wbk = wbks.Add(); wkss = wbk.Worksheets(); wks = wkss.Item(1); wks.Name('AdoTestSheet'); rng = wks.Range('A1'); // ---------------------------------------------------------------------------- // выводим строку имен полей (1-я строка листа Excel) flds = rstAxa.Fields(); iMax = flds.Count() - 1; for (i = 0; i <= iMax; i += 1) { fld = flds.Item(i); cell = rng.Offset(0, i); cell.Value2(fld.Name()); } rngCR = rng.CurrentRegion(); font = rngCR.Font(); font.Bold(true); // делаем выведенные заголовки жирным шрифтом // ---------------------------------------------------------------------------- // выводим данные, начиная со 2-й строки листа Excel cell = rng.Offset(1, 0); cell.CopyFromRecordset(rstAxa); // ---------------------------------------------------------------------------- // подгоняем ширину столбцов Excel rngCR = rng.CurrentRegion(); entCol = rngCR.EntireColumn(); entCol.AutoFit(); // замораживаем строку заголовков Excel cell.Select(); actWin = xlApp.ActiveWindow(); actWin.FreezePanes(true); // ---------------------------------------------------------------------------- rstAxa.Close(); } С комментариями все работает, а если убрать комментарии со строк // fld = flds.Item('Zakaz' ); fld.Value(inventTrans.TransRefId ); // fld = flds.Item('Voucher' ); fld.Value(inventTrans.Voucher ); выдается ошибка: Вариантный тип, который используется методом СОМ - объекта, не поддерживается. В чем может быть засада?? Заранее благодарен. P.S. Ах 30 SP1 office 2003 SP3
__________________
Александр |
|