Здравствуйте,
Работаю с большими текстами, и макрос работает над документом долго. Может кто знает, возможно ли сделать так, чтобы макрос работал с одним документом, а я в это время с другим?
На данный момент, когда я во время работы макроса переключаюсь в другой документ, макрос вылетает с ошибкой.
Макрос работает с ThisComponent. Может есть возможность указать что-то другое, чтобы макрос не переключался на новое окно, когда я перелючаюсь на другой документ?
Нашел пока выход такой, что запускаю OpenOffice Portable и работаю в нем. Или это единственный выход?
С уважением,
Сергей
виндов в переменную. Либо запускать второй процесс, как зависит от ОС.
а по сути работа объектов в ооо отвратительна, мсо пережил это еще в ексель 4 (уже не было), оно напоминает тупых программеров с вечным актив и селект...
StarDesktop.CurrentComponent:
http://wiki.services.openoffice.org/wiki/Currently_active_document
Но как я понял если его вызывать из отладчика - то будет указывать на отладчик!
Макрос который вставит слово "Привет!" во все открытые документы Writer:
REM ***** BASIC *****
Sub Main
N=StarDesktop.Frames.Count-1
p=chr(13)
Dim Doc(N) As Object, TK(N) As Object
For i=0 to StarDesktop.Frames.Count-1
If not isNull(StarDesktop.Frames(i).Controller) then
If StarDesktop.Frames(i).Controller.Model.supportsService("com.sun.star.text.TextDocument") then
Doc(i)=StarDesktop.Frames(i).Controller.Model
TK(i)=Doc(i).Text.createTextCursor()
TK(i).gotoEnd(FALSE)
TK(i).String=p+p+"Привет!"
Endif
Endif
Next
End Sub
Клио Вы не в теме
Цитата: serhiy.k от 12 августа 2010, 20:15Макрос работает с ThisComponent. Может есть возможность указать что-то другое, чтобы макрос не переключался на новое окно, когда я перелючаюсь на другой документ?
Вместо ThisComponent можно использовать StarDesktop.Frames(i).Controller.Model, при запуске макроса показывать диалог со всеми документами StarDesktop.Frames(i).Controller.Title, выбираете их по имени, и макрос будет с ним работать. См, к примеру, Table of Contents | OpenOffice.org repository for Extensions (http://extensions.services.openoffice.org/ru/project/zindex) ( там макрос запускается из меню, а не из диалога).
[вложение удалено Администратором]
А с чего это документ в переменной должен изменится? Или вы постоянно дёргаете ThisComponent?
dr.Faust - макрос может не один запускаться и не зависимо от действий пользователя или опосредованно
извиняюсь Клео - в некоторых случаях можно и титулом идентифицировать конечно, но может быть масса доков с одним именем (конечно есть еще и пути и т.д.)
но вернее по всей видимости будет автору макрос в доке держать
Цитата: smaharbA от 13 августа 2010, 05:11dr.Faust - макрос может не один запускаться и не зависимо от действий пользователя или опосредованно
И что?
Запускается же он в активном документе. Заберите доку в переменную и всё. Какие проблемы? Что не так?
макрос может не один запускаться и не зависимо от действий пользователя или опосредованно
если не в доке процедура - будет болт при активном рыскании усера по докам
Цитата: smaharbA от 13 августа 2010, 10:24макрос может не один запускаться и не зависимо от действий пользователя или опосредованно
Ну и что?
Хорошо, если так непонятно попробую развернуть доказательство того, что это не имеет никакого отношения к вопросу:
1 Если макрос запускается из активного документа, он получит "правильный" ThisComponent, который можно забрать в переменную, после чего не важно рыскает ил юзер по активным докам.
2 Если макрос запускается не из активного документа, обращение к ThisComponent бессмысленно в принципе и соответственно так же всё-равно рыскает ли юзер по докам или нет. Вообще в этом случае вопрос превращается в нечто похожена "Почему не работает этот цикл - If a=0 Then a=1 ?" Ну как минимум, потому. что это не цикл:
- Алло, я туда попал?
- Не знаю. А куда вы целились?
3 Если макрос запускается с целью отличной от ThisComponent, то вообще не имеет никакой разницы чем занимается юзер.
В итоге имеем Марковскую цепочку, где "Вашпе никакой разницы что делает юзер!" - наше настоящие...
пункт 2 обычный подход, о чем в сабже и речь на все сотни процентов !
У меня этот макрос работает в одном документе (imacros.ods), и я могу открывать другой и работать в нем, причем в первом макрос продолжает работать.
Или я что-то не понял?
Sub SVP
Dim oDoc As Object, oSheet As Object, oCell As Object
oDoc=ThisComponent
oSheet=oDoc.Sheets.getByName("Лист1")
oCell=oSheet.getCellByposition(2,5)
For i=0 To 500
For k=0 To 500
oCell.setValue(i)
Next k
Next i
End Sub
[вложение удалено Администратором]
Цитата: convas от 13 августа 2010, 12:00У меня этот макрос работает в одном документе (imacros.ods), и я могу открывать другой и работать в нем, причем в первом макрос продолжает работать.
А чего бы ему не работать?
Цитата: smaharbA от 13 августа 2010, 11:10пункт 2 обычный подход, о чем в сабже и речь на все сотни процентов !
Возможно, возможно...
Цитата: dr.Faust от 13 августа 2010, 12:15А чего бы ему не работать?
А тогда из-за чего всё это обсуждение? В чём проблема?
Так в этом же и вопрос...
Всем большое спасибо. Не имел времени ответить раньше. Отпишусь тут, когда выберу какой-то из предложеных вами тут и в соседних темах способ.
Здравствуйте еще раз.
Попробовал несколько вариантов, чтобы дальше в макросе уже использовать oDocument:
oDocument = ThisComponent.getURL()
oDocument = ThisComponent.Title
oDocument = ThisComponent.CurrentController.Frame.Title
И во всех случаях получаю сообщение на этой строчке "Объект недоступен. Неверное использование объекта". Макрос запускаю из меню Сервис—Макросы—Управление макросами—OpenOffice.org Basic.
До этого использовал просто:
oDocument = ThisComponent
Возможно, я делаю что-то не так? Сам я не программист, макросы делаю из тех кусков кода и примеров других макросов, что нахожу в интернете.
В данном случае я имею в виду Типографику, так как на больших книжках она долго расставляет кавычки, а я бы за это время хотел делать что-то другое.
С уважением, Сергей
Ваш файл с неработающим макросом покажите.
PS.Правильно только:
oDocument = ThisComponent
Вот, например, макрос. Это другой, так как тот - слишком большой (Типографика для ООо), но в этом вылетает такая же ошибка, если я добавляю что-нибудь после ThisComponent
Sub RemoveEmptyParagraphs 'поиск и удаление одиночных пустых абзацев
Dim oDocument As Object
Dim oReplace As Object
oDocument = ThisComponent
oReplace = oDocument.createReplaceDescriptor
oReplace.SearchString = "^$" 'регулярное выражение, пустой абзац
oReplace.ReplaceString = "" 'заменяем ничем, то есть, удаляем
oReplace.SearchRegularExpression=True 'использовать регулярное выражение
oReplace.searchAll=True 'обработать весь документ
REM Выполнить макрос!
oDocument.replaceAll(oReplace)
End Sub
ЦитироватьPS.Правильно только:
Код:
oDocument = ThisComponent
Это значит, что невозможно работать с другим документом, пока макрос работает над первым?
У меня никакой ошибки не вылетело с Вашим макросом на документе в 1169 страниц, 8820 абзацев, при переключении на работу с другим документом.
Пришлось, правда переключаться очень быстро, т.к. макрос тоже очень быстро отработал.
Хотелось бы увидеть Ваш документ полностью.
Вы пробовали с моим тестовым макросом из Ответа#12 на Calc? У Вас работает или нет?
PS. Может, конечно, работать на Calc'е и не работать на Writer'е. Поэтому нужен аналогичный тестовый макрос для Writer.
Тестовый макрос для Writer:
Sub prnt()
Dim oText
Dim vTextCursor
Dim i As Integer
Dim Chaine$
oDocument = ThisComponent
oText = oDocument.Text
vTextCursor = oText.createTextCursor()
For i = 1 To 20000
Chaine=CStr(i) & " "
oText.insertString(vTextCursor, Chaine, TRUE)
Next i
MsgBox "Finished"
End Sub
Этот макрос работает в одном документе, Вы работаете в другом - никаких проблем.
Цитата: serhiy.k от 23 сентября 2010, 09:02Это значит, что невозможно работать с другим документом, пока макрос работает над первым?
oDocument = ThisComponent - это тот документ, из которого запускается макрос - запускаете макрос в нужном документе, а затем переключаетесь на другой и там делаете что хотите. В макросе oDocument будет указывать на тот документ, из которого вы его запустили, независимо от того, какой документ сейчас является активным.
Клио - а если макрос не документа ? или макрос из другого документа ?
не было и нет объектной модели в ООо
Господа, давайте подкреплять свои мнения (или сомнения) конкретными примерами.
Цитата: smaharbA от 23 сентября 2010, 13:09Клио - а если макрос не документа ? или макрос из другого документа ?
Макрос может хранится в документе а может в профиле OOo. В любом случае, когда вы его запускаете, ThisComponent указывает на активный документ. Запустить макрос, который хранится в другом документе, по-моему, нельзя, т.к. его не видно среди макросов из меню Сервис/Макросы/Выполнить макрос... Там только макросы активного документа и макросы который хранятся независимо от документов. (в предыдущем сообщении имелось ввиду что макрос запускается из документа, т.е. через меню Сервис/Макросы/Выполнить макрос... активного документа)
В тестовом макросе для Writer можно строчку
Chaine=CStr(i) & " "
заменить на
Chaine=CStr(i) & Chr(10) & ThisComponent.getURL() & Chr(10) & ThisComponent.Title & Chr(10) & ThisComponent.CurrentController.Frame.Title & Chr(10) & " "
чтобы посмотреть, на какой документ ссылается ThisComponent в макросе.
PS. Особенно интересно во время выполнения макроса сохранить документ под другим именем (Файл - Сохранить как ...).
Цитата: smaharbA от 23 сентября 2010, 13:09Клио - а если макрос не документа ? или макрос из другого документа ?
И что? oDocument от этого не изменится. Какой бы документ не был бы в него передан из ThisComponent.
Цитата: smaharbA от 23 сентября 2010, 13:09не было и нет объектной модели в ООо
Это как?
Да и не относится ThisComponent к объектной модели - это функция Бэйсик де-факто.
Цитата: Клио от 23 сентября 2010, 13:33В любом случае, когда вы его запускаете, ThisComponent указывает на активный документ.
?
Если макрос в документе, то ThisComponent указывает на тот документ в котором макрос, даже если он не активный.
мможно узнать понятие активного документа точнее ?
всегда ругал и буду за использование Active... и Selection... в МСО
в ООо все гораздо хуже...
Доказывать ничего никогда не стану - идите на обработку сотен документов (хотя бы) там осознаете
Вот пробный макрос:
Sub testMacro
Dim vSearch
Dim vFound
Dim oCursor
Dim oText
oDoc = ThisComponent
' создаем дескрипторы поиска.
vSearch = oDoc.createSearchDescriptor()
vSearch.SearchString = " " 'определяем, что искать, в данном случае двойной пробел
' создаем дескриптор найденного
vFound = oDoc.findFirst(vSearch)
Do While Not IsNull(vFound) 'циклические поиск и замена пока есть хоть один двойной пробел
If IsNull(vFound) Then
'если больше не найдено, выходим
Exit Do
Else
vFound.setString("test ") 'заменяем найденный двойной пробел одинарным
oCursor = vFound.Text.createTextCursorByRange( vFound )
Wait 500
vFound = ThisComponent.findFirst(vSearch) 'ищем опять
End If
Loop
Beep
MsgBox ("Done!")
End Sub
Он заменяет двойной пробел словом "test". Чтобы не было слишком быстро, добавил команду ожидания полсекунды.
Есть два документа, каждый с пробелами. Запускаю макрос из одного документа, меняет там. Переключаюсь на другой документ, меняет пробелы в другом ???
Строка
oDoc = ThisComponent.Text
дает ошибку на следующей строке
vSearch = oDoc.createSearchDescriptor()
Готов пробовать, только не всегда сразу буду отвечать, собираю урожай на поле :)
А так?
Sub testMacro
Dim vSearch
Dim vFound
Dim oCursor
Dim oText
oDoc = ThisComponent
' создаем дескрипторы поиска.
vSearch = oDoc.createSearchDescriptor()
vSearch.SearchString = " " 'определяем, что искать, в данном случае двойной пробел
' создаем дескриптор найденного
vFound = oDoc.findFirst(vSearch)
Do While Not IsNull(vFound) 'циклические поиск и замена пока есть хоть один двойной пробел
If IsNull(vFound) Then
'если больше не найдено, выходим
Exit Do
Else
vFound.setString("test ") 'заменяем найденный двойной пробел одинарным
oCursor = vFound.Text.createTextCursorByRange( vFound )
Wait 500
vFound = oDoc.findFirst(vSearch) 'ищем опять
End If
Loop
Beep
MsgBox ("Done!")
End Sub
Клио - дак ведь ThisComponent в запущеном макросе это и есть документ - или что то поменялось ?
Хм, так работает. Буду разбираться, почему и пробовать применять это к "Типографике"
оно конечно будет, оно так и должно
но как же поступить с "ThisComponent указывает на активный документ. "
осталось выяснить что такое "активный документ"
как теперь поступать со следующим
function myfunc()
doc=thiscomponent
end function
Цитата: serhiy.k от 23 сентября 2010, 21:38
Есть два документа, каждый с пробелами. Запускаю макрос из одного документа, меняет там. Переключаюсь на другой документ, меняет пробелы в другом ???
В точности повторил Ваш эксперимент:
Есть два документа, каждый с двойными пробелами. Запускаю макрос из первого документа, меняет там. Переключаюсь на другой документ, НЕ МЕНЯЕТ пробелы в другом, а продолжает менять в первом - макрос НЕ ПЕРЕКЛЮЧАЕТСЯ с одного документа на другой!
convas вот и мантейнеры всегда отвечают - в нашей сборке все работает
У меня OOo 3.2.1 pro (Инфра).
Windows XP SP3.
Завтра посмотрю на openSUSE 11.3 c OOo 3.2.1 (Novell).
а это не зависит от системы абсолютно !
Это может зависеть от сборки.
В свое время из-за похожей причины (связанной с работой макросов в связанных документах) пришлось менять на старых компах MS Office 97 на MS Office XP.
Это не может зависить от сборки !
а менять скорее пришлось Вам из за любви к активещит
Я не любитель геморроев с гонками за новомодностью, так как слегка ленив.
А ставить Office XP на компы с Windows 98 - не самое увлекательное занятие.
Зато ошибки в работе макросов сразу пропали.
Цитата: smaharbA от 23 сентября 2010, 21:25Клио - дак ведь ThisComponent в запущеном макросе это и есть документ - или что то поменялось ?
Да, поменялось, т.к. oDoc указывает на документ, который был назначен ThisComponent в момент присвоения значения oDoc (в памяти хранится не слово "ThisComponent", а ссылка на документ), т.е. почти мгновенно после запуска макроса. К примеру, если макрос открывает новый документ, StarDesktop.loadComponentFromUrl ... , то после открытия ThisComponent укажет на этот новый документ, а не на старый, из которого макрос был запущен. Функция myfunc в случае если окно этого документа активно указывает на него, а вот если обновить значения функции при неактивном состоянии окна, то не знаю что будет. ThisComponent кстати, если макрос хранится в документе, всегда указавает на тот документ. Поэтому тут не "активный документ", а какой-то "родительский документ", который в частном случае даёт документ, окно которого в данный момент активно.
Вы уходите от ответа ? А если нет ни единого окна то какой ?
вопросов масса и подумайте над ответами не так как в предидущем посте.
Цитата: smaharbA от 23 сентября 2010, 22:54Вы уходите от ответа ? А если нет ни единого окна то какой ?
А, т.е. если все документы скрыты? Тогда не знаю. Нужно внимательно изучать, что такое ThisComponent в коде, но для практики проще бывает провести эксперимент (но в этом случсе я не знаю как провести эксперимент) (Search (http://svn.services.openoffice.org/opengrok/search?q=ThisComponent&defs=&refs=&path=&hist=&project=%2FCurrent+%28trunk%29)).
Цитата: smaharbA от 23 сентября 2010, 20:41
мможно узнать понятие активного документа точнее ?
:) А ThisComponent - ни разу не активный документ.
Цитата: smaharbA от 23 сентября 2010, 19:45всегда ругал и буду за использование Active... и Selection... в МСО
Я скажу так - это плохо не всегда, а особенно Selection (например ваш макрос должен обработать выделенный текст). Но в общем - таки да - тулят и к месту и не к месту, причём второе чаще.
Цитата: smaharbA от 23 сентября 2010, 19:45в ООо все гораздо хуже...
А вот и не соглашусь - всё гораздо так же.
Цитата: smaharbA от 23 сентября 2010, 22:25
Клио - дак ведь ThisComponent в запущеном макросе это и есть документ - или что то поменялось ?
Всё поменялось - ThisComponent - ссылка на ЭтотДокумент, что кстати, гораздо запутаннее чем АктивныйДокумент, но он тоже должен был изменится так же.
Цитата: convas от 23 сентября 2010, 22:18Есть два документа, каждый с двойными пробелами. Запускаю макрос из первого документа, меняет там. Переключаюсь на другой документ, НЕ МЕНЯЕТ пробелы в другом, а продолжает менять в первом - макрос НЕ ПЕРЕКЛЮЧАЕТСЯ с одного документа на другой!
Всё дело в том, что ваш макрос сохранён в документе, а макрос serhiy.k в сторонней библиотеке.
Цитата: Клио от 24 сентября 2010, 00:07
Цитата: smaharbA от 23 сентября 2010, 22:54Вы уходите от ответа ? А если нет ни единого окна то какой ?
А, т.е. если все документы скрыты? Тогда не знаю. Нужно внимательно изучать, что такое ThisComponent в коде, но для практики проще бывает провести эксперимент (но в этом случсе я не знаю как провести эксперимент) (Search (http://svn.services.openoffice.org/opengrok/search?q=ThisComponent&defs=&refs=&path=&hist=&project=%2FCurrent+%28trunk%29)).
Ещё раз - ThisComponent указывает на ЭтотДокумент - это не АктивныйДокумент, иначе так бы и было написано - ActiveComponent.
Поведение его с виду не логично - оно более очеловечено, что ли. Это документ в котором сохранён макрос, а если нет, то последний документ в котором была некоторая активность. Заметьте - это не обязательно тот, который сейчас в активном окне на экране!
Дак как быть с этим ?
function myfunction()
doc=thisComponent
....
end function
Sub Main()
бла-бла-бла
myfunction()
бла-бла-бла
End Sub
+ А в случае перекрестных вызовов ?
Цитата: smaharbA от 24 сентября 2010, 07:06Дак как быть с этим ? + А в случае перекрестных вызовов ?
К примеру, когда макрос хранится в документе - тут всё ясно, ThisComponent указывает на родной документ, а вот случай, когда макрос хранится в сторонней библиотеке - проверьте что будет. Было бы интересно узнать.
Цитата: smaharbA от 24 сентября 2010, 07:06Дак как быть с этим ?
Не пойму - а что с этим не так?
1. Автор темы serhiy.k нигде не писал, где он хранит свой макрос.
2. Я просил его приложить проблемный файл - он его не приложил.
Если бы его макрос не хранился бы в файле - его в нем и не было бы.
3. Пока все эти разговоры - пустое теоретизирование на пустом месте.
Работающих примеров так никто и не приводит.
Если вставить этот немного измененный макрос от serhiy.k не в документ, а в "Мои Макросы"
Sub test_My_Macro
Dim vSearch, vFound, oCursor, oText
oDoc = ThisComponent
' создаем дескрипторы поиска.
vSearch = oDoc.createSearchDescriptor()
vSearch.SearchString = " " 'определяем, что искать, в данном случае двойной пробел
' создаем дескриптор найденного
vFound = oDoc.findFirst(vSearch)
Do While Not IsNull(vFound) 'циклические поиск и замена пока есть хоть один двойной пробел
If IsNull(vFound) Then
'если больше не найдено, выходим
Exit Do
Else
strdoctitle=" =" & oDoc.Title & "= "
vFound.setString(strdoctitle) ' ВСТАВЛЯЕМ ЗАГОЛОВОК ДОКУМЕНТА связанного с oDoc
oCursor = vFound.Text.createTextCursorByRange( vFound )
Wait 500
vFound = ThisComponent.findFirst(vSearch) 'ищем опять
End If
Loop
MsgBox ("Done!")
End Sub
то проблема serhiy.k воспроизводится - при переключении на другой документ МАКРОС ТОЖЕ ПЕРЕКЛЮЧАЕТСЯ на него,
но при этом oDoc продолжает ссылаться на первый документ - тот, из которого макрос был запущен.
Если в данном коде макроса заменить oDoc.Title на ThisComponent.Title, то ThisComponent будет ссылаться уже на новый документ - тот в котором этот макрос выполняется.
Цитата: convas от 24 сентября 2010, 15:05
МАКРОС ТОЖЕ ПЕРЕКЛЮЧАЕТСЯ на него,
но при этом oDoc продолжает ссылаться на первый документ - тот, из которого макрос был запущен.
vFound =
ThisComponent.findFirst(vSearch)
не смущает?
Цитата: bormant от 24 сентября 2010, 23:10
vFound = ThisComponent.findFirst(vSearch)
не смущает?
Нет, не смущает.
Я же и написал, что в данном случае oDoc ссылается на один документ, а ThisComponent на другой.
Если вы про то,что надо было поэкспериментировать с заменой ThisComponent на oDoc везде, то могли бы и сами это проделать и сообщить о своих результатах.
convas - никакого теризирования, Вы просто не имели реальной практики и Вам кажется все на пустом месте.
про
функция мояфункция()
док=этоткомпонент
Вы видимо так и не поняли
Когда я что-то пишу, я в первую очередь думаю о том, что написанное будут читать не "узколобые спецы", а те пользователи, которые с этой проблемой сталкиваются впервые, для которых даже мелкие подробности очень важны и которые, может быть, захотят самостоятельно это проверить.
Ваши же "огрызки" кода вряд ли кого-то интересуют, кроме таких же "просвещенных".
На таком уровне проблемы можно обсуждать в личной переписке, но не на общественном форуме
Здравствуйте,
исправленный Клио вариант макроса работает как надо, поэтому уже не думал прилагать документ, а решил искать, почему этот способ не работает в Типографике.
Я не указал, где храню макрос, так как не думал, что это имеет значение. Но макрос храню в Моих макросах, а не в документах, так как я работаю с разными документами, и также с текстовыми файлами.
Сейчас прилагаю документы:
- ro-BR - это книга, в которой я исправляю кавычки на типографские (в данном случае на английские)
- quotmarks-macro.txt - это набор макросов для исправления кавычек
- dummytext - это любой текст
Что я делаю: макрос сохранен в моих макросах, открываю оба документа, в документе ro-Br с помощью меню Сервис-Макросы-Управление макросами-OpenOffice Basic запускаю макрос ReplaceQuotMark и он начинает работу в этом документе. Затем переключаюсь на документ dummytext и макрос сразу останавливает работу.
Не хотел сразу давать этот макрос, думал дать проще, чтобы не забирать ваше время, а получилось наоборот. :(
[вложение удалено Администратором]