Il Vb di Aoo e Lo non implementano questa funzione. Sul forum francese ho trovato le macro che emulano CallByName del vba (vedi qui). Ho preso quelle macro e le ho modificate per ciò che mi interessava.
Il Disagio: Quando sviluppo un file calc con molte macro complesse e vari pulsanti di lancio, durante la fase dello sviluppo riorganizzo spesso le varie macro suddividendole nei moduli e non contento rinomino spesso le macro e i moduli
![Hammer-Head :knock:](./images/smilies/icon_marteau.gif)
Dopo aver fatto queste modifiche una buona parte dei pulsanti non trova più (giustamente) la macro da lanciare dato che gli ho biato il percorso. A questo punto o modifico gli eventi dei pulsanti oppure devo ripristinare i vecchi nomi e le posizioni delle macro in questione.
![Shocked :shock:](./images/smilies/icon_eek.gif)
Obiettivo: Voglio rendere l'associazione Pulsante/macro più flessibile, ovvero mi piacerebbe poter cambiare/rinominare il modulo in cui è inserita la macro ogni qual volta mi va senza dover essere poi costretto a cambiare l'evento del pulsante. Inoltre, se volessi rinominare la macro, vorrei evitare di modificare gli eventi del pulsante (si aprono varie finestre di dialogo e bisogna selezionare la macro dopo aver selezionato prima il modulo, dopo aver selezionato prima la libreria)...vorrei intervenire facendo una modifica altrettanto efficace ma più rapida.
Soluzione trovata: Mi sto trovando bene nell'assegnare a tutti i pulsanti la stessa macro dal nome banale "Pulsanti", nel classico modulo "Module1". Quando sviluppo macro complesse, in cui anche il nome della sub mi aiuta a dare un ordine mentale, mantenere fissi i nomi "Pulsanti" e "Module1" non mi da alcun problema, detta in altri termini questi nomi sono perfetti così come sono e non mi viene in mente di cambiarli.
Codice: Seleziona tutto
Sub Pulsanti(oEv)
SubOrFunc= oEv.source.model.label
call CallByName(SubOrFunc,array())
End Sub
I vari pulsanti eseguiranno quindi tutti la sub "Pulsanti", ma grazie alla macro CallByName riesco ad ottenere comportamenti differenti semplicemente usando come label del pulsante il nome della macro che avrei associato direttamente. Potrei anche usare, invece del label, il name del pulsante.
Ora posso cambiare la posizione delle macro tra i moduli senza alcun problema, basta che non sposti la sub Pulsanti.
Se decido di rinominare le macro, devo solo impostare nel label il nuovo nome della macro.
Se devo inserire 100 pulsanti, una volta inserito il primo e impostata l'associazione con sub "Pulsanti", posso copiare il pulsante e incollarlo 99 volte. Successivamente mi basta solo cambiare i vari label e ecco che tutti i pulsanti sono sistemati.
Codice: Seleziona tutto
sub CallByName(sFonction as string ,aParams as variant)
dim oDS as object 'objet dispatch helper utilisé pour le call de la sub
dim sURL as string 'string qui contient l'URL de la fonction a appeler
on error goto CallByName_error
'initilisation objet dispatchhelper
oDS = createUnoService("com.sun.star.frame.DispatchHelper")
'initialisation de l'URL du script Basic a appeler : Standard,CallByName."+sFonction+"?language=Basic&location=document
'le script est dans la bibliothèque Standard du document contenant les macro
'le script a appeler est dans le module CallByName
'le nom du script basic a appeller est dans la variable sFonction
sURL = "vnd.sun.star.script:Standard."+getModule(sFonction)+"."+sFonction+"?language=Basic&location=document"
'appel du script
oDS.executeDispatch(ThisComponent.CurrentController.frame,sURL,"",0,aParams())
exit sub
CallByName_error:
on error resume Next
msgbox "erreur dans la procédure CallByName"
on error goto 0
end sub
Codice: Seleziona tutto
function getModule(sFunction as string) as string
CONST LibraryName = "Standard"
dim oLib as object 'objet libarie Standard
dim aModules() 'tableau de tous les modules de la librairie Standard
dim iC as Integer 'indice de boucle
dim sModule 'le module à analyser (texte basic)
on error goto getModule_error
oLib = BasicLibraries.getByName( LibraryName ) 'initialise l'objet librarie
getModule = ""
aModules = oLib.getElementNames() 'initialise le tableau qui contient tous les modules
for iC = 0 to ubound(aModules) 'pour chacun des modules
sModule = oLib.getByName(aModules(iC)) 'charge le contenu texte du module dans la variable Smodule
if instr(sModule,"Sub " & sFunction) > 0 Then
getModule = aModules(iC)
exit Function
Elseif instr(sModule,"function " & sFunction) >0 Then
getModule = aModules(iC)
exit function
end if
next iC
exit function
getModule_error:
on error resume next
msgbox "erreur dans la procédure getModule"
on error goto 0
end function
Delle macro trovate nel forum francese, ho modificato la funzione "getmodule" in cui ho scelto di usare la funzione "Instr" per stabilire se il modulo presenta o no la macro cercata.
Criticità All'interno dei vari moduli non devono essere presenti tra i commenti "sub nomemacro" o "function nomemacro" altrimenti viene individuato il modulo sbagliato. Inoltre tra sub e il nomemacro deve esserci uno e un solo spazio, stessa cosa se si tratta di una function
Conclusioni: Forse altri utenti troveranno utile queste macro per i miei stessi motivi o trovarle utili per risolvere un problema di compatibilità con il vba qualora fosse impiegata proprio la funzione CallByName o forse ci sarà qualcuno che le troverà semplicemente interessanti o di spunto per fare tutt'altro.
Di certo ci sarà chi sbadiglierà
![Laughing :lol:](./images/smilies/icon_lol.gif)