Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何确保Excel计算在VBA过程中完成

如何确保Excel计算在VBA过程中完成
EN

Stack Overflow用户
提问于 2017-10-24 02:46:53
回答 2查看 5.8K关注 0票数 1

在excel-电子表格中,用户定义的函数用于计算基本结果作为扩展表矩阵(复合元素的横截面值)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Public Function XSValues(inputRange as Range) as variant
    [...]
    ' returns an array and used as matrix-formula (Ctrl-Shift-Enter)
End Function

这些结果一方面在电子表格中使用。另一方面,根据这些电子表格结果中的一些值,使用VBA-过程来执行相对复杂和耗时的计算(结构模型的静态分析)。此过程由按钮触发。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Public Sub Recalculate()
    [...]
    myValue = range("SomeXLResult").Value
    ' calculation
    ' notification updates
    ' drawing
    ' places different results into cells
End Sub

现在,我的问题是,当触发Sub Recalculate时,扩展表计算是过时的。我发现在Excel 2016中,扩展表的计算被分割成多个线程。并且体验到用户交互有时比电子表格计算更快。

因此,我得到折旧值,以便在VBA-过程中进行进一步处理。我的问题是:如何保证从扩展表范围更新值?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-24 19:54:58

如果你在答案中解释的解决方案对你有用,那就太好了。我只是想知道您是否知道应用程序的AfterCalculate事件(https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-aftercalculate-event-excel):

只要计算完成,并且没有未完成的查询,就会发生此事件。在事件发生之前必须满足这两种条件。即使工作簿中没有工作表数据,也可以引发该事件,例如,无论何时完成整个工作簿的计算,并且没有查询正在运行。 外接程序开发人员使用AfterCalculate事件来知道工作簿中的所有数据何时已经通过任何可能正在进行的查询和/或计算完全更新。 此事件发生在所有工作表之后。算一算,图表。计算、AfterRefresh和SheetChange事件。它是在所有刷新处理和所有calc处理完成之后,以及在Application之后发生的最后一个事件。CalculationState设置为xlDone。

对您来说,这可能是一个更简单的实现。访问应用程序对象事件的诀窍是在类模块中声明它为WithEvents。举个例子,我调用了类clsAppEvents

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Option Explicit

Private WithEvents mApp As Application

Private Sub Class_Initialize()
    Set mApp = Application
End Sub

Private Sub mApp_AfterCalculate()
    Debug.Print "Calc ended at: " & Now
    ConsumeAfterCalculate
End Sub

在您的模块中,只需使用调用和事件处理代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Option Explicit

Private mAppEvents As clsAppEvents
Private mEnableConsume As Boolean

Public Sub RunMe()
    Set mAppEvents = New clsAppEvents
End Sub
Public Sub ConsumeAfterCalculate()
    If mEnableConsume Then
        Debug.Print "Sub called at: " & Now
        mEnableConsume = False
    End If
End Sub
Public Sub ConsumeButtonClick()
    Debug.Print "Button clicked at: " & Now
    mEnableConsume = True

    'For demo purposes I'm just forcing a calculation on existing data.
    Sheet1.EnableCalculation = False
    Sheet1.EnableCalculation = True
End Sub

FYI,调试结果如下:

按下按钮:2017年10月25日下午4:49:20。 加州大学洛杉矶分校于2017年10月25日下午4:49:22结束。 电话:2017年10月25日下午4:49:22。

票数 3
EN

Stack Overflow用户

发布于 2017-10-24 06:23:21

以下解决方案满足了我的需要:

按下重新计算按钮时,vba将检查当前Excel计算状态。在进行计算的情况下,直接启动计算Recalculate的VBA过程.如果计算模式挂起或正在计算,则只有本地工作表变量p_RecalcButtonClicked设置为true。在完成excel计算时,每个工作表在计算Worksheet_Calculate事件后触发事件。这样我们就可以指导Excel到Recalculate

