This is the Personal Stock Monitor scripting developers forum.
Subscribe to RSS Feed
Developing Custom Stock Market Software using PSM -> OnHistoryUpdated() Question
Not logged in.
2010-11-24 17:48:30
1 of 13
#2548
Howdy Everyone,

When OnHistoryUpdated() is executed, how can I isolate code inside of this method (If xxx Then) to execute ONLY for MY extension, and not every time PSM calls this method?

I looked through the Application and Document objects, but there doesn't appear to be a Property for the Name of the extension currently being executed.

The CurrentView is "Active Securities", which is also the case for PSM itself.

Thank you,

-Don
Posted by: dgoyette
2010-11-27 15:45:26
2 of 13
#2576
in reply to #2548
I'm sorry, but I'm not sure exactly what you're asking. PSM will call all extensions, including yours, at the appropriate time. There doesn't need to be a property for the extension being executed because they are all called one after another.
Posted by: Anatoly
2010-11-27 18:06:14
3 of 13
#2583
in reply to #2576
I want to add code to OnHistoryUpdated() but only want it executed when MY extension is calling it -- not when PSM calls it -- such as when PSM displays a chart and has to download historical data.

Does this help explain what I'm asking for?

Thank you,

-Don
Posted by: dgoyette
2010-11-27 20:52:30
4 of 13
#2592
in reply to #2583
I would suggest putting that code in a separate function and calling that. You should not be calling OnHistoryUpdated, since it has a specific purpose.
Posted by: Anatoly
2010-11-27 21:22:09
5 of 13
#2595
in reply to #2592
Misunderstanding ... I am not calling OnHistoryUpdated - PSM calls it automatically after DownloadHistoryData

In your article, "How to Create a Custom Report Extension", you have the following code ...

public Function OnHistoryUpdated ( Ticker )
  ' We only care about this event if the user is looking at the
  ' Reports view ...
    If (Application.GetCurrentView() = "Reports") Then
      ' We want to go through the app timer event because
      ' OnHistoryUpdated will be called once for every
      ' ticker that is updated and we don't want to update
      ' the report multiple times
        Set EventManager = Application.GetObject("EventManager")
        EventManager.RegisterHandlerMethod me, "OnAppTimer"
    End If
End Function
	
public Function OnAppTimer
  ' Make sure we don't get called repeatedly, unnecessarily ...
    EventManager.UnregisterHandlerMethod me, "OnAppTimer"

    ' Now that we have the historical data we requested, update
    ' the report ...
      Set ReportManager = Application.GetObject("ReportManager")
      ReportManager.UpdateCurrentReport
End Function

Is this just specific to writing report extensions?


Posted by: dgoyette
2010-11-30 21:08:31
6 of 13
#2607
in reply to #2595
No, it's for any extension. It's just an example of creating event handlers and handling events.
Posted by: Anatoly
2010-12-01 18:14:56
7 of 13
#2619
in reply to #2607
The reason I asked if this code example you wrote was specific to Reports is due to the following check you have in the code ...

If (Application.GetCurrentView() = "Reports")

This check returns False if the View is anything but a Report.

Changing it to "Active Securities" means the code will be executed every time PSM performs an internal (NOT my code) update of the History data -- OUTSIDE of MY code.

This is why I asked the question above (slightly re-worded), "... how can I isolate code inside of this method (via If xxx Then) to execute ONLY for MY code, and not every time PSM calls this method internally?"

