LibreOffice BASE, Edit Mode in forms

Hello,

My first post so apologies if I get things wrong.
I wish to present a form linked to a table of record eg, Customers. When the form is first presented I want the records locked to prevent any accidental changes. On the form is an edit button which the user can press to make changes to a record.

I have used the Form Property “Allow Modifications” set to “No” on the Data tab to initially present the form such that the user cannot change the data. The edit button is linked to this macro:

Sub ChangeFormReadWrite(oEvent)
oForm = oEvent.Source.Model.Parent
MRI oForm
oForm.setPropertyValue(“AllowUpdates”, True)
MRI oForm
End Sub

MRI shows me that the form property does change when the button is pressed, however I still cannot edit the date.

If I toggle the setting manually it works as expected.
Can anyone tell me what I am missing please?
Many thanks
Hans

Might be it is missing oForm.reload().

So after trawling the internet and lots of head scratching. I have found a solution that works. The code below enables a button to change the form “Allow Updates” property using a button pressed event to drive the macro. Huge thanks to Sean Johnson for the direction. Code below if useful to anyone. https://www.youtube.com/@BusinessProgrammer.

Sub AllowUpdates(e as Object)
DIm oForm as Object
oForm = getFormFromEvent(e)
oForm.setPropertyValue(“AllowUpdates”, True)
End Sub

Private Function getFormFromEvent(e as Object) as Object
Dim szModuleRoutineName as String
szModuleRoutineName = “m_frmMoveRecord.GetFormFromEvent”
On Error Goto ErrorCheck

select case e.Source.ImplementationName
case “com.sun.star.form.FmXFormController”
GetFormFromEvent = e.source.model
case “com.sun.star.form.OButtonControl”
GetFormFromEvent = e.source.model.parent
case “com.sun.star.comp.forms.ODatabaseForm”
GetFormFromEvent = e.source
case else
msgbox e.Source.ImplementationName
msgbox “Unknown event in mSwitchboard.LoadMainKeywordFile”
msgbox “Need to look at the locals window to trace up the stack” & chr(13) & “to find the form reference.”
end select
Exit Function

ErrorCheck:
MsgBox "Error in " & szModuleRoutineName & chr(13) & "Error Number: " & err & " " & Error$ & chr(13) & "Error Line : " & erl
End Function

Much code for doing the same you posted. oForm in your post is the same form as oForm in the long code above…

Thank you. Yes it is a mystery to me why the bottom code works when the top one did not. I will try paying some more with both, including oForm.reload(). Having experimented a little I am experiencing a new problem that when the form reloads, it reverts to display the first entry in the table rather than the one I am looking to edit. I want the form to refresh but keep the current record in focus. It seems really difficult to find comprehensive documentation on how to these kind of things.

Yes…
To me here .reload does it.

Sub AllowModifications(Evt As Object)
	Dim F As Object
	InitializeMRI()
	F = Evt.Source.Model.Parent
	F.setPropertyValue("AllowUpdates", True)
	MRI F
	F.reload
End Sub

It allows editing and on reopening, starts blocked, as it should be.

Yes, this is the behavior. Will need code.
Try this — don’t know if it will work :thinking:

  1. Select the desired record.
  2. Click the button.
Sub AllowModifications(Evt As Object)
	Dim F As Object
	Dim r As Long
	F = Evt.Source.Model.Parent
	F.setPropertyValue("AllowUpdates", True)
	r = F.getRow()
	F.reload
	F.absolute(r)
End Sub	

 
24.2.7.2 (X86_64) / LibreOffice Community
Ubuntu package version: 4:24.2.7-0ubuntu0.24.04.4

2 Likes

Thank you for your comment. I am very new to LO Base and macro coding so I am trying to work things out for myself wherever I can from forums and documentation. So I really appreciate your comment. thank you.

I agree that .reload does seem to work and do the trick.

It seems to me that keeping a record in focus would be a very simple function. But I am again spending hours trawling the web to try to find a simple way to just keep the current record in focus after a oForm.reload. The process I want is:

Open form In safe mode (Allow Updates = False)
Navigate to desired record.
Click “Edit” Button to edit selected record. (OK to this point - changes form property to allow updates = true)
Edit desired record
Click “Save” button to save edited record and restor form status to (Allow Updates = False)

On reload I want to display the selected record for editing.
I did find a way to apply a filter to just show the one record. But then could not find the way to clear the filter after saving the record.

Can you recommend a comprehensive literature that covers this kind of thing?

Many thanks
Hans

Try this one: Base Guide 7.3
It’s a translation of an older Base Handbuch, which I have written for the German community.

@CRDF : Wanted to write the same code you did.

Remember, you are dealing with databases. While your record may be something simple like a bunch of bytes in a local dBase file, it can also be a key to a record in a multi-user database somewhere else on the world, accessed through the internet. You don’t know here, if that may be a columnar storage or if your data is internally generated by the database. All this you leave to the database.
.
As a result you need to make a note, where you are, before a reload of the form, either by absolute record numbers, or by referencing an Id.
.
On databases you are allowed to edit, if your “role” allowes this. Your idea is “lets add an additional childs safety”, wich leads to additional problems to solve. An alternative approach could be to have the same form twice. One for reading data, one for changing. Your button would then simply switch between this two forms instead of using code to modify the loaded form. (Not recommended until your form is “stable” to avoid double maintanance.)

What about
@ [Event After update] of last row field you want to edit; or another button of course:

oForm.ApplyFilter = False
oForm.setPropertyValue(“AllowUpdates”, False)
oForm.reload

:grey_question:

Thank you. This works. :slight_smile: