I removed flickering from continuous form, but I do not understand how it works (1 Viewer)

bonds

New member
Joined
Mar 27, 2024
Messages
12
I've removed the flickering from the continuous form, but I don't understand how it works. Perhaps there is another, clearer solution, or a different approach. I'll get to the details. I created a cascading combobox with a progressive filter (search as you type) in continuous form. However, I later noticed that when switching from a new record to any previous record - the form flickered. I solved the flickering problem using code:
Code:
Private Sub Form_Dirty(Cancel As Integer)
On Error Resume Next
If Me.NewRecord Then
Me.Recordset.AddNew
Me.Recordset!ItemID = DMax("ItemID", "TestOrders") + 1      ' to make sure that primary key is non-zero
Me.Recordset.Update
End If
End Sub
Additionally, I have to change the properties of the combo that is close to the record selectors. Border width = Hairline; Left = 0,019cm. The idea was to move it a little bit from the record selectors, otherwise there was a little flick on the record selectors.
The idea behind the code was to create and save a new record before actually updating it. It worked. "On Error Resume Next" is neccesary to remove probable errors. But maybe when errors occur it does not flick. I tested - this is a solution to the flickering problem (attached). However, I do not understand how it works. Maybe there is a better way to solve this kind of flickering problems? I know there are API solutions, but I am wondering if I can do it without any API.
 

Attachments

We have a minor problem in telling you how to solve flickering problems because all WE can do is report what has worked for us. You see, Access code is not open-source, so we don't always know what it is doing internally.

I have found that flickering will occur when you have something that has to do a LOT of .Repaint, .Refresh, or .Requery actions in a tight sequence. Updating a record in a way to indirectly trigger a .Requery and also before or after that update, do a manual .Requery can sometimes cause a flicker because the update might trigger a Form_Current event which implies a .Requery has to occur. And there is the issue that a .Requery implies a .Refresh which leads to a .Repaint. Something in a tight loop that has the effect of trying to update a visible control can also exhibit flickering.

Remember that most modern CPUs can run in the Gigahertz range, which means up to 1 billion (with a B) instructions per second. If you have a typical display, your video latency is on the rough order of 10 msec, or 100 frames per second - which is quite decent response for non-gamer displays. (Gamer displays have closer to 1 msec latency, but most folks don't have those beasts.) You only need 30 frames per second for modern movie DVDs most of the time, so that 10 msec would be 3 times faster than needed for smooth-motion movie replay. BUT... if you have 10 msec latency, that is time enough for 10 MILLION CPU instructions. All it would take for flickering to be noticeable would be for some program to attempt to drive video changes more often than the screen can respond to refresh requests. Access code is not super-efficient but it easily can manage code loops that exceed 1000 loops per second.

Another issue, though, is that if you are still debugging code, don't EVER suppress error messages until you know what errors are being incurred and why. Once you figure that out and fix the steps that cause the error, you don't need to suppress errors anyway. But an error handler can cause problems if it does something to the form that affects graphics directly or indirectly. This is a bit vague, but as I said, we don't know what Access is doing behind the scenes so a lot of it is guesswork.
 
So if you are on a new record, you add another record via the recordset? :unsure:
 
don't EVER suppress error messages until you know what errors
Code:
Private Sub Form_Dirty(Cancel As Integer)
'On Error Resume Next
If Me.CurrentRecord = 1 Then Exit Sub
If Me.NewRecord Then
Me.Recordset.AddNew
Me.Recordset!ItemID = Nz(DMax("ItemID", "TestOrders") + 1), 0)
Me.Recordset.Update
End If
End Sub
I removed the supressor of errors by this new code. Also one note - there should be no user-unfriendly required fields. Otherwise there will be another error (3314) in this code. This error can be cured by setting default values in required fields.
 
Last edited:
So if you are on a new record, you add another record via the recordset?
I do not know how this idea came to my mind. But it does remove the flickering. The idea was to separate the creation of a new record from its update or whatever happens to it. I do not understand my last sentence but it worked!:) Or maybe using recordset is a cure. I do not know.
 
If you are experiencing flickering, you almost certainly have your other code in the wrong events.

I use a very simple method that does NOT require constantly changing the RowSource of the combos. Perhaps that is why I have never experienced flickering with cascading combos.

Each combo has code to clear dependent combos in their click events.
Combo1
Me.Combo2 = Null
Me.Combo3 = Null
Me.Combo4 = Null
Me.Combo2.Requery
Me.Combo3.Requery
Me.Combo4.Requery

Combo2
Me.Combo3 = Null
Me.Combo4 = Null
Me.Combo3.Requery
Me.Combo4. Requery

Combo3
Me.Combo4 = Null
Me.Combo4.Requery

Then in their RowSource querydefs, they have a Where clause that references their parent combo

Combo2
Where SomeFK = Forms!myform!FK1

Combo3
Where SomeFk = Forms!myform!FK2

Combo4
Where SomeFK = Forms!myform!FK3
 
@bonds You are very new to the forum. While we appreciate "likes", they are truly meaningless when used this way. We are adults, we don't judge ourselves by how many likes we get. So, if a post solved your problem or helped you in any way, please use your words. The "like" doesn't tell anyone who reads this thread anything.
 
