Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cells в QT при работе с MS Office
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Общие вопросы
Страницы: 1, 2
abra
Привет.
Здесь столкнулся с такой заботой.
QAxObject *range = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A1:B6"))); (выделяем диапозон для работы)
QAxObject *range = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A1"))) (выделяем 1 ячейку)
QAxObject *range = StatSheet->querySubObject( "Cells(const QVariant&)",QVariant(QString("1"))) ( выделяем 1 ячейку(аналог Cells(1,1))
QAxObject *range = StatSheet->querySubObject( "Cells(const QVariant&)",QVariant(QString("2"))) (выделяем вторую ячейку (аналог Cells(1,2))

Но у меня есть таблица БД.В ней поля.СЛедовательно,должна соблюдаться структура при выводе данных в Эксель

1 поле 2 поле 3 поле 4 поле 5 поле

Но!Как мне обратиться скажем к Cells(2,2)...или Cells(3,4)...Причем это обязательно нужно сделать через цифры (Cells(X,Y) (X,Y- целочисленные указатели на ячейки))
Потому что через A1 нельзя вызывать(в таком случае будет слишком мудрено вызываться ячейка B1)


________________________________________________________________________________
____________________________________________

Хм...Ребят,подождите...Сейчас одна идейка возникла...Может написать

QAxObject *range = StatSheet->querySubObject( "Cells(const QVariant&,const QVariant&)",QVariant(QString("2")),QVariant(QString("1")))

попробовать.........

________________________________________________________________________________
______________________________________________
Не помогло........

QAxObject *range = StatSheet->querySubObject( "Cells(const QVariant&;const QVariant&)",QVariant(QString("4")),QVariant(QString("8")));

Пишет значение в ячейку D1(принял первый параметр равный 4) :((((
Он почему то принимает только первый параметр,и всё.........

Какие будут предложения?
abra
Проблема решена)))

Может кому понадобится

QAxObject *range = StatSheet->querySubObject( "Cells(const QVariant&,const QVariant&)",QVariant(4),QVariant(8 ));

Вместо 4 и 8 можно использовать например i и j ,как входные параметры.
Rocky
abra, а можно вопросик? А как вообще начинать работу с офисом? Не подскажешь, может ссылки какие-нить, можно на английском. Сейчас сам вплотную подошел к этому: надо выгружать данные в Excel или word (не особо важно вочто). А чистый COM не хочется использовать....
ViGOur
abra, если не лень, то может и правда опишешь?
А то эта тема очень плохо освещена. :(

Заодно и в вику выложим, как и что там.
abra
Оу.Извините))))
Чот как то решил для себя проблему,описал вам её,так и не заходил больше.
Я вот сейчас вплотную занимаюсь работой с MS Office под QT на высоком уровне.Вот сейчас сам ищу статьи,но в инете их нет,поэтому писать самому приходится.

Для начала советую почитать вам вот это

http://hardclub.donntu.edu.ua/projects/qt/...s/qt-excel.html

Чтобы подключить библиотеку,вам необходимо в .pro файле (в каталоге с вашим проектом),дописать LIBS += -lqaxcontainer
Ну теперь собственно приступаем к кодингу.

#include <ActiveQt/qaxobject.h>
#include <ActiveQt/qaxbase.h>

    QAxObject *mExcel = new QAxObject( "Excel.Application",this);  //Это мы получаем указатель на Excel
    QAxObject *workbooks = mExcel->querySubObject( "Workbooks" ); //это на книги
    QAxObject *workbook = workbooks->querySubObject( "Open(const QString&)", "C:\\q\\1\\otchet.xls" ); //это на директорию,откуда грузить книгу
    QAxObject *mSheets = workbook->querySubObject( "Sheets" ); //это на листы(снизу вкладки)
    QAxObject *StatSheet = mSheets->querySubObject( "Item(const QVariant&)", QVariant("topic") ); //Это мы указываем,какой лист выбрать.У меня он называется topic.


Здесь идёт работа с макросами MS Office.

Скопировать данные из 1 ячейки в другую:

