AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 10.06.2012, 01:55   #1  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
.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)
T.e напрямую рекордсет не передается, ошибка компиляции.

Через System.Object при исполнении дает ошибку о неправильном типе аргумента.
__________________
The Variable men power.

Последний раз редактировалось Varmen; 10.06.2012 в 02:00.
Старый 10.06.2012, 17:21   #2  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
попробовал по разному опеределять переменную, передавать пустой,
ошибка врмени исполнения 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  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от Varmen Посмотреть сообщение
переписываю старый класс под .net, избавлясь от COM обьектов экселя.
Натолкнулся на ошибку при пользовании метода Range.CopyFromRecordset(Data, MaxRows, MaxColumns)
определние по МСДН
C#
CopyFromRecordset( [In] object Data, [In, Optional] object MaxRows, [In, Optional] object MaxColumns);
Как это у вас легко получается передать COM объект в качетве аргумента NET функции.



Тут писать либо все на 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  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Хочется отметить, что основная идея рассматриваемого здесь метода - это возможность быстрой вставки массива информации (recordSet) в Excel с использованием NET. (Для увеличения скорости экспорта ? Или еще какие то причины...)

Вариант с использованием SysExcel такой возможности не предусматривает.
Там возможна лишь построчная вставка, как я понял...
Старый 13.06.2012, 19:42   #6  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
Именно! Сам сис эксель не подходит мне нужен именно копи рекордсет для скорости.
__________________
The Variable men power.
Старый 13.06.2012, 19:46   #7  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
дело в том что я уже соеденял, ADODB.Recorset и передавал его пустым в самый первый раз. Однако замучавшись инциализировать его. Бросил.

А вот ADODB.RecordsetClass не пробовал.
__________________
The Variable men power.
Старый 13.06.2012, 20:15   #8  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
по ходу вопросик, а как заставить такое воспринимать?

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  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Varmen Посмотреть сообщение
А вот ADODB.RecordsetClass не пробовал.
Работает!!!
Старый 13.06.2012, 22:26   #10  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Varmen Посмотреть сообщение
дело в том что я уже соеденял, ADODB.Recorset и передавал его пустым в самый первый раз. Однако замучавшись инциализировать его. Бросил.
Уверены, что он был пустой? Не надо бы было ему rSet.MoveFirst сделать перед CopyFromRecordset?
Старый 14.06.2012, 00:39   #11  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
Я его не мог инициализировать.

rSet = new ADODB.Recordset() ;
__________________
The Variable men power.
Старый 14.06.2012, 11:29   #12  
someOne is offline
someOne
Участник
Аватар для someOne
 
173 / 423 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Цитата:
Сообщение от Varmen Посмотреть сообщение
Я его не мог инициализировать.

rSet = new ADODB.Recordset() ;
наверное все же

X++:
rSet = new ADODB.RecordsetClass();
Только прежде нужно добавить сборку в Reference Аксапты
Миниатюры
Нажмите на изображение для увеличения
Название: Безымянный.GIF
Просмотров: 499
Размер:	30.7 Кб
ID:	7784  
За это сообщение автора поблагодарили: Varmen (1).
Старый 15.06.2012, 19:49   #13  
Varmen is offline
Varmen
Участник
 
190 / 13 (1) ++
Регистрация: 02.10.2007
Цитата:
Сообщение от someOne Посмотреть сообщение
наверное все же

X++:
rSet = new ADODB.RecordsetClass();
Только прежде нужно добавить сборку в Reference Аксапты
, ну это я из твоего когда уже почерпнул. А до обращения в дорум безуспешно возился "rSet = new ADODB.RecordsetClass();"

Reference библиотека конечно добавлена. Но тип тем не менее enum, параметры функций не доступны. Изза чего все время надо лезть в МСДН и смотреть параметры, типы и вручную их создавать. Может в четверке такое не предусмотрено или чего то другого не хватает.

В целом огромное спасибо за подсказку про Recordsetclass. Нaконец то заработало все на .NET.
__________________
The Variable men power.

Последний раз редактировалось Varmen; 15.06.2012 в 19:51.
Старый 15.06.2012, 20:29   #14  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5788 (200) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Varmen Посмотреть сообщение
по ходу вопросик, а как заставить такое воспринимать? ADODB.DataTypeEnum::adVarChar
Цитата:
Сообщение от Varmen Посмотреть сообщение
Может в четверке такое не предусмотрено
Похоже на то. 2009-я вот понимает .net-овские енумы, и IntelliSence'ом они поддерживаются.
Теги
.net, ado, excel, recordset, как правильно

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
emeadaxsupport: Writing Data Upgrade Scripts Part 1: Understanding the components of the process Blog bot DAX Blogs 0 10.02.2012 05:16
dynamicscpm: Creating Consolidated Financial Statements using Management Reporter – Consolidating with data in a non-Dynamics ERP (Part 5 of 7) Blog bot DAX Blogs 0 10.01.2012 03:14
axinthefield: Data Management Views used in Performance Analyzer for Microsoft Dynamics Blog bot DAX Blogs 0 13.06.2011 00:11
saveenr: Dynamics AX 2012: An Introduction to Report Data Providers Blog bot DAX Blogs 0 07.03.2011 12:11
axStart: Change data on a data source on a Form Blog bot DAX Blogs 0 04.09.2008 15:05

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 09:46.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.