|  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 | |||
| 
 |