Как вызвать функцию в ячейке из собственной библиотеки модулей?

Автор paulsmith, 10 ноября 2011, 15:39

0 Пользователи и 1 гость просматривают эту тему.

JohnSUN

Не продают их... Дешевые спросом не пользуются...
А чего спросил-то? Купить хочешь?.. Продать?.. Или заняться изготовлением на продажу?
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

А ты дом для суперкомпьютера уже купил?
В квартире, гараже и на садовом участке не помещается, зараза. Проверено.

RFJ

Не дают жить спокойно достижения иных "гениально озабоченных"?
Россиянин собрал суперкомпьютер на коленке:
http://hi-tech.mail.ru/news/misc/supercomp_hand_made.html

JohnSUN

Круто! "В данном случае суперкомпьютер — это машина, которая формально состоит из нескольких компьютеров..."

Сколько волос нужно потерять, чтобы начать считаться лысым? Или другими словами: Сколько Atom'ов нужно выдрать из корпуса "суперкомпьютера", чтобы язык больше не повернулся так его назвать?...

PS. Может разделим тему? А то ведь оффтоп...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне


dr.Faust

Да просто я подумал, это же сколько будет рассчитываться лист усеянный такими формулами на персоналке...
Представь - из листа вызывается функция, она шерстит библиотеки в поисках функции по имени, находит вычисляет, принимает результат, возвращает его на лист...
Жесть.
Свобода информации - свобода личности!

JohnSUN

А-а-а!.. Так вот почему в этой теме!
Не беспокойся, это не так страшно, как могло показаться с первого раза.
Даже если весь лист усеем этими формулами, Железному Мозгу придется напрячься только при вычислении первой из них, дальше пойдет легче. Это я беру вариант, когда из загруженных библиотек имеем только Standard, а ищем во всех остальных. Ну, тот вариант, который до сих пор не написан  ;D
Там задумка какая была: первый параметр - строка вида [[библиотека.][модуль].]функция. То есть:
- "MyFunc" - перекопать все модули всех библиотек пока не встретим функцию с таким именем;
- "MyLib..MyFunc" - перерыть все модули одной библиотеки MyLib;
- "MyLib.Module1.MyFunc" - просто загрузить, если еще не загружена, библиотеку MyLib, сунуться в её модуль Module1 и выполнить функцию MyFunc из него. Само собой, при условии, что все трое найдутся;
- ".Module1.MyFunc" - просмотреть все библиотеки, в которых есть модуль с именем Module1, в котором в свою очередь есть (должна найтись) эта самая функция MyFunc. Само собой, задачу "написать функцию MyFunc и затолкать её в модуль, если до сих пор нету" не рассматриваем.
Синтаксисом вызова предусмотрен еще и такой вариант:
- ".MyFunc" - перекопать все модули загруженных библиотек, а если не найдем функцию с таким именем, то заглянуть в каждую из еще не загруженных.

После первого же нахождения нужной функции библиотека, из которой мы её вызвали остается загруженной. И значит при следующем пересчете формул хотя бы на загрузке время уже сэкономим.

По большому счету сам Калк поступает точно так же. В смысле, должен был бы поступать, если бы не ошибка до которой столько лет руки не доходят. Ну, может быть, с той разницей, что изначально он должен был рыться во всех уже загруженных библиотеках, не обращая внимания на имеющиеся, но не загруженные.

Реализация этого так и ненаписанного макроса должна была начинаться со Split() первого параметра по точке... А потом - начался обед :beer:
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

Если указывать сразу и Модуль
=RUNMACRO2("myLib";"Module1";"myFunc";A1)
то поиск не нужен и всё упрощается и ускоряется:
Function runMacro2(libName As String,  ModuleName As String,  funcName As String, _
Optional Param1, Optional Param2, Optional Param3, _
Optional Param4, Optional Param5)

REM Преобразовать цепочку Param1..Param5 в массив
''''''''''''''''''''''''''''''''''''
If IsMissing(Param1) Then
inpParams = Array()
ElseIf IsMissing(Param2) Then
inpParams = Array(Param1)
ElseIf IsMissing(Param3) Then
inpParams = Array(Param1, Param2)
ElseIf IsMissing(Param4) Then
inpParams = Array(Param1, Param2, Param3)
ElseIf IsMissing(Param5) Then
inpParams = Array(Param1, Param2, Param3, Param4) ' Так можно продолжать долго
Else
inpParams = Array(Param1, Param2, Param3, Param4, Param5)
EndIf
''''''''''''''''''''''''''''''''''''

On Error GOTO ERR

oDoc = ThisComponent

If GlobalScope.BasicLibraries.HasByName (LibName) Then GlobalScope.BasicLibraries.LoadLibrary(LibName)

macroName = "vnd.sun.star.script:" & libName & "." & ModuleName & "." & funcName & "?language=Basic&location=application"

oScriptProvider = ThisComponent.getScriptProvider()

oScript = oScriptProvider.getScript(macroName)

runMacro2 = oScript.invoke(inpParams, aOutParamIndex(), aOutParam())

Exit Function
ERR:
End Function


PS. А можно запихать полный путь в одну строчку "myLib.Module1.myFunc" и вызывать так
=RUNMACRO2("myLib.Module1.myFunc";A1)

JohnSUN

Ну да... Только в постскриптуме, наверное, уже не RUNMACRO2(), а какой-нибудь RUNMACRO3(whereSearchFunc As String,  Optional Param1,...) должен быть. У RUNMACRO2 эта строчка "myLib.Module1.myFunc" уже должна быть развалена на три первых параметра.
И внутри RUNMACRO3, получается, нужно будет сделать что-то вроде такого:
arrNames = Split(whereSearchFunc, ".")
If UBound(arrNames) = LBound(arrNames)  Then' Один параметр - имя функции -
REM                                        искать во всех модулях всех библиотек
funcName = arrNames(0) ' Или arrNames(1), или arrNames(LBound(arrNames)) - от Options Base зависит
....
ElseIf (UBound(arrNames) - LBound(arrNames)) = 1 Then ' Две строки - или имя модуля и функции через
REM                                              точку, или просто функция с точкой впереди
  If arrNames(LBound(arrNames)) = "" Then ' Первая строка пустая, значит имени модуля нет,
REM                                                искать по всем загруженным библиотекам
...
  Else ' Имя модуля есть - искать такой модуль, а в нём функцию
...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

neft

А можно и так
=RUNMACRO4("myLib";"Module1.myFunc";A1)
отделив имя библиотеки от полного пути к функции, тогда и имя библиотеки через Split выдирать не надо.

Тут, кстати, нет проблем со случаем, когда в разных модулях могут оказаться функции с одинаковыми именами.