Hi,

Attached is a small basic module.
If you would be willing to hep me check it out:

Import the bas file into a basic library embedded in an ODB file - will not work as a stand alone Basic library

Create a form with the Property Insert Data Only true.
You should make sure the dataform Cycle property is set to "Active Record "
You should disable the navigator.

OK - you can add a button to the form, a custom toolbar or a custom menu
assign the macro insertFirstDataForm

Just try it - let me know if you get any errors, please.

I've used it with  HSQLdb and dBase Base files w/out problem.

MS Access has an error in the executeUpdate command on the prepared statement.

MySQL and PostgerSQL haven't checked.

Anyway, if anyone gives it a try I'd appreciate it.

Thanks

Drew
'    Copyright (C) 2010  Andrew 'Drew' Jensen
'        atjen...@openoffice.org
'
'    This program is free software: you can redistribute it and/or modify
'    it under the terms of the GNU General Public License as published by
'    the Free Software Foundation, either version 3 of the License, or
'    (at your option) any later version.
'
'    This program is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'    GNU General Public License for more details.
'
'    To review a full a copy of the GNU General Public License
'    please see, <http://www.gnu.org/licenses/>.
'
'//     
'//     The library module was intended to be used as a aid in 
'//     working around an anomily in the 3.2 release of OpenOffice.org Base
'//     
'//     For reference see:
'//     http://www.openoffice.org/issues/show_bug.cgi?id=108377
'//     
'//     The library includes 4 rooutines for use in these
'//     Insert Data Only forms
'//     
'//     Two are suitable for use from menu, toolbar, HotKey, 
'//     or dialog displayed by data entry form
'//             
'//     insertdFistDataForm     
'//     reloadFistDataForm
'//
'//             Two when called from a button owned by the dataform
'//             that owns the controls to write to the database
'//
'//             insertThisDataForm
'//     reloadThisDataForm              
                
option explicit 

        '//     GLOBALS
        '//     
GLOBAL BoundFields() as string
        
        '//             Timestamp fields can be associeated with 
        '//             both a date and time GUI control
        '//             
        '//             In face any data field could be bound to any 
        '//             number of GUI Control Models
        '//             
        '//             Data fields do not have to be bound to 
        '//             any GUI Control Model
        '//             
        '//             in our loops then we will iterated
        '//             over the GUI Control Models
        '//             to avoid any non bound data fields
        '//             
        '//             but this means we must watch for 
        '//             controls bound to more then one 
        '//             data field - such as timestamp fields
        '//             
        '//             to do this we will employ an array
        '//             to keep track of each field name
        '//             we come across as we move through
        '//             the Control Models
        '//             
        '//     haveField
        '//     
        '//     helper function for insertDataForm
        '//                             
function haveField( DataFieldName as string ) as boolean
        dim cntr 
        dim foundit as boolean

        if UBound(BoundFields) = 0 then
                haveField = False
                REDIM BoundFields(1)
                BoundFields(1) = DataFieldName
        else
                foundit = false
                for cntr = 0 to UBound(BoundFields) - 1
                        if BoundFields(cntr) = DataFieldName then
                                foundit = True
                        end if
                next
                if not foundit then
                        cntr = UBound(BoundFields)
                        REDIM BoundFields( cntr + 1 )
                        BoundFields( uBound(BoundFields) ) = DataFieldName
                        haveField = False
                else
                        haveField = True
                end if
        end if
end function

        '//     
        '//     reloadFistDataForm
        '//     
        '//             can be called from menu or toolbar or HotKey
        '//             can be called from dialog displayed by data entry form
        '//             
        '//             will clear all controls of the first dataform 
        '//             on the top most base form window
        '//             
