Форум » 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 Как нужно правильно сделать ?

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

Andrey: Вот есть вариант что предлагал Григорий (только я заменил CreateObject) : [pre2] IF ( oExcel := win_oleCreateObject( "Excel.Application" ) ) == NIL MsgStop( "Excel not available. [" + win_oleErrorText() + "]", "Error" ) RETURN Nil ENDIF[/pre2] Можно его использовать, или по другому надо ?

PSP: Ну, эта конструкция сработает, если будет RTE при вызове win_oleCreateObject. А в твоем случае переменная oExcel получает значение NIL, т.е. никакой RTE не возникает. Проверяй значение oExcel.

PSP: Andrey пишет: Вот есть вариант что предлагал Григорий (только я заменил CreateObject) : Можно его использовать, или по другому надо ? Именно так.


Andrey: PSP пишет: Проверяй значение oExcel. А при отсутствии Экселя переменная oExcel := win_oleCreateObject( "Excel.Application" ) действительно равна NIL !

Dima: Andrey пишет: Можно его использовать, или по другому надо ? Хотя бы как в этой теме Start_Excel (только его надо переделать под твои нужды) http://clipper.borda.ru/?1-4-0-00000876-000-0-0-1373554002

Andrey: PSP пишет: Именно так. СПАСИБО !

Andrey: __oleVariantNew() - это что то .... Таблица из 25000 строк в Эксель экспортируется за 8 сек. Стандартный метод ExcelOle() делает эту операцию за 58 сек.

Andrey: Есть ли возможность перенести код из Экселя:[pre2] cRange := "A" + LTrim(Str(nStart))+":" + Chr( 64 + nColDbf) + LTrim( Str( nLine -1) ) oRange:=oSheet:Range(cRange):Value := __oleVariantNew( WIN_VT_VARIANT, aSet, nIndexaSet, nColDbf ) [/pre2] для Ворда ? Есть ли такой метод в Ворде ?

Pasha: Нет. В ворде есть только методы insertafter/insertbefore, которым можно передать в качестве параметра только текст, а никак не значения типа Variant или массив

Andrey: А как тогда можно ускорить процесс переноса таблицы в Ворд ? Т.е. отказаться от буфера обмена...

Pasha: Думаю, что через буфер обмена как раз и будет самый быстрый способ. Не по ячейкам же заносить текст.

Andrey: А если типа так сделать:[pre2] var range = doc.Paragraphs(doc.Paragraphs.Count).Range; range.Text = "1,data12,data13\n"+ "1,data22,data23\n"+ "1,data32,data33\n"+ .......... "1,data22,data23\n"+ "1,data32,data33\n"; var table = range.ConvertToTable(",",1,3);[/pre2] https://msdn.microsoft.com/ru-ru/vba/word-vba/articles/range-converttotable-method-word Быстрее будет, чем через буфер обмена ?

Pasha: Andrey пишет: Быстрее будет, чем через буфер обмена ? Я не пробовал ни через буфер обмена, ни с помощью этого фокуса. О таком фокусе только что и узнал. Наверное речь тут пойдет уже не о скорости, а о применимости такого метода. Одно дело заполнять уже существующую таблицу с готовым форматированием, и совсем другое - автоматически формировать новую таблицу вызовом метода ConvertToTable. А как же шрифт, выравнивание, границы и прочее ? После автоформирования таблицы еще и задавать необходимые свойства ячеек ? Накладно получится.

Pasha: В word есть такая функция: Преобразовать в таблицу. Это тот же метод ConvertToTable. только с заданием параметров в диалоге. Поиграйся с этой функцией, оцени, насколько она пригодна. На мой взгляд так не очень.

