Vba excel формула не пересчитывает

 

Иван Фильченков

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

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

#1

23.07.2016 10:39:24

Доброго всем времени суток.
Прошу помощи в решение проблемки.
Есть макрос, он подставляет значение и выводит на печать определенные листы, выполняет это в цикличности.
Т.е. вставил значение — отправил на печать, следущее вставил — отправил на печать.
Но файл большой и он не успевает обновить все формулы (пересчитать)
Как прописать в макросе после подстановки значения пересчет формул?
Макрос прилагаю

Код
Sub АОСР()

    Dim c As Range, el
    Application.ScreenUpdating = False
    With Sheets("ФормаСети")
        For Each c In .Range(.Range("F57"), .[F57].End(xlDown)).Cells
            Sheets("ФОРМА").Range("DF123") = c.Value
            Sheets(Array("1ГидИз1", "2Гео", "3ГидИз2", "3ГидИз2", "4Тран", "5РазрТрКол", "6ПеОснКол", "7ПеОснКан", "8МонтТруб", "9БетЗам", "10ОбЗасПеТр", "11БетЛот", "12ШтукКол", "13МонтКол", "14ОбрЗасПеКол", "15МонГол", "16ОбрЗасГрТр", "17ОбрЗасГрКол")).Select
            ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
                ThisWorkbook.Path & Application.PathSeparator & c.Value & ".pdf", Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
        Next
    End With
    Application.ScreenUpdating = True
End Sub
 

JayBhagavan

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

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

ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64

#2

23.07.2016 10:51:22

Если стоит автомат. пересчёт, то перед печатью добавьте строку:

Код
doevents

<#0>
Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori

 

Извините я полный профан в макросах, это перед какой строчкой?

 

JayBhagavan

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

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

ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64

Попробуйте между 7 и 8 строками.

<#0>
Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori

 
 

Юрий М

Модератор

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

Контакты см. в профиле

 

Karataev

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

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

#7

23.07.2016 11:16:27

Если формулы только на листе «ФОРМА»:

Скрытый текст

Если формулы на листе «ФОРМА» и на тех листах, которые Вы выделяете:

Скрытый текст

P.S. Я из цикла убрал выделение листов, чтобы каждый раз листы не выделялись, т.к. достаточно выделить один раз.
Коды не тестировал, поэтому возможны опечатки или ошибки.

 

