|
|||||||
Кто вызвал функцию или процедуру?
Время создания: 16.03.2019 23:43
Текстовые метки: Caller
Раздел: Разные закладки - VBA - VBA управление кодами
Запись: xintrea/mytetra_db_adgaver_new/master/base/1514990747kp9kjavbps/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
Кто вызвал функцию или процедуру? Предположим вы написали два макроса - один скрывает строки, другой отображает. 'скрываем строки Sub HideRows() Range("A3:A14").EntireRow.Hidden = True End Sub 'показываем строки Sub UnhideRows() Range("A3:A14").EntireRow.Hidden = False End Sub
И, конечно - создали кнопки для вызова этих двух кодов (подробнее про создание кнопок - Как создать кнопку для вызова макроса на листе ). Но потом захотелось большего - чтобы была всего одна кнопка и первым нажатием строки скрывались, а вторым отображались. Сделать это не проблема, если применить такой финт: Sub HideUnhideRows() Range("A3:A14").EntireRow.Hidden = Not Range("A3:A14").EntireRow.Hidden End Sub
Но если код делается для пользователей, то лучше как-то дать понять им, в каком состоянии сейчас строки - скрыты или отображены и к какому действию приведет нажатие на кнопку. И лучше всего это сделать надписью на самой кнопке. Если кнопка одна на одном листе, то проблем быть не должно: Sub HideUnhideRows() If Range("A3:A14").EntireRow.Hidden Then Range("A3:A14").EntireRow.Hidden = False ActiveSheet.Shapes(1).TextFrame2.TextRange.Text = "Скрыть строки" Else Range("A3:A14").EntireRow.Hidden = True ActiveSheet.Shapes(1).TextFrame2.TextRange.Text = "Показать строки" End If End Sub Но если в книге несколько листов и на каждом по несколько кнопок, то не очень удобно будет в коде макроса указывать нужную кнопку. Да, можно указать по имени фигуры: ActiveSheet.Shapes("Скругленный прямоугольник 1"). Но опять же - если кнопок много придется давать той единственной свое уникальное имя, совпадающее на всех листах. Но можно сделать проще - использовать свойство Caller: Sub HideUnhideRows() Dim sShName As String sShName = Application.Caller If ActiveSheet.Shapes(sShName).TextFrame2.TextRange.Text = "Показать строки" Then Range("A3:A14").EntireRow.Hidden = False ActiveSheet.Shapes(sShName).TextFrame2.TextRange.Text = "Скрыть строки" Else Range("A3:A14").EntireRow.Hidden = True ActiveSheet.Shapes(sShName).TextFrame2.TextRange.Text = "Показать строки" End If End Sub Теперь рассмотрим другую ситуацию, более распространенную. Вы написали свою пользовательскую функцию , которая должна суммировать данные ячейки со всех листов книги, кроме того, в котором сама функция. Часто это делают так: Function СуммаЯчеекВсехЛистов(Ячейка As Range) Dim ws As Worksheet 'объявляем переменную для обращения к листам в цикле Dim dblSum As Double 'переменная для хранения суммы 'цикл по листам книги For Each ws In ActiveWorkbook.Worksheets If Not ws Is ActiveSheet Then 'исключаем активный лист из суммирования dblSum = dblSum + ws.Range(Ячейка.Address).Value End If Next ws 'присваиваем значение суммы функции СуммаЯчеекВсехЛистов = dblSum End Function
Function СуммаЯчеекВсехЛистов(Ячейка As Range) Dim ws As Worksheet 'объявляем переменную для обращения к листам в цикле Dim dblSum As Double 'переменная для хранения суммы Dim rFuncCell As Range 'переменная для хранения ссылки на ячейку с функцией Dim wsFunc As Worksheet 'переменная для хранения ссылки на лист с функцией Dim wbFunc As Workbook 'переменная для хранения ссылки на книгу с функцией Set rFuncCell = Application.Caller 'ячейка с функцией Set wsFunc = rFuncCell.Parent 'лист с функцией Set wbFunc = wsFunc.Parent 'книга с функцией 'для листа и книги можно записать одной строкой: 'Set wsFunc = Application.Caller.Parent 'лист с функцией 'Set wbFunc = Application.Caller.Parent.Parent 'книга с функцией 'цикл по листам книги с функцией For Each ws In wbFunc.Worksheets If Not ws Is wsFunc Then 'исключаем лист с функцией из суммирования dblSum = dblSum + ws.Range(Ячейка.Address).Value End If Next ws 'присваиваем значение суммы функции СуммаЯчеекВсехЛистов = dblSum End Function А теперь попробуем разобраться, что же за зверь такой, этот Caller.
Хотел бы так же отметить, что для определения ячейки с функцией можно использовать объект Application.ThisCell, который возвращает ссылку на ячейку, из которой была вызвана функция. Этот объект внутри функций пользователя можно применять точно так же, как и Caller. Но он не может быть применен для определения других методов вызова функций и процедур, как Caller. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|