Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

8 Март 2021, 09:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Часто задаваемые вопросы по LibreOffice и Apache OpenOffice.org
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1   Вниз
  Печать  
Автор Тема: Создать макросом/функцией другой макрос/функцию и выполнить его/ee.  (Прочитано 8929 раз)
0 Пользователей и 1 Гость смотрят эту тему.
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Стартовое сообщение: 25 Ноябрь 2012, 20:25 »

Давно как то интересовался этим вопросом, но воспроизвести так и не получилось.
например макрос

sub test

'создаем функцию ff1 в модуле
Function ff1(a,b)
ff1=a+b
End Function

далее по ходу выполнения макроса обращаемся к этой функции

var123=ff1(3,6)

end sub

как то так в общем.
Записан
Hasim
Форумчанин
***
Offline Offline

Сообщений: 754

Woe from wit


« Ответ #1: 25 Ноябрь 2012, 23:23 »

Как-то так.
Функция создается в новом модуле New_Module.

Код:
Sub InsertFunction
   oBLibs = BasicLibraries
   oBL =  oBLibs.getByName("Standard")

' Код функции в виде строки
    s = "Function ff1(a,b)" & CHR(10) & "ff1=a+b" & CHR(10) & "End Function" & CHR(10)

' Записывается код функции в новый модуль
If Not oBL.hasByName("New_Module") Then
    oBL.insertByName("New_Module", s)
End If

' Выполняется новая функция
If oBL.hasByName("New_Module") Then
var123=ff1(3,6)
MsgBox var123
End If

End Sub

Записан
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #2: 26 Ноябрь 2012, 03:49 »

ого спасибо!
А вот странно почему этот код удаляет модуль а вставляет его опять через раз
мистика какая то. Как правильно заменить вставленную функцию для повторного использования (повторной вставки)?

Код:
Function TableOfResults( formula As String , LowerPoint As Double, UpperPoint As Double, NumOfValues As Integer) As Variable

'Create UserFunction in the New Module
   oBLibs = BasicLibraries
   oBL =  oBLibs.getByName("Standard")

'Text of new Function
Dim TextOfFunction As String

TextOfFunction = "Function results_by_formula(x)" & CHR(10) & "results_by_formula="& Str(formula) & CHR(10) & "End Function" & CHR(10)  

'Write the test of new function into the new module

If oBL.hasByName("New_Module") Then oBL.removeByName("New_Module")

oBL.insertByName("New_Module", TextOfFunction)

'.....to be continued

End Function
« Последнее редактирование: 26 Ноябрь 2012, 05:32 от calc4fem » Записан
Hasim
Форумчанин
***
Offline Offline

Сообщений: 754

Woe from wit


« Ответ #3: 26 Ноябрь 2012, 11:14 »

почему этот код удаляет модуль а вставляет его опять через раз

Нужно закрыть окно редактора Basic (спасибо mathnew за подсказку), повесить макрос, например fff на панель инструментов (создать кнопку) и запускать макрос с панели инструментов при закрытом окне редактора Basic.

Макрос теперь срабатывает без пропусков, каждый раз перезаписывая функцию.

Код:
Sub fff
For n=1 To 10
    s = "Function ff1(a,b)" & CHR(10) & "ff1=a+b+" & Trim(Str(n)) & CHR(10) & "End Function" & CHR(10)
InsertFunction(s)
Next n
End Sub


Sub InsertFunction(s)
   oBLibs = BasicLibraries
   oBL =  oBLibs.getByName("Standard")

If oBL.hasByName("New_Module") Then
    oBL.removeByName("New_Module")
End If

' Записывается код функции в новый модуль
If Not oBL.hasByName("New_Module") Then
    oBL.insertByName("New_Module", s)
End If

' Выполняется новая функция
If oBL.hasByName("New_Module") Then
var123=ff1(3,6)
MsgBox var123
End If

End Sub


Записан
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #4: 27 Ноябрь 2012, 03:51 »

да - кстати спасибо
дело было в открытом модуле потому и через раз. вот пример функции на эту тему (без обработчика ошибок код - надо вводить переменную корректно, а то будет двадцать раз MsgBox)



[вложение удалено Администратором]
« Последнее редактирование: 27 Ноябрь 2012, 04:37 от calc4fem » Записан
Hasim
Форумчанин
***
Offline Offline

Сообщений: 754

Woe from wit


« Ответ #5: 27 Ноябрь 2012, 22:10 »

Ваш пример очень понравился.
Очень познавательно, не только в плане данной темы, но и в плане функции массива и в плане построения графиков.
Записан
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #6: 28 Ноябрь 2012, 15:38 »

спасибо вам за подсказку
обнаружил что в ООо бэйсик свободно работает рекурсия (ссылка например функции на саму себя). то есть это нормально - просто я раньше не задавался вопросом. Тот же факториал числа.