Andrey: Pasha пишет: Одно дело заполнять уже существующую таблицу с готовым форматированием, и совсем другое - автоматически формировать новую таблицу вызовом метода ConvertToTable. А как же шрифт, выравнивание, границы и прочее ? После автоформирования таблицы еще и задавать необходимые свойства ячеек ? Накладно получится. В Ворд как то это всё хитро работает, без пробы и не поймёшь. Сейчас уже испытал заполнение таблицы:[pre2] ////////// таблица с автоподстройкой по ширине странице (вариант 1) ////////////// oTbl:= oWord:ActiveDocument:Tables:Add(oRange,nRowDbf,nColDbf,wdWord9TableBehavior,wdAutoFitContent)[/pre2] и [pre2] ///////// таблица без автоподстройки по ширине странице (вариант 2) //////////// oTbl:= oWord:ActiveDocument:Tables:Add(oRange,nRowDbf,nColDbf,wdWord8TableBehavior,wdAutoFitFixed)[/pre2] Всё равно потом приходиться менять ширину колонок таблицы. Напрямую - как ширина колонок в таблице Tsbrowse (источник данных) сделать нельзя, так как экспорт в Ворд задаю как правило другим размером шрифта. Из за этого и приходиться пропорционально ставить ширину колонок в Ворде всегда. Эта операция быстрая. Вот что касается переноса шрифтов, цвета из таблицы Tsbrowse (источник данных) в документ Ворда, то это да - операция "тормоз". Пройтись по каждой ячейки таблицы Tsbrowse потом перенести в Ворд - ! А если 10 тыс.записей таблица ? Тушите свет. Но есть вариант ускорения. Испытал уже на Экселе и Ворде. В Экселе вообще это быстро происходит. Таблица из 1000 строк. [pre2]HBOLE.LIB экспорт таблицы через буфер обмена одним шрифтом - 00:00:03 HBOLE.LIB экспорт таблицы и перенос цветов и фонтов каждой ячейки - 00:00:44 HBWIN.LIB экспорт таблицы по 100 строк __oleVariantNew() одним шрифтом - 00:00:00 HBWIN.LIB экспорт таблицы и перенос цветов и фонтов по строкам/блокам - 00:00:06[/pre2] В Ворде чутот помедленнее происходит, да и ещё не доделал...

Pasha: Я в word обычно делаю в бланке таблицу с одной (или несколькими) строками с уже готовым форматированием, а затем добавляю нужное мне количество строк вызовом метода InsertRowsBelow().

Andrey: Сделал тест для Ворда. Таблица из 1000 строк. [pre2]HBOLE.LIB экспорт таблицы через буфер обмена одним шрифтом - 00:00:10 HBOLE.LIB экспорт таблицы и перенос цветов и фонтов каждой ячейки - 00:40:44 [/pre2] Т.е. 40 минут требуется для того чтобы перенести цвета и фонты на таблицу из 1000 строк. Ужас сколько времени.

Pasha: Андрей, я посмотрел ваш пример работы с Excel Маленький совет по оптимизации Такой код: oSheet:Cells( nLine, nColHead ):Value := uData oSheet:Cells( nLine, nColHead ):Font:Name := aFont[ 1 ] oSheet:Cells( nLine, nColHead ):Font:Size := aFont[ 2 ] oSheet:Cells( nLine, nColHead ):Font:Bold := aFont[ 3 ] можно написать немного по другому: oRange := oSheet:Cells( nLine, nColHead ) oRange:Value := uData oFont := oRange:Font oFont:Name := aFont[ 1 ] oFont:Size := aFont[ 2 ] oFont:Bold := aFont[ 3 ] В первом случае будет 4 обращения к oSheet, 4 вызова метода Cells, 4 промежуточных обращения к Range, 3 обращения к Font, и по одному к Value, Name, Size, Bold Во в втором случае - все по одному. Обращение к объектам и вызов методов ole - это межпрограммное взаимодействие, а это самая медленная операция. Различия по скорости при выполнении в первом и втором случае думаю очевидны.

Pasha: Andrey пишет: Т.е. 40 минут требуется для того чтобы перенести цвета и фонты на таблицу из 1000 строк. Ужас сколько времени. Можно же эти действия делать не для каждой ячейки отдельно, а выделить некую область (например, колонку таблицы, одну или несколько), и устанавливать для нее соответствующие свойства. Или установить свойства по умолчанию для всей таблицы, а затем менять свойства только тех ячеек, если их значения отличны от значений по умолчанию. Значения же самих ячеек задавать через вставку из буфера обмена.

Pasha: В сырцах TSBrowse есть такое формирования адреса ячейки для Excel: cRange := Chr( 64 + ::aSuperHead[ nCol, 1 ] - nVar ) + LTrim( Str( nLine ) ) + ":" + ; Chr( 64 + ::aSuperHead[ nCol, 2 ] - nVar ) + LTrim( Str( nLine ) ) В том случае, когда номер колонки больше чем 26, адрес будет неправильный. Я для таких целей использую функцию ниже: Function ExcelAdr(nRow, nCol) Return if(nCol>26,Chr(Int((nCol-1)/26)+64),'')+Chr((nCol-1)%26+65) + LTrim(Str(Int(nRow))) и до кучи еще одну функцию (для адреса диапазона ячеек): Function ExcelAdr2(nRow1, nCol1, nRow2, nCol2) Return ExcelAdr(nRow1, nCol1) + ':' + ExcelAdr(nRow2, nCol2)

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, там в произвольных местах лезли непредсказуемые ошибки.

