Форум: "Основная";
Текущий архив: 2009.12.27;
Скачать: [xml.tar.bz2];
ВнизНужно получить кол-во Chart-ов в текущем Excel Sheet-е Найти похожие ветки
← →
du_hast (2008-12-24 19:23) [0]Привет всем!
Нужно получить кол-во 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 09:25) [1]В Delphi это будет выглядеть точно так же:
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
← →
du_hast (2008-12-25 11:49) [2]У меня
ExcelApplication: Excel2000._Application;iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
Если взять ваш код, то это выражение не правильно, т.к.ExcelApplication.ActiveSheet
возвращает IDispatch нужно преобразование к интервейсу _WorkSheet.
У интерфейса _WorkSheet имеется функция ChartObjects(Index: OleVarinat; lcid: integer): IDispatch которая уже сама по себе требует ввиде парметра индекс чарта. C Count она ни как не может иметь отношение.
Через эту функциб при помощи индекса можно добраться до самого чарта - но найти их кол-во нельзя!
Возможно Ваш объект ExcelApplication имеет иной тип?
← →
du_hast (2008-12-25 12:04) [3]Даже если брать
Var
Ex: TExcelApplication;
Ex.ActiveSheet возвращает интерфейс IDispatch
После преобразования имеем тоже самое
((Ex.ActiveSheet) as _Worksheet).ChartObjects(Index: OleVarinat; lcid: integer): IDispatch.
По этому в данном контексте выражение
iChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
Не имеет смысла
← →
Сергей М. © (2008-12-25 12:09) [4]Ах вон ты про что ..
Тут все просто.
СтрокаiChartsCount := ExcelApplication.ActiveSheet.ChartObjects.Count;
- это пример доступа к сабжу при позднем связывании
При раннем же связывании с использованием tlb та же строка должна выглядить чуть иначе:iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
Тот же результат достигается и иначеiChartsCount := SomeChartObject.ChartObjects(EmptyParam, 0);
← →
du_hast (2008-12-25 12:36) [5]Если бы это
iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
работало при раннем связывании, то компилятор его пропустил бы, но
он это не пропускает
← →
Сергей М. © (2008-12-25 13:03) [6]
> он это не пропускает
Что говорит ?
← →
du_hast (2008-12-25 13:12) [7]Всё, понял свою ошибку!
Нужно было использовать 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:34) [8]iChartsCount := SomeWorkSheetObject.ChartObjects(EmptyParam, 0);
Здесь SomeWorkSheetObject - диспинтерфейсный объект типа _WorkSheet, а не IDispath и не Olevariant !
← →
du_hast (2008-12-25 13:42) [9]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:51) [10]Пардон, вот так будет верно
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;
← →
Сергей М. © (2008-12-25 13:54) [11]Так же и везде и всюду - получили результатом IDispath, привели его к нужному типу (точнее - запросили у "безликого" диспобъекта конкретно интересующий интерфейс) - и вперед с песней !)
← →
Сергей М. © (2008-12-25 13:55) [12]
Var
count: integer;
wsh: _Worksheet;
FExcel: _Application;
Begin
WSH := FExcel.ActiveSheet as _WorkSheet;
count := ChartObjects(WSH.ChartObjects(EmptyParam, 0)).Count;
end;
← →
du_hast (2008-12-25 14:16) [13]Понял!
Я в принципе и раньше с этим выражением сталкивался:ChartObjects(WSH.ChartObjects(EmptyParam, 0)).Count
Но меня смущал параметра Index в методе ChartObjects(Index....
Я не знал что туда передать чтобы таким образом получить кол-во чартов.
Большое спасибо за помощь!
← →
Сергей М. © (2008-12-25 14:19) [14]
> не знал что туда передать чтобы таким образом получить кол-
> во чартов
А для этого нужно было всего лишь заглянуть в Excel_tlb.pas в реализацию метода
function TExcelWorksheet.ChartObjects: IDispatch;
← →
Сергей М. © (2008-12-25 14:25) [15]
> не знал что туда передать чтобы таким образом получить кол-
> во чартов
Не кол-во чартов тем самым возвращается..
При пустом первом параметре возвращается диспинтерфейс объекта-коллекции ChartObjects, при непустом - диспинтерфейс соотв. объекта-элемента этой коллекции ChartObject. Причем индексом, полагаю, может быть не только целое число, но и имя объекта-чарта (имена чартов в пределах коллекции-контейнера уникальны).
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2009.12.27;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.006 c