sub reloadFistDataForm()
        '//             
        '//             only want to work with forms
        '//                     
        '//             a Query window will not be picked up with 
        '//             in ActiveFrame          
        '//             NULL Model then 
        if isNull( 
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model ) then
                exit sub
        end if

        '//     
        '//             Report Builder editor
        '//                             
        if 
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model.supportsService("com.sun.star.sdb.ReportDesign")
 then
                exit sub
        end if  

        '//             ASSUME - ASSUME - ASSUME
        '//             this is a form
        '//             unlses of course it is a ReportWizard report?
        '//                             

        
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model.DrawPage.Forms(0).reload
end sub 

        '//             
        '//             insertFirstDataForm
        '//             
        '//             can be called from menu or toolbar or Kotkey
        '//             can be called from dialog displayed by data entry form
        '//             
        '//             will write the values from the bound data columns 
controls
        '//             of the first dataform on the top most base form window
        '//             
sub insertFirstDataForm()
        '//             
        '//             only want to work with forms
        '//                     
        '//             a Query window will not be picked up with 
        '//             in ActiveFrame          
        '//             NULL Model then 
        if isNull( 
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model ) then
                exit sub
        end if

        '//     
        '//             Report Builder editor
        '//                             
        if 
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model.supportsService("com.sun.star.sdb.ReportDesign")
 then
                exit sub
        end if  

        '//             ASSUME - ASSUME - ASSUME
        '//             this is a form
        '//             unlses of course it is a ReportWizard report?
        '//                             
        InsertDataForm( 
thisDatabaseDocument.CurrentController.Frame.ActiveFrame.Controller.Model.DrawPage.Forms(0)
 )
        
end sub 

        '//     
        '//     reloadThisDataForm
        '//             
        '//             can be called from a button that has a dataform as 
parent
        '//             
sub reloadThisDataForm( oEvent as object )
        oEvent.Source.Model.Parent.reload
end sub 

        '//             
        '//             insertThisDataForm
        '//             
        '//             can be called from a button that has a dataform as 
parent
        '//             
sub insertThisDataForm( oEvent as object )
        InsertDataForm( oEvent.Source.Model.Parent )
end sub

        '//             
        '//             insertDataForm
        '//                     do it
        '//             
sub InsertDataForm(oDataForm as object )
        dim CurrentConnection
        dim CurrentControl
        dim cntr, fldcnt
        dim strCmdFirst, strCmdLast, SQLCmd, QuoteString
        dim QryComposer
        dim prepStatement

        '//             
        '//             use the connection that is
        '//             used by the datatform control
        '//             
        CurrentConnection = oDataForm.ActiveCOnnection 

        '//             
        '//             only inerested in quote used for identifieers
        '//             
        QuoteString = CurrentConnection.MetaData.IdentifierQuoteString

        '//             
        '//             use this for getting different
        '//             parts of the SQL command used
        '//             by the dataform control
        '//             in our case here
        '//             the table name for the SQL statement
        '//             
        QryComposer = CurrentConnection.createQueryComposer

        '//             
        '//             populate the composer with the
        '//             current dataforms SQL command
        '//             
        QryComposer.Query = oDataForm.ActiveCommand

        '//             reset our BoudFields array for keeping
        '//             track of duplicate data fields
        '//             
        REDIM BoundFields(0)    

        '//             
        '//             build the two parts of 
        '//             of an SQL insert statement
        '//                     
        '//             
        '//             iterate over the contols
        '//             to extract the column names
        '//             from the bound data controls
        '//             
        for cntr = 0 to oDataForm.Count - 1
                CurrentControl = oDataForm.ControlModels(cntr)          
                select case CurrentControl.ServiceName
                        
                        '//             
                        '//             include only those controls types
                        '//             that support bound data controls
                        '//             
                        case "stardiv.one.form.component.Edit", 
"stardiv.one.form.component.DateField", 
"stardiv.one.form.component.ImageControl"
                                if not haveField( 
CurrentControl.BoundField.Name ) then 
                                        strCmdFirst = strCmdFirst + QuoteString 
+ CurrentControl.BoundField.Name + QuoteString
                                        strCmdLast = strCmdLast + " ? "
                                        if cntr <> oDataForm.Count - 1 then
                                                strCmdFirst = strCmdFirst + + 
