Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.127.232] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Задача вроде бы не сложная: вывести в TImage график из Excel. Для этого запускаю Excel через OLE и открываю в нем нужный мне файл с графиками:
Variant vVarApp, vVarBook, vVarBooks, vVarSheet, vVarSheets, charts; vVarApp = CreateOleObject("Excel.Application"); vVarApp.OlePropertySet("Visible",true); vVarBooks = vVarApp.OlePropertyGet("Workbooks"); vVarBooks.OleProcedure("Open","C:\\test.xls"); Далее начинается самое интересное. Непонятно, как обратиться к нужному мне листу по его имени? Например, лист называется ДМ, как его сделать активным? Как я понял, есть код для переключения между листами по индексу: vVarBook = vVarBooks.OlePropertyGet("Item",1); vVarSheets = vVarBook.OlePropertyGet("Worksheets"); vVarSheet = vVarSheets.OlePropertyGet("Item",2); vVarSheet.OleProcedure("Activate"); Этим кодом я перешел на Лист 2. Но дело в том, что у меня в документе листы идут так: Диаграмма1 | Лист 1 | Лист 2 | Лист 3 Так вот Лист 1, 2 и 3 мне удалось сделать активными, а как выбрать лист "Диаграмма1" вобще не понятно. |
Сообщ.
#2
,
|
|
|
vVarSheets.OlePropertyGet("Item","Диаграмма1"); не работает?
или vVarBook.OlePropertyGet("Worksheets","Диаграмма1"); |
Сообщ.
#3
,
|
|
|
Цитата trainer @ vVarSheets.OlePropertyGet("Item","Диаграмма1"); не работает? или vVarBook.OlePropertyGet("Worksheets","Диаграмма1"); Пробовал. Не работает. Текст ошибки: "Project raised exception class EOleSysError with message 'Неизвестное имя'" или 'Ошибка' в 1м варианте. |
Сообщ.
#4
,
|
|
|
попробуй так :
Variant vVarCharts = vVarApp.OlePropertyGet("Charts"); // либо vVarBook - поэксперементируешь Variant vChart = vVarCharts .OlePropertyGet("Item",1); |
Сообщ.
#5
,
|
|
|
popsa, отлично. Прогресс есть. Эксель открывается, копируется график и закрывается. Осталось решить два вопроса:
1. Как все-таки копировать график с определенного листа, зная его имя, а не по индексу. Вот так копируется первый график: vVarCharts = vVarApp.OlePropertyGet("Charts"); vChart = vVarCharts.OlePropertyGet("Item",1); vChartArea = vChart.OlePropertyGet("ChartArea"); vChartArea.OleProcedure("Copy"); Нашел один способ - перебирать все листы в цикле, пока не найдется нужный с именем. Но тут есть одна проблема - индексация листов и графиков может не совпадать, т.к. все идет по порядку и на 1м листе графика может небыть. Вот код перебора листов: Variant vSheetName; short nSheetIndex = 0; while (vSheetName != edSheet->Text) { nSheetIndex++; vVarSheets = vVarApp.OlePropertyGet("Sheets"); vVarSheet = vVarSheets.OlePropertyGet("Item",nSheetIndex); vSheetName = vVarSheet.OlePropertyGet("Name"); } vVarCharts = vVarApp.OlePropertyGet("Charts"); vChart = vVarCharts.OlePropertyGet("Item",nSheetIndex); vChartArea = vChart.OlePropertyGet("ChartArea"); vChartArea.OleProcedure("Copy"); 2. Столкнулся с одной помехой автоматизации. Т.к. весь процесс должен проходить невидимо для пользователя без вопросов и предупреждений, свойства Visible и DisplayAlerts выставляются в false. Но заметил такую закономерность: на простом документе без связей все отрабатывает нормально, но в документе, который имеет связи с другими документами при открытии задается вопрос (игнорируя DisplayAlerts), обновить ли связи. После закрытия этого диалога сразу же выдается ошибка "Runtime error '13': Type mismatch", которая ломает весь процесс автоматизации. Нашел, что Номер ошибки 13 означает "Недопустимые данные". А вот что именно недопустимое и как ее избежать? Добавлено Первый вопрос решил. Вот как: Variant vSheetName; short nSheetIndex = 0; while (vSheetName != edSheet->Text) { nSheetIndex++; vVarSheets = vVarApp.OlePropertyGet("Sheets"); vVarSheet = vVarSheets.OlePropertyGet("Item",nSheetIndex); vSheetName = vVarSheet.OlePropertyGet("Name"); } vVarSheet.OleProcedure("Select"); vChartArea = vVarSheet.OlePropertyGet("ChartArea"); vChartArea.OleProcedure("Copy"); Остается вопрос с ошибкой 13 (Run-time error). Интересно, что если открывать этот файл вручную, отвечая на вопрос об обновлении связей, то ошибка не появляется. Значит дело не в файле, а в скрипте. |
Сообщ.
#6
,
|
|
|
читал описание здесь ?
судя по vVarSheet=vVarBook.OlePropertyGet("Worksheets","Желтый лист"); тоже самое можно сделать и с диаграммой. По второму вопросу ничего сказать не могу |
Сообщ.
#7
,
|
|
|
Цитата Shad0FF @ Для того, чтоб он не задавался - есть свойство AskToUpdateLinks (там же, в Application). Сбрось его в False... в документе, который имеет связи с другими документами при открытии задается вопрос (игнорируя DisplayAlerts), обновить ли связи. |
Сообщ.
#8
,
|
|
|
Цитата Shad0FF @ Параметр UpdateLinks функции Open коллекции Workbooks установи в VARIANT_FALSE Но заметил такую закономерность: на простом документе без связей все отрабатывает нормально, но в документе, который имеет связи с другими документами при открытии задается вопрос (игнорируя DisplayAlerts), обновить ли связи. |
Сообщ.
#9
,
|
|
|
popsa, по идее должно быть вот так правильно:
Variant vVarApp,vVarBooks,vVarBook,vVarSheets,vVarSheet,vVarCells,vVarCell,vChartArea; vVarApp = CreateOleObject("Excel.Application"); vVarApp.OlePropertySet("Visible",true); vVarBooks = vVarApp.OlePropertyGet("Workbooks"); vVarBooks.OleProcedure("Open",edFile->Text.c_str()); vVarBook = vVarBooks.OlePropertyGet("Item",1); vVarSheet = vVarBook.OlePropertyGet("Worksheets","Диаграмма1"); vVarSheet.OleProcedure("Activate"); vChartArea = vVarSheet.OlePropertyGet("ChartArea"); Но на последней строчке выдает ошибку "Неизвестное имя". trainer volvo877 Установил, но все равно при открытии Ошибка 13 (run-time error) и еще после нее ошибка 1004 "Method 'cells' of object '_Global' failed. Может ли это быть из-за того, что у меня эксель 2003й (2007го под рукой нету чтоб проверить, вечером смогу посмотреть). |
Сообщ.
#10
,
|
|
|
Вчера проверял на 2007м офисе. На той машине все файлы есть, поэтому при открытии документа эксель не требует обновлять связи. Но ошибки все равно появляются. Как 13я так и 1004я. Начал эксперементировать. Вот весь код, который копирует график в буффер обмена и вставляет в моей проге в TImage:
Variant vVarApp, vVarBook, vVarBooks, vVarSheet, vVarSheets, vVarCharts, vChart, vChartArea; vVarApp = CreateOleObject("Excel.Application"); vVarApp.OlePropertySet("Visible",false); vVarApp.OlePropertySet("DisplayAlerts",false); vVarApp.OlePropertySet("AskToUpdateLinks",false); vVarBooks = vVarApp.OlePropertyGet("Workbooks"); vVarBooks.OleProcedure("Open",edFile->Text.c_str()); Variant vSheetName; short nSheetIndex = 0; while (vSheetName != edSheet->Text) { nSheetIndex++; vVarSheets = vVarApp.OlePropertyGet("Sheets"); vVarSheet = vVarSheets.OlePropertyGet("Item",nSheetIndex); vSheetName = vVarSheet.OlePropertyGet("Name"); } vVarSheet.OleProcedure("Select"); vChartArea = vVarSheet.OlePropertyGet("ChartArea"); vChartArea.OleProcedure("Copy"); Clipboard()->Open(); unsigned int ClipboardHandle = Clipboard()->GetAsHandle(CF_METAFILEPICT); if (ClipboardHandle != 0) imgGraph->Picture->LoadFromClipboardFormat(CF_METAFILEPICT, ClipboardHandle, 0); Clipboard()->Close(); vVarApp.OlePropertyGet("WorkBooks",1).OleProcedure("Close"); vVarApp.OleProcedure("Quit"); vVarSheets.Clear(); vVarApp.Clear(); Как выяснилось, если из кода убрать последние 4 строки, которые закрывают эксель, то все работает на УРА - ошибок нету, график копируется и отображается в TImage, только вот эксель остается висеть в памяти, но ошибок никаких не возникает. Я так понял, что все дело в том участке кода, где происходит открытие листа с графиком и копирование графика, т.к. код закрытия экселя написан правильно и врядле дело в нем. P.S. popsa, мне так и не получилось обращаться к листу по имени (код в предыдущем сообщении). При выполнении получаю ошибку. |
Сообщ.
#11
,
|
|
|
Цитата P.S. popsa, мне так и не получилось обращаться к листу по имени (код в предыдущем сообщении). При выполнении получаю ошибку. я думал, что это будет выглядеть так vVarSheet = vVarBook.OlePropertyGet("Charts","Диаграмма1"); не получиться, ковыряй дальше |
Сообщ.
#12
,
|
|
|
Цитата Shad0FF @ Только что проверил у себя на 2002/2003 Офисе (сделал файл, который берет Source Data для чарта из другого XLS-файла) - никаких ошибок не возникает, все открывается, без предупреждений, без ошибок, копирует картинку и заталкивает ее в TImage, закрывается... Не знаю уж что у тебя там за файлы, что они дают сбой...Вчера проверял на 2007м офисе. На той машине все файлы есть, поэтому при открытии документа эксель не требует обновлять связи. Но ошибки все равно появляются. Как 13я так и 1004я. Кстати, цикл я бы переделал на постусловие: String vSheetName; short nSheetIndex = 0; vVarSheets = XL.OlePropertyGet("Sheets"); // На кой ты это делаешь на каждой итерации? do { nSheetIndex++; vVarSheet = vVarSheets.OlePropertyGet("Item",nSheetIndex); vSheetName = vVarSheet.OlePropertyGet("Name"); } while(vSheetName != edSheet->Text); |
Сообщ.
#13
,
|
|
|
Макросы в файле или в загрузке случаем не присутствуют?
|
Сообщ.
#14
,
|
|
|
Всем огромнейшее спасибо!!! При использовании кода, кототорый предложил popsa ошибок не возникает. Но еще нужно протестировать работоспособность кода, т.к. заметил что раз было эксель не закрылся, а продолжал висеть в памяти.
volvo877, все-таки вариант с прямым обращением к графику более удобный. Кстате, да, выполнять vVarSheets = XL.OlePropertyGet("Sheets"); на каждой итерации не нужно и не правильно. trainer, макросы в файле присутствуют. Это может как-то влиять? |
Сообщ.
#15
,
|
|
|
Цитата Shad0FF @ Естественно. Особенно если выполнять макросы от более поздней версии на более ранней. макросы в файле присутствуют. Это может как-то влиять? |