Worksheet_Change事件与实时数据馈送崩溃的Excel

我试图运行由Private Sub Worksheet_Change(ByVal target As Range)事件驱动的代码。 我希望我的代码能够实时分析数据,而不必每隔15-20分钟input一大块数据来分析新数据。

我试图运行的数据是通过API从数据服务提供的,并stream入我的Excel表格。 我使用了一个名为CMED.MA的函数,它有两个不同的参数(在当前不相关)。 它以滚动行的方式提供,所以你有一行,然后新的数据会在下一行,等等,有时它相当快(每隔几秒)…其他时间是非常停滞(每隔几分钟左右)。 注意:数据一次input一行

我创build了一堆函数来使用它们,并将它们存储在一个单独的模块(所有Public Functions )中,以保持工作表模块的清洁和简洁。

问题

在写了一小段文字来覆盖实时数据的分析之后,我想testing它(谢天谢地决定testing它),现在当我试图让代码在工作表模块中生效时,它完全崩溃了。 我必须closures源的数据馈送,以便我可以禁用工作表模块中的代码。 任何想法或明显的问题与我的代码? 这是我第一次尝试使用Worksheet_Change事件

工作表模块代码

 Option Explicit Private Sub Worksheet_Change(ByVal target As Range) Dim initialTradeStructure As String, finalTradeStructure As String, rawStructure As String 'RFQs If target.Item(1, 3) = "RequestForQuote" Then 'Do Nothing....no analysis of RFQs is necessary....will be filtered later 'Screen Trades ElseIf target.Item(1, 3) = "GlobexTrades" Then rawStructure = target.Item(1, 2) initialTradeStructure = Right(rawStructure, Len(rawStructure) - 4) 'Bulk of analaysis conducted in analsyis engine to keep worksheet code clean/short finalTradeStructure = OptionStructureAnalysisEngine(initialTradeStructure, target) 'Block screen represented as Multileg in datafeed structure ElseIf target.Item(1, 3) = "Block" Then If target.Item(1, 17) = "TRUE" Then rawStructure = target.Item(1, 2) initialTradeStructure = Right(rawStructure, Len(rawStructure) - 4) 'Bulk of analysis conducted in analysis engine to keep worksheet code clean/short finalTradeStructure = OptionStructureAnalysisEngine(initialTradeStructure, target) ElseIf target.Item(1, 17) = "FALSE" And target.Item(1, 16) = "FALSE" Then 'Live block trade Else 'Do Nothing....No analysis of single block legs is necessary End If End If If Not finalTradeStructure = "Nothing" Then target.Item(1, 1) = finalTradeStructure End If End Sub 

function模块

 Public Function OptionStructureAnalysisEngine(tradeStructure As String, tradeDataRange As Range) As String 'analyzes and translates tradeStructure and dataRange 'Driver Dim structureAssemblyString As String, optionType As String 'Tests for / in tradeStructure to determine if it's a LIVE option trade or if it's a multi leg structure If InStr(1, tradeStructure, "/") < 1 Then 'Declares LIVE and option Type structureAssemblyString = "LIVE " & GetOptionCodes(Mid(tradeStructure, 8, 2)) & " " & TranslateExpirationDate(Mid(tradeStructure, 11, 6)) _ & " " & GetCallOrPut(Mid(tradeStructure, 18, 1)) Else 'Place holder for multileg structures structureAssemblyString = "Nothing" End If OptionStructureAnalysisEngine = structureAssemblyString End Function Public Function GetOptionCodes(optionType As String) As String Select Case optionType Case "LO" GetOptionCodes = "WTI American" Case "OH" GetOptionCodes = "HO American" Case "OB" GetOptionCodes = "RB American" Case "LN" GetOptionCodes = "NG European" End Select End Function Public Function TranslateExpirationDate(expirationDate As Double) As String Select Case Right(expirationDate, 2) Case 1 TranslateExpirationDate = "F" & Mid(expirationDate, 3, 2) Case 2 TranslateExpirationDate = "G" & Mid(expirationDate, 3, 2) Case 3 TranslateExpirationDate = "H" & Mid(expirationDate, 3, 2) Case 4 TranslateExpirationDate = "J" & Mid(expirationDate, 3, 2) Case 5 TranslateExpirationDate = "K" & Mid(expirationDate, 3, 2) Case 6 TranslateExpirationDate = "M" & Mid(expirationDate, 3, 2) Case 7 TranslateExpirationDate = "N" & Mid(expirationDate, 3, 2) Case 8 TranslateExpirationDate = "Q" & Mid(expirationDate, 3, 2) Case 9 TranslateExpirationDate = "U" & Mid(expirationDate, 3, 2) Case 10 TranslateExpirationDate = "V" & Mid(expirationDate, 3, 2) Case 11 TranslateExpirationDate = "X" & Mid(expirationDate, 3, 2) Case 12 TranslateExpirationDate = "Z" & Mid(expirationDate, 3, 2) End Select End Function Public Function GetCallOrPut(legOption As String) As String 'Translates C to Call and P to Put in option Structure If legOption = "C" Then GetCallOrPut = "Call" ElseIf legOption = "P" Then GetCallOrPut = "Put" End If End Function 

我看不到你的数据,也看不到你的数据,也不知道这些子和函数如何与它们交互,但是这是我对你的问题的盲目重写。 我也重写了你的一个函数,使它更易读(对我来说)。