QAxObject *rangec = StatSheet->querySubObject( "Cells(const QVariant&,const QVariant&)",QVariant(2),QVariant(1)); /получаем указатель на ячейку,откуда будем копировать.
QAxObject *rangep = StatSheet->querySubObject( "Cells(const QVariant&,const QVariant&)",QVariant(3),QVariant(1)); / получаем указатель на ячейку,куда будем копировать.
rangec->dynamicCall("Copy()"); /осуществляем запрос на копирование.
rangep->dynamicCall("Select()"); ///выбираем ячейку,в которую будем вставлять данные
StatSheet->dynamicCall("Paste()");  ///вставляем.



Работа со шрифтами.Дополнение:

QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant("D2")); //Получаю указатель на D2
QAxObject *rangep = StatSheet->querySubObject("Cells(const QVariant&,const QVariant&)",QVariant(2),QVariant(2)); //получаю указатель на 2;2
(ну тут и Range можно,просто разные ячейки.В одной у меня текст забит,и я хочу получить,каким шрифтом он напечатан)
QAxObject *shrift = rangep->querySubObject("Font"); //ввожу новую переменную,обращаюсь к параметру Font(шрифт) в данной чейке(где у меня текст уже вбит(хотя можно и без текста))
QString lol = shrift->property("Name").toString(); // Возвращаю имя шрифта.
rangec->dynamicCall("setValue(const QVariant&)",QVariant(lol));// отображаю в D2 имя шрифта,который установлен в 2;2



Редактирование высоты,ширины строк или столбцов(вместо Rows указываем Columns,вместо RowHeight указываем ColumnWidth )

QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant("D2"));//опять же,указатель на D2
QAxObject *razmer = rangec->querySubObject("Rows"); //получаю указатель на строку
razmer->setProperty("RowHeight",34);// устанавливаю её размер.


Объединение ячеек:

QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("D2:D5")));//получаю указатель
rangec->dynamicCall("Select()");//выбираю их
rangec->dynamicCall("MergeCells",TRUE);//устанавливаю свойство объединения.


Вот еще сейчас покодил.Разрешает перенос:

QAxObject *rangep = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A5"))); //указатель на А5
rangep->dynamicCall("Select()"); //выбираю её
rangep->dynamicCall("WrapText",TRUE);//устанавливаю свойство разрешения переноса
rangep->dynamicCall("setValue(const QVariant&)",QVariant("This text is so long:)))WordWrap is working"));//Всё пашет :))))Сорри за мой английский)))


Вот еще накодил)))) Устанавливает положение текста.

QAxObject *rangep = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A5")));//указатель,как обычно)))
rangep->dynamicCall("Select()");//выбираю
rangep->dynamicCall("HorizontalAlignment",-4108);//по горизонтальной оси \\устанавливаю по центру.(Excel интерпретирует числовые значения положений в свои строковые.например xlCenter.)

Я здесь напишу основные.
Выравнивание по левому краю: -4131
Выравнивание по центру: -4108
Выравнивание по правому краю: -4152

Это для вертикального выравнивания:
QAxObject *rangep = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A5")));//указатель,как обычно)))
rangep->dynamicCall("Select()");//выбираю
rangep->dynamicCall("VerticalAlignment",-4160) //по вертикальной оси


Выравнивание по верхнему краю: -4160
Выравнивание по центру: -4108
Выравнивание по нижнему краю: -4107

Вот еще написал=)))

Удаление\добавление строк
QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("4:4")));
    rangec->dynamicCall("Select()");
    rangec->dynamicCall("Delete");

QAxObject *rangec1 = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("2:2")));
    rangec1->dynamicCall("Select()");
    rangec1->dynamicCall("Insert");


Удаление\добавление столбцов
QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("E:E")));
    rangec->dynamicCall("Select()");
    rangec->dynamicCall("Delete");

QAxObject *rangec1 = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("B:B")));
    rangec1->dynamicCall("Select()");
    rangec1->dynamicCall("Insert");


Обещаная работа с границами ячеек =)))
 QAxObject *rangec = StatSheet->querySubObject( "Range(const QVariant&)",QVariant(QString("A4")));//указатель на ячейку
    QAxObject *border = rangec->querySubObject("Borders(xlEdgeTop)"); //  xlEdgeTop(верхняя граница) (xlEdgeLeft) левая, (xlEdgeRight) правая,(xlEdgeBottom) нижняя и 2 диагонали (xlDiagonalDown) (xlDiagonalUp)
    border->setProperty("LineStyle",1); //тип линии (там пунктиры,сплошная и так далее)
    border->setProperty("Weight",2);  //толщина