спасибо, сейчас попробую
не не изменяет, не пересчитывает (((

Изменено: Иван Фильченков23.07.2016 11:33:58

 

Karataev

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

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

#9

23.07.2016 11:45:45

Пересчет на всех листах активной книги и на всех листах всех других открытых книг:

Код
Sub АОСР()
    Dim c As Range, el
    Application.ScreenUpdating = False
    Sheets(Array("1ГидИз1", "2Гео", "3ГидИз2", "3ГидИз2", "4Тран", "5РазрТрКол", "6ПеОснКол", "7ПеОснКан", "8МонтТруб", "9БетЗам", "10ОбЗасПеТр", "11БетЛот", "12ШтукКол", "13МонтКол", "14ОбрЗасПеКол", "15МонГол", "16ОбрЗасГрТр", "17ОбрЗасГрКол")).Select
    With Sheets("ФормаСети")
        For Each c In .Range(.Range("F57"), .[F57].End(xlDown)).Cells
            Sheets("ФОРМА").Range("DF123") = c.Value
            Application.Calculate
            ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
                ThisWorkbook.Path & Application.PathSeparator & c.Value & ".pdf", Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
        Next
    End With
    Application.ScreenUpdating = True
End Sub
 

JayBhagavan

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

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

ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64

Попробуйте после пересчёта добавить рекомендуемую мной ранее команду.

<#0>
Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori

 

не пересчитывает, пересчитывает только после первой подстановке (((

 

JayBhagavan

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

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

ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64

Иван Фильченков, сделайте файл-пример и приложите к теме, чтобы не гадать больше. И озвучьте что у Вас за офис (год, разрядность) и ОС.

<#0>
Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori

 

Karataev

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

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

#13

23.07.2016 12:11:46

Может быть убрать ScreenUpdating. В этом коде нет обновления формул (то есть это Ваш первоначальный код, только я вынес из цикла выделение листов):

Код
Sub АОСР()
    Dim c As Range, el
    Sheets(Array("1ГидИз1", "2Гео", "3ГидИз2", "3ГидИз2", "4Тран", "5РазрТрКол", "6ПеОснКол", "7ПеОснКан", "8МонтТруб", "9БетЗам", "10ОбЗасПеТр", "11БетЛот", "12ШтукКол", "13МонтКол", "14ОбрЗасПеКол", "15МонГол", "16ОбрЗасГрТр", "17ОбрЗасГрКол")).Select
    With Sheets("ФормаСети")
        For Each c In .Range(.Range("F57"), .[F57].End(xlDown)).Cells
            Sheets("ФОРМА").Range("DF123") = c.Value
            ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
                ThisWorkbook.Path & Application.PathSeparator & c.Value & ".pdf", Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=False
        Next
    End With
End Sub

Изменено: Karataev23.07.2016 12:13:02

 

Юрий М

Модератор

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

Контакты см. в профиле

Иван Фильченков, Calculate пробовали?

 

Karataev

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

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

Юрий М, да я предлагал Calculate в постах 7 и 9.

 

Karataev

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

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

#16

23.07.2016 12:15:16

Цитата
Иван Фильченков написал:
пересчитывает только после первой подстановке (((

а в каком коде пересчитывает? В Вашем исходном или в том, который я предложил? Или при использовании DoEvents?

 

Юрий М

Модератор

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

Контакты см. в профиле

#17

23.07.2016 12:19:56

Цитата
Karataev написал:
Юрий М, да я предлагал Calculate в постах 7 и 9

Я вижу, но мой вопрос автору темы )

 

Раньше был мой исходный код и он пересчитывался. Сейчас файл большой 20 метров и много связей как и листов и он перестал все пересчитывать.
Офис 13

 

Да делал, пересчета после подстановки нет (

 

Karataev

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

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

Иван Фильченков, а код из поста 13 пробовали? Только у Вас должен быть включен автоматический пересчет формул: вкладка «Формулы» — Параметры вычислений — Автоматически.

 

Юрий М

Модератор

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

Контакты см. в профиле

#21

23.07.2016 12:35:21

Цитата
Karataev написал: у Вас должен быть включен автоматический пересчет формул

Думаю, что автор проверил это первым делом.

 

Я конечно чайник, но действительно сразу проверил

 

Karataev

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

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

Иван Фильченков, ну так что, Вы тестировали код из поста 13?

 

Попробовал, результат тот же, не пересчитывает ((

 

Karataev

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

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

#25

23.07.2016 14:30:42

Может быть какие-нибудь косвенные действия делать, чтобы обновились формулы. Попробуйте такой способ:

Скрытый текст

 

Попробовал, не обновляет.
Странно то что мой исходный файл раньше работал и все обновлялось. Что же может быть такое?? ((

 

Karataev

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

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

#27

23.07.2016 14:49:57

А так? Макрос сохраняет файл после каждого изменения ячейки «DF123»:

Скрытый текст

 

Извини за дурацкий вопрос, я в макросах совсем ни как, но он где должен быть записан, сейчас он у меня торчит в Module4. Это может как то сказаться на его работоспособности?
Последний тоже код не обновляет ((

Изменено: Иван Фильченков23.07.2016 15:20:04

 

Karataev

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

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

Вставьте его туда, где у Вас был Ваш код.

 

Karataev

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

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

#30

23.07.2016 15:01:14

А вручную, когда Вы изменяете ячейку «DF123», формулы обновляются сейчас?

In VBA, I am updating the formula in a cell (which works ok), but automatic recalculation does not work:

updated_formula = "=COUNT(Sheet1!A3:A" & nr_points & ")"
Cells(x, y).Formula = updated_formula
ActiveWorkbook.Save
Cells(x, y).Calculate

The formula simply counts the number of existing rows in another sheet. When I run the macro, the cell’s value in the function textfield is correct, but in the cell itself I have "#NAME?" and I need to press ENTER in the function to recalculate the formula.

Am I expecting too much of Excel? Or am I doing something wrong?

EDIT: Screenshot of the situation — this is what I see after running the macro.
(Sorry for the black censoring, have to maintain anonimity for the client company)

enter image description here

1) А если все-таки покажите нам снимок этого белого куска.

2) Если виновата память, нужно провести тест стабильности компонентов и предоставить полный отчет о параметрах Вашей системы. Готовы к этому?

Цитата
Сообщение от Дундук
Посмотреть сообщение

Не нравится идея сносить все не разобравшись.

Мне тоже не нравится.
Но иногда даже полного обнуления настроек бывает недостаточно. Если таки решитесь, нужно делать не просто переустановку, а со сбросом настроек (уже не помню поможет ли способ № 2, я лично использовал способ № 4 по приведенной выше ссылке). И даже в этом случае на одном и компьютеров продолжала возникать проблема.

Шаблон должен влиять на создаваемую, а не открываемую книгу.
На открываемую могут влиять макросы, записанные в личную книгу макросов, если такие имеются.

3) Вот еще попробуйте добавить новую подпрограмму в один из своих модулей:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sub auto_open()
with application
  Application.Volatile
  .Calculation = xlCalculationAutomatic
  .ScreenUpdating = true
  .EnableEvents = true
  With .ErrorCheckingOptions
      .BackgroundChecking = true
      .NumberAsText = true
      .InconsistentFormula = true
  End With
  .CalculateFull
end with
end sub

4) Как вариант, может там установлен Excel со специфической локализацией. Т.о. формулы не распознаются.

5) Поставьте курсор на ячейку, которая у Вас якобы не вычисляется -> правая кнопка мыши -> форма ячеек -> какой у Вас показан установленый формат ячеек (общий, текстовой, числовой) ?

6) Если поставить курсор в эту ячейку, затем нажать {F2} и затем {ENTER} — значение в ячейке будет пересчитано?

7) Зайдите ПУСК -> Панель управления -> Часы язык и регион -> Язык и региональные стандарты -> Дополнительные параметры -> Вкладка «Числа» -> Разделитель целой и дробной части -> Какой разделитель установлен? Должен быть знак запятой (,) После применения изменений перезагрузите компьютер.

Функция не пересчитывается при открытии документа

maonang

Дата: Четверг, 14.12.2017, 18:55 |
Сообщение № 1

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Доброго времени суток.
Использую Excel 2016.Структура документа (для понимания): В документе ведется учет сотрудников некой фирмы с формированием статистических данных.
Листы:
— приложения отчета, в которые сводятся все данные по критериям отбора сотрудников;
— список сотрудников с указанием личных данных и перерасчетом стажа работы (и многое другое);
— список сотрудников по отделам с подкатегориями:
Принятые на работу
* Руководители
* Специалисты
* Технические исполнители
Уволенные с работы
* Руководители
* Специалисты
* Технические исполнителиЗадача, при решении которой возникла проблема:
Необходимо сформировать отчет, в котором будет подсчитано количество сотрудников по трем критериям:
1. Возраст — попадание возраста сотрудника в один из шести диапазонов (1) до 30 лет, 2) от 30 до 39 лет и т.д.)
2. Специальность — одна из четырех специальностей (Врач, ММП, СМП, Прочие)
3. Образование — одно из шести вариантов (среднее полное, среднее специальное, высшее, 2 и более высших, основное общее и неполное высшее). Два последних входят по отдельности в сумму к среднему полному и среднему специальному.

Данный отчет должен содержать в себе статистику из трех подразделов принятых сотрудников (Руководители, Специалисты и Технические исполнители)

Проблема заключается в том, что ячейки, в которых записан вызов макроса, реализующий выполнение поставленной задачи, не обновляют данные при открытии документа, выводят везде ноль вместо того, что должно быть.
Если в таких ячейках нажать F2, а потом Enter, то данные пересчитываются локально.
Комбинации F9 и Shift+F9 не помогают.
Параметры вычислений везде стоят в автоматическом режиме (На панели и во вкладке Параметры — Формулы).
Остальные мною написанные функции сбоя при работе не дают, но они не обрабатывают массив данных через циклы.

Макрос прописан в модуле под стандартным названием «Module1».

Текст макроса:
[vba]

Код

Public Function КоличествоТекущийГод(ДиапазонНачало, ДиапазонКонец As Integer, _
                    СпециальностьНазвание As String, _
                    СпециальностьСтолбец As Range, _
                    Высшее As String, _
                    ОбразованиеСтолбец, КНСтолбец, ДНСтолбец, ВозрастСтолбец As Range) As Integer
    ‘Application.Volatile
    Dim ОбщаяСумма As Integer
    ОбщаяСумма = 0
    Dim i As Integer
        For i = ДиапазонНачало To ДиапазонКонец Step 1
            If cells(i, ВозрастСтолбец.Column).Value <> «» And _
               cells(i, СпециальностьСтолбец.Column).Value = СпециальностьНазвание Then
               If cells(i, ОбразованиеСтолбец.Column).Value = «+» Or (Высшее <> «» And _
               (cells(i, КНСтолбец.Column).Value = «+» Or _
                cells(i, ДНСтолбец.Column).Value = «+»)) Then
                   ОбщаяСумма = ОбщаяСумма + 1
               End If
           End If
       Next i
    КоличествоТекущийГод = ОбщаяСумма
End Function

[/vba]

Упрощенную выдержку из рабочей таблицы прилагаю в формате xls 2003. В основном документе много других расчетов и выделений ячеек по условиям.

Как сделать автоматическое обновление значений ячеек с использованием вышеуказанного макроса при изменении данных и перезапуске самого документа?

К сообщению приложен файл:

12.xls
(71.0 Kb)

Сообщение отредактировал maonangПятница, 15.12.2017, 02:47

 

Ответить

sboy

Дата: Пятница, 15.12.2017, 11:41 |
Сообщение № 2

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2566


Репутация:

724

±

Замечаний:
0% ±


Excel 2010

Добрый день.
Вот эту строчку расскоментируйте(удалить апостроф в начале)
[vba][/vba]


Яндекс: 410016850021169

 

Ответить

maonang

Дата: Пятница, 15.12.2017, 15:09 |
Сообщение № 3

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Это была одна из попыток решить проблему.

Цитата

Вот эту строчку расскоментируйте(удалить апостроф в начале)

Убрал комментирование — при открытии по прежнему нули (данные не обновляются)

 

Ответить

sboy

Дата: Пятница, 15.12.2017, 15:46 |
Сообщение № 4

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2566


Репутация:

724

±

Замечаний:
0% ±


Excel 2010

maonang, а по F9 пересчитывает? Проверьте тогда автопересчет формул (может вручную в книге стоит)
я на вашем примере удалял данные, функция пересчитывалась.


Яндекс: 410016850021169

 

Ответить

maonang

Дата: Пятница, 15.12.2017, 18:05 |
Сообщение № 5

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Цитата

а по F9 пересчитывает? Проверьте тогда автопересчет формул (может вручную в книге стоит)
я на вашем примере удалял данные, функция пересчитывалась.

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

Только после «перерасчета» формул в проблемных ячейках через комбинацию клавиш F2 -> Enter, данные изменяются при корректировке значений в связных ячейках.
F9 до вышеописанного действия не дает результата.

Сообщение отредактировал maonangПятница, 15.12.2017, 18:10

 

Ответить

InExSu

Дата: Пятница, 15.12.2017, 23:20 |
Сообщение № 6

Группа: Друзья

Ранг: Ветеран

Сообщений: 646


Репутация:

96

±

Замечаний:
0% ±


Excel 2010

Привет!
Вставил в код
[vba][/vba]
Сохранил, закрыл, запустил.
При запуске видно, что код работает.

К сообщению приложен файл:

1651267.jpg
(31.3 Kb)


Разработчик Битрикс24 php, Google Apps Script, VBA Excel

 

Ответить

maonang

Дата: Суббота, 16.12.2017, 03:39 |
Сообщение № 7

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Привет, InExSu.
Я попробовал добавить оператор Stop в макрос. При открытии документа на нем остановка не происходит, значит, макрос не выполняется.
Перерасчет происходит только тогда, когда идет изменение указанных в аргументе функции ячеек. Это логично. А так как в реализации задачи используются адреса на динамически изменяющийся диапазон, то значения в ячейках с данной функцией изменяться не будут при корректировке данных самих сотрудников..
Спасибо за предложение, InExSu.
Возник дополнительный вопрос: учитывая данное исполнение листа проще сделать перерасчет формул после нажатия дополнительной кнопки или как-то можно без вмешательства пользователя обойтись?

Сообщение отредактировал maonangСуббота, 16.12.2017, 03:40

 

Ответить

InExSu

Дата: Суббота, 16.12.2017, 08:49 |
Сообщение № 8

Группа: Друзья

Ранг: Ветеран

Сообщений: 646


Репутация:

96

±

Замечаний:
0% ±


Excel 2010


Что у вас с «Центр управления безопасностью»? Там много опций …


Разработчик Битрикс24 php, Google Apps Script, VBA Excel

 

Ответить

maonang

Дата: Суббота, 16.12.2017, 13:43 |
Сообщение № 9

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Цитата

Что у вас с «Центр управления безопасностью»? Там много опций …

Параметры ActiveX:

  • Включить все элементы управления

Параметры макросов:

  • Включить все макросы
  • Доверять доступ к объектной модели проектов VBA

Защищенный просмотр — Все CheckBox сняты
Внешнее содержимое:

  • Включить все подключения к данным
  • Включить автоматическое обновление для всех связей в книге

Параметры блокировки файлов — Не менял

Остальные параметры, думаю, описывать не нужно, так как они не влияют на работу формул и макросов.

 

Ответить

maonang

Дата: Вторник, 19.12.2017, 15:46 |
Сообщение № 10

Группа: Пользователи

Ранг: Прохожий

Сообщений: 7


Репутация:

0

±

Замечаний:
0% ±


Excel 2013

Проблема решена. Нужно было в качестве аргумента добавить диапазон с данными сотрудников, чтобы при изменении или открытии документа пересчитываемые параметры влияли на ячейки с указанным выше макросом.
Измененный макрос (добавлен аргумент ДиапазонДляПерерасчета):
[vba]

Код

Public Function КоличествоТекущийГод(ДиапазонНачало, ДиапазонКонец As Integer, _
                    СпециальностьНазвание As String, _
                    СпециальностьСтолбец As Range, _
                    Высшее As String, _
                    ОбразованиеСтолбец, КНСтолбец, ДНСтолбец, ВозрастСтолбец, ДиапазонДляПерерасчетаТекущийЛист, ДиапазонДляПерерасчетаСведенияОСотрудниках As Range) As Integer
    ‘Привязка к листу, от которого происходит вызов функции
    Dim ws As Worksheet
        Set ws = Application.Caller.Worksheet
    Dim ОбщаяСумма As Integer
    ОбщаяСумма = 0
    Dim i As Integer
        For i = ДиапазонНачало To ДиапазонКонец Step 1
            If ws.cells(i, ВозрастСтолбец.Column).Value <> «» And _
               ws.cells(i, СпециальностьСтолбец.Column).Value = СпециальностьНазвание Then
               If ws.cells(i, ОбразованиеСтолбец.Column).Value = «+» Or (Высшее <> «» And _
               (ws.cells(i, КНСтолбец.Column).Value = «+» Or _
                ws.cells(i, ДНСтолбец.Column).Value = «+»)) Then
                   ОбщаяСумма = ОбщаяСумма + 1
               End If
           End If
       Next i
    КоличествоТекущийГод = ОбщаяСумма
End Function

[/vba]

Формула в одной из ячейки (добавлен диапазон в конце A:AD):
[vba]

Код

=КоличествоТекущийГод($N104;$N105;»В»;$P$1;»»;$AB$2;$AD$2;$AE$2;$F$2;A:AD)+КоличествоТекущийГод($N104;$N105;»В»;$P$1;»»;$AC$2;$AD$2;$AE$2;$F$2;A:AD)

[/vba]

Но возникла немного другая. Если перейти в другой лист, изменить там данные, то значения ячеек, с которыми была проблема, обнуляются.
Почему так может происходить? Попробовал передать в качестве аргумента диапазон столбцов другого листа, но нули так и остались.

Сообщение отредактировал maonangСреда, 20.12.2017, 15:40

 

Ответить


Re[9]: Пересчет формул в Excel

От:

PA

 
Дата:  05.06.07 13:13
Оценка:

23 (2)

Как вариант — пересчитывать только ячейки с определённой формулой:

Dim r As Range
    
For Each r In Application.Cells.SpecialCells(xlCellTypeFormulas, xlTextValues)
    If InStr(1, r.Formula, "=НужнаяФормула()", vbTextCompare) > 0 Then
        r.Dirty
    End If
Next
If Application.Calculation = xlCalculationManual Then Application.Calculate


Re[3]: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  04.06.07 12:56
Оценка:

14 (2)

Здравствуйте, Аноним, Вы писали:

А>так я тоже пробовал, у меня 10 страничек и на каждой по 10 000 формул и когда начинается любые изменения на страничке всё невероятно медленно перерисовываются. Есть ещё предложения?

1) Если речь именно о данных из базы, возможно, имеет смысл использовать QueryTable — такая разновидность связанных таблиц — лист привязывается к данным, может обновляться автоматически или по запросу.

2) Если формулы, то использовать формулы массива, поскольку по каждой формулы идет вызов, лучше если сразу для нескольких ячеек делается. Обычно, если много формул, они именно относятся к однородным данным, которые можно передать в виде массива, и в виде массива вернуть результат.

3) Я в таких случаях предлагаю довольно нудную конструкцию, предполагающую переход на ручной пересчет и пересчет только конкретных формул. Имеет смысл, если функции в одной книге собраны функции из базы, например, а других нет. Примерно это выглядит так:

При открытии книги для всех листов свойство EnableCalculation устанавливается в False, а пересчет в Автоматический
Перед сохранением книги пересчет устанавливается в ручной, а после сохранения восстанавливается автоматический, чтобы не влиять на другие книги.

Таким образом, мы добиваемся того, что автоматически вообще ничего не пересчитывается.

А потом, для расчета конкретного диапазона используется конструкция следующего типа, то есть в любой момент автоматический расчет отключен, поэтому ничего лишнего не происходит. Такой «шлюз» образуется.

    Application.Calculation = xlCalculationManual
    wks.EnableCalculation = True
    wks.Range("D2:D500").Calculate
    wks.EnableCalculation = False
    Application.Calculation = xlCalculationAutomatic

Но это вариант на крайний случай. По 10 000 формул — первое — это попробовать свести их к формулам массива.

Пользователь — друг программиста!

От: Аноним

 
Дата:  04.06.07 10:33
Оценка:

Я создал пару формул в Excel ( UDF ). Эти формулы подгружают данные с сервера и не зависят от других ячеек. Какой код VBA в Excel может пересчитать значения этих формул для активной книги с сервера принудительно ( данные поменялись только на сервере и Excel об этом «не знает» ).
Обычный Calculate не помогает ( он пересчитывает только если формула зависит от других ячеек, которые поменялись), CalculateAll помогает, но он пересчитывает во всех книгах Excel — так не подходит.


Re: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  04.06.07 10:40
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Я создал пару формул в Excel ( UDF ). Эти формулы подгружают данные с сервера и не зависят от других ячеек. Какой код VBA в Excel может пересчитать значения этих формул для активной книги с сервера принудительно ( данные поменялись только на сервере и Excel об этом «не знает» ).

А>Обычный Calculate не помогает ( он пересчитывает только если формула зависит от других ячеек, которые поменялись), CalculateAll помогает, но он пересчитывает во всех книгах Excel — так не подходит.

см. Application.Volatile в начале функции, тогда будут пересчитываться по Calculate

Пользователь — друг программиста!


Re[2]: Пересчет формул в Excel

От: Аноним

 
Дата:  04.06.07 11:40
Оценка:

так я тоже пробовал, у меня 10 страничек и на каждой по 10 000 формул и когда начинается любые изменения на страничке всё невероятно медленно перерисовываются. Есть ещё предложения?

Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, Аноним, Вы писали:


А>>Я создал пару формул в Excel ( UDF ). Эти формулы подгружают данные с сервера и не зависят от других ячеек. Какой код VBA в Excel может пересчитать значения этих формул для активной книги с сервера принудительно ( данные поменялись только на сервере и Excel об этом «не знает» ).

А>>Обычный Calculate не помогает ( он пересчитывает только если формула зависит от других ячеек, которые поменялись), CalculateAll помогает, но он пересчитывает во всех книгах Excel — так не подходит.

E_>см. Application.Volatile в начале функции, тогда будут пересчитываться по Calculate


Re[4]: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  04.06.07 13:21
Оценка:

Здравствуйте, Elena_, Вы писали:

И совсем забыла, вариант 4) часто совсем это не должны быть собственно формулы, а структура листа известна заранее. Тогда можно просто сделать выборку, подключаясь из программы, например при помощи ADO, получить курсор, выложить данные на лист функцией CopyFromRecordset — очень быстрая операция, просто данные как массив копируются во внутреннюю память листа. Это очень быстрый вариант, формулы для получения данных из базы нужны только тогда, когда пользователь хочет лист по-своему макетировать каждый раз и по-разному, это довольно редко бывает. Это, на мой взгляд, предпочтительнее QueryTable, так как гибче, хотя qt позволяют настроить автоматическое обновление.

Пользователь — друг программиста!


Re[4]: Пересчет формул в Excel

От: Аноним

 
Дата:  04.06.07 15:30
Оценка:

большое спасибо за большой ответ, но он не подходит
Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, Аноним, Вы писали:


А>>так я тоже пробовал, у меня 10 страничек и на каждой по 10 000 формул и когда начинается любые изменения на страничке всё невероятно медленно перерисовываются. Есть ещё предложения?


E_>1) Если речь именно о данных из базы, возможно, имеет смысл использовать QueryTable — такая разновидность связанных таблиц — лист привязывается к данным, может обновляться автоматически или по запросу.

знаю есть такое, но у меня пользователи выстраивают данные как им угодно и привязки не подойдут, потому что тогда будет прямая связь Excel — БД, что не приемлимо, у меня идет связь через IIS сервер который отдает xml по запросам из Excel.

E_>2) Если формулы, то использовать формулы массива, поскольку по каждой формулы идет вызов, лучше если сразу для нескольких ячеек делается. Обычно, если много формул, они именно относятся к однородным данным, которые можно передать в виде массива, и в виде массива вернуть результат.