Sheet1 – 代码表

 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Target.Rows(1).Cells.Count = 18 Then 'set a custom error procedure; essentially revert to as normal as ppossible On Error GoTo bm_Safe_Exit 'turn off event handling so if anything is changed, the sub procedure does not try to walk on top of itself Application.EnableEvents = False 'only dim things now that you know that something is actually going to happen Dim iTS As String, fTS As String, rS As String 'always determine text comparisons as case-insensitive Select Case LCase(Target.Cells(1, 3).Value2) caae "requestforquote" 'do nothing caae "globextrades" rS = Target.Cells(1, 2).Value2 initialTritsadeStructure = Right(rS, Len(rS) - 4) 'Bulk of analaysis conducted in analsyis engine to keep worksheet code clean/short fTS = OptionStructureAnalysisEngine(iTS, Target) 'Block screen represented as Multileg in datafeed structure caae "block" 'Is this actually TRUE/FALSE or text...????!!!????? Select Case UCase(Target.Item(1, 17).Text) Case "TRUE" rS = Target.Item(1, 2).Value2 iTS = Right(rS, Len(rS) - 4) Case "FALSE" 'Bulk of analysis conducted in analysis engine to keep worksheet code clean/short fTS = OptionStructureAnalysisEngine(iTS, Target.Cells(1, 1)) '<~~ need to know which of a typical target's 18 cells to throw into this Case Else 'do nothing End Select Case Else 'do nothing End Select End If If Not fTS = "Nothing" And CBool(Len(fTS)) Then Target.Item(1, 1) = fTS End If bm_Safe_Exit: Application.EnableEvents = True End Sub 

Module1代码表

 Option Explicit Public Function OptionStructureAnalysisEngine(tradeStructure As String, tradeDataRange As Range) As String 'analyzes and translates tradeStructure and dataRange 'Driver Dim structureAssemblyString As String, optionType As String 'Tests for / in tradeStructure to determine if it's a LIVE option trade or if it's a multi leg structure If InStr(1, tradeStructure, "/") < 1 Then 'Declares LIVE and option Type structureAssemblyString = "LIVE " & GetOptionCodes(Mid(tradeStructure, 8, 2)) & " " & TranslateExpirationDate(Mid(tradeStructure, 11, 6)) _ & " " & GetCallOrPut(Mid(tradeStructure, 18, 1)) Else 'Place holder for multileg structures structureAssemblyString = "Nothing" End If OptionStructureAnalysisEngine = structureAssemblyString End Function Public Function GetOptionCodes(optionType As String) As String Select Case UCase(optionType) Case "LO" GetOptionCodes = "WTI American" Case "OH" GetOptionCodes = "HO American" Case "OB" GetOptionCodes = "RB American" Case "LN" GetOptionCodes = "NG European" Case Else 'do nothing End Select End Function Public Function TranslateExpirationDate(expirationDate As Long) As String Dim c As Integer, str As String c = CInt(Right(expirationDate, 2)) str = Mid(expirationDate, 3, 2) Select Case c Case 1, 2, 3 TranslateExpirationDate = Chr(c + 69) & str Case 4, 5 TranslateExpirationDate = Chr(c + 70) & str Case 6, 7 TranslateExpirationDate = Chr(c + 71) & str Case 8 TranslateExpirationDate = Chr(c + 72) & str Case 9, 10 TranslateExpirationDate = Chr(c + 76) & str Case 11 TranslateExpirationDate = Chr(c + 77) & str Case 12 TranslateExpirationDate = Chr(c + 78) & str Case Else 'do nothing End Select End Function Public Function GetCallOrPut(legOption As String) As String Select Case UCase(legOption) Case "C" GetCallOrPut = "Call" Case "P" GetCallOrPut = "Put" Case Else 'do nothing End Select End Function 

如前所述,我做了这个盲人。 如果您不能使用或修改它以达到自己的目的,请编辑原始问题以包含最小,完整和可validation示例 (根据需要对您的示例数据进行编辑)。

行说

 target.Item(1, 1) = finalTradeStructure 

可能会导致一个无限循环,因为如果它被执行,它将触发一个新的Change事件。

我build议你只看一列(不是你可能修改的那一列),例如:

 Option Explicit Private Sub Worksheet_Change(ByVal target As Range) Dim initialTradeStructure As String, finalTradeStructure As String, rawStructure As String 'See if the change affects something in column 3 and only process if it does If Not Intersect(Target, Columns(3)) Is Nothing Then With Target.Rows(1) 'RFQs If .Cells(1, "D") = "RequestForQuote" Then 'Do Nothing....no analysis of RFQs is necessary....will be filtered later 'Screen Trades ElseIf .Cells(1, "D") = "GlobexTrades" Then rawStructure = .Cells(1, "C") initialTradeStructure = Right(rawStructure, Len(rawStructure) - 4) 'Bulk of analaysis conducted in analsyis engine to keep worksheet code clean/short finalTradeStructure = OptionStructureAnalysisEngine(initialTradeStructure, target) 'Block screen represented as Multileg in datafeed structure ElseIf .Cells(1, "D") = "Block" Then If .Cells(1, "R") = "TRUE" Then rawStructure = .Cells(1, "C") initialTradeStructure = Right(rawStructure, Len(rawStructure) - 4) 'Bulk of analysis conducted in analysis engine to keep worksheet code clean/short finalTradeStructure = OptionStructureAnalysisEngine(initialTradeStructure, target) ElseIf .Cells(1, "R") = "FALSE" And .Cells(1, "Q") = "FALSE" Then 'Live block trade Else 'Do Nothing....No analysis of single block legs is necessary End If End If If Not finalTradeStructure = "Nothing" Then .Cells(1, "B") = finalTradeStructure End If End With End If End Sub 

注意:我已将Target.Items(1,x)格式更改为Target.Rows(1).Cells(1,x+1)格式(x + 1被编码为实际字母列名称)认为这将更容易看到哪些列被引用。