Пересчет пользовательских функций в excel

 

Excell 2003. Вставил  модуль с пользовательской функцией. При этом ячейки с формулами, содержащими эту функцию не пересчитываются автоматически — только при пинке Alt-Ctrl_F9. В  настройках, ессно, указано пересчитывать автоматом. Формулы, не обращающиеся к этой функции пересчитываются нормально, автоматом. Вопрос: Как заставить пересчитывать автоматом ВСЕ формулы, даже включающие пользовательские функции.

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

Добавить в функции другие, летучие.

 

Добавьте в текст каждой пользовательской функции, желательно первым исполняемым оператором:  
Application.Volatile

 

Увы, не помогает ни тот ни другой ни оба вместе… :-(((  
Ничего не изменилось. Не помогает даже изменение высоты строки (мышкой)  
Функция для подсчета ячеек с определённым цветом фона:  

  Function color_count(my_range As Range, active_color_cell As Range) As Integer  
Application.Volatile  
curdate = Now() — 1  
color_count = 0  
active_color = active_color_cell.Interior.ColorIndex  

  For Each cc In my_range.Cells  

  If cc.Interior.ColorIndex = active_color Then  
color_count = color_count + 1  
End If  

  Next cc  
End Function

 

Libera

Пользователь

Сообщений: 112
Регистрация: 01.01.1970

привяжите пересчет к событию Worsheet_SelectionChange и после смены фона ячейки переходите на другую ячейку

 

Если не сложно, можно чуть подробнее, что вписать в тело модуля?  

  Private Sub Worksheet_SelectionChange(ByVal Target As Range)  

  ?????????????????????  

  End Sub

 

Application.Calculate — все книги и листы  
или  
Target.Worksheet.Calculate — лист, на котором произошло событие  

  пс. это не «тело модуля», это тело процедуры ;)

 

The_Prist, а Target.Worksheet.Calculate не сработает? или медленнее будет на пару миллионных долей секунды? :)

 

Спасибо. Заработало.  
Но обнаружился пренеприятнейший побочный эффект: невозможность вставки. В меню пункт «вставить» неактивен (хотя в буфере есть данные), а при выполнении, например, кода:  

  Columns(«A:B»).Select  
   Selection.Copy  
   Columns(«BA:BB»).EntireColumn.Select  
   ActiveSheet.Paste  

  выдаётся сообщение об ошибке.  

  Может у кого есть ещё идеи???

 

Me.usedrange.Calculate  
Работает без побочных эффектов!!!  

  Спасибо всем принявшим участие, и отдельное спасибо The_Prist!!!

 

ясно, а то я испугался немножко поначалу.  
согласен, Me — и короче, и красивше.  
просто до сих пор я до этого не дошёл.  
теперь запомню, спасибо.

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

Дим, а чем плохо  
Range(«A:B»).Copy [BA1]
?

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

И правильней:  
Intersect(ActiveSheet.UsedRange, [a:b]).Copy [ba1]

Я сам — дурнее всякого примера! …

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

А как в таком выражении со второй строки?  
Range(«BA:BB»).EntireColumn  
или в таком:  
Range(«A:B»).Copy [BA1]
Но во всех случаях(кроме случая, когда столбец полностью заполнен) решает  
Intersect(ActiveSheet.UsedRange, [a:b]).Copy [ba1]

Я сам — дурнее всякого примера! …

 

ikki

Пользователь

Сообщений: 9709
Регистрация: 22.12.2012

{quote}{login=KukLP}{date=11.04.2011 07:29}{thema=}{post}Но во всех случаях(кроме случая, когда столбец полностью заполнен) решает  
Intersect(ActiveSheet.UsedRange, [a:b]).Copy [ba1]{/post}{/quote}

  а если UsedRange на листе начинается не с первой строки?  
результат будет немного неожиданным для пользователя? :)

фрилансер Excel, VBA — контакты в профиле
«Совершенствоваться не обязательно. Выживание — дело добровольное.» Э.Деминг

 

KuklP

Пользователь

Сообщений: 14868
Регистрация: 21.12.2012

E-mail и реквизиты в профиле.

#16

11.04.2011 19:46:18