Вместо массива я пользую xml, почти то же самое но проще в связи со спецификой данных. И вот как раз то что xml изменился Excel не знает и когда я жму кнопку «перегрузить», этот внутренний xml перегружается с сервера а данные в формулах не меняются.

E_>3) Я в таких случаях предлагаю довольно нудную конструкцию, предполагающую переход на ручной пересчет и пересчет только конкретных формул. Имеет смысл, если функции в одной книге собраны функции из базы, например, а других нет. Примерно это выглядит так:


E_>При открытии книги для всех листов свойство EnableCalculation устанавливается в False, а пересчет в Автоматический

E_>Перед сохранением книги пересчет устанавливается в ручной, а после сохранения восстанавливается автоматический, чтобы не влиять на другие книги.

E_>Таким образом, мы добиваемся того, что автоматически вообще ничего не пересчитывается.


E_>А потом, для расчета конкретного диапазона используется конструкция следующего типа, то есть в любой момент автоматический расчет отключен, поэтому ничего лишнего не происходит. Такой «шлюз» образуется.

E_>

E_>    Application.Calculation = xlCalculationManual
E_>    wks.EnableCalculation = True
E_>    wks.Range("D2:D500").Calculate
E_>    wks.EnableCalculation = False
E_>    Application.Calculation = xlCalculationAutomatic
E_>


