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

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

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

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

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

Обновлять

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


person tbone    schedule 04.02.2011    source источник
comment
Я примерно на 95% уверен, что сделать именно то, что вы хотите, невозможно, поэтому я позволю тому, кто на 100% уверен, дать нам обоим официальный ответ. Вы, вероятно, должны сделать свою процедуру журнала похожей на журнал (вызов Wbk As Workbook, text As String) и вызывать ее из каждого места с ThisWorkbook в качестве параметра. Однако у вас может быть локальная подпрограмма журнала для каждой рабочей книги, которая вызывает ваш регистратор надстройки, поэтому ваши фактические вызовы журнала могут оставаться простыми.   -  person jtolle    schedule 04.02.2011


Ответы (4)


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

Итак, формулируя проблему:

вам нужна подпрограмма, написанная в надстройке, которая при вызове из 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"

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

person chris neilsen    schedule 07.02.2011

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

Application.Caller.Worksheet.Parent.Name

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

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

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

person chris neilsen    schedule 06.02.2011
comment
все это правда, но я думаю, что @tbone ищет способ получить эту информацию, когда вызов не исходит из Range. - person jtolle; 06.02.2011

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

person Ronald E Johnson    schedule 24.04.2016

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

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

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

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

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

person Jade    schedule 21.07.2017