А почему мы априори считаем пользователя полным идиотом? И кто ему мешает вместо [BA1] указать [BA5] и т.д. И UsedRange врядли будет часто ерзать по листу. Но если так уж хочется копировать колонки целиком — на здоровье, есть предыдущие два варианта. Вариант с Intersect как раз для того, чтоб не копировать лишнее.

  П.С. если задаться целью придумывать разные А ЕСЛИ, то и за комп садиться не стоит:-)

Я сам — дурнее всякого примера! …

stalkervfrc

0 / 0 / 1

Регистрация: 09.08.2018

Сообщений: 14

1

09.08.2018, 20:57. Показов 3916. Ответов 5

Метки function, запуск команд, пересчет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте. Написал функцию в Excel, которая производит суммирование ячеек с определённым цветом фона для определённого диапазона ячеек

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
Public Function суммп(Table As Range)
Dim summ As Double
summ = 0
For i = 1 To Table.Rows.Count
    For j = 1 To Table.Columns.Count
        If Table(i, j).Interior.Color = 14277081 Then
            summ = summ + Table(i, j).Value
        End If
    Next j
Next i
суммп = summ
End Function

Проблема в том, что когда я меняю цвет ячейки в заданном диапазоне не происходит автоматического пересчёта.
Знаю что сочетание клавиш Ctrl + Alt + F9 запустит пересчёт. Но у меня имеется ещё ряд Функций которые работают с большим массивом данных, и каждый такой перезапуск это 3-5 секунд ожидания.

Вопрос в том как запустить пересчёт определённой функции?



0



6599 / 4709 / 1961

Регистрация: 02.02.2014

Сообщений: 12,616

09.08.2018, 21:23

2

повесить конкретный макрос на кнопку или задать свою комбинацию клавиш…



0



stalkervfrc

0 / 0 / 1

Регистрация: 09.08.2018

Сообщений: 14

09.08.2018, 22:00

 [ТС]

3

Лучший ответ Сообщение было отмечено The trick как решение

Решение