Код:
Function factori(n)

If n=0 Then factori=1
If n=1 Then factori=1
If n>1 Then factori=factori(n-1)*n

End Function

У функций массива есть один недостаток который связан с тем, что например в данном примере для того чтобы поменять количество точек (количество строк) на большее
нужно функцию выделить, потом удалить, и ввести снова. иначе выданы будут не все значения. если ввести функцию с меньшим числом точек - то в оставшихся с предыдущего ввода будет возвращено N/A (not applicable)
Чтобы преодолеть эти особенности функция массива - я делаю обычно так. Массив для результата беру больше чем это может быть нужно с запасом (например таблица может содержать 15-20 строк, редко 50, я беру в коде массив на 50 в запас) а чтобы не было неряшливо перед определением результата ставлю во всех ячейках пустой текст  " "
у меня есть идея как это можно было бы преодолеть программно - я имею в виду этот недостаток. например чтобы функция искала свою ячейку куда введена, а потом удаляла все данные что ниже и возвращала массив нужной величины на ячейку ниже.
« Последнее редактирование: 28 Ноябрь 2012, 16:02 от calc4fem » Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 764


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #7: 28 Ноябрь 2012, 17:05 »

у меня есть идея как это можно было бы преодолеть программно - я имею в виду этот недостаток. например чтобы функция искала свою ячейку куда введена, а потом удаляла все данные что ниже и возвращала массив нужной величины на ячейку ниже.
А вот этот фокус, к сожалению, провернуть не удастся: во время пересчета функции ТЕКУЩИЙ лист (на котором расположена рассчитываемая ячейка) блокируется от изменений. В соседних листах и в других книгах делай что хочешь, а на текущем листе - ни-ни... И в принципе это правильно
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #8: 29 Ноябрь 2012, 06:04 »

Можно наверно разлочить текущий лист ниже от введенной функции а потом после ввода - залочить же? Пароль прицепить в виде переменной строковой или сделать постоянным в коде. хотя конечно это сложно, в функциях то главное - простота.
Записан
JohnSUN
Капитана в тот день называли на "ты"
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Киев
Сообщений: 2 764


Помогаю людям и компьютерам понимать друг друга


WWW
« Ответ #9: 29 Ноябрь 2012, 12:08 »

Ну, для "простоты" уже придумали несколько вариантов... Например, передавать в функцию в явном виде (например, строкой) диапазон, подготовленный для результата. Или отдельными параметрами указать количество строк-колонок отведенных под него. Или оформить весь алгоритм не функцией, а процедурой - пусть она вычисляет сколько строк-колонок потребуется для результата и вставляет в эти ячейки функцию массива, очищая ячейки, которые в этот раз не понадобятся...
А, вообще-то, это обсуждение уже отклонение от первоначально объявленной темы.
Записан

Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #10: 13 Июль 2013, 06:13 »

а можно ли как то запустить макрос из функции. я понимаю что нельзя,но если очень хочется?
Записан
Hasim
Форумчанин
***
Offline Offline

Сообщений: 754

Woe from wit


« Ответ #11: 13 Июль 2013, 11:25 »

Можно, но с ограничениями (типа указанных JohnSUN).
Простейший пример:
Код:
Global nn As Integer

Sub Main1
nn = nn + 1
MsgBox nn
End Sub


Function FU() As Integer
Main1
FU=nn
End Function


[вложение удалено Администратором]
Записан
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #12: 13 Июль 2013, 15:00 »

Спасибо. Попробовал с имеющимися у меня макросами (довольно сложными). http://sourceforge.net/projects/calc4fem/
Например макрос main
Функция
Function Fu()
main
Fu=1
End Function

Из пяти запусков 2 раза программа упала. Например падает когда запускаю
main
main
Может быть из за параллельного обращения к одним и тем же данным
А какие в общим ограничения? Можно ли найти формулировку чтобы понять?
« Последнее редактирование: 13 Июль 2013, 15:54 от calc4fem » Записан
Hasim
Форумчанин
***
Offline Offline

Сообщений: 754

Woe from wit


« Ответ #13: 13 Июль 2013, 17:20 »

Вставил FU с двумя main в ваш ODS на лист UserFun в Н1, не вникая.
Код:
Global nn As Integer
Function Fu()
main
main
Fu=nn
End Function
Работает, не падая.
Выполняются оба main (Н1 увеличивается на 2, счетчик добавлен в main)
Пересчет функции FU() выполняется при изменении данных на листе, или просто при нажатии Delete на пустой ячейке.



[вложение удалено Администратором]
Записан
calc4fem
Форумчанин
***
Offline Offline

Сообщений: 278


« Ответ #14: 13 Июль 2013, 17:45 »

Libre3.5/Ubuntu при первом запуске упало. При повторном открытии работало без падений. Проверю потом на винде
Записан
Страниц: 1   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!