E_>Но это вариант на крайний случай. По 10 000 формул — первое — это попробовать свести их к формулам массива.

этот вариант тоже не подходит, потому что он не пересчитает формулы строчкой worksheet.calculate которые зависят от глобального xml, Excel просто не видит что их надо пересчитывать.


Re[5]: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  04.06.07 17:27
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Вместо массива я пользую xml, почти то же самое но проще в связи со спецификой данных. И вот как раз то что xml изменился Excel не знает и когда я жму кнопку «перегрузить», этот внутренний xml перегружается с сервера а данные в формулах не меняются.

Формулы массива — это разновидность формул Excel, которые получают в качестве входных параметров диапазоны (что иногда и обычные формулы получают) и возвращают массивы, которые размещаются в диапазонах Excel. Главная экономия идет за счет того, что один вызов заполняет сразу много ячеек. К xml не имеет вроде бы никакого отношения.

Если xml возвращается по запросам из Excel, можно сразу данные из него просто загрузить на скрытый лист, а формулы привязать к этому листу. Или это так и делается — тогда торможение связано исключительно с количеством пользовательских формул и к базе вообще не имеет отношения? Тогда вопрос в том, как ускорить работу пользовательских формул в книге, а есть база или нет — вообще не при чем? Можно оптимизировать пользовательские формулы различным кэшированием, например. Это кроме формул массива.

