Можно сказать, какая книга вызвала функцию в надстройке Excel (xla) - PullRequest
7 голосов
/ 04 февраля 2011

Я хочу написать небольшую функцию регистрации в надстройке Excel, которую я буду вызывать из разных книг.Я хотел бы иметь возможность просто вызвать его, передав только текст журнала, а сама функция журнала может обрабатывать метку времени, имя рабочей книги и т. Д.

Однако я не могу использовать ниThisWorkbook или ActiveWorkbook, чтобы определить, какая книга была ответственна за выполнение вызова, поскольку Thisworkbook будет возвращать ссылку на саму надстройку, тогда как код VBA, выполняемый в книге, отличной от книги с активным фокусом в Excel, мог бы сделать вызов, ноActiveWorkbook возвращает тот, который имеет фокус в окне.

Application.Caller выглядел как возможное решение, но, похоже, это работает только тогда, когда функция вызывается из ячейки, а не из VBA.

То, что я пытаюсь сделать, невозможно?

Обновление

По словам> 1 человека, это на самом деле невозможно.Если кто-то знает какой-нибудь умный обходной путь, пожалуйста, говорите.

Ответы [ 4 ]

4 голосов
/ 07 февраля 2011

Хорошо, поэтому, прочитав вопрос правильно, я попробую еще раз ...

Итак, чтобы сформулировать проблему:

вам нужна подпрограмма, написанная в надстройке, которая при вызовеиз vba в другой книге можно выяснить (помимо прочего), какая книга содержит vba, которая сделала вызов, без необходимости явно передавать эту информацию.

Как указано, это невозможно (это аналогичный вопросдоступ к стеку вызовов из кода: что, насколько мне известно, невозможно)

Однако вы можете почти получить то, что хотите, вот так

Объявите свою функцию журнала следующим образом:

Sub MyLogger(wb as Workbook, LogText as String)
    Dim CallerName as String
    CallerName = wb.name
    ' your code...
End Sub

Тогда везде, где вы вызываете подпрограмму, используйте

MyLogger ThisWorkbook, "Log Text"

Не так хорошо, как ничего не передавать, но, по крайней мере, всегда одно и то же

2 голосов
/ 06 февраля 2011

Чтобы получить имя вызывающей книги, используйте

Application.Caller.Worksheet.Parent.Name

Application.Caller возвращает информацию о том, как вызывался Visual Basic. При вызове из пользовательской функции, введенной в одной ячейке, возвращается объект Range, указывающий, что эта ячейка

Получив ссылку на ячейку, .Worksheet.Parent.Name даст вам имя рабочей книги

Обратите внимание, что Application.Caller будет возвращать другие данные в зависимости от того, как вызывается ваша функция (см. Справку VBA)

0 голосов
/ 21 июля 2017

У меня была такая же проблема при кодировании пользовательской функции.Функция работает хорошо, но каждый раз, когда вычисляется или активируется другая рабочая книга, все ячейки, использующие эту функцию, возвращаются к # значению.Это может быть очень неприятно при работе с несколькими файлами по этой формуле.

Чтобы получить книгу, которую я использовал:

Dim CallingWb As Workbook
Set CallingWb = Application.Caller.Parent.Parent

Это должно работать, если ваша функция находится в ячейке.

Слишком поздно для оригинального сообщения, но может помочь другим!

0 голосов
/ 25 апреля 2016

В надстройке, вызываемой вызовом функции, введенного в массив листа Excel, я обнаружил, что «Application.Caller.Parent.name» дает имя листа (имя вкладки, а не номер листа).

...