![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Нужно получить кол-во Chart-ов в текущем Excel Sheet-е [WinXP]
du_hast © (2008-12-24 19:23:00)Привет всем!
Нужно получить кол-во Chart-ов в текущем Excel Sheet-е, чтобы потом обращаться к каждому и работать далее с ним.
В VBA это можно сделать так:
Sub x()
For i = 1 To ActiveSheet.ChartObjects.Count
ActiveSheet.ChartObjects(i).Name = i
Next i
End Sub
В Delphi можно обратиться к определённому Chart-у при помощи
ChartObjects() с послдующим преобразованием.
Но вот узнать кал-во Chart -ов я не нашол как.
Можно конечно в защищённом блоке попробовать перебирать все чарты по очереди пока не вывалится - но это не кузяво.
Кто-нибудь сталкивался с такой проблемой?
Сергей М. (2008-12-25 14:25:00) [1]
> не знал что туда передать чтобы таким образом получить кол-
> во чартов
Не кол-во чартов тем самым возвращается..
При пустом первом параметре возвращается диспинтерфейс объекта-коллекции ChartObjects, при непустом - диспинтерфейс соотв. объекта-элемента этой коллекции ChartObject. Причем индексом, полагаю, может быть не только целое число, но и имя объекта-чарта (имена чартов в пределах коллекции-контейнера уникальны).
Сергей М. (2008-12-25 14:19:00) [2]
> не знал что туда передать чтобы таким образом получить кол-
> во чартов
А для этого нужно было всего лишь заглянуть в Excel_tlb.pas в реализацию метода
function TExcelWorksheet.ChartObjects: IDispatch;
du_hast (2008-12-25 14:16:00) [3]Понял!
Я в принципе и раньше с этим выражением сталкивался:
ChartObjects(WSH.ChartObjects(EmptyParam, 0)).Count
Но меня смущал параметра Index в методе ChartObjects(Index....
Я не знал что туда передать чтобы таким образом получить кол-во чартов.
Большое спасибо за помощь!
Сергей М. (2008-12-25 13:55:00) [4]
Var
count: integer;
wsh: _Worksheet;
FExcel: _Application;
Begin
WSH := FExcel.ActiveSheet as _WorkSheet;
count := ChartObjects(WSH.ChartObjects(EmptyParam, 0)).Count;
end;
Сергей М. (2008-12-25 13:54:00) [5]Так же и везде и всюду - получили результатом IDispath, привели его к нужному типу (точнее - запросили у "безликого" диспобъекта конкретно интересующий интерфейс) - и вперед с песней !)
Сергей М. (2008-12-25 13:51:00) [6]Пардон, вот так будет верно
Var
count: integer;
wsh: _Worksheet;
FExcel: _Application;
Begin
WSH := FExcel.ActiveSheet as _WorkSheet;
count := ChartObjects(WSH.Var
count: integer;
wsh: _Worksheet;
FExcel: _Application;
Begin
WSH := FExcel.ActiveSheet as _WorkSheet;
count := ChartObjects(WSH.ChartObjects(EmptyParam, 0)).Count; // <<Error: Incompatible type "Integer" and "IDispatch"
end;
).Count;
end;
du_hast (2008-12-25 13:42:00) [7]Var
count: integer;
wsh: _Worksheet;
Excel: Excel2000._Application;
Begin
WSH := FExcel.ActiveSheet as _WorkSheet;
count := WSH.ChartObjects(EmptyParam, 0); // <<Error: Incompatible type "Integer" and "IDispatch"
end;
Сергей М. (2008-12-25 13:34:00) [8]iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
Здесь SomeWorkSheetObject - диспинтерфейсный объект типа _WorkSheet, а не IDispath и не Olevariant !
du_hast (2008-12-25 13:12:00) [9]Всё, понял свою ошибку!
Нужно было использовать OleVariant.
Var
WorkSheet: OleVariant;
WorkSheet := FExcel.Worksheets.Item[1] as _WorkSheet;
i := WorkSheet.ChartObjects.count;
А я использовал
Var
WorkSheet: _Worksheet;
Единственно, что хочу заметить сто позднее свзяывание не совсем удомбно, т.к.
я не знаю возможности объекта (так при раннем связывании я хоть знаю что объект может)
в принципе, как я ранее писал, можно было и спользовать и раннее связывание, тогда метод подсчёта кол-ва чартов выглядел бы так:
function TChartWorker.GetChartsCount(CurSheet: _Worksheet): integer;
Var ChartCount: integer;
bException: boolean;
begin
ChartCount := 0;
bException := false;
while not bException do
try
CurSheet.ChartObjects(ChartCount+1, 0) as ChartObject;
Inc(ChartCount);
except
bException := true;
end;
Result := ChartCount;
end;
Но это несовсем корректно, хотя и работает
Сергей М. (2008-12-25 13:03:00) [10]
> он это не пропускает
Что говорит ?
du_hast (2008-12-25 12:36:00) [11]Если бы это
iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
работало при раннем связывании, то компилятор его пропустил бы, но
он это не пропускает
Сергей М. (2008-12-25 12:09:00) [12]Ах вон ты про что ..
Тут все просто.
Строка
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
- это пример доступа к сабжу при позднемсвязывании
При раннем же связывании с использованием tlb та же строка должна выглядить чуть иначе:
iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
Тот же результат достигается и иначе
iChartsCount := Some ChartObject.ChartObjects(EmptyParam, 0);
du_hast (2008-12-25 12:04:00) [13]Даже если брать
Var
Ex: TExcelApplication;
Ex.ActiveSheet возвращает интерфейс IDispatch
После преобразования имеем тоже самое
((Ex.ActiveSheet) as _Worksheet).ChartObjects(Index: OleVarinat; lcid: integer): IDispatch.
По этому в данном контексте выражение
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
Не имеет смысла
du_hast (2008-12-25 11:49:00) [14]У меня
ExcelApplication: Excel2000._Application;
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
Если взять ваш код, то это выражение не правильно, т.к.
ExcelApplication.ActiveSheetвозвращает IDispatch нужно преобразование к интервейсу _WorkSheet.
У интерфейса _WorkSheet имеется функция ChartObjects(Index: OleVarinat; lcid: integer): IDispatch которая уже сама по себе требует ввиде парметра индекс чарта. C Count она ни как не может иметь отношение.
Через эту функциб при помощи индекса можно добраться до самого чарта - но найти их кол-во нельзя!
Возможно Ваш объект ExcelApplication имеет иной тип?
Сергей М. (2008-12-25 09:25:00) [15]В Delphi это будет выглядеть точно так же:
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;