Добавлено через 1 минуту
Krasme, В том и суть вопроса, как в макросе обратиться к этой функции? Да и как задать сочетание клавиш для функции я тоже не знаю (((

Добавлено через 25 минут
Нашёл решение своей проблемы, добавил следующую строку в функцию и теперь пересчёт происходит при нажатии сочетания клавиш Ctrl + «в», добавленная строка выглядит следующим образом:

Visual Basic
1
Application.MacroOptions Macro:="суммп", ShortcutKey:="^в"

Макрос в целом выглядит вот так:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
Public Function суммп(Table As Range)
Application.MacroOptions Macro:="суммп", ShortcutKey:="^в"
Dim summ As Double
summ = 0
For i = 1 To Table.Rows.Count
    For j = 1 To Table.Columns.Count
        If Table(i, j).Interior.Color = 14277081 Then
            summ = summ + Table(i, j).Value
        End If
    Next j
Next i
суммп = summ
End Function



0



pashulka

4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

09.08.2018, 22:26

4

stalkervfrc, Вот так можно работать и с несмежными диапазонами, типа =SumColor((A1:A10;E1:E10))

Visual Basic
1
2
3
4
5
6
7
8
Public Function SumColor#(r As Range, Optional color2& = 14277081)
    Dim c As Range
    For Each c In r
        If c.Interior.color = color2 Then
           SumColor = SumColor + c.Value
        End If
    Next
End Function



2



0 / 0 / 1

Регистрация: 09.08.2018

Сообщений: 14

09.08.2018, 22:37

 [ТС]

5

pashulka, Спасибо, такая функция изящнее. Но проблема таже. При изменении цвета одной из ячеек диапазона, не происходит автоматического пересчёта, при использовании предложенного Вами кода. Тот вариант который я написал выше работает, но коряво, данное сочетание помимо запуска пересчёта копирует вышестоящую ячейку с оформлением.

А вот как правильнее назначить сочетание клавиш или как с помощью макроса обратиться к функции вопрос всё ещё открыт.



0



pashulka

4131 / 2235 / 940

Регистрация: 01.12.2010

Сообщений: 4,624

09.08.2018, 22:50

6

stalkervfrc, Я не отвечал на Ваш вопрос, а просто намекнул, что при работе с несмежными диапазонами For Each более правильный вариант.

Что касается исходного задания, то если заменить Application.MacroOptions на

Visual Basic
1
Application.Volatile True

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

А если захотите пересчитать функцию программно, то

Visual Basic
1
Range("A1").Calculate



2



Я
   dk

30.11.05 — 09:56

В excel прописал в VBA свою функцию

Добавил в столбце вызов своей функции.

Затем зашел в VBA и изменил свою функцию, сохранил.

Проблема:

Не пересчитывается столбец с вызовом моей функции, т.е. если зайти в ячейку и нажать Enter, то пересчитывается, но только в этой ячейке.

Пробовал сервис — параметры — вычисления — (стоит галка автоматически) Вычислить и пересчет листа — не помогает :(

——-

ЗЫ В функции простой case

   dk

1 — 30.11.05 — 10:14

Up мне

   dk

2 — 30.11.05 — 10:31

Блин, даже после закрытия excel и открытия файл заново данные не пересчитываются

   Бит

3 — 30.11.05 — 10:43

Вы не пробовали Хелпом пользоваться?  В меню Сервис выберите команду Параметры, а затем — вкладку Вычисления.

Запись макросов тоже не кто не отменял  Calculate.

   dk

4 — 30.11.05 — 10:47

2(Бит) А если внимательно перечитать (0)?

Понимаю, что много буков, но нужно

   Бит

5 — 30.11.05 — 10:51

(4)ActiveSheet.Calculate

З.Ы. «Заводы стоят, а в стране одни гтьаристы»(с)

   Билли Г

6 — 30.11.05 — 10:53

Добавь в свою функцию конструкцию

Application.Volatile True

тогда будет пересчитываться при любых чихах на листе…

  

dk

7 — 30.11.05 — 11:01

2(Билли Г) Спасибо

2(Бит) Опять мимо :)

Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн

Модератор:Naeel Maqsudov

a.p.

Сообщения:3
Зарегистрирован:01 сен 2008, 19:28

Здравствуйте.
Бьюсь с одной распространненой проблемой — пересчет пользовательских функций (VBA UDF) по нажатию на F9 или Ctrl+F9. Как известно, UDF пересчитывается только при изменении какого-нибудь входного параметра. А как организовать пересчет UDF при каждом нажатии F9 или Ctrl+F9 (даже если параметры остались прежними)? Метод volatile абсолютно не подходит, т.к на листе содержится достаточно много данный (по этой же причине отпадает вариант Ctrl+Alt+F9). Я пытался что-то организовать с использованием Application event SheetCalculate, но безуспешно :(
Буду рад любым советам.
Спасибо.

a.p.

Сообщения:3
Зарегистрирован:01 сен 2008, 19:28

23 сен 2008, 11:41

Serge_Bliznykov писал(а):а можно пример конкретного файла, где это нужно и не работает?

согласен с Вами — информации, конечно, недостаточно.
Дело в том, что проблема изначально связана с использованием C++ функции, созданной в C++ XLL. В качестве параметра, ей передается строка — название некоторого объекта, также созданного в C++. С течением времени содержимое данного объекта меняется, но Excel не может об этом знать, т.к параметр-строка остается неизменной (если пользователь нажмет Ctrl+Alt+F9 функция естественно пересчитается, однако этот вариант не устраивает). Я пытался схитрить и поместить вызов данной функции в специально созданную VBA-функцию, используя для этого Application.Run(«xllFunction», objectId), где objectId имеет тип string. Далее я пытался заставить Excel пересчитывать данную VBA-функцию по каждому нажатию F9, но ничего не получилось :(

Аватара пользователя

Aent

Сообщения:1108
Зарегистрирован:01 окт 2006, 14:52
Откуда:Saratov,Russia
Контактная информация:

23 сен 2008, 20:40

a.p.,постановка специфическая … IMHO надо при модификации вашего объекта менять
какую то ячейку в EXCEL а в функции добавить значение этой ячейки аргументом. Или включить её значение в выражение, использующее вашу UDF

Андрей Энтелис,
aentelis.livejournal.com

a.p.

Сообщения:3
Зарегистрирован:01 сен 2008, 19:28

23 сен 2008, 23:36

Aent, совершенно правильное предложение. Опять моя ошибка, что не объяснил и этот момент. Действительно можно сделать аргумент trigger, который будет ссылаться на ячейку, изменяющуюся при модификации объекта (более того, такая возможность существует). Однако данный вариант тоже не устраивает — аналогичных функций достаточно много на рабочей книги, как и объектов, к которым они обращаются, т.ч пользователю просто не удобно дополнительно каждый раз еще и ссылаться на какие-то ячейки. Именно поэтому возникла идея создания промежуточных VBA-функций, т.к была надежда, что их пересчет можно вызвать

Аватара пользователя

Aent

Сообщения:1108
Зарегистрирован:01 окт 2006, 14:52
Откуда:Saratov,Russia
Контактная информация:

24 сен 2008, 14:42

a.p.,определите в EXCEL имя ИМЯ_ОБЪЕКТА вида =СЦЕПИТЬ(«ИМЯ_ОБЪЕКТА»;ТДАТА())
и обращайтесь к вашей функции с этим ИМЕНЕМ в качестве аргумента
=YourUDF(ИМЯ_ОБЪЕКТА)
Единственно что нужно будет проинструктировать пользователя что бы он не указывал при вызове кавычек вокруг имени объекта
И всё по F9 будет пересчитываться…
Более того, если вы всё таки будете изменять при изменении вашего объекта Worksheet, то перехватывая Worksheet_Change для нужной ячейки и выдавая
Worsheet(…).Calculate,
вы полностью автоматизируете процесс

Андрей Энтелис,
aentelis.livejournal.com

Vlanib

Сообщения:2
Зарегистрирован:18 сен 2008, 14:03

29 сен 2008, 13:56

…Как известно, UDF пересчитывается только при изменении какого-нибудь входного параметра. А как организовать пересчет UDF при каждом нажатии F9 или Ctrl+F9 (даже если параметры остались прежними)?…

Конечно не буду оригинален, но cntr+shift+alt+F9 — безусловный пересчет листа, независимо от изменения аргументов. Т.е. ивент Worksheet_Calculate вызывается по любому!

  • Remove From My Forums

 none

Автопересчет пользовательских функций

  • Вопрос

  • В модуле объявляю пользовательскую функцию:

    Public Function mysumm()
    mysumm = Cells(1, 1) + Cells(1, 2)
    End Function

    Вставляю  через меню «Вставка» эту функцию в клетку, например, B5 и, изменяя содержимое клеток Cells(1, 1) и Cells(1, 2), ожидаю, что функция сработает автоматически и посчитает сумму? однако, этого не происходит. Функция работает только в момент ввода или F2-Enter.
    Вопросы:
    1. это невозможно?
    2. мне не хватает знаний?
    3. как заставить пользовательскую функцию листа автоматически пересчитываться при изменении содержания зависимых полей?

    Функцию листа =СУММ(A1;B1) не предлагайте, пожалуйста. Я для простоты упростил пример, а реальная задача намного сложнее.
    Я пробовал во всех версиях Excel вплоть до 2007.
    Буду  очень благодарен за любой ответ.
    Владимир.
    моб +7 903 6688938
    vshullman@mail.ru

    • Изменено

      17 июля 2009 г. 14:33
      недосмотр

Ответы

  • Владимир,

    1) Мне очень жаль, но это 2-й пункт вашего списка :-)

    2) Для того чтобы функция сама определяла изменились ли входящие параметры, нужно задавать их как аргументы. Т.е.:

    Public Function mysumm(Arg1, Arg2)
          mysumm = Arg1 + Arg2
    End Function

    Если такое невозможно (а это в 99.9% случаев возможно), то есть вариант сделать формулу летучей, чтобы она пересчитывала при каждом событи вызывающем пересчет независимо от того, изменились ли входящие параметры или нет.

    Public Function mysumm(Arg1, Arg2)
         Application.Volatile 
         mysumm = Arg1 + Arg2
    End Function
    

     Но это крайне нежелательно особенно если, как вы говорите, расчет сложный.

    3) Пользовательские функции написанные в VBA опять-таки в 99.9% случаев в разы медленнее стандартных функций листа, т.ч., если скорость пересчета имеет значение, то пользовательские функции — это последний ресурс

    4) Если вы выложите полный код вашей функци, то, возможно, эту «сложную задачу» не так уж сложно решить стандартными функциями рабочего листа (во всяком случае так часто бывает)

    5) Вот тут еще немного основ создания UDF (пользовательских функций):
    http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx


    Si la respuesta te es de utilidad por favor marca la pregunta como respondida.

Понравилась статья? Поделить с друзьями:
  • Пересчет одной ячейки excel
  • Пересчет одной книги excel
  • Пересчет листа в excel что это
  • Пересчет как ячейке в excel
  • Пересчет значений в excel