Basic runtime error: property or method not found: last

I’m just trying to write my first few macros in LO Base and always run into the same problem:
Basic runtime error: property or method not found: last.
or
Basic runtime error: property or method not found: absolute.
or
Basic runtime error: property or method not found: drawpage.

All these methods are descripted in the Base handbook.

Do I have to install some addtional library or something or what else might be the problem?

Code snippet:

Dim loLastRow AS LONG
oForm = oEvent.source
IF oForm.last THEN
loLastRow = oForm.getRow
ELSE
loLastRow = 0
END IF

Thanks in advance for your help!

Based upon your snippet the problem cannot be determined. This is because it is unknown what is assigned to the variable oForm. Typically oEvent.Source is a field and not the parent form. Please provide more information on what you are attempting to accomplish with the code. An entire sub you are having a problem with would be best.

OK. After going through some of the document you referred to I sense some of your anguish. Starting to code macros is at times frustrating. In order to help start you out I have attached a sample DB. It contains one table with three records and four fields within each record.

There are two forms. Form FSFORM1 has a table control displaying the contents of FSTABLE1. It has a simple macro attached to the Record Change event and displays (using a MsgBox) the contents of the currently pointed to record. If the last record is selected, you will additionally get a display of the total number of records in the table.

Form FSFORM2SQL has only a push button on it. The form itself is attached to table FSTABLE1. The button triggers a macro to read the records in the table using SQL and displays the contents of each record. On the last record you also get a count of the total number of records in the table.

The macros have some comments within to help walk you through. Hopefully this help get you started. It’s not easy at first but be persistent.

Edit 10/31/2016:

Modified code per @peterwt comment. Also added Option Explicit and some missing Dim statements.

Sample: FirstMacros.odb

Edit 11/02/2016:

Place a button on the form and attach the following macro to the Execute action event.

Sub RgNr_kopieren (oEvent AS OBJECT)
REM copy RgNr from the first row to all others
 Dim oForm AS OBJECT
 Dim inRgNr AS LONG
 Dim loRecPtr As Long
 oForm = oEvent.Source.Model.Parent
REM loRecPtr used to get records - initially set it to get first record
 loRecPtr = 1
 oForm.absolute(loRecPtr)
 inRgNr = oForm.getLong(10)
Rem Loop through records
 While Not oForm.isLast()
Rem increment Pointer to record by one (to get next record)
    loRecPtr = loRecPtr + 1
    oForm.absolute(loRecPtr)
Rem must use oForm. in next two lines - this is in the book! 
    oForm.updateLong(10,inRgNr)
    oForm.updateRow()
 Wend
 MsgBox "Update Completed"
 End Sub

@Ratslinger I have edited my original posting with a comment on your sample database.

@Ratslinger Thanks for all your efforts! But I still cannot find out what’s wrong. Here is the whole sub:
Sub RgNr_kopieren (oEvent AS OBJECT) REM copy RgNr from the first row to all others
Dim oForm AS OBJECT
Dim inRgNr AS LONG
Dim loRow AS LONG
Dim loLastRow AS LONG
oForm = oEvent.source
IF oForm.last THEN
loLastRow = oForm.getRow
ELSE
loLastRow = 0
END IF
oForm.absolute(1)
inRgNr = oForm.getLong(10)
FOR loRow = 2 to 3
oForm.absolute(loRow)
updateLong(10,inRgNr)
updateRow()
NEXT loRow
End S

What control is generating the Event?

See new edit in my answer.

If this answers your question please click on the :heavy_check_mark: (upper left area of answer).

There are two useful commands that you can include in a macro -

Object.dbg_properties
Object.dbg_methods

So for a Form oForm using

oForm.dbg_properties

you will get in a mesage box -


