30.03.2007, 16:28
|
#12
|
Участник
Регистрация: 28.11.2005
Адрес: Москва
|
В продолжение темы взаимодействия с Excel... Захотел я вычислять диапазон ячеек для Range в формате A1 на основании адреса левой верхней ячейки и количества строк/столбцов в диапазоне. Конечно, удобнее это делать для адресов в формате R1C1, но у Excel.Application есть чудесный метод ConvertFormula(), позволяющий в т.ч. преобразовывать адреса между форматами A1 и R1C1.
PHP код:
Function ConvertFormula( _
<InAttribute()> ByVal Formula As Object, _
<InAttribute()> ByVal FromReferenceStyle As XlReferenceStyle, _
<InAttribute()> Optional ByVal ToReferenceStyle As Object, _
<InAttribute()> Optional ByVal ToAbsolute As Object, _
<InAttribute()> Optional ByVal RelativeTo As Object _
) As Object
Цитата:
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.
Если заглянуть в Excel 11.0 Object Library (или просто нажать print xlR1C1 в отладчике Excel), то можно увидеть, что значение этой константы почему-то равно -4150 (0xffffefca). Непонятно, конечно, ну да ладно. Пишу такой вот код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;
} Здесь excel.my_findRange() - обертка для ComExcelDocument_RU.findRange(). Но app.convertFormula() всегда возвращает пустую строку! Если просто вызватьX++: strAddr = app.convertFormula(strRet, #xlRefStyleA1); то возвращает strRet, как и положено, не преобразуя из формата A1. При всем при этом тестовый VBScript замечательно отрабатывает
PHP код:
const xlRefStyleA1 = 1
const xlRefStyleR1C1 = -4150
const sBmk = "$J$4"
const cRows = 24
const cCols = 2
set oApp = CreateObject("Excel.Application")
strAddr = oApp.ConvertFormula(sBmk, xlRefStyleA1, xlRefStyleR1C1)
wscript.echo sBmk & " == " & strAddr
strAddr = strAddr & ":R" & (4+cRows-1) & "C" & (10+cCols-1)
wscript.echo strAddr & " == " & oApp.ConvertFormula(strAddr, xlRefStyleR1C1, xlRefStyleA1)
Код: $J$4 == R4C10
R4C10:R27C11 == $J$4:$K$27 Пробовал дополнительно указывать значение xlAbsolute (1) параметра ToAbsolute - эффект нулевой. Я что, неправильно задаю xlRefStyleR1C1? Может, отрицательное значение надо как-то по-другому передавать?..
Последний раз редактировалось gl00mie; 30.03.2007 в 16:32.
|
|