30.03.2007, 11:21 | #1 |
Участник
|
Работа с Excel через COM и ошибка 0x800A03EC (Range.AutoFilter)
Пытаюсь сделать простую, казалось бы, вещь: установить автофильтры на некоторые колонки листа Excel, в которые предварительно выводятся данные. В самом Excel вроде бы все просто:
PHP код:
Цитата:
Метод "autoFilter" в COM-объекте класса "Range" возвратил код ошибки 0x800A03EC (<неизвестно>), который означает: Метод AutoFilter из класса Range завершен неверно.
X++: COM app; COM sel; COM range; ; // ... range.select(); app = range.application(); sel = app.selection(); sel.autoFilter(); Ms Office Excel 2003 (11.8120.8122) SP2 Rus, Axapta 3.0 SP5 KR2 |
|
30.03.2007, 11:31 | #2 |
Moderator
|
А эти некоторые колонки они подряд идут? А на самом VBA есть отлаженная процедурка, которая бы работала так как надо или Вы сразу на X++ делаете?
|
|
30.03.2007, 11:50 | #3 |
Участник
|
Попробуйте autoFilter(1);
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: Ace of Database (5), gl00mie (5), pedrozzz (1). |
30.03.2007, 11:54 | #4 |
Участник
|
http://support.microsoft.com/kb/320369/en-us
X++: static void Job29(Args _args) { COM App = new Com("Excel.Application"); COM wb; COM wbs; COM sh; COM r; Com c; Com s; COMDispFunction f; ; App.Visible(true); wbs = App.WorkBooks(); wb = Wbs.Add(); sh = wb.ActiveSheet(); r = sh.Range("A1"); r.value2("1"); r = sh.Range("A2"); r.value2("2"); sh.AutoFilterMode(false); r = sh.Range("A1:A2"); f = new COMDispFunction(r, "AutoFilter", COMDispContext::METHOD); f.call(); //r.AutoFilter(); } Последний раз редактировалось belugin; 30.03.2007 в 11:54. Причина: xpp |
|
30.03.2007, 11:57 | #5 |
Moderator
|
|
|
30.03.2007, 12:01 | #6 |
Участник
|
Ура!!! Заработало!..
Цитата:
PHP код:
Цитата:
Parameters
Field Optional Object. The integer offset of the field on which you want to base the filter (from the left of the list; the leftmost field is field one). Последний раз редактировалось gl00mie; 30.03.2007 в 12:08. |
|
30.03.2007, 12:04 | #7 |
Участник
|
Автофильтр на колонки ставится отдельно на каждую. В качестве "отлаженной процедуры" я, по правде сказать, ограничился кодом в консоли отладчика Excel, который и привел в первом сообщении.
|
|
30.03.2007, 12:22 | #8 |
Участник
|
Интересно, что вот так тоже работает без указания дополнительных параметров
X++: f = new COMDispFunction(r, "AutoFilter", COMDispContext::METHOD); f.call() |
|
30.03.2007, 12:25 | #9 |
Moderator
|
Не очень догоняю... Речь идет о том, чтобы наложить условия на отдельные колонки после того, как режим автофильтра включен в принципе? Т.е. у всех колонок области уже есть "стрелочки" и мы некоторые из них делаем "голубыми". Так?
|
|
30.03.2007, 12:32 | #10 |
Участник
|
Пардон, это я напутал Колонки идут подряд, и автофильтр накладывается на диапазон, включающий эти колонки. Т.е. мне просто нужно было, чтобы у колонок появились «стрелочки».
|
|
30.03.2007, 12:43 | #11 |
Moderator
|
|
|
30.03.2007, 16:28 | #12 |
Участник
|
В продолжение темы взаимодействия с Excel... Захотел я вычислять диапазон ячеек для Range в формате A1 на основании адреса левой верхней ячейки и количества строк/столбцов в диапазоне. Конечно, удобнее это делать для адресов в формате R1C1, но у Excel.Application есть чудесный метод ConvertFormula(), позволяющий в т.ч. преобразовывать адреса между форматами A1 и R1C1.
PHP код:
Цитата:
Parameters
Formula Required Object. A String that contains the formula you want to convert. This must be a valid formula, and it must begin with an equal sign. FromReferenceStyle Required XlReferenceStyle. The reference style of the formula. XlReferenceStyle can be one of these XlReferenceStyle constants: xlA1 xlR1C1 ToReferenceStyle Optional XlReferenceStyle. The reference style you want returned. If this argument is omitted, the reference style isn't changed; the formula stays in the style specified by FromReferenceStyle. X++: #define.xlRefStyleA1 (1) #define.xlRefStyleR1C1 (-4150) //(0xffffefca) // _rows, _cols - dimensions of the range area // _bookmark - the upper-left corner of the range protected Bookmark getXlRangeAddress(Bookmark _bookmark, int _rows, int _cols) { COM range; COM app; str strAddr; str strRet; ; if(!excel) throw error("@SYS54192"); if(_rows<1 || _cols<1) throw error(error::wrongUseOfFunction(funcname())); range = excel.my_findRange(_bookmark); strRet = range.address(); if(_rows>1 || _cols>1) { app = range.application(); // convert _bookmark's upper-left cell address to R1C1 format strAddr = app.convertFormula(strRet, #xlRefStyleA1, #xlRefStyleR1C1); if(!strAddr) throw error(@"Ошибка при вызове Application.ConvertFormula!"); strAddr = strAddr + @":R" + int2str(range.row()+_rows-1) + @"C" + int2str(range.column()+_cols-1); strRet = app.convertFormula(strAddr, #xlRefStyleR1C1, #xlRefStyleA1); } return strRet; } X++: strAddr = app.convertFormula(strRet, #xlRefStyleA1); PHP код:
Код: $J$4 == R4C10 R4C10:R27C11 == $J$4:$K$27 Последний раз редактировалось gl00mie; 30.03.2007 в 16:32. |
|
30.03.2007, 16:50 | #13 |
Участник
|
Нашелся вроде бы обходной вариант с использованием методов colName2Num() и num2NameCell() класса ComExcelDocument_RU, но все же интересно было бы разобраться с этой Application.ConvertFormula()
|
|
30.03.2007, 17:07 | #14 |
Moderator
|
А что сделать в задачке надо физически? Реанимировать формулы в нотации R1C1 после вывода из Аксапты в Excel? Если да, то я использую вот такую мулю:
X++: rng.FormulaR1C1( rng.Value2() );
// кстати, повторным использованием можно превратить формулы в значения |
|
30.03.2007, 17:19 | #15 |
Участник
|
А тут, как раз таки, надо воспользоваться COMDispFunction
X++: Com sheet; Com Range; COMDispFunction f; str s; COMVariant varArg1 = new COMVariant(); COMVariant varArg2 = new COMVariant(); COMVariant varArg3 = new COMVariant(); COMVariant varArg4 = new COMVariant(); COMVariant varArg5 = COMVariant::createNoValue(); COMVariant varRet = new COMVariant(COMVariantInOut::OUT_RETVAL, ComVariantType::VT_ERROR); ; Range = sheet.range("D10:AK258"); s = Range.Address(true, true, -4150); info(s); f = new COMDispFunction(app, "ConvertFormula", ComDispContext::Method); varArg1.bStr(s); varArg2.int(-4150); varArg3.int(1); varArg4.int(1); f.call(varArg1, varArg2, varArg3, varArg4, varArg5, varRet); info(varRet.bStr());
__________________
Axapta v.3.0 sp5 kr2 |
|
30.03.2007, 18:37 | #16 |
Moderator
|
Хм... а у меня как-то просто через COMVariant всё получилось..
X++: static void Job_TestExcelConvertFormula(Args _args) { COM xlApp; // Excel.Application COMVariant cv; ; xlApp = new COM('Excel.Application'); cv = xlApp.ConvertFormula('$A$1:$B$20', 1, -4150); info(cv.bStr()); // R1C1:R20C2 cv = xlApp.ConvertFormula('R1C1:R20C2', -4150, 1); info(cv.bStr()); // $A$1:$B$20 } |
|
|
За это сообщение автора поблагодарили: gl00mie (5). |
|
Похожие темы | ||||
Тема | Ответов | |||
Построчный импорт из Excel через COM | 20 | |||
Ошибка COM-объекта | 15 | |||
Ошибка com 0x800A9C68 | 2 | |||
Работа с Excel через COM в DAX 4.0 | 4 | |||
DLL (BarCode) через COM | 4 |
|