Reputation: 61
This pertains to embedding ESRI MapControls into Access Database Forms.
I have two access files, split into a frontend and backend. My backend is also a PersonalGeoDatabase that ArcGIS uses to store a feature class for display on a From embedded ESRI map control.
The feature class stores polylines, points, and polygons which are associated with a specific ProjectID.
From the frontend, I have the embedded mapControl which loads the MXD file tied to the backend.
I've got a VB function called CenterPoint, which coincidentally, centers the map envelope around the Project's associated feature class (if it exists) and sets the desired viewing extents. If the feature class for a project doesn't yet exist, it centers the map around the entire region all the projects are contained in, giving a general overview.
So, if that all made sense, and I haven't lost you...
I originally called the CenterPoint sub in the Form_Current Event. This worked, in that it performed all the functionality desired; however, while the CenterPoint function ran, the form was unresponsive, preventing changing to another record until the re-draw had finished. This meant, if you wished to jump through 10 records, you would have to jump 1, wait for re-draw, jump another, wait for re-draw, etc. I sped up the re-draw considerably by optimizing the MXD imagery and layers, but it was still unacceptable.
Next, I tried to establish a delay of a few seconds, before it called the CenterPoint sub by running the following:
Private Sub Form_Current()
Dim s_Start As single
Dim s_Delay As single
s_Start = Timer
Do While Timer < s_Start + s_Delay
DoEvents
Loop
CenterPoint
End Sub
Which gives me the desired responsiveness by using the DoEvents call, meaning I can click multiple records before it tries to re-draw the first time.
Unfortunately, it apparently cache's all the Form_Current calls, and if I skip say, 3 records, wait for the delay to end, and watch the screen, it will re-draw (ie. run CenterPoint) 3 times consecutively.
Even more weird, is it sporadically gives me a division by zero error for the line:
Do While Timer < s_Start + s_Delay
despite having no division in the line.
So, I guess my questions are:
Right now, my work around has been to put the CenterPoint sub as a click event for a button on the form, which works, but isn't ideal.
If any of this doesn't make sense, or more information is necessary, please let me know.
Thanks, Spencer
Upvotes: 2
Views: 1466
Reputation: 23067
Another possibility would be to keep the call in the OnCurrent event, but use a time flag outside the OnCurrent to determine whether or not to call the subroutine.
Static s_Start As Single
Dim s_Delay As Single
If s_Start = 0 Then
s_Start = Timer
End If
If Timer > s_Start + s_Delay
Call CenterPoint
s_Start = 0
End If
Now, that's air code, so I may have a mistake or two in it, but the idea is that you run the code only once the delay has expired. And once it's expired, you set the start time back to 0 so that counter will start over again.
The result is that the call to CenterPoint will happen only on those OnCurrent events that happen after your delay has expired.
Upvotes: 0
Reputation: 15414
In answer to your questions:
1) Form_ Current will always run whenever you switch records. No choice. So the next best option is to move the call to CenterPoint to another event. I would use the form timer event, and reset the timer every time you go through Form_ Current, when the timer runs out, it will fire CenterPoint off.
Private Sub Form_Current()
Me.TimerInterval = 10000
End Sub
Private Sub Form_Timer()
CenterPoint
End Sub
2) If you are using the form timer event, you probably don't need this code any more; however,
Private Sub Form_Current()
Dim l_Start As long
Dim l_Delay As long
Dim l_endTime As long 'or integers - time is returning the number of seconds
'since midnight, not a real... this may be the source
'of your problem
l_Delay = 1000 ' I didn't see you set s_Delay any where
l_Start = Timer
l_endTime = l_Start + l_Delay 'lets do the calculation only once.
'This might break down if the user switch records just before midnight
'(never ending loop)
' Do While Timer < l_endTime
' DoEvents
' Loop
'Instead I would do this
Do While (Timer <= l_endTime) _
and (l_start <= timer)
DoEvents
Loop
CenterPoint
End Sub
Upvotes: 1