", "
                                                strCmdLast = strCmdLast + ", "
                                        end if

                                end if

                end select
                
        next

        '//             
        '//             build the final SQL statement
        '//     
        SQLCmd = "INSERT INTO " + QuoteString + QryComposer.Tables(0).Name + 
QuoteString + " ( " + strCmdFirst + " ) VALUES ( " + strCmdLast + " )"
        
        '//             
        '//             and prepare it for data
        '//             
        prepStatement = CurrentConnection.PrepareStatement( SQLCmd )

        '//             reset our BoudFields array for keeping
        '//             track of duplicate data fields
        '//             again
        '//             
        REDIM BoundFields(0)    

        '//             
        '//             again iterate over the contols
        '//             this time to fill the 
        '//             parameters in the prepared statement
        '//             with data
        '//             
        for cntr = 0 to oDataForm.Count - 1
                CurrentControl = oDataForm.ControlModels(cntr)
                select case CurrentControl.ServiceName
                        case "stardiv.one.form.component.Edit", 
"stardiv.one.form.component.DateField", 
"stardiv.one.form.component.ImageControl"
                                if not haveField( 
CurrentControl.BoundField.Name ) then                         
                                        '//             
                                        '//             fldnct <> 
oDataForm.Count
                                        '//             only count controls 
with bound columns
                                        '//             
                                        fldcnt = fldcnt + 1
        
                                        '//
                                        '//     ensure that data in GUI conttol 
is
                                        '//     written to the bound data 
controls
                                        '//
                                        '//             no commit for image 
controls?
                                        '//
                                        if CurrentControl.ServiceName <> 
"stardiv.one.form.component.ImageControl" then
                                                CurrentControl.commit
                                        end if
        
                                        '//
                                        '//     fetch the columns value 
                                        '//     to make wasNull valid
                                        '//
                                        CurrentControl.BoundField.getString
        
                                        '//
                                        '//     NULLS get special attention
                                        '//
                                        if CurrentControl.BoundField.wasNull 
then

                                                '//             
                                                '//             should account 
for different data typs
                                                '//             but for 
expediency
                                                '//             
                                                prepStatement.setNull( fldcnt, 
0 )

                                        else
                                                '//             
                                                '//             now put the 
data into   
                                                '//             the prepared 
statement
                                                '//             parameters
                                                '//             
                                                '//             image controls 
are special
                                                '//
                                                if CurrentControl.ServiceName = 
"stardiv.one.form.component.ImageControl" then
                                                        '//             
                                                        '//             
setBinaryStream insted of setBlob 
                                                        '//             as 
setBlob is not implemented on all
                                                        '//             drivers
                                                        '//
                                                        dim oStream as object
                                                        oStream = 
CurrentControl.BoundField.getBinaryStream
                                                        
prepStatement.setBinaryStream( fldcnt, oStream, oStream.Length )
                                                else
                                                        '//             
                                                        '//             for 
expediency
                                                        '//             move 
the rest as strings
                                                        '//             
                                                        
prepStatement.setString( fldcnt, CurrentControl.BoundField.getString )  
                                                end if
                                        
                                end if
                                        
                        end if
                        
                end select              

        next

        '//             set error trap
        '//                     
        on error goto executeUpdateError

        '//             
        '//             post the data to the table
        '//             
        prepStatement.executeUpdate

        '//             
        '//             clean up the GUI controls
        '//             by reseting the dataform
        '//             
        oDataForm.Reload
        
        '//             
        '//     and exit                
        exit sub
        
        '//             
        '//             error on insert
        '//             tell and resume
        '//                     
executeUpdateError:
        MsgBox "Error " & Err & ": " & Error$ + chr(13) + "At line : " + Erl + 
chr(13) + Now , 16 ,"<< insertDataForm >>"
end sub


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@dba.openoffice.org
For additional commands, e-mail: dev-h...@dba.openoffice.org

Reply via email to