- How should I correctly initialise GUI controls so that my example always works?
- Can I bind the checkbox status directly to the current dataset?
- like an expression:
id > 0for checked and otherwise unchecked
Autochecking a checkbox when loading my form (in view mode) sometimes isn’t working.
I have a checkbox that is checked or unchecked depending on a foreign key being null or not. There is a drop down list that will be toggled active/inactive accordingly. The drop down list is also toggled when checking / unchecking the checkbox.
This works so far. But in some cases, which I CANNOT reproduce, it just doesn’t. When this happens it loads the default status for the checkbox (unchecked) and for the list (disabled). After a crash and restore it was always disabled until I opened the odb again some time later.
I think the GUI form might sometimes not be done initialising when I try to access the bound column. And then it just does not toggle the drop down list. But I don’t understand why that would happen.
Maybe I have to bind it to the MainForm loading instead of the form document opening? The problem testing a solution is that it happens very rarely. So I will not know if something worked or not. That’s why I hope someone has an idea or an example how this is usually done.
I reused my dog database example (see my other question for DB details). It happens in this example too, just very rarely. I left my macro structure as close to the original as possible just in case variable scope is the reason. Hope it is not confusing.
How to reproduce (happens very rarely) :
- open “Dogs” form
- double click a dog without an owner (this will open the “Dog” form)
- apply an owner to the dog
- save and go back
- open any dog that has an owner
- the checkbox will be unchecked and the list will be disabled
- if it’s not disabled remove an owner from a dog, save, then go back to 2
- it can help to close the odb first, then go back to 1
Only some parts here. See example file for full macros. You can enable
DEBUG_MODE in utils if you want to see message box popups for each step.
REM Return a form by name Public Function GetGuiForm(formDocName As String, formName As String) As Object Dim formDoc As Object formDoc = ThisDatabaseDocument.FormDocuments.getByName(formDocName) GetGuiForm = formDoc.Component.DrawPage.Forms.getByName(formName) End Function Public Function IsDoubleClick(event As Object) As Boolean IsDoubleClick = event.ClickCount > 1 End Function
REM ***** BASIC ***** REM Form: Dog Option Explicit Option Compatible Public Property Get FORM_NAME As String Static thisName thisName = "Dog" FORM_NAME = thisName End Property Private Const GUI_FORM_MAIN = "MainForm" Private Const GUI_CHK_OWNER = "chk_hasOwner" Private Const GUI_LST_OWNERS = "lst_owners" Private Const COLUMN_OWNER = "owner_id" REM When opening the form Sub OnLoad utils.Debug("OnLoad called", "frm_dog:OnLoad") utils.Maximise() Init() End Sub REM Load filter data and set MainForm filter Sub Init() utils.Debug("Init called", "frm_dog::Init") Dim sQuery As String sQuery = "SELECT ""filter_int"" FROM ""_Filters"" WHERE ""filter_name"" = 'Forms_Dog'" Dim oResult As Object oResult = utils.SQL_getQueryResults(sQuery) Dim dogId As Integer While oResult.next dogId = oResult.getInt(1) Wend utils.Debug("DogId from Filter: " & dogId, "frm_dog::Init") Dim oMainForm As Object oMainForm = utils.GetGuiForm(FORM_NAME, GUI_FORM_MAIN) oMainForm.Filter = "dog_id = " & dogId utils.Debug("Set MainForm filter to: " & oMainForm.Filter, "frm_dog::Init") utils.Debug("Reloading MainForm now", "frm_dog::Init") oMainForm.reload() SetOwnerStatus() End Sub REM Go back to dogs overview Sub SwitchToDogs() utils.SwitchForm(FORM_NAME, frm_dogs.FORM_NAME) End Sub REM Check owner checkbox if this dog has an owner Private Sub SetOwnerStatus() utils.Debug("SetOwnerStatus called", "frm_dog::SetOwnerStatus") Dim oMainForm As Object oMainForm = utils.GetGuiForm(FORM_NAME, GUI_FORM_MAIN) Dim chkOwner As Object chkOwner = oMainForm.getByName(GUI_CHK_OWNER) Dim bStatus As Boolean Dim dataExists As Boolean dataExists = oMainForm.Columns.hasByName(COLUMN_OWNER) utils.Debug("MainForm column '" & COLUMN_OWNER & "' exists: " & dataExists, "frm_dog::SetOwnerStatus") If dataExists Then Dim colOwner As Object colOwner = oMainForm.Columns.getByName(COLUMN_OWNER) utils.Debug(COLUMN_OWNER & ".Value = " & colOwner.Value) bStatus = (NOT colOwner.wasNull()) AND (NOT IsEmpty(colOwner.Value)) End If Dim status As Integer If bStatus Then status = 1 chkOwner.State = status utils.Debug("Checkbox set to '" & status, "frm_dog::SetOwnerStatus") If dataExists Then ToggleOwners() End Sub REM Enable/Disable dropdown list depending on checkbox status Sub ToggleOwners() utils.Debug("ToggleOwners called", "frm_dog::ToggleOwners") CONST CHECKED = 1 Dim mainForm As Object Dim lstOwners As Object Dim chkOwner As Object mainForm = utils.GetGuiForm(FORM_NAME, GUI_FORM_MAIN) chkOwner = mainForm.getByName(GUI_CHK_OWNER) lstOwners = mainForm.getByName(GUI_LST_OWNERS) If chkOwner.State = CHECKED Then utils.Debug("Owners checked, enabling dropdown list", "frm_dog::ToggleOwners") lstOwners.Enabled = True Else utils.Debug("Owners unchecked, disabling dropdown list and clearing its value", "frm_dog::ToggleOwners") lstOwners.Enabled = False lstOwners.SelectedValue = "" mainForm.Columns.getByName(COLUMN_OWNER).updateNull() End If End Sub
Version: 18.104.22.168 (x64) / LibreOffice