Форум » GUI » Работа с Ole из HBWIN » Ответить

Работа с Ole из HBWIN

Andrey: Pasha пишет: [quote]после этого можно перейти на использование класса win_oleAuto из библиотеки hbwin, заменив строку oExcel := CreateObject( "Excel.Application" ) на win_oleCreateObject( "Excel.Application" ) Используя класс win_oleAuto, можно вместо передачи через буфер обмена передавать в Excel всю таблице одним вызовом __oleVariantNew() В принципе передача через буфер обмена фрагментами по 20к тоже работает быстро, но можно и делать это прямой записью. [/quote] Сделал такую конструкцию: [pre2]#xcommand TRY => BEGIN SEQUENCE WITH {|__o| break(__o) } #xcommand CATCH [<!oErr!>] => RECOVER [USING <oErr>] <-oErr-> ..... Try oExcel := win_oleCreateObject( "Excel.Application" ) Catch MsgStop( "Excel not available. [" + win_oleErrorText() + "]", "Error" ) Return Nil End[/pre2] В системе, где не установлен Эксель, не работает !!! Прога вылетает далее на обращении к oExcel:WorkBooks:Add()...: Error BASE/1004 No exported method: WORKBOOKS Called from WORKBOOKS(0) Called from BRW4XLSOLE(74) in module: Tsb4xlsOle.prg Как нужно правильно сделать ?

Ответов - 52, стр: 1 2 3 All

Andrey: Pasha пишет: Маленький совет по оптимизации Спасибо БОЛЬШОЕ ! Буду переделывать... Pasha пишет: Можно же эти действия делать не для каждой ячейки отдельно, а выделить некую область (например, колонку таблицы, одну или несколько) Да я выкинул этот алгоритм из Ворда, оставил в качестве примера для Экселя - там это шустрей происходит. И алгоритм переноса фонтов и цвета с таблицы Tsbrowse в Эксель и Ворд - делаю по блокам, т.е. по нескольким строкам. Скорость просто возросла на порядок ! Желающие потом сами могут протестировать, когда пример будет готов. Первая версия примера у Григория в библиотеке Tsb_Export.

Andrey: Тестировал Tsb_Export в Word 2003/2007/2010 - работает отлично. Под Word 2016 вылетает с ошибкой: Error WINOLE/1009 No exported method: BOOKMARKS (DOS Error -2147418111) Called from WIN_OLEAUTO:BOOKMARKS(0) Called from BRW4DOCOLE(102) in module: Tsb4DocOle.prg Called from TOWINWORD4(1237) in module: demo2.prg Called from (b)TABLEEXPORT(719) in module: demo2.prg Called from _DOCONTROLEVENTPROCEDURE(0) Вот код:[pre2] IF ( oWord := win_oleCreateObject( "Word.Application" ) ) == NIL cMsg := REPLICATE( "-._.", 16 ) + ";;" IF Hb_LangSelect() == "ru.RU1251" cMsg += "MS Word не доступен !;; Ошибка" cVal := "Ошибка!" ELSE cMsg += "MS Word is not available !;; Error" cVal := "Error!" ENDIF cMsg += " [ " + win_oleErrorText() + " ];;" cMsg += REPLICATE( "-._.", 16 ) + ";;" cMsg := AtRepl( ";", cMsg, CRLF ) MsgStop( cMsg , cVal ) RETURN Nil ENDIF oActive :=oWord:Documents:Add() oMarks := oActive:BookMarks // вот здесь 102 строка oText := oWord:Selection()[/pre2] Как исправить/изменить, чтобы работал код и в Word 2016 ?

Pasha: Andrey пишет: Как исправить/изменить, чтобы работал код и в Word 2016 ? Есть такая проблема. Сталкиваюсь с ней уже года три. Новые версии Office (2013, 2016) - вещь непредсказуемая. Хотят - работают, не хотят - не работают. У меня дома как раз стоит Word 2016. Дней 10 назад я проверял выгрузку в Word через dbedit, и вываливалась похожая ошибка, при обращении не к Bookmarks, а к Tables. Сейчас на том же компьютере запустил тот же dbedit - ошибки нет. Иногда возникают непонятные ошибки с последними версиями Excel


SergKis: Andrey пишет oActive :=oWord:Documents:Add() oMarks := oActive:BookMarks // вот здесь 102 строка oText := oWord:Selection() Вероятно oActive == NIL не объект, который не успел сформироваться, передаться. Попробуй сделать задержку inkeygui(100) \ DoMessageLoop() до получения объекта

Andrey: Pasha пишет: Новые версии Office (2013, 2016) - вещь непредсказуемая. Хотят - работают, не хотят - не работают. А попробуй пожалуйста пример, который я высылал тебе. Там выгрузка в Ворд - работает ?

Pasha: Andrey пишет: А попробуй пожалуйста пример, который я высылал тебе. Там выгрузка в Ворд - работает ? Сейчас работает. Но не факт, что завтра будет работать. У меня тоже сейчас работает, а 10 дней назад та же функция на том же компьютере с тем же word не работала.

Pasha: SergKis пишет: Вероятно oActive == NIL не объект, который не успел сформироваться, передаться. Попробуй сделать задержку inkeygui(100) \ DoMessageLoop() до получения объекта Это конечно вариант. Но помню году так в 15-м я сломал голову с ошибками при выгрузке в Excel 2013 на одном ноуте. Выгрузка иногда выполнялась до конца, а чаще нет, причем ошибки возникали каждый раз разные при обращении к различным объектам. Никакой закономерности я тогда так и не увидел.