Properties of object 
"com.sun.star.comp.forms.ODatabaseForm":
SbxSTRING ActiveCommand; SbxOBJECT/void ActiveConnection; SbxBOOL AllowDeletes; 
SbxBOOL AllowInserts; SbxBOOL AllowUpdates; SbxBOOL ApplyFilter; 
SbxBOOL CanUpdateInsertedRows; SbxSTRING Command; SbxLONG CommandType; 
SbxLONG/void ControlBorderColorOnFocus; SbxLONG/void ControlBorderColorOnHover; SbxLONG/void ControlBorderColorOnInvalid; 
SbxLONG/void Cycle; SbxSTRING DataSourceName; SbxARRAY DetailFields; 
SbxBOOL/void DynamicControlBorder; SbxBOOL EscapeProcessing; SbxLONG FetchDirection; 
SbxLONG FetchSize; SbxSTRING Filter; SbxSTRING GroupBy; 
SbxSTRING HavingClause; SbxBOOL IgnoreResult; SbxBOOL IsBookmarkable; 
SbxBOOL IsModified; SbxBOOL IsNew; SbxBOOL IsRowCountFinal; 
SbxARRAY MasterFields; SbxLONG MaxFieldSize; SbxLONG MaxRows; 
SbxSTRING Name; SbxLONG NavigationBarMode; SbxSTRING Order; 
SbxSTRING Password; SbxLONG Privileges; SbxBOOL PropertyChangeNotificationEnabled; 
SbxLONG QueryTimeOut; SbxLONG ResultSetConcurrency; SbxLONG ResultSetType; 
SbxLONG RowCount; SbxOBJECT SingleSelectQueryComposer; SbxLONG SubmitEncoding; 
SbxLONG SubmitMethod; SbxSTRING TargetFrame; SbxSTRING TargetURL; 
SbxLONG TransactionIsolation; SbxOBJECT/void TypeMap; SbxSTRING URL; 
SbxSTRING UpdateCatalogName; SbxSTRING UpdateSchemaName; SbxSTRING UpdateTableName; 
SbxSTRING User; SbxOBJECT PropertySetInfo; SbxOBJECT Parameters; 
SbxEMPTY Warnings; SbxARRAY Types; SbxARRAY ImplementationId; 
SbxOBJECT Delegator; SbxEMPTY Bookmark; SbxOBJECT MetaData; 
SbxOBJECT Columns; SbxSTRING ImplementationName; SbxARRAY SupportedServiceNames; 
SbxLONG Row; SbxOBJECT Statement; SbxSTRING PropertyToDefault; 
SbxOBJECT Parent; SbxBOOL GroupControl; SbxARRAY ControlModels; 
SbxLONG GroupCount; SbxOBJECT ElementType; SbxARRAY ElementNames; 
SbxLONG Count; SbxSTRING ServiceName; SbxARRAY PropertyValues; 
SbxSTRING Dbg_SupportedInterfaces; SbxSTRING Dbg_Properties; SbxSTRING Dbg_Methods

and the methods -


