10.06.2012, 01:55 | #1 |
Участник
|
.CopyFromRecordset(Data, MaxRows, MaxColumns)
переписываю старый класс под .net, избавлясь от COM обьектов экселя.
Натолкнулся на ошибку при пользовании метода Range.CopyFromRecordset(Data, MaxRows, MaxColumns) определние по МСДН C# CopyFromRecordset( [In] object Data, [In, Optional] object MaxRows, [In, Optional] object MaxColumns); использование X++: ..... Microsoft.Office.Interop.Excel.Range myRange; COM rSet; System.Object d; ....... , ... ...... d = rSet; myRange.CopyFromRecordset(d, missing,missing) Через System.Object при исполнении дает ошибку о неправильном типе аргумента.
__________________
The Variable men power. Последний раз редактировалось Varmen; 10.06.2012 в 02:00. |
|
10.06.2012, 17:21 | #2 |
Участник
|
попробовал по разному опеределять переменную, передавать пустой,
ошибка врмени исполнения CLR, все таже, Неправильный тип аргумента. для полноты картины приведу больше кода. X++: Microsoft.Office.Interop.Excel.Range myRange; Microsoft.Office.Interop.Excel.ApplicationClass excelApp; Microsoft.Office.Interop.Excel.Workbooks excelWbs; Microsoft.Office.Interop.Excel.Worksheets excelWorksheets; Microsoft.Office.Interop.Excel.WorksheetClass excelWorksheet; Microsoft.Office.Interop.Excel.Range excelRange; Microsoft.Office.Interop.Excel.Range excelCells; COM rSet,fld,flds; System.Object d; // или Object System.Type type; System.Object missing; System.Reflection.FieldInfo inforef; type = System.Type::GetType("System.Reflection.Missing"); inforef = type.GetField("Value"); missing = inforef.GetValue(Null); rSet = new COM('ADODB.Recordset'); flds = rSet.Fields(); flds.Append("N1" , this.adoTypeToExcel('str' )); flds.Append("N2" , this.adoTypeToExcel('str' )); rSet.Open(); rSet.AddNew(); fld = flds.Item("N1" ); fld.Value("a"); fld = flds.Item("N2" ); fld.Value("b"); rSet.Update(); fname = "имя файла"; excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass(); excelWbs = excelApp.get_Workbooks(); excelWb = excelWbs._Open(fileName,missing,missing,missing,missing,missing,missing,missing,missing,missing,missing,missing,missing); excelWorksheets = excelWb.get_Worksheets();//excelApp.get_ActiveSheet(); excelWorksheet = excelWorksheets.get_Item(1); excelCells = excelWorksheet.get_Cells(); myRange = excelCells.get_Range("A1",missing); d = rSet; myRange.CopyFromRecordset(d, missing,missing); //здесь выскакивает ошибка
__________________
The Variable men power. |
|
13.06.2012, 09:28 | #3 |
Участник
|
Цитата:
Сообщение от Varmen
переписываю старый класс под .net, избавлясь от COM обьектов экселя.
Натолкнулся на ошибку при пользовании метода Range.CopyFromRecordset(Data, MaxRows, MaxColumns) определние по МСДН C# CopyFromRecordset( [In] object Data, [In, Optional] object MaxRows, [In, Optional] object MaxColumns); Тут писать либо все на COM либо все на NET... Вообще функции Microsoft.Office.Interop.* документированы плохо, и разобратся иногда в них не просто. Чтобы функция CopyFromRecordset заработала, нужно подготовить и передать ей на вход подготовленый объект NET ADODB.Recordset как в примере ниже. (Придется подключить эту сборку предварительно в Reference Аксапта) X++: static void Job91(Args _args) { Microsoft.Office.Interop.Excel.ApplicationClass excelApp; Microsoft.Office.Interop.Excel.Workbooks excelWbs; Microsoft.Office.Interop.Excel.WorkbookClass excelWb; Microsoft.Office.Interop.Excel.Worksheets excelWorksheets; Microsoft.Office.Interop.Excel.WorksheetClass excelWorksheet; Microsoft.Office.Interop.Excel.Range excelCells; Microsoft.Office.Interop.Excel.Range excelCell; Microsoft.Office.Interop.Excel.Range myRange; System.Type type; System.Object missing; System.Object tmp; System.Reflection.FieldInfo inforef; ADODB.RecordsetClass recordSet; ADODB.Fields fields; ADODB.Field field; ; try { type = System.Type::GetType("System.Reflection.Missing"); inforef = type.GetField("Value"); missing = inforef.GetValue(Null); excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass(); // можно сделать excel видимым excelApp.set_Visible(true); excelWbs = excelApp.get_Workbooks(); excelWb = excelWbs._Open("c:\\1.xls",missing,missing,missing,missing,missing,missing,missing,missing,missing,missing,missing,missing); // Можно открыть чистый лист Excel // excelWb = excelWbs.Add(missing); excelWorksheets = excelWb.get_Worksheets(); excelWorksheet = excelWorksheets.get_Item(1); excelCells = excelWorksheet.get_Cells(); myRange = excelCells.get_Range("A1", missing); // Подготовка набора записей для вставки recordSet = new ADODB.RecordsetClass(); fields = recordSet.get_Fields(); fields.Append("name", ADODB.DataTypeEnum::adVarChar, 100, ADODB.FieldAttributeEnum::adFldFixed, null); fields.Append("count", ADODB.DataTypeEnum::adDecimal, 3, ADODB.FieldAttributeEnum::adFldFixed, null); fields.Append("sum", ADODB.DataTypeEnum::adDecimal, 2, ADODB.FieldAttributeEnum::adFldFixed, null); recordSet.Open(missing, missing, ADODB.CursorTypeEnum::adOpenKeyset, ADODB.LockTypeEnum::adLockOptimistic, 1); recordSet.AddNew(missing, missing); field = fields.get_Item(0); field.set_Value("Привет из Акспта"); field = fields.get_Item(1); field.set_Value(365465); field = fields.get_Item(2); field.set_Value(36.123); recordSet.Update(missing, missing); // так можно вставить набор записей myRange.CopyFromRecordset(recordSet, missing, missing); //здесь ошибка больше не выскакивает // а так вставляется значение в отдельную ячейку myRange = excelCells.get_Item(2, 2); myRange.set_Value2("Hello, world!"); } catch (Exception::CLRError) { error(AifUtil::getClrErrorMessage()); } } |
|
|
За это сообщение автора поблагодарили: gl00mie (10), Jorj (1). |
13.06.2012, 13:54 | #5 |
Участник
|
Хочется отметить, что основная идея рассматриваемого здесь метода - это возможность быстрой вставки массива информации (recordSet) в Excel с использованием NET. (Для увеличения скорости экспорта ? Или еще какие то причины...)
Вариант с использованием SysExcel такой возможности не предусматривает. Там возможна лишь построчная вставка, как я понял... |
|
13.06.2012, 19:42 | #6 |
Участник
|
Именно! Сам сис эксель не подходит мне нужен именно копи рекордсет для скорости.
__________________
The Variable men power. |
|
13.06.2012, 19:46 | #7 |
Участник
|
дело в том что я уже соеденял, ADODB.Recorset и передавал его пустым в самый первый раз. Однако замучавшись инциализировать его. Бросил.
А вот ADODB.RecordsetClass не пробовал.
__________________
The Variable men power. |
|
13.06.2012, 20:15 | #8 |
Участник
|
по ходу вопросик, а как заставить такое воспринимать?
ADODB.DataTypeEnum::adVarChar я пользуюсь неудобным X++: Microsoft.Office.Interop.Excel.XlSaveAction saveAction; saveAction = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlSaveAction', 'xlSaveChanges' );
__________________
The Variable men power. |
|
13.06.2012, 21:52 | #9 |
Участник
|
|
|
13.06.2012, 22:26 | #10 |
Moderator
|
|
|
14.06.2012, 00:39 | #11 |
Участник
|
Я его не мог инициализировать.
rSet = new ADODB.Recordset() ;
__________________
The Variable men power. |
|
14.06.2012, 11:29 | #12 |
Участник
|
наверное все же
X++: rSet = new ADODB.RecordsetClass(); |
|
|
За это сообщение автора поблагодарили: Varmen (1). |
15.06.2012, 19:49 | #13 |
Участник
|
Цитата:
Reference библиотека конечно добавлена. Но тип тем не менее enum, параметры функций не доступны. Изза чего все время надо лезть в МСДН и смотреть параметры, типы и вручную их создавать. Может в четверке такое не предусмотрено или чего то другого не хватает. В целом огромное спасибо за подсказку про Recordsetclass. Нaконец то заработало все на .NET.
__________________
The Variable men power. Последний раз редактировалось Varmen; 15.06.2012 в 19:51. |
|
15.06.2012, 20:29 | #14 |
Участник
|
|
|
Теги |
.net, ado, excel, recordset, как правильно |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|