作为一种安全措施,我使用函数the related two questions from the above comment在子Recalculate的开头保留了在waitForRecalculation中描述的解决方案。为了避免无所作为,我引入了一个计时器来告诉用户,如果计算不能在给定的时间内完成的话。

这是主要工作表的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
' ##### Worksheet-Code

'''
' Private Worksheet-Variable to determine, 
' if the button was pressed prior to worksheet calculated-event
'
Private p_RecalcButtonClicked As Boolean


'''
' Procedure to handle Button Clicked 
' (either using a shape with a macro assigned or 
'  an Active-X-Button with this procedure as event handler: best is to use {Button}_MouseUp as {Button}_clicked is fired occasionally by excel itself)
'
Public Sub ButtonClicked()
    '
    ' depending on the calculation state ...
    '
    Select Case Application.CalculationState
        Case xlDone
            '
            ' ... all done, fine ...
            ' ... directly call the calculation procedure sub Recalculate
            '
            p_RecalcButtonClicked = False
            Recalculate
        Case xlPending
            '
            ' ... pending ...
            ' ... set local worksheet variable true in order to call sub Recalculate
            '     later, when the calculated-event was raised
            '
            p_RecalcButtonClicked = True
            '
            ' instruct excel to recalculate
            '
            Application.CalculateFullRebuild
            '
            ' now let excel perform until worksheet calculated event is raised
            '
        Case xlCalculating
            '
            ' ... calculating ...
            ' ... set local worksheet variable true in order to call sub Recalculate
            '     later, when the calculated-event was raised
            '
            p_RecalcButtonClicked = True
            '
            ' let excel continue until worksheet calculated event is raised
            '
        Case Else
    End Select
    
End Sub


'''
' worksheet calculation finished
' this event is raised AFTER calculation was finished
' (shold actually be named Worksheet_Calculated)
'
Private Sub Worksheet_Calculate()
    ' check if the RecalcButton was clicked 
    If p_RecalcButtonClicked Then
        p_RecalcButtonClicked = False
        Recalculate
    End If
End Sub

'''
' Recalculation
'
Public Sub wm_Recalculate()
        '
        ' wait for calculation to be done
        ' just in case...
        '
        If Not waitForRecalculation Then
            MsgBox "Press Ctrl+Alt+F9 for full recalculation", vbCritical + vbOKOnly, "Excel-calculation not done"
            Exit Sub
        End If

        ' [...] Your calculation here...
End Sub

