在自动计算之前等待外部数据加载? Excel中/ VBA

第一次海报,一直在寻找一个解决scheme,但没有运气。

解释我的问题:术语:OPC =对象链接和embedded(OLE)用于过程控制(允许其他应用程序使用来自PLC标签的数据)PLC =可编程逻辑控制器(用于过程控制的计算机SCADA =监控和数据采集显示来自PLC的值并允许控制)

我有一个excel工作簿,在PLC对一些值进行sorting后的特定时间,由SCADA系统(WonderWare> Intouch,软件)自动打开。 本工作手册使用OPC客户端填充其单元,使用以下方法访问它们:

=OPCLINK|EAST!'r[BELLWWPOWER]DailyValues_Z3[1,21]' 

这工作得很好,但有很多细胞填充,所以需要几秒钟。

我想要自动发生的是这些单元格填充和任何计算完成之前,所有具有公式的单元格更改为这些公式的值。 工作簿然后保存在一个新的工作簿名称(“PowerReports-YesterdaysDate”)与VBA代码剥离和两个工作簿closures(不保存原始,保存公式)。

这一切都运行良好,除非发生得太快,新保存的副本最终在所有带有OPC链接的单元中都只有“#N / A”。 当我将第一张工作表的专用子工具设置为“Worksheet_Activate()”而不是“Worksheet_Calculate()”时,代码将不会自动统计并等待鼠标单击到其中一个工作表的单元格上(FYI:SCADA系统将打开此工作簿打印1自动开始与表1的代码)。 在这种情况下,新副本将成功保存,但是当代码自动统计时,速度太快。 在计算完成之前,如何等待外部数据加载?

我已经尝试了一些东西(我不知道它们是如何实现的),如下所示:-Application.Calculate -Application.RefreshAll -Timers – 尝试从PLC获取一个标记 – 检查剩余的#N / As

看起来如果一个循环或类似的东西正在运行,它不会让外部数据刷新。

 Private Sub Worksheet_Calculate() ' When first sheet "Main" is activated, all formulas are replaced ' with their calculated values. The second sheet, "Monthly Values" is then activated Dim rng As Range, r As Range Set rng = Range("A1:D52") For Each r In rng If r.HasFormula Then r.Value = r.Value End If Next r Worksheets("Monthly Data").Activate End Sub Private Sub Worksheet_Activate() ' When second sheet "Monthly Values" is activated, all formulas are replaced ' with their calculated values. The sub routine, "SaveWithoutMacros" is then called Dim rng As Range, r As Range Set rng = Range("A1:BJ84") 'Worksheets("Monthly Data").Calculate 'If Not Application.CalculationState = xlDone Then 'DoEvents 'End If For Each r In rng If r.HasFormula Then r.Value = r.Value End If Next r Call SaveWithoutMacros End Sub Sub SaveWithoutMacros() 'Purpose : To save a copy of the active workbook without macros Dim vFilename As String Dim wbActiveBook As Workbook '---------------------------------------------------------------------- 'Following two lines causes an error in Excel 97 - comment them out Dim VBComp As VBIDE.VBComponent Dim VBComps As VBIDE.VBComponents '---------------------------------------------------------------------- ' Save to filename in format (yesterdays date) "PowerReports-DD-MM-YYYY" vFilename = ("D:\PowerReports\" & "PowerReport-" _ & Format(Date - 1, "DD-MMM-YYYY") & ".xls") ActiveWorkbook.SaveCopyAs vFilename Set wbActiveBook = Workbooks.Open(vFilename) 'Now strip all VBA, modules, userforms from the copy 'This code is from Chip Pearson's website http://www.cpearson.com Set VBComps = wbActiveBook.VBProject.VBComponents For Each VBComp In VBComps Select Case VBComp.Type Case vbext_ct_StdModule, vbext_ct_MSForm, vbext_ct_ClassModule VBComps.Remove VBComp Case Else With VBComp.CodeModule .DeleteLines 1, .CountOfLines End With End Select Next VBComp wbActiveBook.Save ' saves new version after code is stripped ThisWorkbook.Saved = True ' sets save flag to true, does not actually save Application.Quit ' quits entire application, all workbooks End Sub 

对不起,这个冗长的post,看到别人因为不够细致而被撕掉,哈哈。

这应该适用于你现在通过testing只填写最后一个单元格,然后你将确保所有的数据在你把它们改为值之前

基本上告诉worksheet_calculate什么都不做,直到最后一个单元格有一个公式

注意:请参阅下面的修改代码以了解SCADA状况

  Private Sub Worksheet_Calculate() Dim rngLastCell As Range Set rngLastCell = Range("D52") If rngLastCell.HasFormula Then Dim rng As Range, r As Range Set rng = Range("A1:D52") For Each r In rng If r.HasFormula Then r.Value = r.Value End If Next r Worksheets("Monthly Data").Activate End If End Sub 

结束了! 感谢史蒂文·马丁给我一个跳转点,让你的工作,直到你发布你的答案我不认为如果没有循环if语句工作。

这对我来说是有效的:

  Private Sub Worksheet_Calculate() Dim rngLastCell As Range Set rngLastCell = Range("D52") If WorksheetFunction.IsNA(rngLastCell) = False Then Dim rng As Range, r As Range Set rng = Range("A1:D52") For Each r In rng If r.HasFormula Then r.Value = r.Value End If Next r Worksheets("Monthly Data").Activate End If End Sub 

然后在第二张表的代码中检查“#N / A”的同样的IF语句,现在就像是魅力一样。