Пользователь — друг программиста!


Re[6]: Пересчет формул в Excel

От: Аноним

 
Дата:  05.06.07 06:36
Оценка:

Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, Аноним, Вы писали:

Уважаемый эксперт, мы совсем отошли от темы. Ведь вопрос был вообще простой — «как принудительно заставить Excel пересчитать формулы».
Application.CalculateAll — не подходит, он пересчитает все книги, этого делать не надо,
*.Calculate — не подходит, он пересчитает только если исходные данные поменялись
Application.Volatile — не подходит, он тормозит
Менять идиалогию и объяснять пользователю что для того чтобы работали данные ему прийдется брать определенный Excel файл с кодом или научить его пользоваться мапингом xml-ячейка, вообще не надо.
Необходимо простое решение задачи: «как принудительно заставить Excel пересчитать формулы»

А>>Вместо массива я пользую xml, почти то же самое но проще в связи со спецификой данных. И вот как раз то что xml изменился Excel не знает и когда я жму кнопку «перегрузить», этот внутренний xml перегружается с сервера а данные в формулах не меняются.


E_>Формулы массива — это разновидность формул Excel, которые получают в качестве входных параметров диапазоны (что иногда и обычные формулы получают) и возвращают массивы, которые размещаются в диапазонах Excel. Главная экономия идет за счет того, что один вызов заполняет сразу много ячеек. К xml не имеет вроде бы никакого отношения.