'''
' Helper function to wait and do events until Excel-calculations are done
' returns true if calculation is done within the given time
'
Public Function waitForRecalculation() As Boolean

    Const MAXTIME_S = 10

    Dim t As Double
    t = Timer()


    ' in case of sql-async queries this might be required
    ' 
    ' Application.CalculateUntilAsyncQueriesDone
    
    '
    ' As a safety net,
    ' the second solution is to
    ' do System events until calculation is done
    '
    If Application.CalculationState <> xlDone Then
        Do
            DoEvents
            If Timer() - t > MAXTIME_S Then Exit Do
        Loop Until Application.CalculationState = xlDone
    End If

    '
    ' return true if calculations are done
    '
    waitForRecalculation = (Application.CalculationState = xlDone)

End Function
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46908493

复制
相关文章
Python 按分类权重(区间)随机获取分类样本
活动抽奖,参与抽奖产品有iphone, 华为,小米,魅族,vivo,三星手机,要求为这些不同品牌的手机设置被抽奖的概率(基准概率,非绝对概率,即允许存在一定偏差),iphone为0,华为0.35,小米为0.25, 魅族0.1,vivo和三星为0.15
授客
2020/11/24
9510
Python 按分类权重(区间)随机获取分类样本
如何在Redhat中配置R环境
R是一套完整的数据处理、计算和制图软件系统。其功能包括:数据存储和处理系统;数组运算工具(其向量、矩阵运算方面功能尤其强大);完整连贯的统计分析工具;优秀的统计制图功能;简便而强大的编程语言:可操纵数据的输入和输出,可实现分支、循环,用户可自定义功能。本文档主要讲述如何在Redhat中使用源码方式编译安装及配置R的环境。
Fayson
2018/03/29
3K0
如何在Redhat中配置R环境
如何在R中绘制热力地图
本文介绍了如何利用R语言中的maps包和mapdata包绘制地图,并通过热力地图展示数据分布情况。首先,通过map()函数创建地图对象,并获取每个区域的名字以及顺序。然后,在每个区域的名字和顺序后面,加上需要展示的数据以及经纬度。接着,根据数据的大小设置每个区域的颜色深浅,以区分不同的区域。最后,给地图加上地名标记,并添加热力地图元素。
Erin
2018/01/09
3.2K0
如何在R中绘制热力地图
如何在R中创建日历热图
首先,我们运行Paul Bleicher创建的calendarHeat函数以显示日历热图。 其次,我们创建一些随机的时间序列数据。 最后,我们在两个调色板中绘制时间序列。
用户1359560
2020/04/01
4.5K0
如何在R中创建日历热图
如何在R中绘制树图(TreeMap)
本文介绍了如何利用R语言中的Treemap函数绘制树图,并给出了一个实例,包括使用安装包、设定颜色范围、边框颜色、节点大小、填充颜色等参数。同时还介绍了两种方法,一是通过aggregate函数对数据进行分组,二是通过手动设置index和vSize、vColor、type等参数来绘制树图。
Erin
2018/01/09
5.3K0
如何在R中绘制树图(TreeMap)
如何在30天内,快速累积权重!
我们知道当一个新站建立的时候,快速累积权重很重要,它有利于提高搜索引擎的信任评级,最重要的一点就是有利于友情链接交换,快速的积累相关行业资源。
蝙蝠侠IT
2019/07/12
6110
如何在30天内,快速累积权重!
如何在CDSW中使用R绘制直方图
Cloudera的新产品CDSW(Cloudera Data Science Workbench)集成了R、Scala、Python2、Python3等语言进行统计和数据分析。本文档主要讲述如何在CDSW中使用R语言绘制直方图和饼图,并使用Hive数仓作为数据源。
Fayson
2018/03/29
3.4K0
如何在CDSW中使用R绘制直方图
【R语言】heatmap显示样本类型
今天我们接着讲绘制热图时候的一个小技巧,如何显示样本的类型。我们经常还在文章中看到类似下面这样的热图。会在列的上方用颜色标注样本的类型。这样可以一目了然的看出找到的差异表达基因能否很好的将不同类型的样本区分开。今天我们就来用R代码来实现。
生信交流平台
2022/09/21
6780
【R语言】heatmap显示样本类型
如何用R获取GEO样本信息
以GSE111229为例 方法一 1 下载并保存GEO数据 下载有error可以:设置镜像、访问外国网站、rm(list=ls())一下重试… library(GEOquery) GSE_name = 'GSE111229' options( 'download.file.method.GEOquery' = 'libcurl' ) #windows系统 gset <- getGEO( GSE_name, getGPL = F ) save( gset, file = 'gset.R
生信技能树
2019/05/08
1.8K0
如何用R获取GEO样本信息
SIGIR'23 清华 | 会话推荐中的兴趣趋势挖掘与样本权重自适应分配
标题:Mining Interest Trends and Adaptively Assigning Sample Weight for Session-based Recommendation 地址:https://arxiv.53yu.com/pdf/2306.11610.pdf 会议:SIGIR 2023 学校:清华
秋枫学习笔记
2023/08/18
4920
SIGIR'23 清华 | 会话推荐中的兴趣趋势挖掘与样本权重自适应分配
R语言系列第四期:①R语言单样本双样本差异性检验
之前详细介绍了利用R语言进行统计描述,详情点击:R语言系列第三期:③R语言表格及其图形展示、R语言系列第三期:①R语言单组汇总及图形展示、R语言系列第三期:②R语言多组汇总及图形展示
微点
2019/05/11
2.1K0
R语言参数检验 :需要多少样本?如何选择样本数量
参数检验受制于数据属性的假设。例如,t检验是众所周知的参数检验,假设样本均值具有正态分布。由于中心极限定理,如果样本量足够,测试也可以应用于非正态分布的测量。在这里,我们将研究t检验有效所需的大致样本数。
拓端
2020/11/11
7320
R语言参数检验 :需要多少样本?如何选择样本数量
R语言系列第四期:①R语言单样本双样本差异性检验
之前详细介绍了利用R语言进行统计描述,详情点击:R语言系列第三期:③R语言表格及其图形展示、R语言系列第三期:①R语言单组汇总及图形展示、R语言系列第三期:②R语言多组汇总及图形展示
百味科研芝士
2019/05/23
1.8K0
如何在R中操作非结构化数据?
本文由CDA作者库成员HarryZhu原创,并授权发布。 CDA作者库凝聚原创力量,只做更有价值的分享。 介绍 现代化数据科学中的 DataFrame 概念源起R语言,而 Python Pandas
CDA数据分析师
2018/02/24
3.3K0
如何在R中操作非结构化数据?
如何在Redhat中安装R的包及搭建R的私有源
继上一章如何在Redhat中配置R环境后,我们知道对于多数企业来说是没有外网环境的,在离线环境下如何安装R的包,能否搭建R的私有源对R的包进行管理。
Fayson
2018/03/29
4.2K0
如何在Redhat中安装R的包及搭建R的私有源
工具 | 如何在Python中调用R语言包?
R语言是非常强大的做统计分析和建模方面的开源软件,它有非常丰富的统计软件包,做统计可以说只有你想不到的,没有R办不到的。Python又是当下最流行的编程软件之一,Python也是开源的,包含了非常丰富的第三方库(如机器学习算法),那么如何让Python和R共同工作呢?利用Python中的rpy2包就可以实现这一想法。 如何安装rpy2? 首先需要安装Python的科学计算环境Anaconda和R软件(最好再安装个Rstudio,好用到爆的R软件IDE,安装和管理R包太方便了),安装好Anaconda和R软件
小莹莹
2018/04/24
12K0
工具 | 如何在Python中调用R语言包?
【DB笔试面试511】如何在Oracle中写操作系统文件,如写日志?
可以利用UTL_FILE包,但是,在此之前,要注意设置好UTL_FILE_DIR初始化参数。
AiDBA宝典
2019/09/30
28.8K0
【DB笔试面试511】如何在Oracle中写操作系统文件,如写日志?
如何在 Pycharm 中高效使用 R 语言 (图文详解)
最新的 Pycharm 大量更新了对 R 的功能支持,在 IntelliJ 的大名加持下,拥有自动补全代码(最新加入了机器学习的新特性),自动格式化代码,版本控制,以及大量的插件支持。
白墨石
2021/01/13
1.4K0
如何在 Pycharm 中高效使用 R 语言 (图文详解)
「R」TCGA barcode(样本ID)以及重名过滤
接触和分析过TCGA数据的朋友肯定会经常处理TCGA barcode的前15位(有时12位),实际从上图可以看出TCGA的barcode设计总共有28位之多。
王诗翔呀
2020/07/03
2.3K0
「R」TCGA barcode(样本ID)以及重名过滤
点击加载更多

相似问题

R:如何在样本权重中使用describe()

14

如何分配R中样本的权重

27

LightFM:权重和样本权重

12

如何在R中应用与NIS (国家住院患者样本)相关的权重

1227

如何在Keras中使用样本权重和数据增强?

12
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文