Показать сообщение отдельно
Старый 01.07.2009, 16:24   #38  
tolstjak is offline
tolstjak
Участник
 
440 / 16 (1) ++
Регистрация: 05.01.2003
Недавно стал разбираться с возможностью использования данного функционала при формировании отчетов в Эксел. Столкнулся с проблемой, которая для остальных возможно не является таковой.
Ее суть:

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
__________________
Александр