E_>Если xml возвращается по запросам из Excel, можно сразу данные из него просто загрузить на скрытый лист, а формулы привязать к этому листу. Или это так и делается — тогда торможение связано исключительно с количеством пользовательских формул и к базе вообще не имеет отношения? Тогда вопрос в том, как ускорить работу пользовательских формул в книге, а есть база или нет — вообще не при чем? Можно оптимизировать пользовательские формулы различным кэшированием, например. Это кроме формул массива.


Re[7]: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  05.06.07 09:44
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Уважаемый эксперт, мы совсем отошли от темы. Ведь вопрос был вообще простой — «как принудительно заставить Excel пересчитать формулы».

А>Application.CalculateAll — не подходит, он пересчитает все книги, этого делать не надо,
А>*.Calculate — не подходит, он пересчитает только если исходные данные поменялись
А>Application.Volatile — не подходит, он тормозит
А>Менять идиалогию и объяснять пользователю что для того чтобы работали данные ему прийдется брать определенный Excel файл с кодом или научить его пользоваться мапингом xml-ячейка, вообще не надо.
А>Необходимо простое решение задачи: «как принудительно заставить Excel пересчитать формулы»

Дело в том, что Application.Volatile и есть ответ, и довольно простой («Необходимо простое решение задачи»), но Вы говорите, что он тормозит, поэтому я и предложила другие решения. Тормозит не сам Application.Volatile, это просто указание Excel, что надо пересчитывать эту формулу.