In the topic over at ( http://www.personalstockmonitor.com/developing-custom-s... ), you re-iterate the code in the example above.

HOWEVER, the OnHistoryUpdated function is called EVERY time PSM does something internally (ie. display a Chart) that requires an update of the ticker's History data.

I DO NOT want MY code to be executed EVERY time PSM internally (from the Chart view or whatever) updates a ticker's History. I want to isolate my OnHistoryUpdated code to execute ONLY when MY code needs it to be executed.

How is this possible?

To demonstrate what I want to do in code, see "---> WHAT DO I CODE HERE? <---" below ...

public Function OnHistoryUpdated ( ticker )
  ' We only care about this event if THIS EXTENSION is active ...
    If ( --->  WHAT DO I CODE HERE?  <--- ) Then
      ' Any code I want to execute during this event ...
      ' ...
      ' ...
    End If
End Function

Thank you,

-Don

Posted by: dgoyette
2010-12-02 11:21:51
8 of 13
#2630
in reply to #2619
That check was there because we're only interested in updating the report if the reports view is visible. Otherwise we're just wasting our time since the user will never see the report. So that check is appropriate for the report, but not necessarily for other extensions that don't have to deal with reports.

I understand what you want, but there is no way to distinguish a call coming from your extension versus a request from the charts, etc. If you want to set some kind of variable in your extension before you call DownloadHistoryData, that would probably work. The variable would have to be a member of your extension class. Then you would check your flag variable such as

If InMyExtension = True Then
   ' do something here

   ' clear the flag
   InMyExtension = False
End If

Posted by: Anatoly
2010-12-02 22:52:50
9 of 13
#2640
in reply to #2630
Yes, I tried using two different global variables as shown below, uncommenting only ONE "If" statement at a time in OnHistoryUpdated. Neither of them worked. The code was ALWAYS executed, even when displaying a chart.

Thus, I am assuming that a global variable is also seen by PSM code.

Not sure how else to code this kind of check.



Class UserEntryFormHandler

  public Function OnMenuItemSelected ( id )
    If (id <> G_MenuUserEntryForm) Then
      Exit Function
    Else
      G_MyScript = "Update 1-Share Transactions"
      G_Myid = id
    End If
    ...
    ...
  End Function


  public Function OnFormSubmitted ( form )
    ...
  End Function


  public Function UpdateForm ( Process )
    ...
    GetHistoryData ticker, HistoryStartDate, HistoryEndDate, HistoryRecs, HistoryPrice, HistoryRecNo, G_HistoryDataError
    ...
  End Function


  public Function GetHistoryData ( ticker, HistoryStartDate, HistoryEndDate, HistoryRecs, HistoryPrice, HistoryRecNo, rtnCode )
    ...
    ticker.DownloadHistoryData HistoryStartDate, HistoryEndDate
    ...
  End Function


  public Function OnHistoryUpdated ( ticker )
'   If this OUR script extension ...
    If G_MyScript = "Update 1-Share Transactions" Then
'   If (G_Myid = G_MenuUserEntryForm) Then
      MsgBox "OnHistoryUpdated for ticker: " & ticker.Symbol, vbOKOnly, "Test"
'     MsgBox "Got downloaded history data for " _
'           & ticker.GetProperty("Symbol"), vbOKOnly, "Test"
    Else
      MsgBox "OnHistoryUpdated - Not my script code.", vbOKOnly, "Test"
    End If
  End Function


' Dimension global variables ...
  Dim G_MyScript
  Dim G_Myid

End Class  ' (UserEntryFormHandler)


' Initialization (executed at PSM run) ...
  Set EventManager = Application.GetObject("EventManager")
  Set MenuManager  = Application.GetObject("MenuManager")
  Set FormHandler  = new UserEntryFormHandler


' Register our event handlers (executed at PSM run) ...
  If Not EventManager Is Nothing Then
    EventManager.RegisterHandlerMethod FormHandler, "OnMenuItemSelected"
    EventManager.RegisterHandlerMethod FormHandler, "OnHistoryUpdated"
  Else
'   Could not get EventManager object ...
'   MsgBox "Could not get EventManager object.", vbOKOnly, "Test"
  End If



Posted by: dgoyette
2010-12-03 01:21:28
10 of 13
#2647
in reply to #2640
dgoyette wrote

Yes, I tried using two different global variables as shown below, uncommenting only ONE "If" statement at a time in OnHistoryUpdated. Neither of them worked. The code was ALWAYS executed, even when displaying a chart.


Where are you calling DownloadHistoryData? I would recommend setting the global variables as close to the DownloadHistoryData call as possible, since they are related to how you're processing the results. Also, are you ever un-setting the global variables after you're processed the history data in your code in OnHistoryUpdated()? If you're not, then your code will continue to get executed for all instances of history data downloads.
Posted by: Anatoly
2010-12-03 03:46:31
11 of 13
#2655
in reply to #2647
Anatoly wrote
Where are you calling DownloadHistoryData?

I edited the code box above to include some of the other functions as well as the DownloadHistoryData statement.

Anatoly wrote
I would recommend setting the global variables as close to the DownloadHistoryData call as possible, since they are related to how you're processing the results.

Looks like they are pretty close now.


Anatoly wrote
Also, are you ever un-setting the global variables after you're processed the history data in your code in OnHistoryUpdated()? If you're not, then your code will continue to get executed for all instances of history data downloads.

No, I am not setting them to Nothing. I will add this code -- at the completion of the Run button code (OnFormSubmitted function)? Or when the Close button is clicked?

[ UPDATE on this portion -- After clearing the global variables upon exit of the extension, and then trying to display a chart, the If statement in OnHistoryUpdated() fails because the variable is undefined. ]

Thank you Anatoly,

-Don
Posted by: dgoyette
2010-12-03 08:40:53
12 of 13
#2659
in reply to #2655
dgoyette wrote

No, I am not setting them to Nothing. I will add this code -- at the completion of the Run button code (OnFormSubmitted function)? Or when the Close button is clicked?


At the end of OnHistoryUpdated.

dgoyette wrote

[ UPDATE on this portion -- After clearing the global variables upon exit of the extension, and then trying to display a chart, the If statement in OnHistoryUpdated() fails because the variable is undefined. ]


Yes, because you're setting the variable to Nothing. Instead you should set it to 0 or "", whatever is appropriate, just so your If test fails properly.
Posted by: Anatoly
2010-12-03 20:22:25
13 of 13
#2682
in reply to #2659
Thank you Anatoly. Based on your suggestions, I came up with the following order in which to execute the code and it works!


public Function GetHistoryData ( stuff )
  G_MyScript = "Update 1-Share Transactions"
  On Error Resume Next
    ticker.DownloadHistoryData HistoryStartDate, HistoryEndDate
  On Error Goto 0
End Function

public Function OnHistoryUpdated ( ticker )
' Is this OUR script extension? ...
  If G_MyScript = "Update 1-Share Transactions" Then
    MsgBox "We're in OnHistoryUpdated()", vbOKOnly, "Test"
    G_MyScript = ""
' Else  ' It's not our extension code who's calling
  End If
End Function

Posted by: dgoyette