Изменение значений других ячеек из пользовательской функции VBA Excel с помощью методов Range.Replace и Application.Volatile. Примеры кода.
В первых двух параграфах описано нетрадиционное использование процедуры 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:
- В ячейке A1 вычисляется сумма значений ячеек B1 и C1 – аргумент a=1.
- В ячейке A2 вычисляется разность значений ячеек B2 и C2 – аргумент a=2.
- В ячейке 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 |
Результаты будут те же, что и в четвертом примере.
Содержание
- Метод Application.Volatile (Excel)
- Синтаксис
- Параметры
- Пример
- Поддержка и обратная связь
- Name already in use
- VBA-Docs / api / Excel.Application.Volatile.md
- Application Volatile VBA to Recalculate Function
- The VBA Tutorials Blog
- Introduction — Application.Volatile
- Example — Application.Volatile
- Tutorial — Application.Volatile
- Application Ideas — Application.Volatile
- VBA Excel. Изменение значений других ячеек из функции
- Функция с методом Range.Replace
- Метод Application.Volatile
- Безопасное использование функции
- Application.Volatile method (Excel)
- Syntax
- Parameters
- Example
- Support and feedback
Метод Application.Volatile (Excel)
Помечает определяемую пользователем функцию как переменную. Изменяемая функция должна пересчитываться при каждом вычислении в любых ячейках на листе. Неизменяемая функция пересчитывается только при изменении входных переменных. Этот метод не действует, если он не находится внутри определяемой пользователем функции, используемой для вычисления ячейки листа.
Синтаксис
expression. Volatile (Volatile)
выражение: переменная, представляющая объект Application.
Параметры
Имя | Обязательный или необязательный | Тип данных | Описание |
---|---|---|---|
Volatile | Необязательный | Variant | Значение true , чтобы пометить функцию как переменную. Значение false , чтобы пометить функцию как неизменяемую. Значение по умолчанию — True. |
Пример
В этом примере определяемая пользователем функция My_Func помечает как переменную. Функция будет пересчитываться при изменении значения любой ячейки в любой книге в окне приложения. Пересчет функции не ограничивается изменениями или циклами вычислений на листе, к которому применяется эта функция. Поэтому используйте его умеренно, чтобы избежать задержки вычислений.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Name already in use
VBA-Docs / api / Excel.Application.Volatile.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
Copy raw contents
Copy raw contents
Application.Volatile method (Excel)
Marks a user-defined function as volatile. A volatile function must be recalculated whenever calculation occurs in any cells on the worksheet. A nonvolatile function is recalculated only when the input variables change. This method has no effect if it’s not inside a user-defined function used to calculate a worksheet cell.
expression.Volatile (Volatile)
expression A variable that represents an Application object.
Name | Required/Optional | Data type | Description |
---|---|---|---|
Volatile | Optional | Variant | True to mark the function as volatile. False to mark the function as nonvolatile. The default value is True. |
This example marks the user-defined function My_Func as volatile. The function will be recalculated when any cell in any workbook in the application window changes value. Recalculation of the function is not restricted to changes or calculation cycles on the worksheet for which this function applies. Therefore, use it moderately to avoid calculation lag.
Источник
Application Volatile VBA to Recalculate Function
The VBA Tutorials Blog
Introduction — Application.Volatile
Placing Application.Volatile at the top of your custom VBA function makes your function recalculate each time a calculation occurs in another cell on your worksheet. By default, this does not happen. By default, user-defined functions (UDFs) are only recalculated when one of the arguments of the UDF is changed.
Let’s walk through an example of Application Volatility. We’ll make a function that returns the current time and we’ll see how it behaves differently when we change the Application.Volatile method.
Example — Application.Volatile
Make powerful macros with our free VBA Developer Kit
This is actually pretty neat. If you have trouble understanding or remembering it, our free VBA Developer Kit can help. It’s loaded with VBA shortcuts to help you make your own macros like this one — we’ll send a copy, along with our Big Book of Excel VBA Macros, to your email address below.
Tutorial — Application.Volatile
Notice the Application.Volatile at the top of the function. After pasting this function in a module in your VBA Editor, go to cell C2 and type =VolatileDemo(A1)
If formatted to time, the current time will show up in cell C2. Cell A1 is never used in our function, but it will help us understand what VBA volatility means.
Once you’ve done that, type something into cell A2. It doesn’t matter what you type.
What happened? A new time appeared in cell C2, even though we entered a value into a cell that had nothing to do with our custom function. That’s what happens when Application.Volatile is turned on (set to True). Whatever cell you change on your sheet will trigger your calculation to run again.
Let’s run an experiment. Delete the Application.Volatile line from your VBA function and run it one time. You’ll have to run your function once so the VBA compiler knows it’s no longer volatile.
Your macro will look like this:
and your spreadsheet should look something like this once you run your function again:
Now, I want you to change the value in cell A2, just like we did earlier.
The time in cell C2 did not change! Like I said, when Application.Volatile is set to false, the default, your function only recalculates when one of the arguments change.
To drive this point home, change the value in cell A1.
Recall, cell A1 is the cell that is fed into our custom VBA function. In other words, it’s an argument of our function. That’s why the time reported in cell C2 was updated once we changed the value in cell C2.
Application Ideas — Application.Volatile
Most UDFs have no reason to be volatile. Volatile functions take more calculation time and can produce answers that you didn’t really want. Instead, you should design your UDFs to accept the arguments that are crucial to the calculation and leave application volatility set to false.
However, if you still want to use Application.Volatile in your VBA functions, you know how it behaves and what you can expect.
Now you know everything you should need to know about Application.Volatile. When you’re ready to take your VBA to the next level, subscribe using the form below.
Ready to do more with VBA?
We put together a giant PDF with over 300 pre-built macros and we want you to have it for free. Enter your email address below and we’ll send you a copy along with our VBA Developer Kit, loaded with VBA tips, tricks and shortcuts.
Before we go, I want to let you know we designed a suite of VBA Cheat Sheets to make it easier for you to write better macros. We included over 200 tips and 140 macro examples so they have everything you need to know to become a better VBA programmer.
Источник
VBA Excel. Изменение значений других ячеек из функции
Изменение значений других ячеек из пользовательской функции VBA Excel с помощью методов Range.Replace и Application.Volatile. Примеры кода.
Функция с методом Range.Replace
Пользовательская функция не предназначена для изменения значений ячеек, кроме той, в которой она расположена. Попытка присвоить какое-либо значение из функции другой ячейке приводит к неработоспособности функции и отображению в ячейке, где она расположена, сообщения «#ЗНАЧ!».
Но, как ни странно, внутри процедуры Function работает метод Range.Replace, которым мы воспользуемся для изменения значений других ячеек из пользовательской функции.
Пример 1
Эта функция заменяет значение ячейки Cell1 на значение ячейки Cell2 увеличенное на 100. Сама функция размещается в третьей ячейке, чтобы не возникла циклическая ссылка.
В этом примере мы не присваиваем пользовательской функции значение, поэтому отображается значение по умолчанию – 0. Если объявить эту функцию как строковую: Function Primer1(Cell1 As Range, Cell2 As Range) as String , будет возвращена пустая строка.
Изменение значения ячейки C1 (Cell2) приведет к пересчету значения ячейки B1 (Cell1).
Попробуйте очистить или перезаписать ячейку B1 (Cell1), ничего не получится, так как функция Primer1 вновь перезапишет ее значением C1 (Cell2) + 100.
Метод Application.Volatile
Рассмотрим пересчет функции на следующем примере:
Пример 2
Эта функция будет пересчитываться только при изменении значений ячеек B1 и C1, присвоенных переменным Cell1 и Cell2. При изменении значения ячейки C2, значение ячейки B2 не изменится, так как не будет запущен пересчет функции Primer2.
Функция Primer2 начнет вести себя по-другому, если добавить в нее оператор Application.Volatile (переименуем ее в Primer3):
Пример 3
Теперь при смене значения в ячейке C2, значение ячейки B2 тоже изменится.
В предыдущих примерах функциям не присваивалось конечное значение, чтобы показать, что такое возможно. При присвоении значения пользовательской функции следует следить за тем, чтобы не возникало циклических ссылок между ячейками с изменяемыми функцией значениями, в том числе и той, в которой размещена функция.
Безопасное использование функции
Если вам все-таки хочется в важном проекте VBA Excel с помощью одной пользовательской функции изменять значения нескольких ячеек, есть полностью безопасный вариант.
Он заключается в добавлении дополнительного аргумента в пользовательскую функцию, с помощью которого для каждой ячейки можно вывести отдельный результат. Функция размещается в каждой изменяемой ячейке.
В простых случаях для выбора можно использовать функцию Choose или, в более сложных, оператор If…Then…Else и оператор Select Case.
Пример 4
Используем функцию Choose для выбора способа вычисления пользовательской функции в зависимости от значения дополнительного аргумента:
В функцию Primer4 добавлен дополнительный аргумент a, от которого зависит, какое действие будет произведено со значениями ячеек B1 и C1:
На следующем скриншоте представлены результаты вычисления функции в зависимости от значения аргумента a:
- В ячейке A1 вычисляется сумма значений ячеек B1 и C1 – аргумент a=1.
- В ячейке A2 вычисляется разность значений ячеек B2 и C2 – аргумент a=2.
- В ячейке A3 вычисляется произведение значений ячеек B3 и C3 – аргумент a=3.
Пример 5
Используем оператор If…Then…Else в сокращенном виде (If…Then…) для выбора способа вычисления функции в зависимости от значения дополнительного аргумента:
Источник
Application.Volatile method (Excel)
Marks a user-defined function as volatile. A volatile function must be recalculated whenever calculation occurs in any cells on the worksheet. A nonvolatile function is recalculated only when the input variables change. This method has no effect if it’s not inside a user-defined function used to calculate a worksheet cell.
Syntax
expression.Volatile (Volatile)
expression A variable that represents an Application object.
Parameters
Name | Required/Optional | Data type | Description |
---|---|---|---|
Volatile | Optional | Variant | True to mark the function as volatile. False to mark the function as nonvolatile. The default value is True. |
Example
This example marks the user-defined function My_Func as volatile. The function will be recalculated when any cell in any workbook in the application window changes value. Recalculation of the function is not restricted to changes or calculation cycles on the worksheet for which this function applies. Therefore, use it moderately to avoid calculation lag.
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Источник
Serge Пользователь Сообщений: 11308 |
Из справки: Вопрос: Зачем может понадобиться летучесть? |
Сергей, ну, предположим, вы написали UDF (пользовательскую функцию), вставили её на лист — она пересчитала и выдала какой-то результат. |
|
Serge Пользователь Сообщений: 11308 |
«…и она будет пересчитываться при любом изменении значений в листе, ДАЖЕ ТОМ, КОТОРОЕ ЕЕ НЕ КАСАЕТСЯ…» А что в ВБА нет метода, который пересчитывал бы функцию только при изменениях в зависимых ячейках? |
Serge Пользователь Сообщений: 11308 |
И чем тогда Volatile отличается от Calculate? |
Ну, метод Calculate — пересчитывает формулы на всех листах, в указанном листе, или в указанном диапазоне, а метод Volatile — помечает пользовательскую функцию как «летучую», чтобы она автоматически пересчиталась вместе с другими ячейками на листе. А «нелетучая» функция пересчитается лишь тогда, когда изменятся значения в зависимых ячейках, т.е. когда изменятся аргументы этой функции (а не любая ячейка на листе) P.S. Небольшой пример. |
|
{quote}{login=}{date=22.05.2010 01:12}{thema=}{post}Сергей, ну, предположим, вы написали UDF (пользовательскую функцию), вставили её на лист — она пересчитала и выдала какой-то результат. и т.п. |
|
Serge Пользователь Сообщений: 11308 |
|
{quote}{login=}{date=22.05.2010 01:12}{thema=}{post}…и она становится летучей — и работает как обычная функция листа Excel.{/post}{/quote} |
|
))) тогда так «…и работает как одна из 7 летучих функций Excel» )) |
|
{/quote}а если точнее, то их 7{/quote} |
|
{quote}{login=}{date=22.05.2010 06:54}{thema=Re: Re: }{post}{/quote}а если точнее, то их 7{/quote} Еще можно почитать тут: http://www.decisionmodels.com/calcsecretsi.htm |
|
{quote}{login=The_Prist}{date=22.05.2010 07:13}{thema=}{post}Добавлю, что для счастливых обладателей 2007 Офиса и старше функций 8. Еще есть СЛУЧМЕЖДУ. Если мне не изменяет память, то она тоже летучая…{/post}{/quote}действительно, как-то упустил из виду бывшую надстройку — пакет анализа спасибо за поправку. |
|
Serge Пользователь Сообщений: 11308 |
{quote}{login=KL}{date=22.05.2010 07:09}{thema=Re: Re: Re: }{post}В версиях с 97 по 2007 — это следующие функции: |
lapink2000 Пользователь Сообщений: 2186 |
#15 22.05.2010 23:53:05 {quote}{login=Serge 007}{date=22.05.2010 11:02}{thema=Re: Re: Re: Re: }{post}Т.е. ДРВ() — не летучая? KL |
title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date |
---|---|---|---|---|---|---|
Application.Volatile Method (Excel) |
vbaxl10.chm133230 |
vbaxl10.chm133230 |
excel |
Excel.Application.Volatile |
27047561-9d76-b37d-100d-1c58e6edf494 |
06/08/2017 |
Application.Volatile Method (Excel)
Marks a user-defined function as volatile. A volatile function must be recalculated whenever calculation occurs in any cells on the worksheet. A nonvolatile function is recalculated only when the input variables change. This method has no effect if it’s not inside a user-defined function used to calculate a worksheet cell.
Syntax
expression . Volatile( Volatile )
expression A variable that represents an Application object.
Parameters
Name | Required/Optional | Data Type | Description |
---|---|---|---|
Volatile | Optional | Variant | True to mark the function as volatile. False to mark the function as nonvolatile. The default value is True |
Example
This example marks the user-defined function «My_Func» as volatile. The function will be recalculated when any cell in any workbook in the application window changes value. Recalculation of the function is not restricted to changes or calculation cycles in the worksheet for which this function applies. Therefore, use it moderately to avoid calculation lag.
Function My_Func() Application.Volatile ' ' Remainder of the function ' End Function
See also
Concepts
Application Object
This Excel tutorial explains the use of Application Volatile Method to recalculate custom Function (User Defined Function).
You may also want to read:
Excel Workbook Calculation Automatic and Manual
In Excel VBA, you can create your own Functions, we call it User Defined Function (UDF), usually I simply call it custom Function. Function is a Procedure that can take argument and return a value.
There are two kinds of custom Functions.
The first kind does not need to reference to other Cells, the Function can have an argument with constant value or without an argument. For example, you can use Rnd Function inside a custom Function to generate a number, therefore you don’t need any reference.
The second kind needs to reference to other Cells and return a value. For example, you need to reference to a Range when you use SUM Function.
Excel uses a special mechanism to minimize the number of calculation to speed up the process. Excel builds “Dependency Trees”, which keeps track on the following changes
- Formulae/Names that have changed.
- Formulae containing Volatile Functions
- Formulae dependent on changed or volatile formulae or cells or names
Navigate to Excel Options to turn Workbook Calculation to Automatic, then your formula Cell will recalculate automatically if the relationship is in the Dependency Trees.
According to the above rules, Functions that do not depend on other changed cells would not recalculate, unless Application Volatile Method is used.
To illustrate the above concepts, I refer to the custom Functions I previously wrote.
Custom Function that do no require Application Volatile Method
In the previous post, I wrote a custom Function to count substring in a string, for example, it can count how many “p” appears in “apple”.
Public Function wCountSubStr(str As String, substr As String) As Integer lenstr = Len(str) lensubstr = Len(substr) For i = 1 To lenstr tempString = Mid(str, i, lensubstr) If tempString = substr Then count = count + 1 End If Next i wCountSubStr = count End Function
This Function requires two parameters, if you refer the argument to a Cell, the Function would recalculate automatically when the Cell changes.
For example, the formula recalculates every time A1 value is changed.
=wCountSubStr(A1,”p”)
Custom Function that requires Application Volatile Method
In the below example, the Function does not have any argument and the result depends on A1.
Function test() test = Range("A1").Value * 2 End Function
Excel cannot recognize you are referencing A1 value because Excel builds the Dependency Tree using reference in arguments but not VBA. So even if you change A1, the formula would not recalculate automatically.
If you insert Application Volatile Method in this Function, this Function will recalculate whenever a Cell is edited, regardless of whether it is Cell A1 or not, therefore Application Volatile should be avoided if possible as it slows down Excel performance.
Function test()
Application.Volatile
test = Range("A1").Value * 2
End Function
Outbound References
https://msdn.microsoft.com/en-us/library/office/ff195441.aspx