PSP: SergKis пишет: Вероятно oActive == NIL не объект, который не успел сформироваться, передаться. Попробуй сделать задержку inkeygui(100) \ DoMessageLoop() до получения объекта Очень похоже, учитывая нестабильность ошибки. Нужна пауза.

Dima: PSP пишет: Очень похоже, учитывая нестабильность ошибки. Нужна пауза. При чем тут она ? Павел же пишет что при обращении к объектам. Не ставить же паузу перед каждой строкой при обращении........

Andrey: SergKis пишет: Вероятно oActive == NIL не объект, который не успел сформироваться, передаться. Попробуй сделать задержку inkeygui(100) Заработала в этом варианте ! Но в другом варианте нет - не заработало ! Там вызов другой, через переходник: [pre2] Try oWord := CreateObject( "Word.Application" ) Catch cMsg := REPLICATE( "-._.", 16 ) + ";;" cMsg += SPACE( 5 ) + "On this computer MS Word is not installed !;;" cMsg += SPACE( 5 ) + " Error code [" + win_oleErrorText() + "];;" cMsg += SPACE( 5 ) + " Error code [" + Ole2TxtError() + "];;" cMsg += REPLICATE( "-._.", 16 ) + ";;" cMsg := AtRepl( ";", cMsg, CRLF ) MsgStop( cMsg , "Error!" ) Return .F. End Try[/pre2] Ну хоть одно решение есть !!! Как пример закончу, то выложу для тестирования.

PSP: Dima пишет: При чем тут она ? Павел же пишет что при обращении к объектам. Не ставить же паузу перед каждой строкой при обращении........ Ошибка непостоянна. Это значит, что объект создается, но "не всегда вовремя") У Андрея задержка "сработала". Значит нужно учитывать эту особенность всегда.

SergKis: Dima пишет При чем тут она ? Павел же пишет что при обращении к объектам. Не ставить же паузу перед каждой строкой при обращении........ Там где формируется сторонний объект - придется ставить. проверка по valtype(...) != 'O' Помнится в "лохматых" годах 200 мсек было мало, ставили наверняка 500 мсек

Dima: PSP пишет: Ошибка непостоянна. Это значит, что объект создается, но "не всегда вовремя") ок

Pasha: Пока собрался ответить, колумбийцы забили гол :) Андрей, твой пример и у меня сваливался. Вяляется Errlog.htm: Date: 27.06.2018 Time: 22:01:28<BR> Time from start: 0 days 0 hours 0 mins 56 secs<BR> Error WINOLE/1009 No exported method: BOOKMARKS (DOS Error -2147418111) Called from TOLEAUTO:BOOKMARKS(0) У тебя идет обращение к Bookmarks сразу после oWord:Documents:Add() У меня последовательность другая: oDoc := oWord:ActiveDocument oSel := oWord:Selection oSel:Font:Name := 'Arial' oSel:Font:Size := 12 oSel:InsertAfter(cText) .. oDoc:Tables:Add(oSel:Range, 1, nColCount) здесь при обращении к Tables программа сваливается: Error description: Error Word.Application:ACTIVEDOCUMENT/1 Unknown error: TABLES то есть после создания документа удалось таки выполнить с ним несколько операций перед сваливанием

Pasha: Подумалось вот, что сразу после oWord:Documents:Add() oDoc := oWord:ActiveDocument не отработал, а oSel := oWord:Selection отработал. И операции с Selection затем выполнились, а как только было обращение к ActiveDocument, программа свалилась. Это все наводит на грустные мысли. При таком асинхронном выполнении команд может быть все что угодно. Скажем, после добавлении какого-нибудь объекта, например, таблицы, только что добавленная таблица может еще "не существовать", и пойдут ошибки.

Andrey: Pasha пишет: Это все наводит на грустные мысли. Согласен с этим, но на старых версиях всё работает. Эксель вообще пока без проблем. Нужно наверное под Word 2016 сделать отдельную ветку и всё. Как порекомендуешь это сделать ? [pre2] IF VAL( oWord:Version ) >= 16 // Word 2016 - не знаю точно прав ли я ? // ???? как здесь сделать ? ELSE oActive :=oWord:Documents:Add() oMarks := oActive:BookMarks oText := oWord:Selection() ENDIF[/pre2]

SergKis: Andrey пишет Согласен с этим, но на старых версиях всё работает. Эксель вообще пока без проблем Сплюнь, а то появится антивирус (не даст экселю работать) и будет без разницы версия ... старая, новая ...

Andrey: SergKis пишет: Сплюнь, а то появится .... Сплюнул....

SergKis: Andrey Ты этим очень помог экселю

Pasha: Andrey пишет: // ???? как здесь сделать ? Так причина же непонятна, вот и ответа нет. По доке метод Add должен вернуть объект, а он возвращает непонятно что, и дальнейшие операции с "этим" приводят к ошибке. Есть рекомендация Сергея по задержке, может она поможет. Хотя у меня были похожие проблемы и с Excel, там в произвольных местах лезли непредсказуемые ошибки.



полная версия страницы