Methods of object 
"com.sun.star.comp.forms.ODatabaseForm":
SbxEMPTY queryInterface ( SbxOBJECT ) ; SbxOBJECT getPropertySetInfo ( void ) ; SbxVOID setPropertyValue ( SbxSTRING, SbxVARIANT ) ; SbxEMPTY getPropertyValue ( SbxSTRING ) ; SbxVOID addPropertyChangeListener ( SbxSTRING, SbxOBJECT ) ; SbxVOID removePropertyChangeListener ( SbxSTRING, SbxOBJECT ) ; SbxVOID addVetoableChangeListener ( SbxSTRING, SbxOBJECT ) ; SbxVOID removeVetoableChangeListener ( SbxSTRING, SbxOBJECT ) ; 
SbxVOID setFastPropertyValue ( SbxLONG, SbxVARIANT ) ; SbxEMPTY getFastPropertyValue ( SbxLONG ) ; SbxOBJECT getPropertySetInfo ( void ) ; SbxVOID setPropertyValues ( SbxARRAY, SbxARRAY ) ; SbxARRAY getPropertyValues ( SbxARRAY ) ; SbxVOID addPropertiesChangeListener ( SbxARRAY, SbxOBJECT ) ; SbxVOID removePropertiesChangeListener ( SbxOBJECT ) ; SbxVOID firePropertiesChangeEvent ( SbxARRAY, SbxOBJECT ) ; 
SbxOBJECT createResultSet ( void ) ; SbxVOID addRowSetApproveListener ( SbxOBJECT ) ; SbxVOID removeRowSetApproveListener ( SbxOBJECT ) ; SbxVOID addRowsChangeListener ( SbxOBJECT ) ; SbxVOID removeRowsChangeListener ( SbxOBJECT ) ; SbxARRAY deleteRows ( SbxARRAY ) ; SbxVOID setNull ( SbxLONG, SbxLONG ) ; SbxVOID setObjectNull ( SbxLONG, SbxLONG, SbxSTRING ) ; 
SbxVOID setBoolean ( SbxLONG, SbxBOOL ) ; SbxVOID setByte ( SbxLONG, SbxINTEGER ) ; SbxVOID setShort ( SbxLONG, SbxINTEGER ) ; SbxVOID setInt ( SbxLONG, SbxLONG ) ; SbxVOID setLong ( SbxLONG, SbxINT64 ) ; SbxVOID setFloat ( SbxLONG, SbxSINGLE ) ; SbxVOID setDouble ( SbxLONG, SbxDOUBLE ) ; SbxVOID setString ( SbxLONG, SbxSTRING ) ; 
SbxVOID setBytes ( SbxLONG, SbxARRAY ) ; SbxVOID setDate ( SbxLONG, SbxOBJECT ) ; SbxVOID setTime ( SbxLONG, SbxOBJECT ) ; SbxVOID setTimestamp ( SbxLONG, SbxOBJECT ) ; SbxVOID setBinaryStream ( SbxLONG, SbxOBJECT, SbxLONG ) ; SbxVOID setCharacterStream ( SbxLONG, SbxOBJECT, SbxLONG ) ; SbxVOID setObject ( SbxLONG, SbxVARIANT ) ; SbxVOID setObjectWithInfo ( SbxLONG, SbxVARIANT, SbxLONG, SbxLONG ) ; 
SbxVOID setRef ( SbxLONG, SbxOBJECT ) ; SbxVOID setBlob ( SbxLONG, SbxOBJECT ) ; SbxVOID setClob ( SbxLONG, SbxOBJECT ) ; SbxVOID setArray ( SbxLONG, SbxOBJECT ) ; SbxVOID clearParameters ( void ) ; SbxVOID disposing ( SbxOBJECT ) ; SbxVOID insertRow ( void ) ; SbxVOID updateRow ( void ) ; 
SbxVOID deleteRow ( void ) ; SbxVOID cancelRowUpdates ( void ) ; SbxVOID moveToInsertRow ( void ) ; SbxVOID moveToCurrentRow ( void ) ; SbxVOID updateNull ( SbxLONG ) ; SbxVOID updateBoolean ( SbxLONG, SbxBOOL ) ; SbxVOID updateByte ( SbxLONG, SbxINTEGER ) ; SbxVOID updateShort ( SbxLONG, SbxINTEGER ) ; 
SbxVOID updateInt ( SbxLONG, SbxLONG ) ; SbxVOID updateLong ( SbxLONG, SbxINT64 ) ; SbxVOID updateFloat ( SbxLONG, SbxSINGLE ) ; SbxVOID updateDouble ( SbxLONG, SbxDOUBLE ) ; SbxVOID updateString ( SbxLONG, SbxSTRING ) ; SbxVOID updateBytes ( SbxLONG, SbxARRAY ) ; SbxVOID updateDate ( SbxLONG, SbxOBJECT ) ; SbxVOID updateTime ( SbxLONG, SbxOBJECT ) ; 
SbxVOID updateTimestamp ( SbxLONG, SbxOBJECT ) ; SbxVOID updateBinaryStream ( SbxLONG, SbxOBJECT, SbxLONG ) ; SbxVOID updateCharacterStream ( SbxLONG, SbxOBJECT, SbxLONG ) ; SbxVOID updateObject ( SbxLONG, SbxVARIANT ) ; SbxVOID updateNumericObject ( SbxLONG, SbxVARIANT, SbxLONG ) ; SbxVOID cancel ( void ) ; SbxVOID executeWithCompletion ( SbxOBJECT ) ; SbxOBJECT getParameters ( void ) ; 
SbxEMPTY getWarnings ( void ) ; SbxVOID clearWarnings ( void ) ; SbxARRAY getTypes ( void ) ; SbxARRAY getImplementationId ( void ) ; SbxOBJECT queryAdapter ( void ) ; SbxVOID setDelegator ( SbxOBJECT ) ; SbxEMPTY queryAggregation ( SbxOBJECT ) ; SbxVOID dispose ( void ) ; 
SbxVOID addEventListener ( SbxOBJECT ) ; SbxVOID removeEventListener ( SbxOBJECT ) ; SbxEMPTY getBookmark ( void ) ; SbxBOOL moveToBookmark ( SbxVARIANT ) ; SbxBOOL moveRelativeToBookmark ( SbxVARIANT, SbxLONG ) ; SbxLONG compareBookmarks ( SbxVARIANT, SbxVARIANT ) ; SbxBOOL hasOrderedBookmarks ( void ) ; SbxLONG hashBookmark ( SbxVARIANT ) ; 
SbxBOOL wasNull ( void ) ; SbxSTRING getString ( SbxLONG ) ; SbxBOOL getBoolean ( SbxLONG ) ; SbxINTEGER getByte ( SbxLONG ) ; SbxINTEGER getShort ( SbxLONG ) ; SbxLONG getInt ( SbxLONG ) ; SbxINT64 getLong ( SbxLONG ) ; SbxSINGLE getFloat ( SbxLONG ) ; 
SbxDOUBLE getDouble ( SbxLONG ) ; SbxARRAY getBytes ( SbxLONG ) ; SbxOBJECT getDate ( SbxLONG ) ; SbxOBJECT getTime ( SbxLONG ) ; SbxOBJECT getTimestamp ( SbxLONG ) ; SbxOBJECT getBinaryStream ( SbxLONG ) ; SbxOBJECT getCharacterStream ( SbxLONG ) ; SbxEMPTY getObject ( SbxLONG, SbxOBJECT ) ; 
SbxOBJECT getRef ( SbxLONG ) ; SbxOBJECT getBlob ( SbxLONG ) ; SbxOBJECT getClob ( SbxLONG ) ; SbxOBJECT getArray ( SbxLONG ) ; SbxOBJECT getMetaData ( void ) ; SbxLONG findColumn ( SbxSTRING ) ; SbxOBJECT getColumns ( void ) ; SbxSTRING getImplementationName ( void ) ; 
SbxBOOL supportsService ( SbxSTRING ) ; SbxARRAY getSupportedServiceNames ( void ) ; SbxBOOL next ( void ) ; SbxBOOL isBeforeFirst ( void ) ; SbxBOOL isAfterLast ( void ) ; SbxBOOL isFirst ( void ) ; SbxBOOL isLast ( void ) ; SbxVOID beforeFirst ( void ) ; 
SbxVOID afterLast ( void ) ; SbxBOOL first ( void ) ; SbxBOOL last ( void ) ; SbxLONG getRow ( void ) ; SbxBOOL absolute ( SbxLONG ) ; SbxBOOL relative ( SbxLONG ) ; SbxBOOL previous ( void ) ; SbxVOID refreshRow ( void ) ; 
SbxBOOL rowUpdated ( void ) ; SbxBOOL rowInserted ( void ) ; SbxBOOL rowDeleted ( void ) ; SbxOBJECT getStatement ( void ) ; SbxVOID execute ( void ) ; SbxVOID addRowSetListener ( SbxOBJECT ) ; SbxVOID removeRowSetListener ( SbxOBJECT ) ; SbxVOID close ( void ) ; 
SbxINT64 getSomething ( SbxARRAY ) ; SbxVOID enableChangeListenerNotification ( SbxBOOL ) ; SbxLONG getPropertyState ( SbxSTRING ) ; SbxARRAY getPropertyStates ( SbxARRAY ) ; SbxVOID setPropertyToDefault ( SbxSTRING ) ; SbxEMPTY getPropertyDefault ( SbxSTRING ) ; SbxOBJECT getParent ( void ) ; SbxVOID setParent ( SbxOBJECT ) ; 
SbxBOOL getGroupControl ( void ) ; SbxVOID setGroupControl ( SbxBOOL ) ; SbxVOID setControlModels ( SbxARRAY ) ; SbxARRAY getControlModels ( void ) ; SbxVOID setGroup ( SbxARRAY, SbxSTRING ) ; SbxLONG getGroupCount ( void ) ; SbxVOID getGroup ( SbxLONG, SbxARRAY, SbxSTRING ) ; SbxVOID getGroupByName ( SbxSTRING, SbxARRAY ) ; 
SbxVOID loaded ( SbxOBJECT ) ; SbxVOID unloading ( SbxOBJECT ) ; SbxVOID unloaded ( SbxOBJECT ) ; SbxVOID reloading ( SbxOBJECT ) ; SbxVOID reloaded ( SbxOBJECT ) ; SbxVOID cursorMoved ( SbxOBJECT ) ; SbxVOID rowChanged ( SbxOBJECT ) ; SbxVOID rowSetChanged ( SbxOBJECT ) ; 
SbxBOOL approveCursorMove ( SbxOBJECT ) ; SbxBOOL approveRowChange ( SbxOBJECT ) ; SbxBOOL approveRowSetChange ( SbxOBJECT ) ; SbxVOID addParameterListener ( SbxOBJECT ) ; SbxVOID removeParameterListener ( SbxOBJECT ) ; SbxVOID addDatabaseParameterListener ( SbxOBJECT ) ; SbxVOID removeDatabaseParameterListener ( SbxOBJECT ) ; SbxVOID errorOccured ( SbxOBJECT ) ; 
SbxVOID addSQLErrorListener ( SbxOBJECT ) ; SbxVOID removeSQLErrorListener ( SbxOBJECT ) ; SbxVOID reset ( void ) ; SbxVOID addResetListener ( SbxOBJECT ) ; SbxVOID removeResetListener ( SbxOBJECT ) ; SbxVOID submit ( SbxOBJECT, SbxOBJECT ) ; SbxVOID addSubmitListener ( SbxOBJECT ) ; SbxVOID removeSubmitListener ( SbxOBJECT ) ; 
SbxVOID load ( void ) ; SbxVOID unload ( void ) ; SbxVOID reload ( void ) ; SbxBOOL isLoaded ( void ) ; SbxVOID addLoadListener ( SbxOBJECT ) ; SbxVOID removeLoadListener ( SbxOBJECT ) ; SbxSTRING getName ( void ) ; SbxVOID setName ( SbxSTRING ) ; 
SbxOBJECT getElementType ( void ) ; SbxBOOL hasElements ( void ) ; SbxEMPTY getByName ( SbxSTRING ) ; SbxARRAY getElementNames ( void ) ; SbxBOOL hasByName ( SbxSTRING ) ; SbxVOID replaceByName ( SbxSTRING, SbxVARIANT ) ; SbxVOID insertByName ( SbxSTRING, SbxVARIANT ) ; SbxVOID removeByName ( SbxSTRING ) ; 
SbxLONG getCount ( void ) ; SbxEMPTY getByIndex ( SbxLONG ) ; SbxVOID replaceByIndex ( SbxLONG, SbxVARIANT ) ; SbxVOID insertByIndex ( SbxLONG, SbxVARIANT ) ; SbxVOID removeByIndex ( SbxLONG ) ; SbxVOID addContainerListener ( SbxOBJECT ) ; SbxVOID removeContainerListener ( SbxOBJECT ) ; SbxOBJECT createEnumeration ( void ) ; 
SbxVOID registerScriptEvent ( SbxLONG, SbxOBJECT ) ; SbxVOID registerScriptEvents ( SbxLONG, SbxARRAY ) ; SbxVOID revokeScriptEvent ( SbxLONG, SbxSTRING, SbxSTRING, SbxSTRING ) ; SbxVOID revokeScriptEvents ( SbxLONG ) ; SbxVOID insertEntry ( SbxLONG ) ; SbxVOID removeEntry ( SbxLONG ) ; SbxARRAY getScriptEvents ( SbxLONG ) ; SbxVOID attach ( SbxLONG, SbxOBJECT, SbxVARIANT ) ; 
SbxVOID detach ( SbxLONG, SbxOBJECT ) ; SbxVOID addScriptListener ( SbxOBJECT ) ; SbxVOID removeScriptListener ( SbxOBJECT ) ; SbxVOID propertyChange ( SbxOBJECT ) ; SbxSTRING getServiceName ( void ) ; SbxVOID write ( SbxOBJECT ) ; SbxVOID read ( SbxOBJECT ) ; SbxOBJECT createClone ( void ) ; 
SbxVOID addProperty ( SbxSTRING, SbxINTEGER, SbxVARIANT ) ; SbxVOID removeProperty ( SbxSTRING ) ; SbxARRAY getPropertyValues ( void ) ; SbxVOID setPropertyValues ( SbxARRAY ) 

