Список форумов Форум Libreoffice

Форум Libreoffice

Добро пожаловать на Форум Libreoffice!
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

English French German Italian Portuguese Russian Spanish
Чтение и запись кода модуля из макроса

 
Начать новую тему   Ответить на тему    Список форумов Форум Libreoffice -> Basic
Предыдущая тема :: Следующая тема  
Автор Сообщение
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Чт Окт 20, 2011 9:16 pm    Заголовок сообщения: Чтение и запись кода модуля из макроса Ответить с цитатой

Пример макроса, который читает и записывает Module6 (код макроса Sub Main6).
Код:
Sub Main6
MsgBox  33
End Sub

Хотелось иметь макрос, из которого можно было бы менять код другого макроса, но это возможно только, перезаписывая (remove+insert) весь модуль, содержащий этот макрос.
Код:
Sub RemoveInsertModule6
   oBLibs = BasicLibraries
   oBL = oBLibs.getByName("Standard")

If oBL.hasByName("Module6") Then
      MsgBox oBL.getByName("Module6")
      MsgBox "pre-remove"
   oBL.removeByName("Module6")
''' Макрос прекращает работу в этом месте!?
      MsgBox "remove"
End If

    s = "Sub Main6" & CHR$(10) & "MsgBox " & Str(Int(100 * Rnd)) &  CHR$(10) & "End Sub"

If Not oBL.hasByName("Module6") Then
      MsgBox "pre-insert"
    oBL.insertByName("Module6", s)
      MsgBox "insert"
End If

End Sub

Но почему-то и это не получается сделать в одном макросе.
На строке
Код:
   oBL.removeByName("Module6")

весь макрос прекращает работу, т.е. модуль удаляется, но вставить модуль можно только перезапустив макрос ещё раз.
Это глюк Офиса, или я чего-то не понимаю?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
mathnew



Репутация: 0    

Зарегистрирован: 20.08.2011
Сообщения: 24

СообщениеДобавлено: Пт Окт 21, 2011 6:36 am    Заголовок сообщения: Ответить с цитатой

Макрос работает без ошибок, но при одном условии:
окно редактора Basic должно быть закрыто!

И для проверки лучше макрос повесить на панель инструментов



Макрос для проверки лучше такой:
Код:
Sub RemoveInsertModule6
   oBLibs = BasicLibraries
   oBL = oBLibs.getByName("Standard")

If oBL.hasByName("Module6") Then
   oldcode=oBL.getByName("Module6")
   oBL.removeByName("Module6")
End If

    s = "Sub Main6" & CHR$(10) & "MsgBox " & Str(Int(100 * Rnd)) &  CHR$(10) & "End Sub"

If Not oBL.hasByName("Module6") Then
    oBL.insertByName("Module6", s)
   newcode=oBL.getByName("Module6")
End If

   MsgBox "     OldCode: " & Chr(10) & oldcode & Chr(10) & Chr(10) & Chr(10) & "     NewCode: " & Chr(10) & newcode

End Sub

Результат выполнения макроса RemoveInsertModule6:

Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Пт Окт 21, 2011 8:09 am    Заголовок сообщения: Ответить с цитатой

Возникает два вопроса, которые не имеют прямого отношения к действиям макроса, а, скорее, касаются "честного отношения к пользователю".
mathnew писал(а):
Макрос работает без ошибок, но при одном условии:
окно редактора Basic должно быть закрыто!

1. То есть, по-хорошему, при запуске макроса нужно перебрать все фреймы StarDesktop.getComponents().createEnumeration() и убедиться, что среди них нет окна редактора бэйсика. Если все-таки есть, то прекратить работу (молча или с предупреждением). Или спросить у пользователя разрешения на закрытие этого окна, закрыть и продолжить.
По каким признакам отлавливается окно редактора кода?

Второй вопрос по поводу перезаписи кода.
Код:
oBL.removeByName("Module6")

2. Может, все-таки не удалять? Переименовать в какой-нибудь .bak? А удаляет пусть сам пользователь, руками... А то такое поведение макроса смахивает на работу вируса, ИМХО

PS. Как отличить окно редактора от других уже сообразил: только этот "документ" поддерживает сервис "com.sun.star.script.BasicIDE". Но остается вопрос, что правильнее делать с этим окном - ругаться или спрашивать разрешения на закрытие?
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Пт Окт 21, 2011 9:23 am    Заголовок сообщения: Ответить с цитатой

mathnew, спасибо за подсказку.

JohnSUN, как переименовать модуль программно я не знаю (rename?).
Хотя, можно конечно, прочитать код Module6, записать его в Module6_backup_001, удалить Module6, записать Module6 с новым кодом.

Цитата:
что правильнее делать с этим окном - ругаться или спрашивать разрешения на закрытие?

Это уж должен решать сам программист в зависимости от той задачи, которая стоит перед программой.

Но общий принцип, я думаю, должен быть таким.
Окно редактирования кода Basic должно быть открыто только во время редактирования вручную кода. Запуск макроса прямо из окна редактора Basica нужен только для быстрой проверки кода макроса, и только для этого. Но, как видно из данного примера, это не гарантирует правильную работу макроса. Так что следует всё-таки при отладке проверять работу макроса из пользовательской программы, а в ней окно редактора Basica должно быть закрыто. И зачем оно пользователю во время работы программы?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Пт Окт 21, 2011 10:53 am    Заголовок сообщения: Ответить с цитатой

RFJ писал(а):
...окно редактора Basica должно быть закрыто. И зачем оно пользователю во время работы программы?

Ну, случаи бывают разные... (с) Поручик Ржевский
Например, разработка-отладка какого-то решения с попутной локализацией... Локализация натравливается на код и занимается именно перезаписью в модуль... А поскольку занимались отладкой, то и окно редактора могли не закрыть... Это так, для примера только...

RFJ писал(а):
Это уж должен решать сам программист в зависимости от той задачи, которая стоит перед программой

Я тут подумал: это, наверное, просто выбор поведения интерфейса - или молчаливо и продуктивно сделать порученное дело, как это принято в иксах, или нагрузить пользователя кучей сообщений и вопросов с очевидными ответами - лишь бы не молчать и имитировать бурную деятельность - как это делается в "некоторых других системах"... А если так, то можно было бы реализовать оба варианта поведения и выбирать нужный в зависимости от системы, под которой сейчас запускается офис. Ну, например, перед каждым MsgBox добавить If thisIsWin Then Wink

RFJ писал(а):

как переименовать модуль программно

insertByName для .bak (с предварительным If hasByName("...bak") Then removeByName("...bak")) и replaceByName для перезаписи?
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Пт Окт 21, 2011 11:58 am    Заголовок сообщения: Ответить с цитатой

Да, верно, для перезаписи кода (s) модуля Module6 достаточно
Код:
replaceByName("Module6", s)


insertByName("Module6", s) вставит новый модуль с кодом s
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
JohnSUN



Репутация: 0    

Зарегистрирован: 29.08.2011
Сообщения: 39
Откуда: Киев, Украина

СообщениеДобавлено: Пт Окт 21, 2011 12:14 pm    Заголовок сообщения: Ответить с цитатой

Но может выбросить исключение ElementExistException, если модуль с таким именем уже есть.
Поэтому и предлагаю использовать его именно для бэкапа: если уже есть модуль с исходным именем и "расширением" .bak (реально-то это не расширение, а суффикс) - прибить, считать текущее содержимое модуля и через insertByName вставить его копию с оригинальным именем+".bak", и, наконец, перезаписать модуль новым содержимым.
_________________
Владислав Орлов aka JohnSUN
LibreOffice 3.4.0 OOO340m1 (Build:12) WinXP SP2
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Посетить сайт автора
RFJ



Репутация: +1    

Зарегистрирован: 02.08.2011
Сообщения: 59

СообщениеДобавлено: Пт Окт 21, 2011 1:30 pm    Заголовок сообщения: Ответить с цитатой

JohnSUN писал(а):
Но может выбросить исключение ElementExistException, если модуль с таким именем уже есть.

Так есть же проверка на отсутствие модуля с таким именем:
Код:
If Not oBL.hasByName("Module6") Then
    oBL.insertByName("Module6", s)
...

А для бэкапа делается аналогично.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
neft



Репутация: 0    

Зарегистрирован: 19.10.2011
Сообщения: 28

СообщениеДобавлено: Сб Окт 22, 2011 6:48 am    Заголовок сообщения: Ответить с цитатой

А дальше?
Как разделить код модуля на подпрограммы Sub...End Sub и функции Function...End Function?
Как выделить из кода комментарии?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Admin



Репутация: 0    

Зарегистрирован: 02.08.2011
Сообщения: 24

СообщениеДобавлено: Сб Окт 22, 2011 1:07 pm    Заголовок сообщения: Ответить с цитатой

neft писал(а):
Как разделить код модуля на подпрограммы Sub...End Sub и функции Function...End Function?

Как выделить из кода комментарии?


К данной теме (Чтение и запись кода модуля из макроса) это имеет косвенное отношение.

Если хотите продолжить обсуждение данных вопросов, создайте новую тему.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Форум Libreoffice -> Basic Часовой пояс: GMT
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group
Вы можете бесплатно создать форум на MyBB2.ru, RSS