to clear dependent combos in their click events.
I think it has to be in the after_update, not click event. One does not want to clear dependents before updating parents.
Another point - I don't think I have a regular cascading combobox since I want to be able to choose dependent by SAYT not only after but also before choosing parent. The flickering was even in the original database that was made by your stratergy (attached). Once new record is created and the user clicks on any other record - there is a little flicker, which my code removes.
 

Attachments

I think it has to be in the after_update, not click event.
We are talking about a combobox. When you click on an item, you select it, that should clear the lower level combos. If you prefer to do it in a different event, you can use the BeforeUpdate or AfterUpdate event of the control but those events don't fire until the control loses focus.

I don't think I have a regular cascading combobox since I want to be able to choose dependent by SAYT not only after but also before choosing parent.
That makes no sense. The higher level combos control the contents of the RowSource of the lower level events. Why do you think a "child" can be selected before its parent? No wonder you are seeing a flicker. There is some logical flaw here. Perhaps you can explain.
 
Perhaps you can explain.
If user knows the dependent but does not remember the parent then he can start typing the dependent and the dropdown will show it (if SAYT is intergrated into the code). After update of the dependent the parent will be chosen automatically (as shown in my database with SAYT). The original database cboxs is a regular cascading combobox, but it still flickers. My extra additions do not cause the flicker.
 
You do see the conflict you have created, right? The child combo depends on the parent and the parent depends on the child.
 
They are dependent on each other in any case. But as I said before - even in the case of second file (cboxs) where there is a regular cascading combobox - there is a flicker. In order to observe it one has to create a new record and place the mouse pointer on any other record above.
 
The flicker happens because the dependency you have created puts Access into a loop. A depends on B but B depends on A. So A changes B but that forces B to change A and that forces A to change B and on and on and on. Eventually Access figures out it is in a loop and gracefully exits. Earlier versions of Access never recovered from these infinite loops and you had to reboot to break out of the loop.

You might want to add another combo to say which combo should be the "parent". That way you can adjust your code to avoid the loop. If you don't want the user to always have to choose, set one value as the default "parent".
 
I repeat - there is no difference. I already forgot about my database. I am talking about your case. For example the regular cascading combos are used in Northwind Traders Developer database. For example edition 2.3 in the form frmOrderDetails.
This database was made by access developers so that users learn how to create dependent combos. There is the same kind of flickering in this database. For example the user chooses category Dried Fruit & Nuts, then - product Dried Apples, quantity 5, status allocated. Next record - Pasta/Gnocchi, quantity 2, status allocated. Then user returns to the previous record by clicking on it at any place. And we observe the flickering. I attached it so that people understand me. Same situation was in the file cboxs. There is a normal child-parent structure in there, same as you suggest, and there is a flickering.
 

Attachments

That app doesn't flicker for me but it is running lots of code behind the scenes so if your computer is slow, that will also cause flicker.

My method of doing the cascade does NOT cause flicker because it doesn't change the RowSource and it doesn't take any more code. Do what you want.
 
That app doesn't flicker for me but it is running lots of code behind the scenes so if your computer is slow, that will also cause flicker.

My method of doing the cascade does NOT cause flicker because it doesn't change the RowSource and it doesn't take any more code. Do what you want.
I realized that you are the author of the file FixCascadingCombos. I studied this file during weekend. I placed your transparent field over the combo and rearanged the positions of all controlls so that they are all on the same line. There is the same flicker. I can not post any changes made on your file. I removed this flicker by this code, which is similar to mine:
Code:
Private Sub Form_Dirty(Cancel As Integer)
If Me.CurrentRecord = 1 Then Exit Sub
If Me.NewRecord Then
Me.Recordset.AddNew
Me.Recordset!TestId = Nz(DMax("TestId", "tblTest"), 0) + 1
Me.Recordset!Cityid = Nz(DMax("CityID", "tblCities"), 0) + 1
Me.Recordset!Cityid = Nz(DMax("CityID", "tblTest"), 0) + 1
Me.Recordset.Update
End If
End Sub
 
At least in theory, @bonds, you should not directly add records via a form's (open) recordset.

If your goal is to update a record and yet not make it flicker, don't do anything visible to it. You might want to try your solution using a different form property. Instead of Me.Recordset, use Me.RecordsetClone. After the update, if you want to have that new record become the current record after the update, you can use

Code:
Me.Recordset.Bookmark = Me.RecordsetClone.Bookmark

Since at the start of a Form_Current event, Me.Recordset and Me.RecordsetClone point to the same record, they should be synchronized. When you add a new record to Me.Recordset, you are "diddling" with something that will potentially be visible. However, when you add a new record via Me.RecorsetClone, that is entirely behind the scenes and may induce less flicker. There are "wizard"-based methods for finding a particular record that employ Me.RecordsetClone as part of the process, so it is obviously fair game for simple manipulation of the form's recordset.
 
What do you think your code is dong? You never got any code like that from me. It makes no sense.

If you want to set default values on a form, there are better ways but in NO case would you ever move to a new record or do anything except populate the form's controls directly.
Code:
If Me.CurrentRecord = 1 Then Exit Sub
If Me.NewRecord Then
    Me.TestId = Nz(DMax("TestId", "tblTest"), 0) + 1
    Me.Cityid = Nz(DMax("CityID", "tblCities"), 0) + 1
    Me.Cityid = Nz(DMax("CityID", "tblTest"), 0) + 1
End If
If the use typed into the TestID control and that is what made the record dirty, your code would not place the correct value in that control. Whatever the user typed would show there.
 

Users who are viewing this thread

Top Bottom