Andrey: Тестировал программу в Office 2003, 2007, 2010 - экспорт нормально работает. Поставил в Oracle VM VirtualBox Win7 32bit + Office 2016. Программа экспорта в Ворд работает отлично, БЕЗ ВЫЛЕТА !!! Если тестирую на Win10 64bit + Office 2016 на игровом компе (там 8 ядер, 32 ОЗУ), то программа продолжает вылетать. Может быть из-за того что комп не "офисный" ? Может и криво установлен Офис, с какими то дополнениями. Там доп.вопросы возникают - типа Word программа не по умолчанию. Вот такое сообщение: Т.е. нужно тестировать дальше программу на Office 2016 на других компах.

Andrey: Всем привет ! Выгружать больше 32767 строк в WinWord НЕЛЬЗЯ ! Ограничение WinWord 2003-2016. Выгружать больше 65533 строк в Excel НЕЛЬЗЯ ! Ограничение Excel 2003. В OO Calc и Excel 2007 - 2016 можно выгружать больше (сколько не уточнял), но появляется окно с предупреждением, которое чаще всего висит под моей программой, так как Экселем запущен в скрытом режиме. А Юзер и не видит это окно, и сразу претензия - программа висит и не работает. Замучился с этим. Как сделать, чтобы это окно можно было выводит на передний план ? Или есть возможность в коде, как то игнорировать такие предупреждения ? P.S. Кстати такие типовые предупреждения появляются и в Ворде и Экселе, если версии созданных документов не совместимы. Юзеру трудно объяснить, как с этим бороться. Хотелось что бы такие сообщения выводились на передний план экрана.

Pasha: Ээ. так есть же oExcel:DisplayAlerts, о котором здесь стотыщмильёнов раз говорилось

Dima: Pasha пишет: о котором здесь стотыщмильёнов раз говорилось та даже больше ))

Andrey: Pasha пишет: так есть же oExcel:DisplayAlerts, о котором здесь стотыщмильёнов раз говорилось Забыл про это... СПАСИБО !

Pasha: Андрей, я опять запустил твой демо с Excel 2016 Excel дуркует. Идут ошибки, каждый раз в разном месте: Error WINOLE/1006 Argument error: _SIZE (DOS Error -2146777998) Called from WIN_OLEAUTO:_SIZE(0) Called from BRW4XLSOLE(122) in module: Tsb4xlsOle.prg Error WINOLE/1006 Argument error: _SIZE (DOS Error -2146777998) Called from WIN_OLEAUTO:_SIZE(0) Called from BRW4XLSOLE(279) in module: Tsb4xlsOle.prg Error WINOLE/1009 No exported method: FONT (DOS Error -2147418111) Called from WIN_OLEAUTO:FONT(0) Called from BRW4XLSOLE(166) in module: Tsb4xlsOle.prg Error WINOLE/1008 No exported variable: BOLD (DOS Error -2147418111) Called from WIN_OLEAUTO:_BOLD(0) Called from BRW4XLSOLE(141) in module: Tsb4xlsOle.prg Error WINOLE/1007 Argument error: FONT (DOS Error -2147418111) Called from WIN_OLEAUTO:FONT(0) Called from BRW4XLSOLE(166) in module: Tsb4xlsOle.prg Правда один раз пример отработал до конца, обойдя все мины с обращениями к Font, Bold, Size и тому подобное. Я не удивлюсь, если завтра все заработает безупречно. И вопрос: Подскажите пожалуйста почему так происходит и как исправить ?