Пользователь — друг программиста!


Re[8]: Пересчет формул в Excel

От: Аноним

 
Дата:  05.06.07 12:08
Оценка:

Здравствуйте, Elena_, Вы писали:

E_>Здравствуйте, Аноним, Вы писали:


А>>Уважаемый эксперт, мы совсем отошли от темы. Ведь вопрос был вообще простой — «как принудительно заставить Excel пересчитать формулы».

А>>Application.CalculateAll — не подходит, он пересчитает все книги, этого делать не надо,
А>>*.Calculate — не подходит, он пересчитает только если исходные данные поменялись
А>>Application.Volatile — не подходит, он тормозит
А>>Менять идиалогию и объяснять пользователю что для того чтобы работали данные ему прийдется брать определенный Excel файл с кодом или научить его пользоваться мапингом xml-ячейка, вообще не надо.
А>>Необходимо простое решение задачи: «как принудительно заставить Excel пересчитать формулы»

E_>Дело в том, что Application.Volatile и есть ответ, и довольно простой («Необходимо простое решение задачи»), но Вы говорите, что он тормозит, поэтому я и предложила другие решения. Тормозит не сам Application.Volatile, это просто указание Excel, что надо пересчитывать эту формулу.

Да решение простое, но Application.Volatile говорит о том что формулу нужно всегда пересчитывать при любых событиях в документе. И тогда например когда у меня в другой книге, связанной с этой начнуться сильные изменения то формулы будут пересчитываться ВСЕ а это больше 100 000 действий которые должно происходить тоько по моей команде.