Ну вот собственно на этом я наверно и завершу написание статьи по работе библиотеки QT c MS Office Excel. Далее задавайте вопросы,будем уже на конкретных примерах разбираться.
:)))
abra
Статью я постоянно редактирую(дополняю),по мере того,как кодю=)))

P.S Сейчас рассмотрю вопрос с границами ячеек,и на этом наверно закончу.Далее задавайте конкретные вопросы.Статью, я могу отредактировать,и можно на Вику выложить.
Litkevich Yuriy
супер!
abra
:) Спасибо.
ViGOur
abra, бросил твою статью в Faq нашей вики: Работе с MS Office с помощью ActiveQt

Если что, то можешь зайти в нее сам и поправить - добавить.
Имя пользователя и пароль в вики тот же, что ты входишь в форум.
abra
Хорошо.Только у меня просьба.Подправь пожалуйста заголовок.
А то там написано - РаботЕ,вместо РаботА
:)
Litkevich Yuriy
abra, ты можешь сделать это сам.
В верху страницы есть вкладки, щёлкни "Переименовать" и введи новое имя статьи.

только желателно залогинится в вики
ViGOur
Поправил...
abra
Цитата(Litkevich Yuriy @ 2.4.2009, 7:31) *
abra, ты можешь сделать это сам.
В верху страницы есть вкладки, щёлкни "Переименовать" и введи новое имя статьи.

только желателно залогинится в вики

Оке=)Буду знать.
Кстати,а вот там каждый человек может статью править.А акт вандализма никто не совершит?
Litkevich Yuriy
Цитата(abra @ 2.4.2009, 12:46) *
Кстати,а вот там каждый человек может статью править.А акт вандализма никто не совершит?
Да каждый. Вслучае вандализма всегда можно откатиться, вики - версионированная система, все правки сохраняются.
abra
Дополнение к статье:
Значения

Выравнивание по верхнему краю: -4160
Выравнивание по центру: -4108 (xlCenter)
Выравнивание по нижнему краю: -4107

