Перейти к содержимому

VBA Excel. Изменение значений других ячеек из функции

Изменение значений других ячеек из пользовательской функции VBA Excel с помощью методов Range.Replace и Application.Volatile. Примеры кода.

  1. Функция с методом Range.Replace
  2. Метод Application.Volatile
  3. Безопасное использование функции
В первых двух параграфах описано нетрадиционное использование процедуры Function, поэтому не применяйте его в серьезных проектах. Тестирование проводилось в Excel 2016.

Функция с методом Range.Replace

Пользовательская функция не предназначена для изменения значений ячеек, кроме той, в которой она расположена. Попытка присвоить какое-либо значение из функции другой ячейке приводит к неработоспособности функции и отображению в ячейке, где она расположена, сообщения «#ЗНАЧ!».

Но, как ни странно, внутри процедуры Function работает метод Range.Replace, которым мы воспользуемся для изменения значений других ячеек из пользовательской функции.

Пример 1
Эта функция заменяет значение ячейки Cell1 на значение ячейки Cell2 увеличенное на 100. Сама функция размещается в третьей ячейке, чтобы не возникла циклическая ссылка.

Function Primer1(Cell1 As Range, Cell2 As Range)
  Cell1.Replace Cell1, Cell2 + 100
End Function

В этом примере мы не присваиваем пользовательской функции значение, поэтому отображается значение по умолчанию – 0. Если объявить эту функцию как строковую: Function Primer1(Cell1 As Range, Cell2 As Range) as String, будет возвращена пустая строка.

Изменение значения ячейки C1 (Cell2) приведет к пересчету значения ячейки B1 (Cell1).

Попробуйте очистить или перезаписать ячейку B1 (Cell1), ничего не получится, так как функция Primer1 вновь перезапишет ее значением C1 (Cell2) + 100.

Метод Application.Volatile

Application.Volatile – это метод, который запускает пересчет функции при изменении значения любой ячейки рабочего листа, а не только той, которая присвоена объявленной в функции переменной. Метод Application.Volatile используется только в функциях.

Рассмотрим пересчет функции на следующем примере:

Пример 2

Function Primer2(Cell1 As Range, Cell2 As Range) As String
  Cell1.Replace Cell1, Cell2 + 100
  Range("B2").Replace Range("B2"), Range("C2") + Cell1
End Function

Эта функция будет пересчитываться только при изменении значений ячеек B1 и C1, присвоенных переменным Cell1 и Cell2. При изменении значения ячейки C2, значение ячейки B2 не изменится, так как не будет запущен пересчет функции Primer2.

Функция Primer2 начнет вести себя по-другому, если добавить в нее оператор Application.Volatile (переименуем ее в Primer3):

Пример 3

Function Primer3(Cell1 As Range, Cell2 As Range) As String
  Application.Volatile
  Cell1.Replace Cell1, Cell2 + 100
  Range("B2").Replace Range("B2"), Range("C2") + Cell1
End Function

Теперь при смене значения в ячейке C2, значение ячейки B2 тоже изменится.

В предыдущих примерах функциям не присваивалось конечное значение, чтобы показать, что такое возможно. При присвоении значения пользовательской функции следует следить за тем, чтобы не возникало циклических ссылок между ячейками с изменяемыми функцией значениями, в том числе и той, в которой размещена функция.

Безопасное использование функции

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

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

В простых случаях для выбора можно использовать функцию Choose или, в более сложных, оператор If...Then...Else и оператор Select Case.

Пример 4
Используем функцию Choose для выбора способа вычисления пользовательской функции в зависимости от значения дополнительного аргумента:

Function Primer4(Cell1 As Range, Cell2 As Range, a As Byte)
  On Error Resume Next
  Primer4 = Choose(a, Cell1 + Cell2, Cell1 - Cell2, Cell1 * Cell2)
End Function

В функцию Primer4 добавлен дополнительный аргумент a, от которого зависит, какое действие будет произведено со значениями ячеек B1 и C1:

На следующем скриншоте представлены результаты вычисления функции в зависимости от значения аргумента a:

  1. В ячейке A1 вычисляется сумма значений ячеек B1 и C1 – аргумент a=1.
  2. В ячейке A2 вычисляется разность значений ячеек B2 и C2 – аргумент a=2.
  3. В ячейке A3 вычисляется произведение значений ячеек B3 и C3 – аргумент a=3.

Пример 5
Используем оператор If...Then...Else в сокращенном виде (If...Then...) для выбора способа вычисления функции в зависимости от значения дополнительного аргумента:

Function Primer5(Cell1 As Range, Cell2 As Range, a As Byte)
  If a = 1 Then Primer5 = Cell1 + Cell2
  If a = 2 Then Primer5 = Cell1 - Cell2
  If a = 3 Then Primer5 = Cell1 * Cell2
End Function

Результаты будут те же, что и в четвертом примере.

Содержание рубрики VBA Excel по тематическим разделам со ссылками на все статьи.

Добавить комментарий

Ваш комментарий будет опубликован после прохождения обязательной модерации. Исходящие ссылки не допускаются. Время модерации составит от нескольких минут до нескольких часов в зависимости от времени суток и занятости модератора. При добавлении в комментарий кода VBA Excel, вставьте перед его началом тег [vb] и по окончании кода - [/vb].