We will be migrating from Ask to Discourse on the first week of August, read the details here

How to stop automatic saving of records in Base [closed]

This post is a wiki. Anyone with karma >75 is welcome to improve it.

I have a subform in Base and would like to require a "Save" button be pressed to ensure that updates are intended and also to allow some basic validation (such as a numeric field being positive). However, when a new row is selected in the main form I see that the row in the subform is saved to the database without confirmation.

This confuses me because the Developer's guide says that "If the cursor is moved to a different row before calling updateRow(), the update is lost. The update can be canceled by calling cancelRowUpdates()".

I have tried writing a macro to catch the "before record change" events on both the main and the subforms but I find that the change is already committed to the database when these events are fired.

Any help would be appreciated.

LO 5.1.3.2

--Tony

edit retag reopen merge delete

Closed for the following reason question is not relevant or outdated by Alex Kemp close date 2020-07-21 06:09:12.965793

Sort by » oldest newest most voted

What you are looking at in the Developers Guide is the manipulation of a data set (think Query) using macros. The cursor referred to here is the field/record currently pointed to within the record set - very similar to the position of the mouse cursor within a table control or control field.

Although not quite clear, it appears your form has two table controls. For sake of argument, Form contains the Master table and the sub-Form contains a table related to the Master. When you select a Master record, the related records appear in the sub-form control. The updating of tables are independent of each other. If in the sub-table you enter data in a new row and BEFORE advancing to another new row you select a different row in the Master table, the sub-table will not be updated. However, once you advance to a new row in the sub-table control, that record is updated.

Depending upon what you are trying to validate in each field, most can be accomplished through settings within the properties for each column in the table control. If this is not enough (hardly ever the case) and you actually need to control the checking through macros, the task is not easy. Using an event such as 'Before record change' actually occurs even when loading records into the table (ie: starting the form, or changing Master record selection'). Instead, you might need to look at individual fields by triggering an event such as 'When receiving focus' or 'When losing focus'.

Using a 'Save' button is not very different. You would typically set the sub-form with individual fields (as opposed to a table control) and set the 'Execute action' event of the button to run your code for validation and update.

Again it is hard to tell what validation you want that can't be handled without code.

more

As @Ratslinger said in his reply the section of the Developers Guide you referred to does not relate to the manipulation of data using Forms. It does refer to using a Macro to run a query. The query in the macro produces a result set (named rs in the Guide) which can then be used to manipulate the data,

more

My apologies for the tardy response, partiularly after the prompt response.

I thought I had asked a perfectly simple question but the two replies indicate that I have not. Ratsinger has correctly surmized my issue when he says "once you advance to a new row in the sub-table control, that record is updated." In my case the movement to the new row in the sub-table is precipitated by a movement in the parent table but that is not particularly relevant,

This default behaviour is what I wanted to supress. I only wanted the update (or insertion) to come from an explicit button press.

My problem was one of English language semantics. Suppose a cursor is pointing to the second row in a resultset. I interprested "before record change" to mean "before a change in the contents of the current row", i.e. the updateRow or insertRow call. However, "record change" actually means movement of the cursor wthin the result set, say to the first or third row. What I needed to do was to write a macro to catche the "before record action" event. This turned out to be non-trivial since the macro is actually fired twice, once with the controller as the source and once with the form.

This is the code I wrote that sort of did the job, but USE IT AT YOUR OWN RISK:

function BeforeRecordAction(event) ' USE AT YOUR OWN RISK
With event.source
If .supportsservice("com.sun.star.form.runtime.FormController") Then
if .currentcontrol.model.classid = com.sun.star.form.FormComponentType.COMMANDBUTTON then
BeforeRecordAction = true ' Button update OK
else
BeforeRecordAction = false ' Updates initiated by row movement disallowed
end if
else
BeforeRecordAction = true ' Not controller so ignore
end if
End With


End Function

However, this seems to confuse the BASIC framework, as does trying to veto row movements with "before record change". It looks like BASIC does not expect you to use event handlers to veto these sorts of things although supressing mouse click and keyboard events seems to be OK.

My advice to any would-be developers that want users to explictly confirm or cancel changes is to either use a dialogue box or write the whole application in Java. If you don't like either of those options try simplifying the form to exclude subforms and minimizing the extent to which the BASIC framework can get itself confused.

more

Every form and subform has its own BeforeRecordAction. So you can assign different sub to every form and subform. Of course you can use the same sub to all and distinguish them in code, using the event.source. Be sure to understand that these events are for all forms included in form navigator. There may exist many MainForm'es if widgets were copied from other forms.