и для остальных,которые содержат xl(указатель на Excel приложение), Вы можете взять из help`a в MS Office Excel
Наставник
Цитата(ViGOur @ 25.3.2009, 20:54) *
abra, если не лень, то может и правда опишешь?
А то эта тема очень плохо освещена. :(

Заодно и в вику выложим, как и что там.


Это все хорошо, но только надо заметить, что все это будет работать только в коммерческой версии QT.
igor_bogomolov
Цитата(Гость_Наставник_* @ 3.5.2009, 20:53) *
Это все хорошо, но только надо заметить, что все это будет работать только в коммерческой версии QT
Эт почему? Исходники activeqt входят в opensource версию, начиная с 4.5.0
Вот здесь (ссылка) ребята писали как этот модуль собрать.
Гость_abra
Вот и ответ получен=))))
Tonal
Включение исходников ещё не значит что они халявные:
Цитата
The ActiveQt modules are part of the Qt Full Framework Edition. They are not part of the Open Source Versions of Qt.

Из документации
Rocky
Всем привет!
Начал потихоньку разбираться с activeqt...
Хочу чутка дополнить пример со шрифтами:
Цитата
QAxObject *pFont = pCell->querySubObject("Font"); //получаем шрифт в выбранной ячейке
pFont->setProperty("Size", 15); //задаем размер шрифта
pFont->setProperty("Bold", bBold); //делаем его полужирным ...
pFont->setProperty("Italic", bItalic);
//... и курсивным

Цитата(abra @ 1.4.2009, 19:42) *
...Далее задавайте конкретные вопросы...

Возникла пара вопросов:
1. Как вставить картинку в ячейку?
2. Как создать новый workbook и в нем sheet с заданным именем?
3. Как изменить формат представления данных в ячейке? (например, я ввожу число "5.2" - а отображается "5 февраля")
4. Как изменить параметры страницы? (например, сделать лист альбомной ориентации, чтобы после вывода данных в excel пользователю в случае печати не нужно было ничего настраивать).

Если кто что знает, отпишитесь плиз )) Спасибо!
ViGOur
Цитата(Rocky @ 29.5.2009, 21:07) *
4. Как изменить параметры страницы? (например, сделать лист альбомной ориентации, чтобы после вывода данных в excel пользователю в случае печати не нужно было ничего настраивать).
На VBA это будет так:
   ' альбомная ориентация 
   ActiveSheet.PageSetup.Orientation = xlLandscape
   ' книжная ориентация
   ActiveSheet.PageSetup.Orientation = xlPortrait
следовательно, делаем примерно так:
QAxObject *mExcel = new QAxObject( "Excel.Application",this); 
QAxObject *workbooks = mExcel->querySubObject( "Workbooks" );
QAxObject *workbook = workbooks->querySubObject( "Open(const QString&)", "C:\\q\\1\\otchet.xls" );
QAxObject *mSheets = workbook->querySubObject( "Sheets" );
QAxObject *StatSheet = mSheets->querySubObject( "Item(const QVariant&)", QVariant("topic") );

QAxObject *pageSetup  = StatSheet ->querySubObject( "PageSetup");
// устанавливаем альбомную ориентацию
pageSetup->setProperty( "Orientation ", "xlLandscape");
код не проверял, но думаю должен работать. :)

Если работает, то можно будет данный код добавить в вики, как и твой.

p.s. будет время приведу пример, как сделать остальные пункты. :)
Rocky
Хе-хе )) работает ))
Rocky
Вспомнил что когда-то давно что-то писал на VBA. Вобщем, общая идея работы с ActiveQT - эта библиотека позволяет работать с любыми библиотеками/приложениями, поддерживающими COM. Список методов и свойств объектов можно посмотреть в tlb-хе соответствующего приложения (например, через OLEView). Если етсь *.tlh или idl-ник - можно и там напрямую через текстовые редакторы. В случае с Excel идеально помогает VBA. Запускаем Excel, жмем Alt+F11, пишем процедуру открытия книги например и там эксперементируем. По "F2" можно посмотреть список классов их методов и свойств. Выбираем метод - давим "F1", читаем как им пользоваться. Далее читаем документацию по функциям ActiveQt - querySubObject/dynamicCall/setProperty/property.

1. Как вставить картинку в ячейку?
На VBA будет так:
Worksheets(1).Shapes.AddPicture "filename.bmp", True, True, 100, 100, 70, 70

Пробовал переписать так:
QAxObject *pShape = pNewSheet->querySubObject("Shapes");
if (pShape)
{
           QAxObject *pShape2 = pShape->querySubObject("AddPicture(const QString&, bool, bool, int, int, int, int)", "filename.bmp", true, true, 100, 100, 70, 70);
           int z = 0;
}

не фурычит. pShape2 == NULL и картинка не грузица. В querySubObject если нужно вызывать функцию, нужно описать сигнатуру этой функции.. А сигнатура такая:
Function AddPicture(Filename As String, LinkToFile As MsoTriState, SaveWithDocument As MsoTriState, Left As Single, Top As Single, Width As Single, Height As Single) As Shape

Я много как пробовал: не хотит пока. Че писать пока не понял (особенно насчет MsoTriState)....

2. Как создать новый workbook и в нем sheet с заданным именем?

Создаем новую книгу (при этом совершенно необязательно что-то там открывать с диска)
QAxObject *pWorkbooks = m_pExcel->querySubObject("Workbooks");
if (!pWorkbooks)
{
         return NULL;
}

QAxObject *pWorkbook = pWorkbooks->querySubObject("Add");
if (!pWorkbook)
{
         return NULL;
}

QAxObject *pSheets = pWorkbook->querySubObject("Sheets");
if (!pSheets)
{
         return NULL;
}


Удалить листы можно так:
QAxObject *pSheet1 = pSheets->querySubObject("Item(const QString&)", qApp->tr("Лист1")); 
if (pSheet1) pSheet1->querySubObject("Delete");
QAxObject *pSheet2 = pSheets->querySubObject("Item(const QString&)", qApp->tr("Лист2"));
if (pSheet2) pSheet2->querySubObject("Delete");
QAxObject *pSheet3 = pSheets->querySubObject("Item(const QString&)", qApp->tr("Лист3"));
if (pSheet3) pSheet3->querySubObject("Delete");

Новый лист создать можно так:
//добавляем новый лист и обзываем его sSheetName
QAxObject *pNewSheet = pSheets->querySubObject("Add");
if (!pNewSheet)
{
          return NULL;
}
pNewSheet->setProperty("Name", sSheetName);



3. Как изменить формат представления данных в ячейке? (например, я ввожу число "5.2" - а отображается "5 февраля")
На VBA так:
Worksheets("Лист1").Range("A1").NumberFormat = "General"


На ActiveQT чет не особо работает. Поэтому решил проблему так:
//проверяем цифра ли sText или текст (чтобы заменить "." на ",")
bool bOK;
sText.toDouble(&bOK);

QString sText2 = sText;
if (bOK) sText2 = sText2.replace('.', ",");

//выводим в ячейку текст
pRange->dynamicCall("setValue(const QVariant&)", sText2);

//вот так пробовал, но формат особо не меняется
//pRange->setProperty("NumberFormat", "General");


4. Как изменить параметры страницы? (например, сделать лист альбомной ориентации, чтобы после вывода данных в excel пользователю в случае печати не нужно было ничего настраивать).

Вот так можно задать границы области печати (и задать ориентацию (собсно ка ViGOur писал выше)):
QAxObject *pPageSetup = pNewSheet->querySubObject("PageSetup");
if (pPageSetup)
{
          pPageSetup->setProperty("LeftMargin", 5);
          pPageSetup->setProperty("RightMargin", 5);
          pPageSetup->setProperty("TopMargin", 5);
          pPageSetup->setProperty("BottomMargin", 5);
          pPageSetup->setProperty("HeaderMargin", 5);
          pPageSetup->setProperty("FooterMargin", 5);
          pPageSetup->setProperty("Orientation", "xlLandscape");
}
Litkevich Yuriy
Цитата(Rocky @ 3.6.2009, 1:59) *
"I:\1\2\4.bmp"
заэкранируй слэши.
croc
А как получать массив значений определенного range?

Иногда ячейке назначено свойство контроля вводимых значений, иногда бывает полезно получить список допустимых значений, искомый обьект называется Validation и является членом класса Range, обратиться к нему можно так:

QAxObject *or = range->querySubObject("Validation"); 
//ссылка на обьект реализующий контроль вводимых значений

QString s = or->dynamicCall("formula1").toString();
//в формула этого обьекта и содержит знание о том какие значения в ячейке будут являться допустимыми, там правда еще formula2 есть, но она в моем случае была пуста.


Не удивительно что там окажется ссылка именнованного массива "Name" (=имя_именнованного_массива) член класса WorkBook или WorkSheet, по этому вот пример обращния к нему:

name = workbook->querySubObject("Names(const QVariant&)", QVariant(s));
//получаем ссылку на именованный массив

s = name->dynamicCall("RefersTo").toString();
//получаем ссылку на искомый массив
ViGOur
Добавил в вики.
croc, в случае чего, каждый участник форума может залогинится в вики, под тем же именем пользователя и паролем, что и на форуме.
admsasha
А как в открытом документе сделать "поиск и замена"

открыл, например test.doc, а дальше ?
    QAxObject word("Word.Application");
    word.setProperty("Visible", true);
    word.dynamicCall("Activate()");
    word.querySubObject("Documents")->querySubObject("Open(QVariant)", "c:\\test.doc");
arial
Цитата(abra @ 1.4.2009, 0:17) *
Вот еще накодил)))) Устанавливает положение текста.
...
Я здесь напишу основные.
Выравнивание по левому краю: -4131
Выравнивание по центру: -4108
Выравнивание по правому краю: -4152

Это для вертикального выравнивания:
...
Выравнивание по верхнему краю: -4160
Выравнивание по центру: -4108
Выравнивание по нижнему краю: -4107

Полный список констант можно найти здесь.
Конкретно по выравниванию:
Цитата
xlHAlignCenter -4108
xlHAlignCenterAcrossSelection 7
xlHAlignDistributed -4117
xlHAlignFill 5
xlHAlignGeneral 1
xlHAlignJustify -4130
xlHAlignLeft -4131
xlHAlignRight -4152
xlVAlignBottom -4107
xlVAlignCenter -4108
xlVAlignDistributed -4117
xlVAlignJustify -4130
xlVAlignTop -4160

admsasha
Открытие и печать документа

    QAxObject * word = new QAxObject("Word.Application");
    word->setProperty("DisplayAlerts", "0");
    word->querySubObject("Documents")->querySubObject("Open(QVariant)", "c:\\test.xml");
    word->querySubObject("ActiveDocument")->dynamicCall("PrintOut()");
    word->querySubObject("ActiveDocument")->dynamicCall("Close()");
    word->dynamicCall("Quit()");

ViGOur
Добавил в вики
Professor
Получение количества таблиц(sheet):
int sheet_count = [b]sheets_ascii[/b]->property("Count").toInt();


Получение количества использованных строк/столбцов:
QAxObject *usedRange = [b]sheet_ascii[/b]->querySubObject("UsedRange");
QAxObject *usedRows = usedRange->querySubObject("Rows");
QAxObject *usedCols = usedRange->querySubObject("Columns");


int rows = usedRows->property("Count").toInt();
int cols = usedCols->property("Count").toInt();
Chesterfilda
Доброго время суток!!!Очень полезная тема...
А не подскажете,как вот такой код на VBA:
Selection.QueryTable.Refresh BackgroundQuery:=False

можно переписать на Qt

Professor
Chesterfilda попробуйте добраться до объекта QueryTable и выполнить generateDocumantation().

Новые находки - доступ к символам внутри ячейки:
cell_ascii = sheet_ascii->querySubObject("cells(int,int)",i,j);
cell_ascii->dynamicCall("Select()");
char_ascii = cell_ascii->querySubObject("Characters(int,int)",s,l);
QChar char = char_ascii->property("Text").toString().at(0);
Chesterfilda
Чуть-чуть разобралась...
Только вот небольшая проблемка...
Есть такая функция:
IDispatch* Add (QVariant Connection, IDispatch* Destination, QVariant Sql)

,которая как раз-таки и создает QueryTable...
только не получается задать второй параметр этой функции,который указывает ячейку с которой начинается вставка данных.
В этом случае должна помочь
IDispatch* Range (QVariant Cell1, QVariant Cell2),но как-то не получается с помощью нее определить ячейку

Точнее никак не получается написть это на QT

    QAxObject *excel = new QAxObject( "Excel.Application",this); //получаем указатьтель на excel
    excel->dynamicCall( "SetVisible(bool)", TRUE ); //делаем его видимым
    QAxObject *workbooks = excel->querySubObject("Workbooks");
    QAxObject *workbook = workbooks->querySubObject("Open(const QString&)", "E:\\workspace\\test\\debug\\Отчет.xls");
    QAxObject *sheets=workbook->querySubObject("Sheets");
    QAxObject *statSheet=sheets->querySubObject("Item(const QVariant&)",QVariant("Лист1"));
    QAxObject *range=statSheet->querySubObject("Range(QVariant &)",QVariant(QString("A4")));
    //range->dynamicCall("Select()");
    QAxObject *table=statSheet->querySubObject("QueryTables");
    QAxObject *result=table->querySubObject("Add(QVariant &,IDispatch *,QVariant &)",QVariant(QString("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=E:\workspace\LS\release\data\oms_LS.mdb")),range,"select * from [result]"); //только сдесь не range нужно указать,а вот как обратится к ячейке в таком случае??

Chesterfilda
Нашла где-то на сайте:
Цитата
Если методу нужно передать аргумент типа IDispatch * или IUnknown *, то можно сначала инкапсулировать его в объект QAxObject, а затем вызвать метод asVariant(), чтобы преобразовать его в тип QVariant

Но это не помогает :-(...Если пишу:
QAxObject *result=table->querySubObject("Add(QVariant &,IDispatch *,QVariant &)",QVariant(QString("DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=E:\workspace\LS\release\data\oms_LS.mdb")),range->asVariant(),QVariant(QString("SELECT * FROM [result]")));

то выдает след ошибку:
QAxBase: Error calling IDispatch member Add: Exception thrown by server
Как же обратится к этой ячейке??
Professor
Chesterfilda а может вместо:
QAxObject *range=statSheet->querySubObject("Range(QVariant &)",QVariant(QString("A4")));
попробовать:
QAxObject *range=statSheet->querySubObject("Range(QVariant &)",QVariant(QString("A4:C8")));
Я не проверят но может сработает.
dim_san
Создаю документ ворда таким образом:

QAxWidget *activeX = new QAxWidget( );
activeX->setControl( "Word.Document" );
ui->verticalLayout->insertWidget(0, activeX );

при этом размещаю его в лайауте. Показывается документ как и надо (встроенный в мой виджет).
Можно ли каким-то образом достать вордовский тулбар и разместить его куда надо мне, например на основной тулбар моего приложения?
Или придется делать собственный?
arial
Цитата(dim_san @ 13.11.2009, 14:09) *
Можно ли каким-то образом достать вордовский тулбар и разместить его куда надо мне, например на основной тулбар моего приложения?
Или придется делать собственный?

Разобрался с этим вопросом?
dim_san
arial, неа.
Такое впечатление, что он пытается сам появиться, панелька пустая появляется и тут же исчезает.
Но теоретически это должно быть можно сделать, т.к. видел работающий пример на mfc вроде...

Кстати, меню вордовское формируется прямо в главном qt-шном окне, но оно не действует...
Rosster
Всем привет. А откуда вы берете все эти команды?
Open(const QString&)
Item(const QVariant&)
QAxObject *rangep = StatSheet->querySubObject( "Cells(const QVariant&,const QVariant&)",QVariant(3),QVariant(1));
rangec->dynamicCall("Copy()");
и так далее?
и еще:
получаем указатель на листы:
QAxObject *mSheets = workbook->querySubObject( "Sheets" );
а как узнать какие листы вообще в документе есть? Ибо возможности узнать название листа и вписать в прогу нету возможности (много разных документов имеются)
Спасибо
ViGOur
В microsoft Excel и Word есть замечательная вешь как макросы, с помощью них и можно это все делать.
А ActiveQt дает механизм работы с ними, а следовательно и манипулирования данными документами.

Смотришь как работает макрос, ставишь запись макроса и делаешь руками необходимые тебе действия, смотришь, что там записалось и затем переводишь в Qt. В принципе ничего сложно нет, если разобраться как работаю макросы. :)
Rosster
Цитата(ViGOur @ 23.11.2009, 21:02) *
В microsoft Excel и Word есть замечательная вешь как макросы, с помощью них и можно это все делать.
А ActiveQt дает механизм работы с ними, а следовательно и манипулирования данными документами.

Смотришь как работает макрос, ставишь запись макроса и делаешь руками необходимые тебе действия, смотришь, что там записалось и затем переводишь в Qt. В принципе ничего сложно нет, если разобраться как работаю макросы.

ну вот я и не понял как получить список листов, уже все перепробовал с этими макросами, все время пишется типа "Лист 1", "Лист 2", но сами названия то я не могу знать,мне как-то названия и надо получить в QT :)
ViGOur
Цитата
Узнать количество листов в книге можно в цикле по коллекции Workbook.Sheets.
Количество листов — свойство Sheets.Count.
Имя листа — свойство Worksheet.Name.


Попробуй руководствуясь данной цитатой набросать макрос в Excel, а потом перевести в Qt.
Была бы у меня винда сам набросал бы, но чего нет того нет. :)
Гость_dim_san_*
Цитата(Rosster @ 23.11.2009, 20:51) *
Всем привет. А откуда вы берете все эти команды?


по командам можно документацию сгенерировать:
http://www.doc.crossplatform.ru/qt/4.3.2/q...teDocumentation
MJIbIu
   
    QString fileName = QFileDialog::getOpenFileName(this, "Open");

    QAxObject *mExcel = new QAxObject( "Excel.Application",this);

    QAxObject *workbooks = mExcel->querySubObject( "Workbooks" );

    QAxObject *workbook = workbooks->querySubObject( "Open(const QString&)", fileName );

    QAxObject *mSheets = workbook->querySubObject( "Sheets" );

    QAxObject *StatSheet = mSheets->querySubObject( "Item(const QVariant&)", QVariant("1") );

    QAxObject* cell = StatSheet->querySubObject("Cells(QVariant,QVariant)", 1, 1);

    QVariant result = cell->property("Value");
    if (result.toString() != NULL)
        qDebug() << result.toString();
  
    delete cell;
    delete StatSheet;
    delete mSheets;
    delete workbook;
    delete workbooks;
    delete mExcel;

все бы ок тока вот у меня в системе висит процесс Excel.ехе и файл который я прочел пишет доступен тока для чтения и так с любой копией моего файла
MJIbIu
Цитата(MJIbIu @ 4.10.2010, 14:08) *
все бы ок тока вот у меня в системе висит процесс Excel.ехе и файл который я прочел пишет доступен тока для чтения и так с любой копией моего файла

workbook->dynamicCall("Close()");
mExcel->dynamicCall("Quit()");
breeve
Может кто подсказать, а если у меня в документе Word есть таблица(правда там есть еще пару строк текста до и после нее), тока как с ней работать. Мне бы, хотя бы узнать как получить данные из 1-ой ячейки этой таблицы.
breeve
Разобрался как доставать текст из таблицы. Но только из 1 элемента, пытаюсь вытащить из всей таблицы. У меня в таблице 3 колонки первые две он считывает должным образом. А вот переходя к 3-ей, он сразу же выдает ошибку.
code1
    mWord = new QAxObject(/*"Word.Application", this*/);
    mWord->setControl("Word.Application");
    mDocs = mWord->querySubObject( "Documents");
    mMyDoc = mDocs->querySubObject("Open(const QString&)", "C:\\timeTable.doc");

    mTimeTable = mMyDoc->querySubObject("Tables(1)");
    int rows = mTimeTable->querySubObject("Rows")->property("Count").toInt();
    int cols = mTimeTable->querySubObject("Columns")->property("Count").toInt();
    qDebug() << rows << cols;
    QStringList list[cols];
    const int b = 1;

    for(int j = 1; j < cols+1; j++)
    {
        for(int i = 1; i < rows+1; i++)
        {
           qDebug() << "i: " << i << "j: " << j;

           QAxObject *cell = mTimeTable->querySubObject("Cell(int, int)", i, j);
           qDebug() << 1;
           if(!cell)
           {
               if(i == rows || j == cols)
               {
                   qDebug() << "break";
                   break;
               }
               else
               {
                   qDebug() << "Continue";
                   continue;
               }
           }
           qDebug() << 2;
           QString str = cell->querySubObject("Range")->property("Text").toString();
           qDebug() << 3;
           if(str.isEmpty())
               list[j].append("Empty");
           else
               list[j].append(str);
           qDebug() <<3<<str;
           delete cell;
        }
    }

Вот вывод:
25 3
i: 1 j: 3
1
2
3
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
.. завершился с кодом 3

Еще появляеться MsgBox следующего содержания:
Microsoft Visual C++ Runtime Library
This application has requested th Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

У меня в таблице 3 колонки первые две он считывает должным образом. А вот переходя к 3-ей, он сразу же выдает ошибку.
Суть даже в том что если я делаю не в цикле а просто вытаскиваю определенный элемент из 3-го столбца то все в порядке.
code2
/    QAxObject *cell = mTimeTable->querySubObject("Cell(int, int)", QVariant(1), QVariant(3));
    qDebug() << cell->querySubObject("Range")->property("Text").toString();




Не могу понять в чем ошибка. И какой такой параметр передается в функцию не правильно.
Rocky
    for(int j = 1; j < cols+1; j++)
    {
        for(int i = 1; i < rows+1; i++)
        {


А если попробовать так:
    for(int j = 0; j < cols; j++)
    {
        for(int i = 0; i < rows; i++)
        {

?
breeve
Цитата(Rocky @ 20.2.2011, 14:57) *
А если попробовать так?

То в функции QAxObject *cell = mTimeTable->querySubObject("Cell(int, int)", i, j);
придется прибавлять единицу, поскольку отсчет элементов идет с единицы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.