832.TXT ===================================================================== Customize Your Own Autonumbered Column ===================================================================== PRODUCT: R:BASE VERSION: 3.1 or Higher ===================================================================== CATLOG: Programming in R:BASE AREA : Data Manipulation ===================================================================== R:BASE's autonumber feature is an excellent tool, but an autonumbered column increments even if a row is discarded. For example, you are entering data in a form that has an autonumbered column placed, and its current value shows 302. If you exit without saving the row and then re-enter the form, the column has incremented to 303, even though the previous row was not saved. This can result in "holes" or "missing" values in the column. This causes problems for applications that need automatically incrementing column values without gaps. Autonumbering is good for columns that serve as links or indexes, but if you need something that increments without gaps or only under certain circumstances, you need to customize the autonumbering process. You can customize autonumbering by using an entry/exit procedure (EEP) to do the actual numbering. In the example below, a user wants to generate an invoice number only if the net amount of the sale is greater than zero. If the net amount is zero, the invoice number needs to be zero. Non- zero invoice numbers must increment by one and there can be no missing numbers. The database has a table named Track with the following columns: Name Description Type colid ID column Autonumbered Integer sale Sale Currency Amount invoicenum Invoice Integer Number The column colid is an autonumber column that serves as the primary key for the table and used to link with other tables. The column invoicenum is the calculated invoice number. Invoicenum can't be used as the primary key for the table since it can have duplicate values_all zero amount invoices have an invoice number of zero (0). The column sale is used to determine if this is a zero amount invoice. Of course, in an actual application, the table will have other columns to hold more information about the sale, such as customer id, tax and shipping amounts, etc. Create a data entry form to enter the sale information. On the form, place the colid and sale columns. Define two expressions for the form: vcolid = colid vnet = sale An entry/exit procedure doesn't know about column values entered in the form, those values need to be passed into variables for use by the EEP. The expressions place the entered values for the sale amount and the id value into variables. Modify the Form Settings to make the form an entry only form_never use the form to edit existing data. The EEP does not calculate correctly when used with Edit. In Table Settings, add the EEP, invocalc.eep, After Saving Row. This is important; the current row must be saved in order for the EEP to correctly find the maximum value for invoicenum. The invoice number is displayed to the screen using the PAUSE command because it is calculated after the row is saved. The PAUSE command displays in either the DOS version of R:BASE 5.5 or the Windows version. *(INVOCALC.EEP) SET VAR vlast INTEGER -- find the maximum invoice number in the table SELECT MAX(invoicenum) INTO vlast FROM track -- check the amount of the invoice: -- if zero, vinvoicenum is set to 0, -- if non-zero, vinvoicenum is set to the -- maximum invoice number + 1 SET VAR vinvoicenum = + (IFEQ(.vnet, 0, 0, (.vlast + 1))) -- update the table with the calculated invoice number UPDATE track SET invoicenum = .vinvoicenum + WHERE colid = .vcolid SET VAR vmsg = + ('Invoice Number: ' + CTXT(.vinvoicenum)) PAUSE 2 USING .vmsg RETURN If you have a lot of rows in your table, you might find the SELECT MAX(invoicenum) command too slow for your application. An alternative method is to use a table to store the maximum number_the table is a single column, single row table. Using this method, the EEP code changes to this: *(INVOCALC.EEP) SET VAR vlast INTEGER -- retrieve the maximum invoice number SELECT invoicenum INTO vlast FROM lastnumber + WHERE LIMIT = 1 -- check the amount of the invoice: -- if zero, vinvoicenum is set to 0, -- if non-zero, vinvoicenum is set to the -- maximum invoice number + 1 IF vnet <> 0 THEN SET VAR vinvoicenum = (.vlast + 1) UPDATE lastnumber SET invoicenum = + (invoicenum + 1) WHERE LIMIT = 1 ELSE SET VAR vinvoicenum = 0 ENDIF -- update the table with the calculated invoice number UPDATE track SET invoicenum = .vinvoicenum + WHERE colid = .vcolid SET VAR vmsg = + ('Invoice Number: ' + CTXT(.vinvoicenum)) PAUSE 2 USING .vmsg RETURN You can modify the "set var vinvoicenum =" line so that the column invoicenum increments the way you want it to. Try this simple example and see how you could use it in your database.