You will see that there is a Form method isLast, so you should use oForm.isLast in your IF loop.

Using oForm.last will move the record pointer to the last record.

As @Ratslinger said it appears you are not setting oForm correctly. If the macro is run from a Button on the Form then to get the Form object you need to use -

oForm = oEvent.Source.Model.Parent

The source of the event being the Button and the Form is the parent of the Button.

EDITED 31/10/2016

@Ratslinger Your sample database is a good example of how to use Basic in a LO Base database.

However I disagree with part of your code. You use the Form Event “After record change” to run the Macro “DisplayCurrentRecordChosen” using the even argument oEvent to get the Form Object oForm. You create oField as the source of the event as it is a result of a change in the Grid Control but the change in the Grid Control triggers the FORM event “After record change”. There is no Field creating the event. oField is in fact oForm.
The line -

oForm = oField.Parent.getByName(“MainForm”)

takes the Event source, the Form, gets the parent which is the Forms Collection, and gets the Form “MainForm” by name. In effect going from the Form to the Forms Collection and back to the Form. So oForm can be found by just having -

oForm = oEvent.Source

which works. If using an Event directly created by a control on a Form then oForm can found using -

oForm = oEvent.Source.Model.Parent

@lobito You can run into problems using snippets of code from various sources. Some of the code may only work in a particular context.
It is also worth pointing out that when you use the Event argument oEvent that you can only run the code using the Form. If you attempt to run the code from Macros - Run macro it will fail as there will be no oEvent argument.

Very helpful. Thank you.

@Ratslinger The event is generated by a control button in the main form. So the hint of @peterwt was what really solved the problem: using oForm = oEvent.Source.Model.Parent instead of only oForm = oEvent.Source. Your code with the while - loop is more elegant than mine, so I’ll use that. Thank you very much!
@peterwt Thank you as well for all your efforts! I learned quite a lot from this expamle besinde the fact that the problem is solved.

If you attempt to run the code from Macros - Run macro it will fail as there will be no oEvent argument.

This is a good hint. I’m just at the beginning but once my macro library has grown a bit I’ll consider that.

The source of the event being the Button and the Form is the parent of the Button.

I’m just wondering why I couldn’t find something that important in the base handbook …

@lobito There is a lot of information here

OpenOffice Macrosorg Explained.pdf.

@lobito make sure you compare the code to yours. Some of your code did nothing and other code was missing parts such as oForm. The “While” statement simply insures you get all the records. It wasn’t just the creation of oForm.

@lobito, Next time please update (i.e. edit) your original question with your response (to a question in a comment), rather than adding an “Answer” which is what you did here. This is not a forum, but rather a question and answer structured site. Thanks.