Possible de dire quel classeur appelé une fonction dans un complément Excel (XLA)
-
29-10-2019 - |
Question
Je veux écrire une petite fonction de journalisation dans un complément Excel que j'appellerai à partir de nombreux classeurs différents. J'aimerais pouvoir l'appeler en passant uniquement le texte du journal, et la fonction de journal elle-même pourrait gérer l'horodatage, nom de travail, etc.
Cependant, je ne peux pas utiliser ce livret de travail ou ActiveworkBook pour déterminer quel classeur était chargé de passer l'appel, car ce livret renverra une référence au complément lui-même, tandis que le code VBA fonctionnant dans un classeur autre que le classeur avec actif dans Excel pourrait Passez l'appel, mais le livre actif retournera celui qui se concentre sur la fenêtre.
Application.Caller ressemblait à une solution possible, mais cela ne semble fonctionner que lorsque la fonction est appelée à partir d'une cellule, pas à partir de VBA.
Est-ce que j'essaie de faire impossible?
Mise à jour
Selon> 1 personne, c'est en fait impossible. Si quelqu'un connaît une solution de contournement intelligente, veuillez parler.
La solution
Ok, donc après avoir lu la question correctement, j'essaierai à nouveau ...
Donc, pour énoncer le problème:
Vous voulez une routine écrite dans un addine, que lorsqu'elle est appelée de VBA dans un autre classeur peut fonctionner (entre autres), quel classeur contient le VBA qui a fait l'appel, sans avoir à passer explicitement ces informations.
Comme indiqué, ce n'est pas possible (c'est une question similaire à l'accès à la pile d'appels à partir du code: quelque chose qui est à ma connaissance non possible)
Cependant, vous pouvez presque obtenir ce que vous voulez comme ça
Déclarez votre fonction de journal comme ceci:
Sub MyLogger(wb as Workbook, LogText as String)
Dim CallerName as String
CallerName = wb.name
' your code...
End Sub
Alors où que vous appeliez le sous-utilisation
MyLogger ThisWorkbook, "Log Text"
Pas aussi bon que de ne rien passer, mais au moins c'est toujours le même
Autres conseils
Pour obtenir le nom du classeur d'appel, utilisez
Application.Caller.Worksheet.Parent.Name
Application.Caller renvoie des informations sur la façon dont Visual Basic a été appelé. S'il est appelé à partir d'une fonction personnalisée entrée dans une seule cellule, un objet de plage spécifiant que la cellule est renvoyée
Ayant une référence à la cellule, .Worksheet.parent.name vous donne le nom du classeur
Notez que Application.Caller renvoie d'autres choses en fonction de la façon dont votre fonction est appelée (voir l'aide VBA pour plus de détails)
Dans une fonction complémentaire appelée par un appel de fonction de feuille de calcul Excel entré, je trouve que "application.caller.parent.name" donne le nom de la feuille (nom d'onglet, non numéro de feuille).
J'ai eu le même problème lors du codage d'une fonction personnalisée. La fonction fonctionne bien, mais chaque fois qu'un autre classeur est calculé ou activé, toutes les cellules utilisant cette fonction reviennent à #Value. Cela peut être très frustrant lorsque vous travaillez avec plusieurs fichiers en utilisant cette formule.
Pour obtenir le classeur que j'ai utilisé:
Dim CallingWb As Workbook
Set CallingWb = Application.Caller.Parent.Parent
Cela devrait fonctionner si votre fonction est dans une cellule.
Trop tard pour le post d'origine, mais pourrait aider les autres!