Re[9]: Пересчет формул в Excel

От:

Elena_

Россия

 
Дата:  05.06.07 13:07
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Да решение простое, но Application.Volatile говорит о том что формулу нужно всегда пересчитывать при любых событиях в документе. И тогда например когда у меня в другой книге, связанной с этой начнуться сильные изменения то формулы будут пересчитываться ВСЕ а это больше 100 000 действий которые должно происходить тоько по моей команде.

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

См. еще ссылку Excel User-Defined Functions и там пункт
UDF not recalculating or always recalculating or calculating in an unexpected sequence. Может быть, что-то оттуда пригодится.

Пользователь — друг программиста!


Re[10]: Пересчет формул в Excel

От: Аноним

 
Дата:  06.06.07 06:36
Оценка:

Здравствуйте, PA, Вы писали:

PA>Как вариант — пересчитывать только ячейки с определённой формулой:

PA>

PA>Dim r As Range
    
PA>For Each r In Application.Cells.SpecialCells(xlCellTypeFormulas, xlTextValues)
PA>    If InStr(1, r.Formula, "=НужнаяФормула()", vbTextCompare) > 0 Then
PA>        r.Dirty
PA>    End If
PA>Next
PA>If Application.Calculation = xlCalculationManual Then Application.Calculate
PA>

Благодарю за ответ, я его немного развил и получил такое элегантное и быстрое решение:
For Each wCurSheet In ActiveWorkbook.Worksheets
wCurSheet.Cells.Dirty
‘ wCurSheet.Calculate — можно убрать если Excel настроен так что идет автоматический пересчет формул
Next

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Like this post? Please share to your friends:
  • Vba excel формула листа
  • Vba excel указать лист
  • Vba excel указание листа
  • Vba excel узнать размерность массива
  • Vba excel узнать последнюю ячейку