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.

Était-ce utile?

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!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top