|
|
#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. |
|
|
|
|
#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. |
|
|
|
|
#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). | |
|
|
#5 |
|
Участник
|
Хочется отметить, что основная идея рассматриваемого здесь метода - это возможность быстрой вставки массива информации (recordSet) в Excel с использованием NET. (Для увеличения скорости экспорта ? Или еще какие то причины...)
Вариант с использованием SysExcel такой возможности не предусматривает. Там возможна лишь построчная вставка, как я понял... |
|
|
|
|
#6 |
|
Участник
|
Именно! Сам сис эксель не подходит мне нужен именно копи рекордсет для скорости.
__________________
The Variable men power. |
|
|
|
|
#7 |
|
Участник
|
дело в том что я уже соеденял, ADODB.Recorset и передавал его пустым в самый первый раз. Однако замучавшись инциализировать его. Бросил.
А вот ADODB.RecordsetClass не пробовал.
__________________
The Variable men power. |
|
|
|
|
#8 |
|
Участник
|
по ходу вопросик, а как заставить такое воспринимать?
ADODB.DataTypeEnum::adVarChar я пользуюсь неудобным X++: Microsoft.Office.Interop.Excel.XlSaveAction saveAction; saveAction = ClrInterop::parseClrEnum('Microsoft.Office.Interop.Excel.XlSaveAction', 'xlSaveChanges' );
__________________
The Variable men power. |
|
|
|
|
#9 |
|
Участник
|
|
|
|
|
|
#10 |
|
Moderator
|
|
|
|
|
|
#11 |
|
Участник
|
Я его не мог инициализировать.
rSet = new ADODB.Recordset() ;
__________________
The Variable men power. |
|
|
|
|
#12 |
|
Участник
|
наверное все же
X++: rSet = new ADODB.RecordsetClass(); |
|
|
|
| За это сообщение автора поблагодарили: Varmen (1). | |
|
|
#13 |
|
Участник
|
Цитата:
, ну это я из твоего когда уже почерпнул. А до обращения в дорум безуспешно возился "rSet = new ADODB.RecordsetClass();"Reference библиотека конечно добавлена. Но тип тем не менее enum, параметры функций не доступны. Изза чего все время надо лезть в МСДН и смотреть параметры, типы и вручную их создавать. Может в четверке такое не предусмотрено или чего то другого не хватает. В целом огромное спасибо за подсказку про Recordsetclass. Нaконец то заработало все на .NET.
__________________
The Variable men power. Последний раз редактировалось Varmen; 15.06.2012 в 19:51. |
|
|
|
|
#14 |
|
Участник
|
|
|
|
| Теги |
| .net, ado, excel, recordset, как правильно |
|
|
|