Страницы: 1
RSS
Использование функций VBA в качестве пользовательской формулы на листе при ее протягивании
 
 Все добрый день ...

Необходимо увеличить значение каждой ячейки в столбце "Номер" на 10, с использованием функции VBA как пользовательской формулы на листе. Результат должен быть записан в соответствующей ячейке (т.е. напротив ячейке исходного значения) в столбце "Формула".
Т.е. должно быть вот так:

Написал функцию VBА, увеличения значения ячеек столбца "Номер" на 10 и помещения результата вычисления в столбец "Формула":
При этом ячейка H3 является именованной с тем же именем что и находящейся в ней текст, т.е. "Номер".
На вход функции и поступает имя этой ячейки. Функция возвращает увеличенное значение номер.
Код
Function РасчетФормулы(Ячейка As Range) As Integer
  РасчетФормулы = Ячейка.Offset(ActiveCell.Row - Ячейка.Row, 0).Value + 10
End Function
Данная функция "ручками" вписывается в каждую ячейку столбца "Формула" и мы получаем тот результат, который ожидаем.
Но если взять и протянуть формулу из ячейки I8, до конца столбца, то получим следующий результат:

Проанализировав ситуация, пришел к выводу, что в этом случае активная ячейка не меняется и остается по адресу I8, который и используется для расчета формулы. Таким образом результат формулы один и тот же: 15. Если бы можно было в формуле использовать не активную ячейку, а текущую ячейку, в которую Excel вставляет на данный момент формулу при протяжке, то, возможно проблема бы решилась. Прошу подсказать как мне правильно написать формулу.
Изменено: kalakom - 22.01.2019 14:35:34
 
Цитата
kalakom написал: Результат должен быть записан в соответствующей ячейке
изучайте: Кто вызвал функцию или процедуру?
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Дмитрий(The_Prist) Щербаков, про Application.Caller не знал - отличная вещь. Но в мое случае он возвращает пустую строку.
При этом функция вызывается столько раз, сколько выделенных ячеек образовалось при протяжке.
Изменено: kalakom - 22.01.2019 14:12:36
 
Цитата
kalakom написал:
Необходимо увеличить значение каждой ячейки в столбце "Номер" на 10, с использованием функции VBA как пользовательской формулы на листе. Результат должен быть записан в соответствующей ячейке (т.е. напротив ячейке исходного значения) в столбце "Формула".
А зачем все эти упражнения с Offset? Без VBA Вы бы написали например =H3+10 и протянули без проблем, не так ли? С VBA то же самое, функция
Код
Function РасчетФормулы(Ячейка As Range)
  РасчетФормулы = Ячейка.Value + 10
End Function
Пишите =РасчетФормулы(H3) и протягивайте.
 
Цитата
kalakom написал:
Но в мое случае он возвращает пустую строку
а он не должен возвращать вообще строку, если не просить. Application.Caller - это ссылка на ячейку, в которой записана сама функция. Т.е. если не вдумываться в Вашу функцию и просто приладить совет, то должно получиться так:
Код
Function РасчетФормулы(Ячейка As Range) As Integer
  РасчетФормулы = Ячейка.Offset(Application.Caller.Row - Ячейка.Row, 0).Value + 10
End Function
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Понял, причина вот в чем:
Заполнение столбца "Номер" идет из файла с помощью VBA. Перед вызовом функции VBA заполнения из файла этого столбца пользователь должен и может определить место где этот столбец в Excel будет находиться. Место он определяет с помощью установки именованной ячейки "Номер" что и является для функции заполнения "стартовой ячейкой".
Далее начинает работать функция, которая должна увеличить каждое значение столбца "Номер" на 10. При этом эта функция знает только расположение именованной ячейки "Номер". Заполнение столбца "Функции" идет параллельно столбцу "Номер". Для того, чтобы эта функция поняла, какое значение из столбца "Номер" надо увеличивать, она определяет номер строки в которой надо вставить формулу и отнимает от этого номера строки номер строки именованной ячейки "Номер" вот так: ActiveCell.Row - Ячейка.Row. Далее это значение используется как смещение относительно расположения именованной ячейки "Номер" и по этому смещению берется значение для увеличения на 10: Ячейка.Offset(ActiveCell.Row - Ячейка.Row, 0).Value + 10. Вот почему используется смещение.
 
Так я выше показал как использовать Application.Caller в Вашем случае. Должно работать на ура.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Да, с Application.Caller все заработало как и планировалось. Я понимаю, что Application.Caller является ссылкой на объект. Просто когда посмотрел в отладчике что он содержит, то увидел пустую строку и подумал что это NULL на объект в нотации VBA и не стал такую ссылку использовать для вызова метода Row. Видно в отладчике VBA не посмотреть действительный адрес объекта.

Большое спасибо, тему считаю закрытой, проблему решенной.
 
Цитата
Казанский написал: Function РасчетФормулы(Ячейка As Range) ...
Алексей прав. Можно также передавать просто значение, а не объект Range.
И предусмотреть второй необязательный параметр (сколько прибавлять)
Код
Function РасчетФормулы(X As Double, Optional Y As Double = 10) As Double
  РасчетФормулы = X + Y
End Function
Изменено: ZVI - 22.01.2019 17:38:18
 
Да, я тоже это решение обдумал - взял на заметку.
Спасибо.
Страницы: 1
Наверх