Andrey: Pasha пишет: Андрей, я опять запустил твой демо с Excel 2016 Excel дуркует. Идут ошибки, каждый раз в разном месте: А может от Офиса это зависит ? Попробуй на другом компе.... Я писал ранее: Тестировал программу в Office 2003, 2007, 2010 - экспорт нормально работает. Поставил в Oracle VM VirtualBox Win7 32bit + Office 2016. Программа экспорта в Ворд работает отлично, БЕЗ ВЫЛЕТА !!! Если тестирую на Win10 64bit + Office 2016 на игровом компе (там 8 ядер, 32 ОЗУ), то программа продолжает вылетать, но ТОЛЬКО Ворд вылетает. Эксель не вылетает ! Может быть из-за того что комп не "офисный" ? Может и криво установлен Офис, с какими то дополнениями. Там доп.вопросы возникают - типа Word программа не по умолчанию. Как программу эту доделаю (твою доработку тоже жду), то выложу для тестировки всем желающим.

SergKis: Andrey [pre2] Если исп. вместо oSheet:Cells( nLine, nColHead ):Value := uData // oSheet:Cells( nLine, nCol ):Borders():LineStyle := xlContinuous oSheet:Cells( nLine, nColHead ):Font:Name := aFont[ 1 ] oSheet:Cells( nLine, nColHead ):Font:Size := aFont[ 2 ] oSheet:Cells( nLine, nColHead ):Font:Bold := aFont[ 3 ] так oSCell := oSheet:Cells( nLine, nColHead ) ? procname(), procline(), oSCell // oSCell:Value := uData oCFnt := oSCell:Font ? procname(), procline(), oCFnt, aFnt[1], aFnt[2], aFnt[3] oCFnt:Name := aFont[ 1 ] oCFnt:Size := aFont[ 2 ] oCFnt:Bold := aFont[ 3 ] oSCell:Value := uData // переставить DoMessageLoop() // сначала без этой строки потом с ней [/pre2]

Andrey: SergKis пишет: Если исп. вместо Да у меня не вылетает вообще... Нужно Павла просить, чтобы попробовал. Pasha пишет: И вопрос: Подскажите пожалуйста почему так происходит и как исправить ? Ну блин, нашли кого спрашивать... Для меня вообще это загадки ...

Pasha: Запустил тест десяток раз. Один раз отработал до конца, остальные попытки дают вылеты в самых разных местах: при обращении к Font, Size, Cells, Name, Value Так что вряд ли такие изменения помогут. Не в одном, так в другом месте будет вылет. Причина непонятна. Как я уже говорил, сталкиваюсь с таким поведением последних версий Office не первый раз. Запустил свою программу, и прогнал различные варианты выгрузки в Excel. Вылет в некоторых случаях происходит, в некоторых нет.

PSP: Может не в тему, но навеяло: вспомните, как винда10 удаляет файл. Даже маленький. Такое впечатление, что сначала она его куда-то отправляет, а потом уже удаляет. Может и со свежими офисами такая же петрушка?

Dima: Pasha пишет: Вылет в некоторых случаях происходит, в некоторых нет. Та же фигня , но в версии 2003 все норм

Pasha: Плохая новость. Есть повод поднять темку. Моя винда с экселем с прошлого раза не глючит, но возникла другая проблема у клиента. Алгоритм у меня такой. В документе помечена строка в качестве шаблона (образца). Мне надо заполнить таблицу с данными, и для начала сделать копию этой строки энцать раз. Я это делаю незамысловатым копи-пасте в цикле: Function CopyExcelRows(oDoc, oSheet, cRow, nCount) Local nRow, nCopied := 1, nCopy, s1, cAdr // перемещение на строку oDoc:Goto(cRow) // адрес строки cAdr := oDoc:Selection:Address(.t.,, 1) s1 := 2 if ! (Substr(cAdr, 2, 1) >= '0' .and. Substr(cAdr, 2, 1) >= '9') s1 := At('$', Substr(cAdr, 2)) + 2 endif nRow := Val(Substr(cAdr, s1)) if nRow # 0 // копирование nCount строк while nCopied < nCount nCopy := Min(nCopied, nCount - nCopied) oSheet:Rows(StrTrim(nRow) + ":" + StrTrim(nRow + nCopy - 1)):Copy() oSheet:Rows(StrTrim(nRow+nCopied)+":"+StrTrim(nRow+nCopied)):Insert(-4121) // xlDown nCopied += nCopy enddo else Alert('Неверная закладка ' + cRow) endif Return nRow На злополучном компе эксель при копировании стал выдавать ошибку: "Рисунок слишком велик и будет усечен", и строки естественно не копируются. Хотя там копируется всего-то несколько десяток строк, и никакого рисунка не наблюдается. Поиск в гугле находит массу аналогичных жалоб на подобную ошибку, и обычные шаманские рекомендации как ее преодолеть.



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