You are on page 1of 160

OpenOffice.

org Base Macro Programming By Andrew Pitonyak

Last Modified Tuesday, July 28, 2009 at 09:54:04 PM Document Revision: 4

Information Page
Copyright
T!is document is "o#y$i%!t 2005&2009 'y its cont$i'uto$s as listed in t!e section titled Authors( )ou can dist$i'ute it and*o$ modify it unde$ t!e te$ms of t!e "$eative "ommons +tt$i'ution License, ve$sion 2(0 o$ late$ ,!tt#:**c$eativecommons(o$%*licenses*'y*2(0*-( +ll t$adema$.s /it!in t!is %uide 'elon% to t!ei$ le%itimate o/ne$s(

Authors
+nd$e/ Pitonya.

Feedback
Maintaine$: +nd$e/ Pitonya. 0and$e/1#itonya.(o$%2 Please di$ect any comments o$ su%%estions a'out t!is document to: aut!o$s1use$&fa3(o#enoffice(o$%

Acknowledgments
4 find it difficult to #$o#e$ly c$edit all of my sou$ces, 'ecause so many #eo#le a$e !el#ful in an en devou$ of t!is si5e( T!e$e a$e, !o/eve$, a fe/ #eo#le /!o do indeed stand out in my mind as !avin% #$ovided si%nificant encou$a%ement( 4 !ave no e6#lanation as to #$ecisely /!y my /ife Mic!elle allo/s me to s#end so muc! time /o$.in% /it! 7#en7ffice(o$%( Pe$!a#s s!e is $eally t!e #e$son t!at you s!ould t!an. fo$ my #$oductivity( 4 Love you Mic!elle, you com#lete me( +ll of t!e #eo#le /it! /!om 4 !ave inte$acted at 8un Mic$osystems !ave 'een ve$y tole$ant and #atient /it! my endless 3uestions( 4n t!e c$eation of t!is document, 9$an. 8c!:n!eit, !o/eve$ stands out in t!is $e%a$d( M$( 8c!:n!eit s#ends a lot of time !el#in% #eo#le /it! #$o'lems and 3uestions, and most nota'le fo$ me, !e ans/e$s my 3uestions( T!an. you 9$an.; T!e$e is a la$%e community voluntee$in% t!ei$ time /it! 7#en7ffice(o$%( D$e/ Jensen !as stood out in my mind as an inc$edi'ly #$olific and .no/led%ea'le individual( D$e/ clea$ly !as vast e6#e$ience usin% data'ase #$oducts, and !e !as '$ou%!t t!is vast e6#e$ience to t!e 77o community( <e !as c$eated nume$ous e6cellent e6am#les on t!e 77o 9o$ums and mailin% lists( T!an. you D$e/( T!e$e is a la$%e community of !el#e$s, /!o a$e sim#ly too nume$ous to mention( 4 o/e you all a t!an. you fo$ you$ !el# and encou$a%ement( 4n t!e %ene$al community, !o/eve$, 4 /ill sin%le out =( Rode$ic. 8in%leton, /!o !el#s nume$ous #eo#le eve$y day on t!e mailin% lists( <e also ve$y #$oactive in .ee#in% t!e documentation u#&to&date( M$( 8in%leton, 4 t!an. you fo$ all of you$ !el# as /ell( T!is document is u#dated a lot, so it !a$dly ma.es sense to t$ac. c!an%es at t!is time( Pe$!a#s /!en 4 come u# /it! at least a ve$sion >(0(

Table 1. Modification History


Date
9*2 *0? *> *0B 4*4*0B >* 0*08 2*>8*08

Comment
4nte%$ated c!an%es f$om Jo @ml1/infi6(itA Moved document to a ne/ fo$mat( Discove$ed t!at 4 did C7T t$ansfe$ t!e mac$os( "omments $elated to fields in fo$ms( Ce/ c!an%es comin% fo$ 77o (0D /atc! out;

4 encou$a%e #eo#le to tu$n on c!an%e t$ac.in% in 77o ,Edit > Changes > Record- and ma.e co$$ections, en!ancements, and*o$ u#dates to t!is document( E!en you a$e finis!ed, #lease send t!e document to me fo$ inte%$ation into t!e final document( Please ma.e note of t!e FLast ModifiedG date ,Tuesday, July 28, 2009 at 09:54:04 PM- and t!e $evision num'e$ ,4 so t!at 4 /ill .no/ if you !ave t!e latest document ve$sion, /!ic! ma.es my life muc! easie$(

iii

Table of Contents
Information Page........................................................................................................................2 Copyright...............................................................................................................................2 Authors..................................................................................................................................2 Feedback...............................................................................................................................2 Acknowledgments.................................................................................................................2 Table of Contents.......................................................................................................................v 1. Introduction...........................................................................................................................1 1.1. Introductory comments.................................................................................................1 1.2. Document organization and introduction......................................................................1 1.3. Prepare for big changes in OOo 3.0..............................................................................2 2. Storing images (binary data) in Base....................................................................................4 2.1. Create the initial Base document...................................................................................4 2.1.1. Using the GUI........................................................................................................4 2.1.2. Using a macro........................................................................................................4 2.1.3. Using a macro to open the wizard.........................................................................5 2.2. Create the table..............................................................................................................5 2.2.1. Using the GUI........................................................................................................5 2.2.2. Using a macro........................................................................................................6 2.2.3. Using SQL statements to modify tables................................................................8 2.2.4. Refresh the tables..................................................................................................8 2.2.5. Creating and deleting tables using SQL................................................................9 2.2.6. Increase a field's length.......................................................................................11 2.3. Create a form...............................................................................................................11 2.3.1. Using the GUI......................................................................................................11 2.3.2. Using a macro......................................................................................................13 2.4. Open a form using a macro.........................................................................................17 2.5. Accessing the binary data............................................................................................20 2.5.1. Adding binary data..............................................................................................20 2.5.2. Extracting binary data..........................................................................................22 3. One-To-Many relationships................................................................................................25 3.1. Create the tables..........................................................................................................25 3.1.1. Create the DEALER table...................................................................................25 3.1.2. Create the ITEM table.........................................................................................26 3.2. Define the data relationships.......................................................................................28 3.3. Add data to the DEALER and ITEM tables................................................................29 4. Forms..................................................................................................................................32 4.1. The internal object model............................................................................................32 4.1.1. A control's shape is in the draw page..................................................................32 4.1.2. A draw page contains forms................................................................................33 4.1.3. A control's data model is in a form......................................................................34 4.1.4. A control's view model is in the controller..........................................................35 v

4.1.5. Enabling and setting controls visible an example............................................36 4.1.6. Finding a control from an event an example....................................................36 4.1.7. Control connected to a database..........................................................................37 4.1.8. Control model summary......................................................................................38 4.2. Database Forms act like a result set............................................................................38 4.2.1. Duplicate record macro.......................................................................................39 4.3. Show one item and the corresponding dealer.............................................................42 4.4. Use a combo box with the dealer id............................................................................44 4.5. Use a list box with the dealer name............................................................................45 4.6. Relations in a single table...........................................................................................47 4.6.1. Solution................................................................................................................47 4.6.2. Solution characteristics........................................................................................48 4.7. Use a help and fill button.........................................................................................49 5. Many-to-many relationships...............................................................................................50 6. Database fields....................................................................................................................51 6.1. Storing numbers..........................................................................................................54 6.1.1. Integer numbers...................................................................................................54 6.1.2. Floating point numbers........................................................................................55 6.1.3. NUMERIC and DECIMAL types.......................................................................56 6.2. Bit and Boolean Types................................................................................................56 6.3. Date and time..............................................................................................................57 6.4. Text data......................................................................................................................57 6.5. Binary data..................................................................................................................58 6.6. Other data type............................................................................................................58 6.7. Database sequences and auto-value fields..................................................................58 7. A few easy database definitions..........................................................................................60 7.1. Schema........................................................................................................................61 8. Database connections..........................................................................................................62 8.1. Obtain a database context............................................................................................62 8.1.1. Registered data sources.......................................................................................63 8.1.2. Unregistering a data source.................................................................................63 8.1.3. Registering a data source.....................................................................................64 8.2. Connect to a database..................................................................................................64 8.3. Connect using an interaction handler..........................................................................65 8.4. Connections.................................................................................................................65 8.4.1. Extended SDB connections.................................................................................67 8.4.2. Meta-data.............................................................................................................67 8.4.3. Inspecting the meta-data......................................................................................74 8.4.4. GetBestRowIdentifier..........................................................................................81 8.4.5. GetColumnPrivileges..........................................................................................82 8.4.6. GetColumns.........................................................................................................83 vi

8.4.7. GetExportedKeys................................................................................................84 8.4.8. GetIndexInfo........................................................................................................85 8.4.9. GetPrimaryKeys..................................................................................................87 8.4.10. GetTablePrivileges............................................................................................87 8.4.11. GetTables...........................................................................................................88 8.4.12. GetTypeInfo()....................................................................................................88 8.4.13. GetUDTS...........................................................................................................89 8.4.14. GetVersionColumns..........................................................................................90 8.5. Connections ................................................................................................................91 8.6. Connections without a data source..............................................................................91 8.6.1. Delimited text files..............................................................................................96 8.6.2. Fixed width text files...........................................................................................98 8.6.3. Help, I still can not import my CSV file...........................................................103 8.6.4. Address books...................................................................................................105 8.6.5. MySQL using JDBC..........................................................................................105 8.6.6. Paradox using ODBC........................................................................................106 8.6.7. Conclusion.........................................................................................................108 9. Connecting to MySQL using JDBC.................................................................................109 10. Mailmerge.......................................................................................................................111 11. Copying an entire database.............................................................................................112 12. General utility macros.....................................................................................................113 12.1. Choose a directory...................................................................................................114 12.2. Get a document's directory......................................................................................115 12.3. Choose a file............................................................................................................115 12.4. Finding a (loaded) OOo document..........................................................................117 12.5. Append to an array..................................................................................................119 12.6. Compare data in an array........................................................................................119 12.7. Create a property.....................................................................................................120 12.8. Create a Point and a Size.........................................................................................120 12.9. Append a data array to a Calc document................................................................121 12.10. Dynamically call object methods..........................................................................122 12.11. Display numeric constants as meaningful text......................................................126 12.12. Select from a list in a list box................................................................................127 13. Database utility macros...................................................................................................130 13.1. Quoting table and field names.................................................................................130 13.2. Convert between an UNO Date and a Basic Date...................................................130 13.3. Convert a result set to an array of data....................................................................132 13.4. Create and populate a dialog from a result set........................................................135 14. Tips and tricks.................................................................................................................137 14.1. Limit the number of returned records.....................................................................137 15. Connect to a Base document using JDBC......................................................................140 vii

Appendix A. Stuff I Own.......................................................................................................143 A.1. Tables.......................................................................................................................143 A.1.1. Category............................................................................................................143 A.1.2. Dealer................................................................................................................143 A.1.3. Images...............................................................................................................144 A.1.4. Item...................................................................................................................144 A.2. Forms........................................................................................................................144 A.2.1. Item Two Tables...............................................................................................144 A.2.2. Item One Table.................................................................................................146 A.2.3. Item Fields........................................................................................................147 A.3. Add an image macro................................................................................................148 A.4. Delete an image macro.............................................................................................149 A.5. Replace an image macro..........................................................................................150 A.6. Extract an image macro............................................................................................152 A.7. Clean the database....................................................................................................153 A.8. Things to do..............................................................................................................153

viii

1. Introduction
1.1. Introductory comments
+lt!ou%! 4 /as %oin% to /$ite a 'oo. on t!is su'Hect, 4 !ave 'een discou$a%ed f$om com#letin% t!is #$oHect( 4 o#ted, instead, to c$eate t!is some/!at f$a%mented, less time intensive document( <o#efully you /ill find it useful( T!is document is not even $emotely finis!ed( 4f you find e$$o$s, o$ !ave some favo$ite additions, t!en #lease do t!e follo/in%: >- Do/nload t!e latest ve$sion of t!e document( 2- Ma.e note of t!e FLast ModifiedG date ,Tuesday, July 28, 2009 at 09:54:04 PM- and t!e $evision num'e$ ,4 - so t!at 4 /ill .no/ if you !ave t!e latest document ve$sion, /!ic! ma.es my life muc! easie$( - Time #e$mittin%, /a$n me a!ead of time so t!at 4 can send you t!e latest ve$sion if 4 !ave not #osted it( 4- Ise Edit > Changes > Record to tu$n on edit t$ac.in%( 5- 4 attem#ted to use t!e t!e styles and fo$mattin% $ecommended at t!e 77o +ut!o$s /e' site ,see !tt#:**///(oooaut!o$s(o$%*-( T!e #$ima$y diffe$ence is t!at 4 do not em'ed #lace %$a#!ics in a f$ame /it! t!e ca#tion( 4 #$efe$ t!em to 'e in t!ei$ o/n #a$a%$a#! and not in a f$ame( 4 e6#e$ienced 'u%s $elated to usin% f$ames fo$ t!is, /!ic! caused me to lose info$mation f$om t!is documentD t!e info$mation is still missin% today( ?- 8end t!e modified document to me( 4 /ill inco$#o$ate t!e c!an%es into t!e latest document and $efo$mat t!e document to 'e com#liant /it! t!e 77o +ut!o$s /e' site c$ite$ia if $e3ui$ed( 4 $eally do a##$eciate 'u% $e#o$ts, and if you desi$e to add sections o$ mate$ial, 4 am o#en to t!at as /ell( T!an.s to 85ymon Ci.li'o$c, /!o #$ovided t!e fi$st 'u% $e#o$t(

1.2. Document organization and introduction


T!e data'ase com#onent in 7#en7ffice(o$% ,77o- contains nume$ous com#le6ities( 4n some /ays t!e vast ca#a'ilities a$e matu$e, and in ot!e$s t!ey a$e not( 4 !ave solved many #$o'lems usin% Jase and 4 add t!em to t!is document as 4 solve t!em and as 4 !ave time to add t!em( T!e advanta%e is t!at all of t!e #$o'lems end u# in a sin%le document( T!e disadvanta%e, !o/eve$, is t!at cove$a%e is disHointed and not consistent( 8ometimes 4 assume t!at you .no/ not!in% a'out Jase, and at ot!e$ times 4 mi%!t assume t!at you a$e an e6#e$t use$( 4, +nd$e/ Pitonya., /as una'le to find si%nificant documentation dealin% s#ecifically /it! 'ina$y data sto$ed in a Jase document, so 4 decided to fi%u$e out !o/ it /o$.s( T!is document sta$ts 'y demonst$atin% !o/ to use 'ina$y fields, /it! an em#!asis on usin% mac$os to mani#ulate t!e data(

TIP

T!e 77o E$ite ve$sion of t!is document contains t!e mac$os desc$i'ed in t!is document( T!e document also contains 'uttons t!at call t!e mac$os contained in t!is document( 9o$ o'vious $easons, if t!is document is conve$ted to a diffe$ent fo$mat, suc! as a PD9 o$ D7", t!e mac$os /ill 'e lost and t!e 'uttons /ill not call t!e mac$os( 4n ot!e$ /o$ds, if you a$e $eadin% a PD9 ve$sion of t!e document, t!e 'uttons donKt /o$.(

T!e initial section dealin% /it! 'ina$y data #$ovides easy ste#s fo$ c$eatin% you$ fi$st data'ase( T!e 'ina$y section also demonst$ates many useful met!ods suc! as c$eatin% and o#enin% fo$ms usin% mac$os( T!is document contains a li'$a$y named +nd$e/Jase, /!ic! contains t!e main mac$os s!o/n in t!is document( Juttons a$e inse$ted t!$ou%!out t!e document to call t!e mac$os s!o/n in t!e te6t( E!en 77o loads a document, only t!e 8tanda$d li'$a$y is loaded, /!ic! means t!at t!e mac$os sto$ed in t!e +nd$e/Jase li'$a$y a$e not availa'le to 'e called f$om a 'utton( T!e standa$d li'$a$y contains !el#e$ mac$os, t!at /$a# calls to t!e mac$os of inte$est( + ty#ical !el#e$ mac$o, "all"$eateJina$yDJ, is s!o/n in Listing 1( +ll !el#e$ mac$os sta$t 'y callin% LoadDJLi's, /!ic! loads t!e li'$a$y containin% t!e /o$.e$ mac$os( Listing 1: Macro used to create the empty Base document.
Const sDBBaseName$ = "BaseFieldDB.odb" Sub LoadDBLibs() If NOT BasicLibraries.isLibraryLoaded("AndrewBase") Then BasicLibraries.LoadLibrary("AndrewBase") End If End sub Sub CallCreateBinaryDB() LoadDBLibs() CreateBinaryDB(GetSourceCodeDir() & sDBBaseName, True) End Sub

Cotice t!at t!e com#ute$ code uses synta6 !i%!li%!tin% as is done 'y t!e Jasic 4DL( 4 feel t!at t!is en!ances t!e $eada'ility of t!e code, so 4 /$ote a mac$o t!at /ill sea$c! t!e enti$e document fo$ com#ute$ code, and t!en c$eate synta6 !i%!li%!tin%(

1.3. repare !or big changes in ""o 3.#


4n 77o 2(6, a Jase document can not contain mac$os, 'ut t!e contained $e#o$ts and fo$ms can( 4n 77o (6, t!is is to 'e $eve$sedD a Jase document can contain mac$os and contained $e#o$ts and fo$ms can not( !tt#:**/i.i(se$vices(o#enoffice(o$%*/i.i*Mac$osMinMData'aseMDocuments

Eit! ve$sion (6, T!is"om#onent /ill al/ays 'e t!e com#onent /!ic! /as active /!en t!e mac$o /as invo.ed( T!is !olds no matte$ /!et!e$ t!e mac$o is located in t!e data'ase documentKs o$ in t!e a##licationKs Jasic li'$a$y( +lso, it !olds no matte$ /!et!e$ t!e active com#onent is a data'ase document o$ any of its su' com#onents( 4n #a$ticula$, t!e va$ious desi%ne$s a$e also availa'le as T!is"om#onent( T!e t$ic. is t!at T!is"om#onent may end u# #ointin% to a data'ase document, es#ecially /!en $unnin% a mac$o f$om an 4DL( T!e va$ia'le T!isData'aseDocument /ill 'e int$oduced fo$ 'asic mac$os em'edded in a Jase document, and al/ays $efe$ to t!e Jase document( T!is may 'e confusin% if a mac$o is invo.ed f$om a $e#o$t, 'ecause fo$ms and $e#o$t definitions a$e documents( T!is"om#onent al/ays se$ved t/o #u$#oses: 9o$ a Jasic mac$o em'edded in a document, it $efe$s to t!e containin% document( 9o$ a Jasic mac$o located else/!e$e, it $efe$s to t!e cu$$ently active document( Info$tunately, t!e te$m cu$$ently active is not /ell&defined ac$oss diffe$ent #latfo$ms and /indo/ mana%e$s( Co/, mac$os can e6ist in data'ase documents and a$e allo/ed to $un mac$os in t!e su' com#onents of t!e Jase document( Info$tunately, t!is #$ovides a cont$adiction, so a c!oice !ad to 'e made on /!ic! of t!e t/o meanin%s fo$ T!is"om#onent to #$ese$ve( T!e final decision /as to .ee# t!e meanin% fo$ T!is"om#onent $efe$in% to t!e document t!at /as invo.ed ,so if a menu o$ 'utton on a menu /as used to call a mac$o- as o##osed to t!e document containin% t!e mac$o( T!is does not $eally c!an%e muc!, e6ce#t fo$ cases /!en T!is"om#onent /ould !ave 'een undefined 'ecause t!e data'ase documents, and its su' com#onents ,fo$ms, $e#o$ts, 3ue$ies, ta'les, $elation desi%ne$- didnKt #a$tici#ate in t!e T!is"om#onent %ame ,since t!e im#lementation of t!is %lo'al #$o#e$ty /as #u$ely 89N 'ased-( 8o, if some'ody /$ote a ,%lo'al- mac$o and t$i%%e$ed t!is f$om /it!in one of t!e DJ com#onents*documents, T!is"om#onent /as effectively undefined( T!is scena$io & e6ecutin% suc! mac$os f$om /it! DJ com#onents & is t!e only one 4 .no/ /!e$e (> diffe$s f$om (0, so t!e$e s!ould 'e no issues(

. !toring images "binary data# in Base


4n t!is section, /e /ill c$eate a data'ase t!at contains a field of ty#e 4ma%e( +n 4ma%e field is $eally a Flon% va$ia'le 'ina$yG field, /!ic! means t!at it can contain any ty#e of 'ina$y data, not Hust ima%es( 4f 4 c!oose to sto$e ima%es in my 'ina$y field, t!en 4 can use an 4ma%e vie/in% cont$ol in a fo$m to see t!e ima%esOand seein% t!e #$etty #ictu$e allo/s fo$ immediate feed'ac. t!at t!in%s a$e /o$.in%(

2.1. Create the initial $ase document


)ou need a 'ase document t!at /ill contain t!e ima%e data(

.1.1. $sing t%e &$I


Ise t!e follo/in% ste# 'y ste# inst$uctions to c$eate a sam#le data'ase fo$ use( >- Ise File > New Database to o#en t!e ne/ data'ase /i5a$d( 2- 8elect t!e Create a new database $adio 'utton and clic. Next( - 8elect t!e No do not register the database $adio 'utton, t!e !pen the database for editing c!ec.'o6, and clic. Finish( 4- Came t!e data'ase 4ma%eDJ and clic. Save(

.1. . $sing a macro


"$eatin% a Jase document usin% a mac$o is easy, 'ut it is easy to ma.e a mista.e in t!e details( T!e$e a$e a fe/ .ey items to c$eate a Jase document( >- Ise t!e Data'ase"onte6t to c$eate an em#ty data sou$ce( 2- 8et t!e data sou$ce IRL to sd'c:em'edded:!s3ld' fo$ an inte$nal <8PL data'ase( - 7'tain t!e data'ase document f$om t!e data sou$ce and save it( )ou can not add ta'les to a Jase document until afte$ it !as 'een saved( T!e mac$o in Listing " demonst$ates !o/ to c$eate a Jase document( 4f t!e data'ase IRL is not s#ecified, t!en a dialo% as.s fo$ a file name( T!e filte$ list, /!ic! contains t!e Jase file e6tensions is o'tained f$om Listing #$, and t!en t!e mac$o in Listing #% dis#lays t!e dialo% as.in% fo$ t!e ne/ data'ase name( Ise t!e Create Database 'utton Create Database to $un t!e /$a##e$ met!od /!ic! calls "$eateJina$yDJ ,see Listing 1 and Listing "-D t!is /ill c$eate t!e Jase9ieldDJ(od' file in t!e same di$ecto$y used 'y t!is document ,see Listing #&-( Listing ": Create an empty Base document.
REM Use "Option Compatible", or you can not use a default argument. Sub CreateBinaryDB(Optional dbURL$ = "", Optional bVerbose = False) Dim oDBContext 'DatabaseContext service. Dim oDB 'Database data source. REM No URL Specified, get one. If dbURL = "" Then dbURL = ChooseAFile(OOoBaseFilters(), False) OpenOffice.org Base 4

Storing images (binary data) in Base

REM Still No URL Specified, exit. If dbURL = "" Then Exit Sub If FileExists(dbURL) Then If bVerbose Then Print "The file already exists." Else If bVerbose Then Print "Creating " & dbURL oDBContext = createUnoService( "com.sun.star.sdb.DatabaseContext" ) oDB = oDBContext.createInstance() oDB.URL = "sdbc:embedded:hsqldb" oDB.DatabaseDocument.storeAsURL(dbURL, Array()) End If End Sub

.1.'. $sing a macro to open t%e wi(ard


T!is is a little sni##et t!at 4 !ave not tested, 'ut acco$din% to 8evastian 9o%lia ,sevastian(fo%lia1yacme(com-, t!e follo/in% s!ould /o$.: Listing ': (tart the Base document wi)ard using a macro.
sURL = "private:factory/sdatabase?Interactive" doc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, args)

2.2. Create the table


T!e ima%e data'ase is intentionally ve$y sim#le ,see Table "-( T!e field names use u##e$case c!a$acte$s and contain no s#aces 'ecause it sim#lifies t!e 8PLOyou do not !ave to 3uote t!e field names in 8PL statements( T!e annoyin% t!in% a'out 3uotin%, is t!at t!e same 3uote c!a$acte$ is not al/ays used( T!e 3ue$y 'uilde$ mi%!t $e3ui$e t!at non&u##e$case c!a$acte$s 'e 3uoted usin% a dou'le 3uote c!a$acte$ ,Q-, 'ut an 8PL statement in a mac$o mi%!t $e3ui$e a 'ac.& tic ,R-( + mac$o t!at deals /it! t!is #$o'lem is demonst$ated in Listing &&( Table ". *ields in the binary table.
Field
4D C+ML D+T+

Field Type
4nte%e$ 04CTL=LR2 Te6t 0S+R"<+R2 4ma%e 0L7C=S+RJ4C+R)2

Comment
Ta'leKs #$ima$y .ey Came fo$ t!e data, most li.ely, a file name( T!e 'ina$y data(

. .1. $sing t%e &$I


Co/, c$eate t!e ta'le to !old t!e ima%e( 8elect Tables f$om t!e left !and side and t!en c!oose t!e Create Table in Design View tas.( Lnte$ t!e fields in t!e ta'le desi%n /indo/( >- "$eate t!e #$ima$y .ey( >- 8et t!e *ield Name to 4D( 2- 8et t!e *ield Type to 4nte%e$( - 8et +uto ,alue to )es( 4- Ri%!t clic. to t!e left of t!e field name and c!oose Pri ar! "e!(
OpenOffice.org Base 5

Storing images (binary data) in Base

2- "$eate t!e name field( >- 8et t!e *ield Name to C+ML( 2- 8et t!e *ield Type to Te6t 0S+R"<+R2( - 8et -ntry re.uired to )es( 4- 8et Length to 255( - "$eate t!e ima%e field( >- 8et t!e *ield Name to D+T+( 2- 8et t!e *ield Type to 4ma%e( - 8et -ntry re.uired to Co( 4- Leave t!e Length at t!e default value of 2>4B48 ?4B( Ise File > Save to save t!e ta'le( Came t!e ta'le J4CD+T+, and t!en use File > Close to close t!e ta'le desi%n /indo/(
Caution
8avin% t!e ta'le saves t!e ta'le definition into t!e Jase document, 'ut t!e document itself !as not 'een saved( )ou must also save t!e Jase document(

. . . $sing a macro
Ise t!e Create #inar! Tables 'utton Create Binary Tables to $un t!e mac$o in Listing /( 4f t!e ta'le e6ists, it /ill 'e deleted and $ec$eated( +lso, if t!e document does not yet e6ist, it /ill 'e c$eated( T!e mac$o uses t!e standa$d 77o +P4( Listing /: Create a table in a Base document using the +01.
REM REM REM REM Sub Create the database specified by dbURL. If it does not exist, then it is created. If bForceNew is True, then an existing table is deleted first. If bVerbose is True, progress messages are printed. CreateBinaryTables(dbURL As String, _ Optional bForceNew = False, _ Optional bVerbose = False) Dim sTableName$ 'The name of the table to creat. Dim oTable 'A table in the database. Dim oTables 'Tables in the document Dim oTableDescriptor 'Defines a table and how it looks. Dim oCols 'The columns for a table. Dim oCol 'A single column descriptor. Dim oCon 'Database connection. Dim oBaseContext 'Database context service. Dim oDB 'Database data source. REM If the database does not exist, then create it. If NOT FileExists(dbURL) Then

OpenOffice.org Base

Storing images (binary data) in Base CreateBinaryDB(dbURL, bVerbose) End If REM Use the DatabaseContext to get a reference to the database. oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(dbURL) oCon = oDB.getConnection("", "") oTables = oCon.getTables() sTableName$ = "BINDATA" If oTables.hasByName(sTableName$) Then If bForceNew Then If bVerbose Then Print "Deleting table " & sTableName oTables.dropByName(sTableName) oDB.DatabaseDocument.store() 'oCon.close() 'Exit Sub Else If bVerbose Then Print "Table " & sTableName & " already exists!" oCon.cose() Exit Sub End If End If REM For now, this should always be True If NOT oTables.hasByName(sTableName$) Then oTableDescriptor = oTables.createDataDescriptor() oTableDescriptor.Name = sTableName$ oCols = oTableDescriptor.getColumns() oCol = oCols.createDataDescriptor() oCol.Name = "ID" oCol.Type = com.sun.star.sdbc.DataType.INTEGER oCol.IsNullable = com.sun.star.sdbc.ColumnValue.NO_NULLS oCol.IsAutoIncrement = True oCol.Precision = 10 oCol.Description = "Primary Key" oCols.appendByDescriptor(oCol) oCol.Name = "NAME" oCol.Type = com.sun.star.sdbc.DataType.VARCHAR oCol.Description = "Filename" oCol.Precision = 255 oCol.IsAutoIncrement = False oCols.appendByDescriptor(oCol) oCol.Name = "DATA" oCol.Type = com.sun.star.sdbc.DataType.LONGVARBINARY oCol.Precision = 2147483647 oCol.IsNullable = com.sun.star.sdbc.ColumnValue.NULLABLE oCol.Description = "Binary Data"

OpenOffice.org Base

Storing images (binary data) in Base oCols.appendByDescriptor(oCol) oTables.appendByDescriptor(oTableDescriptor) End If REM Do not dispose the database context or you will NOT be able to REM get it back without restarting OpenOffice.org. REM Store the associated document to persist the changes to disk. oDB.DatabaseDocument.store() oCon.close() If bVerbose Then Print "Table " & sTableName & " created!" End Sub

TIP

4n my testin%, 4 /anted to com#letely delete an 77o Jase document and sta$t ove$( Info$tunately, afte$ usin% a Jase document, 77o !olds t!e file o#en, so 77o must 'e s!utdo/n and $esta$ted 'efo$e t!e document can 'e deleted( T!is is a .no/n 'u% in 77o ve$sion 2(0 and s!ould 'e fi6ed in 77o 2(0>(

. .'. $sing !)* statements to modify tables


)ou can c$eate and mana%e ta'les usin% 8PL statements $at!e$ t!an t!e 77o +P4( T!e 8PL statements diffe$ de#endin% on t!e 'ac.&end data'ase system, so t!e 8PL is data'ase de#endent Ot!is is neve$ a %ood t!in%( T!e 77o +P4 does a %ood Ho' of insulatin% you f$om t!e system s#ecific details( Info$tunately, some t!in%s Hust can not 'e done usin% t!e +P4( 9o$ e6am#le, as of 77o ve$sion 2(0, you can only set default values to a constant value( 4t is not #ossi'le to default a time o$ date field to t!e cu$$ent date o$ timeOt!is is t$ivial usin% 8PL(

. .+. ,efres% t%e tables


"a$e must 'e ta.en /!en usin% 8PL to modify a ta'le, 'ecause t!e 77o =I4 /ill not automatically notice t!at c!an%es !ave 'een made( )ou must $ef$es! t!e inte$nal 77o st$uctu$es( )ou can use View > Re$resh Tables f$om t!e 77o Jase =I4( + .ind mac$o #$o%$amme$ /ill #e$fo$m t!is tas. in t!e mac$o t!at modifies t!e data'ase st$uctu$e( Ref$es!in% t!e ta'le vie/ s!ould 'e sim#le( Listing #: 2efresh the tables in an !!o Base document should be simple.
oCon.getTables().refresh()

Info$tunately, callin% $ef$es! ,see Listing #- does not al/ays /o$.D in my limited testin%, it did not #$o#e$ly u#date /!en deletin% ta'les, and it sometimes /o$.ed /!en addin% a ta'le( Isin% a dis#atc! ,see Listing 3-, /o$.ed fo$ my fe/ test cases( Info$tunately, t!e data'ase must 'e loaded in t!e =I4 to use a dis#atc!D !o#efully t!is /ill 'e fi6ed in ve$sion 2(0>( TT Listing 3: 2efresh the tables in an !!o Base document using a dispatch.
REM Using SQL DDL commands to modify the table structure bypasses REM the normal OOo API, which does not give OOo an opportunity to REM notice that the table structure has changed. Tell OOo to REM refresh the table view. Sub RefreshTables(sURL$, oCon) Dim oDoc 'Document to refresh. Dim oDisp 'Dispatch helper. Dim oFrame 'Current frame. OpenOffice.org Base 8

Storing images (binary data) in Base

REM This should be the same as REM oCon.getTables().refresh() REM but it is not... oDoc = FindComponentWithURL(sURL, False) If NOT IsNULL(oDOC) AND NOT IsEmpty(oDoc) Then oDisp = createUnoService("com.sun.star.frame.DispatchHelper") oFrame = oDoc.getCurrentController().getFrame() oDisp.executeDispatch(oFrame,".uno:DBRefreshTables", "", 0, Array()) End If End Sub

. .-. Creating and deleting tables using !)*


T!e mac$o in Listing & #e$fo$ms t!e follo/in% tas.s, /!ic! means t!at it demonst$ates !o/ to do t!em usin% 8PL: >- Dete$mine if a ta'le e6ists( To dete$mine !o/ to do t!is, 4 e6amined t!e meta data f$om t!e connection ,see Listing '# and follo/in%-( 2- Delete a ta'le( - "$eate a ne/ ta'le( 4f t!e ta'le e6ists, it is deleted and t!en t!e mac$o $etu$ns( 4f t!e ta'le does not e6ist, t!en it is c$eated( 4f any fo$ms o$ ot!e$ items $ely on t!is ta'le, t!en t!ey /ill also 'e deletedD you !ave 'een /a$ned(
Create Table Using SQ

Listing &: Create a table in a Base document using the +01.


REM REM REM REM Sub Create the database specified by dbURL. If it does not exist, then it is created. If bForceNew is True, then an existing table is deleted first. If bVerbose is True, progress messages are printed. CreateBinaryTablesUseSQL(dbURL As String, _ Optional bForceNew = False, _ Optional bVerbose = False) Dim sTableName$ 'The name of the table to creat. Dim oTable 'A table in the database. Dim oTables 'Tables in the document Dim oTableDescriptor 'Defines a table and how it looks. Dim oCols 'The columns for a table. Dim oCol 'A single column descriptor. Dim oCon 'Database connection. Dim oBaseContext 'Database context service. Dim oDB 'Database data source. Dim oResult 'Restul of executing an SQL statement. Dim nCount As Long 'Counting variable. Dim oStmt Dim sSql$ REM If the database does not exist, then create it. If NOT FileExists(dbURL) Then

OpenOffice.org Base

Storing images (binary data) in Base CreateBinaryDB(dbURL, bVerbose) End If REM Use the DatabaseContext to get a reference to the database. oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(dbURL) oCon = oDB.getConnection("", "") oStmt = oCon.createStatement() sTableName$ = "BINDATA" REM First, check to see if the table exists! sSql = "select count(*) from INFORMATION_SCHEMA.SYSTEM_TABLES " & _ "where TABLE_NAME='" & sTableName & "' " & _ "AND TABLE_SCHEM='PUBLIC'" nCount = 0 oResult = oStmt.executeQuery(sSql) If NOT IsNull(oResult) AND NOT IsEmpty(oResult) Then oResult.Next() nCount = oResult.getLong(1) End If If nCount <> 0 Then If bForceNew Then If bVerbose Then Print "Deleting table " & sTableName REM The default behavior is to use RESTRICT rather than CASCADE. REM RESTRICT prevents the deletion if other things depend on REM this table. sSql = "DROP TABLE " & _ DBQuoteName(sTablename, oCon) & _ "IF EXISTS CASCADE" oStmt.executeQuery(sSql) RefreshTables(dbURL$, oCon) oCon.close() Exit Sub Else If bVerbose Then Print "Table " & sTableName & " already exists!" oCon.close() Exit Sub End If End If REM I did not quote the field names because I know that REM they are all uppercase with nothing special about them. sSql = "CREATE TABLE " & _ DBQuoteName(sTableName, oCon) & _ "(ID INTEGER NOT NULL IDENTITY PRIMARY KEY, " & _ " NAME VARCHAR(255) NULL, " & _ " DATA LONGVARBINARY NULL)" oStmt.executeQuery(sSql)

OpenOffice.org Base

!"

Storing images (binary data) in Base If bVerbose Then Print "Created table in " & dbURL RefreshTables(dbURL$, oCon) REM Do not dispose the database context or you will NOT be able to REM get it back without restarting OpenOffice.org. REM Store the associated document to persist the changes to disk. oDB.DatabaseDocument.store() oCon.close() If bVerbose Then Print "Table " & sTableName & " created!" End Sub

. ... Increase a field/s lengt%


4 needed to inc$ease t!e len%t! of a field, 'ut /as una'le to save my c!an%e( 77o offe$s to delete t!e field and inse$t a ne/ field( T!is $emoves all data associated /it! t!at field( 4 used t!e follo/in% met!od to inc$ease t!e len%t! of t!e te6t field( 4n t!e follo/in% e6am#le, 4 modify t!e field named F"7MMLCTG in t!e 4TLM ta'le( >- 9$om t!e Jase document, $i%!t clic. on t!e ta'le and c!oose edit( 2- Rename t!e "7MMLCT field to somet!in% else suc! as "7MMLCT> and save t!e c!an%e( - +dd a ne/ field named "7MMLCT /it! t!e desi$ed len%t! o$ #$o#e$ties and save t!e c!an%e( 4- 9$om t!e Jase document, use Tools > S%& to o#en t!e L6ecute 8PL 8tatement dialo%( 5- Lnte$ t!e desi$ed 8PL statement to co#y t!e content f$om field "7MMLCT> to "7MMLCTD 4 used FIPD+TL 4TLM 8LT "7MMLCTU"7MMLCT>G( Remem'e$ t!at 4TLM is t!e ta'le name( ?- 7#en t!e 4TLM ta'le and ve$ify t!at t!e data !as 'een co#ied( B- 9$om t!e ta'le desi%n /indo/ ,$emem'e$ $i%!t clic. on t!e ta'le and c!oose edit-, delete t!e old "7MMLCT> field leavin% only t!e ne/ "7MMLCT field( T!ese ste#s may $e3ui$e a fe/ c!an%es if t!e field is used some#lace else ,fo$ e6am#le, in a $elation set usin% Tools > Relationshi's(

2.3. Create a !orm .'.1. $sing t%e &$I


4 /ant a sim#le fo$m so t!at 4 can inse$t ima%es( +lt!ou%! 77o calls a L7C=S+RJ4C+R) field an 4ma%e field, you can sto$e any ty#e of 'ina$y data in an 4ma%e field( +lt!ou%! t!e$e is an 4ma%e field t!at is a'le to dis#lay ima%es, an automated 'ina$y field vie/e$ does not e6ist( 77o does not assume t!at all 'ina$y fields contain ima%e data, /!ic! is /!y 'ina$y fields a$e not added to a fo$m usin% t!e fo$m /i5a$d(
TIP
To add an 4ma%e cont$ol to vie/ an 4ma%e field, you must manually edit t!e fo$m afte$ usin% t!e fo$m /i5a$d(

OpenOffice.org Base

!!

Storing images (binary data) in Base

>- "$eate t!e initial fo$m usin% t!e Ei5a$d >- 8elect For s on t!e left !and side and t!en c!oose t!e (se )i*ard to Create For tas.( 2- 8et t!e tables or .ueries field Ta'le:J4CD+T+( - "lic. on t!e >> 'utton to add all availa'le fields to t!e fo$m( T!is /ill only include t!e 4D and C+ML field( 4ma%e fields a$e not included in t!e /i5a$d in 77o ve$sion 2(0( 4- "lic. Next to continue to t!e su' fo$ms #a%e( 5- "lic. Next to continue /it!out c$eatin% a su' fo$m( ?- 8elect t!e "olumna$ fo$ a sin%le $eco$d #e$ fo$m and clic. Next( 4f you clic. Finish, t!e fo$m /ill automatically 'e saved usin% t!e name J4CD+T+, /!ic! co$$es#onds to t!e ta'le name(

B- 4%no$e t!e data ent$y mode and clic. Next( 8- 4%no$e t!e styles and clic. Next( 9- 8et t!e name to FJ4CD+T+4ma%eG and clic. Finish( 2- T!e fo$m is automatically o#ened fo$ editin%( "lose t!e fo$m usin% File > Close( - Co/, o#en t!e fo$m in edit mode and add an 4ma%e cont$ol( >- 8elect For s on t!e left !and side( 2- Ri%!t clic. on t!e J4CD+T+4ma%e fo$m c$eated usin% t!e /i5a$d and c!oose Edit( - T!e 9o$m "ont$ols tool'a$ s!ould al$eady 'e visi'le( )ou can c!ec. t!is usin% View > ToolbarsD t!e$e s!ould 'e a c!ec. ma$. ne6t to *orm Controls( 4- "lic. on t!e mo$e cont$ols icon ,
OpenOffice.org Base

- to o#en t!e mo$e cont$ols tool'a$(


!#

Storing images (binary data) in Base

5- "lic. on t!e 4ma%e cont$ol icon , - and t!en d$a/ out t!e cont$ol on t!e fo$m( Je /a$ned t!at t!e 4ma%e cont$ol icon is ve$y simila$ to t!e 4ma%e Jutton icon( ?- Ri%!t clic. on t!e ne/ly inse$ted cont$ol and c!oose Control to o#en t!e cont$ol #$o#e$ties dialo%( B- 7n t!e Data ta', set t!e 4ata field to D+T+, /!ic! contains t!e 'ina$y data( 4f /e !a##en to sto$e non&ima%e data, t!is is li.ely to 'e a #$o'lem fo$ t!e ima%e cont$ol, /!ic! no/ e6#ects t!is data to 'e an ima%e( Do not use t!is fo$m if you sto$e non& ima%e data in t!e D+T+ field( 8- Ise File > Save to save t!e fo$m into t!e Jase document( 9- Ise File > Close to close t!e fo$m( 4- T!e fo$m !as only 'een saved into t!e Jase document, 'ut no/ you must save t!e Jase document( Ise File > Save to save t!e Jase document(

.'. . $sing a macro


8tated sim#ly, a fo$m is a document t!at contains cont$ols( 4n t!is case, t!e cont$ols a$e connected to a data'ase( T!e documentKs d$a/ #a%e contains s!a#es and fo$ms( Lac! cont$ol is associated /it! a s!a#e, t!e s!a#e dictates /!e$e t!e s!a#e is dis#layed( T!e mac$o in Listing % c$eates a sim#le fo$m, /!ic! is ve$y simila$ to t!e fo$m c$eated usin% t!e fo$m /i5a$dD t!e$e a$e a fe/ nota'le diffe$ences, !o/eve$( T!e mac$o in Listing % c$eates one s!a#e fo$ eac! cont$ol( T!e$e is a se#a$ate s!a#e fo$ eac! data cont$ol and eac! la'el( T!e fo$m /i5a$d c$eates an additional =$ou#8!a#e fo$ eac! cont$ol*la'el #ai$( T!e %$ou# s!a#e is used to .ee# a data cont$ol /it! its la'el( E!en t!e fo$m is in desi%n mode and you select a cont$ol, you a$e selectin% t!e s!a#e( 4f a cont$ol is %$ou#ed /it! its la'el, you select t!e t/o cont$ols to%et!e$ 'ecause you a$e selectin% t!e %$ou# s!a#e $at!e$ t!an t!e individual cont$ols( T!e disadvanta%e is t!at you can not easily select a s#ecific cont$ol o$ its la'el to edit t!e individual #$o#e$tiesOuse t!e fo$m navi%ato$ to select eac! individual com#onent, even /!en t!ey a$e %$ou#ed /it! ot!e$s( T!e fo$m /i5a$d in 77o ve$sion 2(0 c$eates fo$ms usin% t!e (s6/ file e6tension used in 77o ve$sion >(6( T!e mac$o in Listing % c$eates a E$ite$ document usin% t!e ne/e$ (odt file e6tension( T!e mac$o in Listing % c$eates a E$ite$ document as a fo$m and sto$es it in t!e same di$ecto$y as t!e Jase document( +fte$ t!e fo$m is c$eated, it is added into t!e Jase document( +lt!ou%! 4 !ave not tested t!is, t!e$e is no #a$ticula$ $eason t!at an e6istin% document can not 'e added into a Jase document usin% t!e code s!o/n in t!is mac$o( 4f you c!oose to do t!is, #lease $e#o$t you$ $esults( TT +not!e$ t!in% to conside$ is t!at a fo$m does not $eally im#ly t!at a E$ite$ document is used( My %uess is t!at you s!ould 'e a'le to c$eate and sto$e a "alc document into a Jase document( 4f you t$y t!is, let me .no/ !o/ it /o$.s( TT
Create % &or'

OpenOffice.org Base

!$

Storing images (binary data) in Base

Listing %: Create and add a form to a Base document.


Sub AddBinForm(sDBURL$, sTableName$) Dim oDoc 'Newly created Form document Dim oDrawPage 'Draw page for the form document. Dim s$ 'Generic temporary string variable. Dim oDBDoc 'The Base database document. Dim sDBName$ 'Name portion from sDBURL. Dim sFormURL$ 'URL where the temporary form is stored. Dim oFormDocs 'Form documents in the Base document. Dim sFormName$ 'Form name as stored in the Baes form documents. Dim oDocDef 'Document defition of the form stored in Base. Dim oDBForm Dim NoArgs() As new com.sun.star.beans.PropertyValue Dim oProps(2) as new com.sun.star.beans.PropertyValue REM Create a new document for the form. s$ = "private:factory/swriter" oDoc = StarDesktop.LoadComponentFromURL(s$, "_default", 0, NoArgs()) REM The form will in edit mode, rather than design mode, by default. oDoc.ApplyFormDesignMode = False Dim oViewSettings oViewSettings = oDoc.CurrentController.ViewSettings oViewSettings.ShowTableBoundaries = False oViewSettings.ShowOnlineLayout = True REM Get the document's draw page and force the top level form to REM exist and be named "Standard". oDrawPage = oDoc.DrawPage If oDrawPage.Forms.Count = 0 Then s$ = "com.sun.star.form.component.Form" oDBForm = oDoc.CreateInstance(s$) oDrawpage.Forms.InsertByIndex (0, oDBForm) Else oDBForm = oDrawPage.Forms.GetByIndex(0) End If oDBForm.Name = "Standard" REM Cause the form to use the table as a datasource. oDBForm.DataSourceName = sDBURL oDBForm.Command = sTableName oDBForm.CommandType = com.sun.star.sdb.CommandType.TABLE REM Dim Dim Dim Dim Dim Service names for controls. sLabel$ : sLabel = "com.sun.star.form.component.FixedText" oControl 'A control to insert into the form. oShape 'Control's shape in the draw page. oLControl 'Label control. oLShape 'Label control's shape in the draw page.

OpenOffice.org Base

!4

Storing images (binary data) in Base

REM Anchor the controls to paragraphs. Dim lAnchor As Long lAnchor = com.sun.star.text.TextContentAnchorType.AT_PARAGRAPH REM Insert the ID label oLControl = oDoc.CreateInstance(sLabel$) oLControl.Label = "ID" oLControl.Name = "lblID" oLShape = oDoc.CreateInstance("com.sun.star.drawing.ControlShape") oLShape.Size = createSize(1222, 443) oLShape.Position = createPoint(1000, 1104) oLShape.AnchorType = lAnchor oLShape.control = oLControl REM Do not add the label control yet! REM Insert the ID formatted text field s$ = "com.sun.star.form.component.FormattedField" oControl = oDoc.CreateInstance(s$) oControl.LabelControl = oLControl oControl.BackgroundColor = 14540253 oControl.Border = 1 oControl.DataField = "ID" oControl.EffectiveMax = 2147483647 oControl.EffectiveMin = -2147483648 oControl.EnforceFormat = True oControl.HideInactiveSelection = True oControl.Name = "fmtID" oControl.TreatAsNumber = True oShape = oDoc.CreateInstance("com.sun.star.drawing.ControlShape") oShape.Size = createSize(2150, 651) oShape.Position = createPoint(2522, 1000) oShape.AnchorType = lAnchor oShape.control = oControl oDrawpage.Add(oLShape) oDrawpage.Add(oShape) REM Insert the Name label oLControl = oDoc.CreateInstance(sLabel) oLControl.Label = "NAME" oLControl.Name = "lblName" oLShape = oDoc.CreateInstance("com.sun.star.drawing.ControlShape") oLShape.Size = createSize(1222, 443) oLShape.Position = createPoint(1000, 1954) oLShape.AnchorType = lAnchor oLShape.control = oLControl REM Insert the Name text field s$ = "com.sun.star.form.component.TextField"

OpenOffice.org Base

!5

Storing images (binary data) in Base oControl = oDoc.CreateInstance(s$) oControl.BackgroundColor = 14540253 oControl.Border = 1 oControl.DataField = "NAME" oControl.LabelControl = oLControl oControl.Name = "txtNAME" oShape = oDoc.CreateInstance("com.sun.star.drawing.ControlShape") oShape.Size = createSize(8026, 651) oShape.Position = createPoint(2522, 1850) oShape.AnchorType = lAnchor oShape.control = oControl oDrawpage.Add(oLShape) oDrawpage.Add(oShape) REM Add the Image control s$ = "com.sun.star.form.component.DatabaseImageControl" oControl = oDoc.CreateInstance(s$) oControl.BackgroundColor = 14540253 oControl.Border = 1 oControl.DataField = "DATA" oControl.Name = "imgDATA" oShape = oDoc.CreateInstance("com.sun.star.drawing.ControlShape") oShape.Size = createSize(10504, 7835) oShape.Position = createPoint(2522, 3332) oShape.AnchorType = lAnchor oShape.control = oControl oDrawpage.Add(oShape) REM At this point, we have a Form, which is a Writer document. REM Store the stand alone form to disk. This form is usable as is. REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If sDBName = GetFileNameWithoutExtension(sDBURL, "/") sFormName = "Form_" & sTableName s$ = DirectoryNameoutofPath(sDBURL, "/") & "/" sFormURL = s$ & "Form_" & sDBName & "_" & sTableName & ".odt" REM Store the form to disk and then close the document. oDoc.StoreAsUrl(sFormUrl, NoArgs()) oDoc.close(True) REM Now, convert the form on disk to a document defition and REM store it in a Base document. oDBDoc = FindComponentWithURL(sDBURL$, True) oFormDocs = oDBDoc.getFormDocuments() If oFormDocs.hasByName(sFormName) Then

OpenOffice.org Base

!6

Storing images (binary data) in Base Print "Removing " & sFormName & " from the database" oFormDocs.removeByName(sFormName) End If oProps(0).Name = "Name" oProps(0).Value = sFormName oProps(1).Name = "Parent" oProps(1).Value = oFormDocs() oProps(2).Name = "URL" oProps(2).Value = sFormUrl s$ = "com.sun.star.sdb.DocumentDefinition" oDocDef = oFormDocs.createInstanceWithArguments(s$, oProps()) oFormDocs.insertbyName(sFormName, oDocDef) Print "Added " & sFormName & " to the database" End Sub

2.%. "pen a !orm using a macro


T!e mac$o in Listing $ #e$fo$ms t!e follo/in% o#e$ations: >- 7#en a data'ase document( 2- +llo/ t!e use$ to select a fo$m( - 7#en t!e fo$m usin% t!e mac$o 7#en9o$m4nDJ>,-( Listing $: Choose and open a form from a database.
Sub ChooseAndOpenFormInDB(sDBURL$) Dim oDoc Dim oForms Dim sFormName$ Dim s$ REM Find the database document and open it if required. oDoc = FindComponentWithURL(sDBURL$, True) If IsNULL(oDoc) OR IsEmpty(oDoc) Then Print "The document was not found" Exit Sub End If REM Choose a form to open! oForms = oDoc.getFormDocuments() If oForms.getCount() < 1 Then Print "The database contains no forms" ElseIf oForms.getCount() = 1 Then REM If there is ONLY one form, then open the one form! Dim x() x() = oForms.getElementNames() sFormName = x(0) Else s$ = "Choose A Form To Open"

OpenOffice.org Base

!7

Storing images (binary data) in Base sFormName = DialogSelectItem(oForms.getElementNames(), s$) End If If sFormName = "" Then Exit Sub OpenFormInDB1(sDBURL$, sFormName$) End Sub

T!e fo$m can no/ 'e loaded as s!o/n in Listing 15( T!e fo$m can 'e loaded in desi%n mode /it!out an active connection, 'ut it is $e3ui$ed fo$ all ot!e$ modes(
C(oose %n) Open &or'

)ou /ill not 'e as.ed to c!oose a fo$m if t!e data'ase only

contains one fo$m( Listing 15: Load a form from a database using LoadComponent*rom62L.
Function OpenFormInDB1(sDBURL$, sFormName$) Dim oDBDoc 'The database document that contains the form. Dim oFormDef 'com.sun.star.sdb.DocumentDefinition of the form. Dim oFormDocs 'The form documents container. Dim oFormDoc 'The actual form document. Dim oCon 'Database connection. Dim oParms() As New com.sun.star.beans.PropertyValue Dim oBaseContext 'Global database context service. Dim oDataBase 'Database obtained from the database context. REM Find the database document and open it if required. oDBDoc = FindComponentWithURL(sDBURL$, True) If IsNULL(oDBDoc) OR IsEmpty(oDBDoc) Then Print "The document was not found" Exit Function End If oFormDocs = oDBDoc.getFormDocuments() If NOT oFormDocs.hasByName(sFormName) Then Print "The database does not have a form named " & sFormName Exit Function End If oFormDef = oDBDoc.getFormDocuments().getByName(sFormName) REM Without this, the form opens and then disappears! REM This is a bug that will hopefully be fixed in OOo version 2.0.1. REM oDummyFormDef is defined in the main module. oDummyFormDef = oFormDef oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataBase = oBaseContext.getByName(sDBURL) oCon = oDataBase.getConnection("", "") REM OpenMode is rumored to support "open", "openDesign", REM and "openForMail" AppendProperty(oParms(), "OpenMode", "open") AppendProperty(oParms(), "ActiveConnection", oCon) oFormDoc = oFormDocs.loadComponentFromURL(sFormName, "", 0, oParms()) OpenFormInDB1() = oFormDoc OpenOffice.org Base !8

Storing images (binary data) in Base REM If you close the connection, then the form loses its connection. REM The requirement of an Active connection should be removed, REM hopefully in version 2.0.1. REM This really looks like a resource leak, but I have not checked. REM oCon.close() End Function

TIP

T!e mac$o in Listing 15 o'tains a $efe$ence to t!e data'ase document usin% t!e met!od 9ind"om#onentEit!IRL,-( T!e data'ase document is availa'le f$om t!e data'ase conte6t usin% t!e Data'aseDocument #$o#e$ty(
oDataBase = oBaseContext.getByName(sDBURL) oFormDoc = oDataBase.DatabaseDocument

4n 77o ve$sion 2(0(>, you s!ould 'e a'le to load a fo$m /it!out loadin% t!e document( 4n 77o ve$sion 2(0, t!is causes a c$as!(

4nte$nally, load"om#onent9$omIRL,- #e$fo$ms an e6ecute on t!e fo$m definition o'Hect( T!e mac$o in Listing 11, demonst$ates !o/ to use t!e e6ecute met!od( + connection is not $e3ui$ed to o#en t!e fo$m in desi%n mode, 'ut it is fo$ all ot!e$ modes ,see Listing 1"-( Listing 11: Load a form by e7ecuting the form definition.
Function OpenFormInDB2(sDBURL$, sFormName$) Dim oDBDoc 'The database document that contains the form. Dim oFormDef 'com.sun.star.sdb.DocumentDefinition of the form. Dim oFormDocs 'The form documents container. Dim oFormDoc 'The actual form document. Dim oBaseContext 'Global database context service. Dim oDataBase 'Database obtained from the database context. Dim oCon 'Database connection. Dim oParms() As New com.sun.star.beans.PropertyValue REM Find the database document and open it if required. oDBDoc = FindComponentWithURL(sDBURL$, True) If IsNULL(oDBDoc) OR IsEmpty(oDBDoc) Then Print "The document was not found" Exit Function End If oFormDocs = oDBDoc.getFormDocuments() If NOT oFormDocs.hasByName(sFormName) Then Print "The database does not have a form named " & sFormName Exit Function End If oFormDef = oDBDoc.getFormDocuments().getByName(sFormName) oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataBase = oBaseContext.getByName(sDBURL) 'oCon = oDataBase.getConnection("", "") AppendProperty(oParms(), "ActiveConnection", oCon) Dim identifier as Long identifier = oFormDef.createCommandIdentifier()

OpenOffice.org Base

!9

Storing images (binary data) in Base Dim UcbCommand as new com.sun.star.ucb.Command UcbCommand.Name = "openDesign" 'Or "open" or "openForMail" Dim Arguments as new com.sun.star.ucb.OpenCommandArgument2 Arguments.Mode = com.sun.star.ucb.OpenMode.DOCUMENT UcbCommand.Argument = Arguments Dim environment as Object oFormDoc = oFormDef.execute( UcbCommand, identifier, environment ) OpenFormInDB2() = oFormDoc End Function

T!e mac$o in Listing 1" demonst$ates !o/ to o#en a fo$m /it! t!e cu$$ent connection( T!e on"lic.7#en9o$m met!od /ould 'e called f$om a fo$m in t!e same Jase document( Listing 1": Load a form by e7ecuting the form definition.
Sub onClickOpenForm ( oEvent as variant ) OpenForm(oEvent, "Form Name") End sub Sub OpenForm( oEvent as variant, aFormName as string) as variant Dim args(1) As New com.sun.star.beans.PropertyValue Dim container as variant Dim oCon oCon = oEvent.Source.Model.Parent.ActiveConnection container = oCon.Parent.DatabaseDocument.FormDocuments args(0).Name = "ActiveConnection" args(0).Value = oCon args(1).Name = "OpenMode" args(1).Value = "open" container.loadComponentFromURL(aFormName,"_blank",0,args()) End Sub

+cco$din% to 98, 4f you /ant to o#en a fo$m ,in t!e sense of: dis#lay I4- /!en t!e document loads, you s!ould use met!ods f$om t!e cont$olle$, not f$om t!e document( 8o, somet!in% li.e:
oController = ThisDatabaseDocument.CurrentController If ( Not oController.isConnected() ) Then oController.connect() End If oController.loadComponent(com.sun.star.sdb.application.DatabaseObject.FORM, "my form",FALSE )

2.&. Accessing the binary data .-.1. Adding binary data


+ddin% 'ina$y data usin% a mac$o is #$etty easy( Info$tunately, it is not #ossi'le /it! 7oo ve$sion 2(0 to use an out#ut st$eam di$ectly, you must fi$st $ead t!e data into an a$$ay of 'ytes( TT c!ec. t!is in ve$sion 2(04(

OpenOffice.org Base

#"

Storing images (binary data) in Base

Listing 1': +dd binary data to a table.


Sub InsertImage(sDBURL$, sFileURL$) Dim sFileName$ 'File to save in the database. Dim oData() 'Array of bytes. Dim lLen As Long 'Number of bytes in the file. Dim oDB 'Database object. Dim oStream Dim oSimpleFileAccess Dim oBaseContext Dim oStatement Dim sSQL$ Dim oCon Dim s$ If NOT FileExists(sFileURL) Then Print "Sorry, " & sFileURL & " does not exist" Exit Sub End If If NOT FileExists(sDBURL) Then CreateBinaryDB(sDBURL, True) End If CreateBinaryTables(sDBURL, False, False) REM Load the Tools library If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If REM Call methods in the Tools library to parse the path. sFileName = FileNameOutOfPath(sFileURL, "/") oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(sDBURL) oCon = oDB.getConnection("", "") s$ = "com.sun.star.ucb.SimpleFileAccess" oSimpleFileAccess = createUnoService(s$) oStream = oSimpleFileAccess.openFileRead(sFileURL) REM Get the total length and then dimension the array. lLen = oStream.getLength() ReDim oData(0 To lLen-1) oStream.readBytes(oData(), lLen) REM Use a prepared statement to insert the data. REM Notice that I do not set the ID because it is REM an auto-value field. sSQL = "insert into BINDATA (NAME, DATA) values (?, ?)" oStatement = oCon.PrepareStatement(sSQL) oStatement.SetString( 1, sFileName)

OpenOffice.org Base

#!

Storing images (binary data) in Base

REM I should be able to simply use the stream REM but there is a bug that prevents this. Too bad! 'oStatement.setBinaryStream(2, oStream, oStream.getLength()) oStatement.setBytes(2, oData(), lLen) oStatement.ExecuteUpdate() oStream.closeInput() Print "Inserted " & sFileName oCon.close() Exit Sub End Sub

T!e follo/in% e6am#le, selects a s#ecific file and inse$ts t!e file into a data'ase( +lt!ou%! t!e mac$o name im#lies t!at an ima%e is inse$ted, any file can 'e inse$ted( )ou can add t!e same file many times, t!e mac$o neit!e$ .no/s, no$ ca$es( 4t is li.ely to 'e a #$o'lem /!en you t$y to e6t$act data, !o/eve$(
%)) Binary &ile To DB

Listing 1/: (elect a file and add it to the database.


Sub CallInsertImage() Dim sFileURL$ Dim sDBURL$ LoadDBLibs() sFileURL = ChooseAFile(GraphicFilters(), True) If sFileURL = "" Then Exit Sub End If sDBURL = GetSourceCodeDir() & sDBBaseName InsertImage(sDBURL$, sFileURL$) End Sub

.-. . 01tracting binary data


L6t$actin% a 'ina$y file is easie$ t!an addin% a 'ina$y file( T!e difficult #a$t is dete$minin% /!ic! file to e6t$act( T!e follo/in% ste#s a$e #e$fo$med in t!is e6am#le: >- "onnect to t!e data'ase( 2- T!e data'ase !as a field*column, /!ic! contains a list of file names( E!en a %$a#!ic is added to t!e data'ase, t!e name field is set to contain t!e file name of t!e %$a#!ic( + $esult set is %ene$ated, /!ic! contains a so$ted list of %$a#!ic file names f$om t!e data'ase( - Ise t!e mac$o in Listing %' to select a file name f$om t!e $esult set( 4- 4f t!e file e6ists, t!e chooseAFile() mac$o f$om Listing #% allo/s t!e use$ to select a diffe$ent file( 5- 4f t!e file does not e6ist, t!en it is /$itten into t!e same di$ecto$y containin% t!is document(
*+tract % &ile

9o$ o'vious $easons, you s!ould add data to t!e data'ase 'efo$e you t$y to

e6t$act it(

OpenOffice.org Base

##

Storing images (binary data) in Base

Listing 1#: -7tract a binary file from the database.


Sub ExtractBinaryFile(sPathURL$, sDBURL$) Dim sFileName$ 'File to save from the database. Dim oDB 'Database object. Dim oStream Dim oSimpleFileAccess Dim oBaseContext Dim oStatement Dim oResult Dim sSQL$ Dim oCon Dim sURL$ Dim s$ If NOT FileExists(sDBURL) Then Print "The DB does not exist, sorry" Exit Sub End If oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(sDBURL) oCon = oDB.getConnection("", "") oStatement = oCon.createStatement() sSQL = "SELECT NAME FROM BINDATA ORDER BY NAME" oResult = oStatement.executeQuery(sSQL) sFileName = SelItemFromResult(oResult, 1, 100) If sFileName = "" Then oCon.close() Exit Sub End If sSQL = "SELECT DATA FROM BINDATA WHERE NAME='" & sFileName & "'" oResult = oStatement.executeQuery(sSQL) If Not IsNull(oResult) Then oResult.next() REM I could get a byte array, but this is easier. oStream = oResult.getBinaryStream(1) If oResult.wasNull() Then Print "The image was NULL" Else s = "com.sun.star.ucb.SimpleFileAccess" oSimpleFileAccess = createUnoService(s) sURL = sPathURL & sFileName If FileExists(sURL) Then sURL = ChooseAFile$(GraphicFilters(), False, sURL) End If If sURL <> "" Then oSimpleFileAccess.writeFile(sURL, oStream) Print "Wrote " & sURL End If End If

OpenOffice.org Base

#$

Storing images (binary data) in Base End If oCon.close() End Sub

TT 7#en a document di$ectly into 77o; To o#en a document di$ectly in 77o, 4 must o'tain an a##$o#$iate file st$eam( Info$tunately, t!e file st$eam $etu$ned f$om my 3ue$y is not sufficient V it does not su##o$t all of t!e $e3ui$ed inte$faces( 4 can accom#lis! t!is in Java 'y c$eatin% my o/n class t!at su##o$ts all of t!e $e3uisite inte$faces, 'ut 4 am usin% Jasic in t!is document(

OpenOffice.org Base

#4

'. One2To2Many relations%ips


4 decided to /$ite t!is c!a#te$ 'ecause 4 !ave difficulties fi%u$in% out t!e 'est /ay to $e#$esent associated data in fo$ms( Jy associated data, 4 mean a one to many, o$ many to many $elations!i#( Lve$y attem#t is made to s#ell t!in%s out in detail, so t!at even a fi$st time$ can at least follo/ alon%( T!in%s may 'ecome a 'it mo$e difficult /!en mac$os a$e int$oduced( 9o$ t!e one&to&many $elations!i#, conside$ a sim#lified invento$y t!at associates items to a deale$( T!e assum#tion is t!at eac! item comes f$om one, and only one deale$( )ou need a 'ase document t!at /ill contain t!e data( Ise t!e follo/in% ste# 'y ste# inst$uctions to c$eate a sam#le data'ase fo$ use( >- Ise File > New Database to o#en t!e ne/ data'ase /i5a$d( 2- 8elect t!e Create a new database $adio 'utton and clic. Next( - 8elect t!e No do not register the database $adio 'utton, t!e !pen the database for editing c!ec.'o6, and clic. Finish( 4- Came t!e data'ase 7ooJase+ssociateData(od' and clic. Save(

3.1. Create the tables


T!e fi$st ta'le contains t!e deale$ info$mation ,see Table '-( T!e data'ase is intentionally ve$y sim#le( + FusefulG ta'le is li.ely to contain mo$e info$mation( T!e field names use u##e$case c!a$acte$s and contain no s#aces( Table '. *ields in the 4-+L-2 table.
Field
4D C+ML

Field Type
4nte%e$ 04CTL=LR2 Te6t 0S+R"<+R2

Comment
Ta'leKs #$ima$y .ey Deale$ name(

Maintainin% Fsim#leG t!eme, t!e item ta'le is also ve$y sim#le ,see Table /-( T!e DL+LLR field lin.s 'ac. to t!e 4D field in t!e DL+LLR ta'le( Table /. *ields in the 1T-M table.
Field
4D 4TLM DL+LLR

Field Type
4nte%e$ 04CTL=LR2 Te6t 0S+R"<+R2 4nte%e$ 04CTL=LR2

Comment
Ta'leKs #$ima$y .ey 4tem name( Deale$ 4D(

'.1.1. Create t%e 30A*0, table


8elect Tables f$om t!e left !and side and t!en c!oose t!e Create Table in Design View tas.( Lnte$ t!e fields in t!e ta'le desi%n /indo/(
OpenOffice.org Base #5

One-To-Many relationships

>- "$eate t!e #$ima$y .ey( >- 8et t!e *ield Name to 4D( 2- 8et t!e *ield Type to 4nte%e$( - 8et +uto ,alue to )es( 4- Ri%!t clic. to t!e left of t!e field name and c!oose Pri ar! "e!( 2- "$eate t!e name field( >- 8et t!e *ield Name to C+ML( 2- 8et t!e *ield Type to Te6t 0S+R"<+R2( - 8et -ntry re.uired to )es( 4- Wee# t!e default len%t! of 50( Ise File > Save to save t!e ta'le( Came t!e ta'le DL+LLR, and t!en use File > Close to close t!e ta'le desi%n /indo/(

'.1. . Create t%e IT0M table


+lt!ou%! t!e 4TLM ta'le is easily c$eated usin% t!e same met!od used to c$eate t!e DL+LLR ta'le, it is al/ays inst$uctive to lea$n a ne/ met!odD c$eatin% t!e 4TLM ta'le f$om t!e DL+LLR ta'le( 8elect Tables f$om t!e left !and side to vie/ t!e e6istin% ta'les( >- Ri%!t clic. on t!e DL+LLR ta'le and c!oose co#y( 2- Ri%!t clic. nea$ t!e DL+LLR ta'le, 'ut not on t!e ta'le and c!oose #aste( >- "!an%e t!e Table name f$om DL+LLR to 4TLM 2- T!e$e is no data in t!e DL+LLR ta'le yet, 'ut /e only need to co#y t!e Definition( - Do not c!ec. Create primary 8ey, t!is /ill c$eate a ne/ #$ima$y .ey t!at /e do not /ant( 4- "lic. Next to o#en t!e +##ly columns dialo%( - Ise t!e +##ly columns dialo% to co#y all of t!e fields f$om t!e left !and side to t!e $i%!t !and side( T!is causes all of t!e fields to 'e added to t!e 4TLM ta'le( "lic. Next to o#en t!e Ty#e fo$mattin% dialo%(

OpenOffice.org Base

#6

One-To-Many relationships

*igure 1: 6se the arrows to copy the fields. 4- Ise t!e Ty#e fo$mattin% dialo% to set t!e field ty#es( T!e e6istin% field ty#es a$e fine as is, includin% usin% 4D as t!e #$ima$y .ey( "lic. Create to c$eate t!e 4TLM ta'le(

*igure ": (et the field types. 5- +dd t!e DL+LLR field to t!e 4TLM ta'le( >- Ri%!t clic. on t!e 4TLM ta'le and c!oose -dit( 2- 8et t!e *ield Name to DL+LLR( - 8et t!e *ield Type to 4nte%e$( 4- 8et -ntry re.uired to )es( 5- Leave +uto 9alue as Co( ?- 8et t!e 4efault 9alue to 0 ,5e$o, not a lette$-( TT 4n 77o ve$sion 2(0, t!is seems to co$$u#t t!e data'ase afte$ it !as 'een saved and $eloaded( B- Ise File > Save to save t!e ta'le modifications to t!e Jase document( 8- Ise File > Close to close t!e ta'le desi%n /indo/( ?- Ise File > Save fo$ t!e Jase document, to save t!e ta'le modifications to dis.(

OpenOffice.org Base

#7

One-To-Many relationships

3.2. De!ine the data relationships


+s al$eady stated, it is assumed t!at eac! item comes f$om one, and only one deale$( Ise Tools > Relationshi's to o#en t!e Relations!i# /indo/( E!en t!e $elations!i# desi%n /indo/ o#ens, t!e +dd Ta'les dialo% also o#ens ,see *igure '-( +dd 'ot! t!e DL+LLR and t!e 4TLM ta'le to t!e Relations!i# desi%n /indo/ 'y selectin% eac! ta'le and clic.in% t!e Add 'utton( E!en you a$e finis!ed addin% ta'les, clic. t!e Close 'utton to close t!e +dd ta'les dialo%(

*igure ': +dd tables to the relationship design window. To c$eate a one&to&many $elations!i# f$om, clic. on t!e 4D field in t!e DL+LLR ta'le and d$a% it to t!e DL+LLR field in t!e 4TLM ta'le( + line is d$a/n 'et/een t!e ta'les t!at illust$ates t!e connection ,see *igure /-(

*igure /: Create a one:to:many relationship. T!e esta'lis!ed $elations!i# indicates t!at eac! $eco$d in t!e 4TLM ta'le co$$es#onds to a sin%le $eco$d in t!e deale$ ta'le( 7n t!e ot!e$ !and, eac! $eco$d in t!e DL+LLR ta'le co$$es#onds to 5e$o o$ mo$e $eco$ds in t!e 4TLM ta'le( +ssume t!at item B $efe$s to deale$ , and you t$y to delete deale$ D /!at !a##ensT Dou'le clic. on t!e $elations!i# line to o#en t!e Relations!i# dialo%( T!e Relations!i# dialo% allo/s you to s#ecify /!at to do if t!e deale$ 4D is u#dated ,c!an%ed- o$ deleted( T!e default 'e!avio$ is to do not!in%( 4f 4 c!oose to use an 6pdate cascade, t!en if 4 c!an%e deale$ to !ave a ne/ identifie$, t!en all $eco$ds in t!e 4tem ta'le a$e u#dated to use t!e ne/ value( 4f 4elete cascade is set, t!en deletin% deale$ causes eve$y item t!at $efe$s to deale$ to 'e deleted( 8et t!e u#date action to 6pdate cascade and t!e delete action to (et default ,see *igure #-O$emem'e$ t!at t!e default value fo$ t!e DL+LLR field in t!e 4TLM ta'le is 0( Ise File > Save to save t!e $elations!i#s to t!e Jase document and File > Close to close t!e $elations!i# /indo/(

OpenOffice.org Base

#8

One-To-Many relationships

*igure #: (et the update and delete actions.

3.3. Add data to the D'A(') and I*'+ tables


To #$ovide e6am#les, it is im#o$tant t!at t!e ta'les contain data( Lnte$ t!e sam#le data f$om Table # into t!e DL+LLR ta'le( Table #: (ample data in the 4-+L-2 table.
ID
0 > 2 4 5

NAME
In.no/n Deale$ > Deale$ 2 Deale$ Deale$ 4 Deale$ 5

To add data to t!e DL+LLR, you must o#en t!e ta'le fo$ editin%( "lic. on t!e Ta'les icon in t!e left !and column and t!en dou'le clic. on t!e DL+LLR ta'le ,see *igure 3-(

OpenOffice.org Base

#9

One-To-Many relationships

*igure 3: !pen the 4-+L-2 table for editing. T!e 4D field is an +utoSalue field, and it is s!o/n as suc! in t!e ta'le ,see *igure &-( T!e ta'le is cu$$ently em#ty, and a ne/ em#ty $eco$d is $eady to 'e added( )ou can not #lace t!e cu$so$ in t!e 4D field and ente$ a value 'ecause t!is is an +utoSalue field( Place t!e cu$so$ in t!e C+ML field and ente$ t!e value FIn.no/nG and #$ess t!e -nter .ey( T!e 4D field is automatically %iven t!e value of 5e$o( +s you ente$ ne/ values, t!e 4D field /ill inc$ement 'y one eac! time( E!ile ente$in% data usin% t!e ta'le vie/, can not ente$ a value fo$ t!e 4D field( )ou can, !o/eve$, c!an%e an 4D afte$ ente$in% t!e $eco$d(

*igure &: -mpty 4-+L-2 table waiting for data. T!e inte$nal data'ase $emem'e$s t!e value used in t!e 4D field, /!ic! is t!en used to #$ovide t!e ne6t automatic 4D value( T!e im#o$tant t!in% to $emem'e$, is t!at t!e ne6t value is one la$%e$ t!an t!e la$%est value used so fa$, not one %$eate$ t!an t!e la$%est value t!at is cu$$ently in t!e data'ase( 8o, if you c!an%e an ent$y f$om 4 to >00 and t!en 'ac. to 4, t!e ne6t automatic value /ill 'e >0>( Eit! 8PL, you can set t!e value to any value t!at you desi$e(
TIP
T!e desc$i'ed 'e!avio$ assumes t!at t!e Jase document $efe$ences an inte$nal <8PLDJ data'aseOt!is is t!e default(

Co/ add e6am#le data to t!e 4TLM ta'le ,see Table 3-( Table 3: (ample data in the 1T-M table.
ID
0

NAME
In.no/n

Dealer
0

OpenOffice.org Base

$"

One-To-Many relationships

ID
> 2 4 5

NAME
4tem > 4tem 2 4tem 4tem 4 4tem 5

Dealer
> > 2

OpenOffice.org Base

$!

+. 4orms
+t a !i%! level, a fo$m is a E$ite$ document containin% cont$ols attac!ed to a data'ase( + cont$ol can 'e a 'utton, a list 'o6, a te6t in#ut 'o6, o$ one of many ot!e$ cont$ol ty#es( E!en 4 s#ea. of a fo$m at a !i%! level, 4 $efe$ to t!e enti$e E$ite$ document( T!is is /!at you load /!en you o#en a fo$m( To a fo$m desi%ne$, t!e !i%! level Ffo$mG, /!ic! is a E$ite$ document, contains t!in%s called fo$ms( Lac! fo$m is associated /it! a s#ecific ta'le in a data'ase( Lac! fo$m can contain cont$ols and ot!e$ fo$ms( E!en a fo$m is contained in anot!e$ fo$m, it is called a su'&fo$m(

%.1. *he internal ob,ect model


Mac$o #$o%$amme$s need to unde$stand t!e inte$nal o'Hect model, /!ic! can 'e $at!e$ confusin% O/!ic! is a s!ame 'ecause it is not as confusin% as many #eo#le seem to t!in.( 4f you a$e not a mac$o #$o%$amme$, you mi%!t /ant to s.i# t!is section( Info$tunately, muc! of t!e inte$estin% stuff $e3ui$es t!e use of mac$os(

+.1.1. A control/s s%ape is in t%e draw page


+ E$ite$ document contains a d$a/ #a%e( +ll s!a#es a$e contained in t!e d$a/ #a%e( T!e$e is a s#ecial ty#e of s!a#e called a cont$ol s!a#e, /!ic! co$$es#onds to a sin%le cont$ol( To c!an%e t!e si5e o$ location of a cont$ol, find t!e co$$es#ondin% cont$ol s!a#e and modify it( T!e 9o$m /i5a$d %$ou#s eac! cont$ol /it! its co$$es#ondin% la'el in a %$ou# s!a#e o'Hect( 4t is, t!e$efo$e, im#o$tant t!at any code t!at sea$c!es fo$ cont$ol s!a#es loo.s inside %$ou# s!a#es( Listing 13: *inding control shapes in a ;riter document.
Dim Dim Dim Dim Dim oDrawPage oShape i% sGroupShape sControlShape

sGroupShape = "com.sun.star.drawing.GroupShape" sControlShape = "com.sun.star.drawing.ControlShape" oDrawPage = ThisComponent.getDrawPage() For i = 0 To oDrawPage.getCount() - 1 oShape = oDrawpage.getByIndex(i) If oShape.supportsService(sGroupShape) Then REM The group shape supports the methods getCount() REM and getByIndex() to obtain the contained shapes. REM You should probably use a recursive routine to REM extract the shapes, because the contained shape REM may be another group shape. REM Dim o REM For j = 0 To oShape.getCount() -1 REM o = oShape.getByIndex(j) REM Print o.control.name REM Next OpenOffice.org Base $#

Forms ElseIf oShape.supportsService(sControlShape) Then REM Access the control model using oShape.Control REM Print oShape.control.name End If Next

+.1. . A draw page contains forms


+ d$a/ #a%e contains fo$ms, and fo$ms contain cont$ols and ot!e$ fo$ms( 4t is easy, t!e$efo$e, to find a named fo$m o$ cont$ol( Listing 1&: *ind a named form or control.
REM oObj can be a generic draw page, a form components object, a REM form, or a Writer document. This routine will find any REM form component, which means a form or a control. Function findForm(oObj, sName$) Dim sForm$ : sForm = "com.sun.star.form.component.Form" Dim sForms$ : sForms = "com.sun.star.form.FormComponents" Dim sComp$ : sComp = "com.sun.star.form.FormComponent" Dim oForm Dim i% Dim x REM Extract the forms from a generic draw page. If oObj.supportsService("com.sun.star.drawing.GenericDrawPage") Then findForm() = findForm(oObj.getForms(), sName$) Exit Function End If REM If the object is an office document, assume that it is a Writer REM document. If this is a Calc document, then the object has more REM than one draw page. I am too lazy to worry about this now. If oObj.supportsService("com.sun.star.document.OfficeDocument") Then findForm() = findForm(oObj.getDrawPage().getForms(), sName$) Exit Function End If REM If this is a form component, then it has a name. REM Check to see if the name is the search name. If oObj.supportsService(sComp) Then If oObj.getName() = sName Then findForm() = oObj Exit Function End If End If REM If this object contains components, then search it. If oObj.supportsService(sForms) Then REM Enumerate forms and controls. For i = 0 To oObj.getCount()-1 x = oObj.getByIndex(i) oForm = findForm(x, sName)

OpenOffice.org Base

$$

Forms If NOT IsNull(oForm) AND NOT IsEmpty(oForm) Then findForm() = oForm Exit For End If Next Else End If End Function

+.1.'. A control/s data model is in a form


Lve$y cont$ol contains data suc! as t!e te6t t!at is dis#layed( T!e o'Hect t!at enca#sulates t!is info$mation is called t!e model( T!e cont$olKs model is contained in a fo$m( Ise t!e cont$olKs model to ena'le o$ disa'le t!e cont$ol( T!e com#lete fo$m*cont$ol !ie$a$c!ical st$uctu$e is as follo/s: + E$ite$ document contains a d$a/ #a%e( T!e d$a/ #a%e contains s!a#es and fo$ms( Lac! fo$m can contain cont$ol models and ot!e$ fo$ms( Rat!e$ t!an #$ovide a len%t!y e6#lanation, 4 #$ovide an e6am#le mac$o( Listing 1%: 1nspect control models in a form.
REM oObj can be a generic draw page, a form components object, a REM form, or a Writer document. The lead name usually starts as "". Function getControlNames(oObj, ByVal sLeadName$) As String Dim sForm$ : sForm = "com.sun.star.form.component.Form" Dim sForms$ : sForms = "com.sun.star.form.FormComponents" Dim sControl$ : sControl = "com.sun.star.form.FormControlModel" Dim s$ Dim i% Dim x REM Extract the forms from a generic draw page. If oObj.supportsService("com.sun.star.drawing.GenericDrawPage") Then getControlNames() = getControlNames(oObj.getForms(), sLeadName) Exit Function End If REM If the object is an office document, assume that it is a Writer REM document. If this is a Calc document, then the object has more REM than one draw page. I am too lazy to worry about this now. If oObj.supportsService("com.sun.star.document.OfficeDocument") Then Dim oForms : oForms = oObj.getDrawPage().getForms() s = getControlNames(oForms, sLeadName) getControlNames() = s Exit Function End If REM Add the current form name to the lead name if, and only if, REM the argument is a form. If oObj.supportsService(sForm) Then sLeadName = sLeadName & oObj.getName() ElseIf NOT oObj.supportsService(sForms) Then getControlNames() = "" Exit Function OpenOffice.org Base $4

Forms End If REM Enumerate forms and controls. For i = 0 To oObj.getCount()-1 x = oObj.getByIndex(i) If x.supportsService(sControl) Then s = s & sLeadName & " : " & x.getName() & CHR$(10) ElseIf x.supportsService(sForms) Then If sLeadName = "" Then s = s & getControlNames(x, sLeadName) Else s = s & getControlNames(x, sLeadName & ".") End If End If Next getControlNames() = s End Function

+.1.+. A control/s 5iew model is in t%e controller


Lve$y visi'le document !as a cu$$ent cont$olle$( T!e cont$olle$ !andles use$ inte$action( To cause a cont$ol to 'ecome visi'le, o$ invisi'le, use t!e cont$olKs vie/ model $etu$ned f$om t!e cont$olle$( T!e cont$olle$ !as t!e met!od %et"ont$ol,-, /!ic! acce#ts a cont$ol model as an a$%ument( 4n ot!e$ /o$ds, you must %et a cont$ol model 'efo$e you can %et t!e vie/ model f$om t!e cont$olle$( E!en a cont$ol calls an event !andle$, it #asses an event as an a$%ument( T!e sou$ce #$o#e$ty of t!e event contains t!e cont$olKs vie/ model( T!e data model is o'tained 'y usin% t!e %etModel,met!od on t!e vie/ model( Listing 1$: + 9ery simple e9ent handle< it does nothing.
Sub ButtonEventHandler(oEvent) oEvent.Source 'Control's view model. oEvent.Source.getModel() 'Control's data model. End Sub

T!e cu$$ent cont$olle$ is o'tained f$om t!e E$ite$ document( 4f you !ave a fo$m, 'ut not t!e #a$ent E$ite$ document, you can /o$. you$ /ay 'ac. to t!e containin% #a$ent document as follo/s: Listing "5: =et the containing parent document from a form.
Function getDocumentFromForm(oForm) Dim x Dim sForm$ : sForm = "com.sun.star.form.FormComponent" Dim sDoc$ : sDoc = "com.sun.star.document.OfficeDocument" If NOT oForm.supportsService(sForm) Then Exit Function End If x = oForm Do While NOT x.supportsService(sDoc) x = x.getParent()

OpenOffice.org Base

$5

Forms Loop getDocumentFromForm() = x End Function

+.1.-. 0nabling and setting controls 5isible 6 an e1ample


+s a final e6am#le to illust$ate !o/ to access cont$ols in a fo$m, conside$ a mac$o t!at ena'les, o$ disa'les, all cont$ols in a s#ecific fo$m ,see Listing "1-( 9i$st, t!e document is o'tained f$om t!e fo$m o'Hects usin% t!e mac$o in Listing "5( Lac! cont$ol data model is o'tained f$om t!e fo$m( T!e data model is ena'led, o$ disa'led, de#endin% on t!e 'Lna'le a$%ument( + disa'led cont$ol is still visi'le in a fo$m, 'ut it is s!o/n in a su'dued colo$( T!e data model is used to o'tain t!e vie/ model f$om t!e document cont$olle$( T!e vie/ model is t!en set visi'le, o$ invisi'le( Listing "1: Toggle all controls in a form 9isible and enabled.
REM REM REM REM Sub oForm - Form on which to work. bEnable - Enable, or disable, every control in the form. bVisible - Set every control visible, or invisible. bRecurse - If true, recurse into subforms. EnableControls(oForm, bEnable As Boolean, _ bVisible As Boolean, _ bRecurse As Boolean) Dim sForm$ : sForm = "com.sun.star.form.component.Form" Dim sForms$ : sForms = "com.sun.star.form.FormComponents" Dim sControl$ : sControl = "com.sun.star.form.FormControlModel" Dim oController Dim oDoc Dim i% Dim x oDoc = getDocumentFromForm(oForm) oController = oDoc.getCurrentController() For i = 0 To oForm.getCount()-1 x = oForm.getByIndex(i) If x.supportsService(sControl) Then x.Enabled = bEnable oController.getControl(x).Visible = bVisible ElseIf x.supportsService(sForms) Then If bRecurse Then EnableControls(x, bEnable) End If Next End Sub

+.1... 4inding a control from an e5ent 6 an e1ample


"onside$ a te6t ta'le /it! a 'utton in t!e fi$st column of eve$y $o/( Lac! 'utton in t!e ta'le calls t!e same mac$o( T!e mac$o /ants to .no/ /!ic! cell contained t!e 'utton( T!e solution to t!e #$o'lem is as follo/s: >- 7'tain t!e vie/ model f$om t!e event usin% oLvent(8ou$ce( 2- 7'tain t!e data model f$om t!e vie/ model usin% oLvent(8ou$ce(%etModel,-(
OpenOffice.org Base $6

Forms

- Lnume$ate t!e s!a#es on t!e d$a/ #a%e( T!is code is not $eally safe 'ecause eve$y s!a#e is assumed to 'e a cont$ol s!a#e( 4- 7'tain t!e data model f$om t!e cont$ol s!a#e usin% o8!a#e(cont$ol( 5- Ise L3ualIC77'Hects to com#a$e t!e t/o data models( T!e mac$o in Listing "" im#lements a /o$.in% solution( Listing "": 4etermine which cell contains a button control.
Sub ButtonCall(oEvent) Dim i Dim oButton Dim oModel Dim oShape Dim bFound As boolean REM First, get the button used to call this routine. REM Save the button's model. oButton = oEvent.Source oModel = oButton.getModel() REM Iterate through the controls i = ThisComponent.getDrawPage().getCount() bFound = False Do While (i > 0 AND NOT bFound) i = i - 1 oShape = ThisComponent.getDrawPage().getByIndex(i) bFound = EqualUNOObjects(oShape.Control, oModel) Loop If bFound Then Print "The button is in cell " & oShape.getAnchor().Cell.CellName End If End Sub

+.1.7. Control connected to a database


+ cont$ol can 'e 'ound to a data'ase field( Info$tunately, t!e value in t!e cont$ol is not al/ays and automatically in sync /it! t!e value in t!e data'ase field( >- T!e use$ inte$acts /it! t!e visual com#onent( 2- T!e cont$ol model desc$i'es t!e loo. and 'e!avio$ of t!e cont$ol( - T!e fo$m field !olds t!e data f$om one s#ecific column of t!e $esult set $e#$esented 'y t!e fo$mD did 4 mention t!at a fo$m acts li.e a $esult setT "ode t!at deals di$ectly /it! t!e cont$ol model does not inte$act /it! t!e unde$lyin% $esult set, and t!e$efo$e, does not deal /it! t!e values in t!e data'ase( 9o$ e6am#le, you set ne/ values in t!e fo$m ,usin% a mac$o-, and t!ose values a$e not saved to t!e data'ase ,$esult set-( Ise t!e commit met!od on t!e cont$ol to e6#licitly commit t!e cont$ol*model content to t!e data'ase field(

OpenOffice.org Base

$7

Forms

+nd$e/ Jensen s#ecifically $ecommends o'tainin% t!e cont$ol f$om t!e cont$olle$ and t!e modifyin% t!e cont$ol $at!e$ t!an t!e modelD and /!at M$( Jensen says is almost al/ays co$$ect( +lt!ou%! t!is /o$.s in some cases /!e$e modifyin% t!e cont$ol model does not, it is not conside$ed safe( T!e$e a$e issues $elated to /!ic! listene$s a$e called, and /!at /ill $eally 'e u#dated ,acco$din% to 9$an. 8c!:n!eit-( T!e safest solution is to modify t!e 'ound field di$ectly( 9o$ e6am#le, you$ cu$$ent code may 'e as follo/s:
oControl.setString( "myText" )

4t is 'ette$ if you can use t!e 'ound field:


oControl.BoundField.updateString( "myText" )

T!e $e3ui$ed met!od is de#endent on t!e data ty#e, /!ic! is a d$a/'ac. to t!is met!od( 4 am a/a$e of at least one instance /!e$e t!e s#ecific met!od ,u#dateDate- failed, yet t!e %ene$ate u#date8t$in% met!od #$o#e$ly u#dated t!e 'ound field(

+.1.8. Control model summary


+ lot mo$e can 'e said a'out cont$ols, fo$ms and t!ei$ st$uctu$e( 4 leave t!is discussion until it is needed fo$ an e6am#le(

%.2. Database Forms act like a result set


+ fo$m fulfills seve$al tas.s, li.e sto$in% t!e st$uctu$e of its fo$m com#onents, sto$in% t!e info$mation conce$nin% ta' o$de$in% and cont$ol %$ou#in%, and #$ovidin% t!e event envi$onment fo$ its contained elements( + data'ase fo$m adds t!e a'ility to connect to a data'ase( Table &: (ome ser9ices supported by database forms.
Service
9o$m

Description
8#ecifies a fo$m /!ic! is a %$ou# of 9o$m"om#onents( T!e fo$m se$vice allo/s a s#ecific fo$m com#onent to 'e identified as a fo$m $at!e$ t!an a cont$ol ,see Listing 1%-( +llo/s a fo$m to 'e contained in anot!e$ fo$m( +llo/s a fo$m to contain multi#le com#onents( 8#ecifies a fo$m t!at is connected to a data'ase, dis#layin% t!e $esults of 8PL 3ue$ies( + data'ase fo$m can add, modify, and delete $eco$ds( + data'ase fo$m is essentially an en!anced $o/ set, /!ic! can dis#lay and mani#ulate t!e data( + Result8et, /!ic! is usually %ene$ated 'y e6ecutin% a 8tatement, maintains a cu$so$ #ointin% to its cu$$ent $o/ of data( 4nitially t!e cu$so$ is #ositioned 'efo$e t!e fi$st $o/( F=etG $outines a$e #$ovided to $et$ieve column values fo$ t!e cu$$ent $o/( + Ro/8et is a client side Result8et, /!ic! com'ines t!e c!a$acte$istics of a 8tatement and a Result8et( + Ro/8et can 'e used to im#lement ca#a'ilities fo$ a $esult set, /!ic! a$e not su##o$ted 'y a d$ive$ $esult setD cac!in% and u#date ca#a'ilities, fo$ e6am#le( + Ro/8et #$ovides event notification fo$ va$ious c!an%es in state(

9o$m"om#onent 9o$m"om#onents Data9o$m

Result8et

Ro/8et

OpenOffice.org Base

$8

Forms

+. .1. 3uplicate record macro


4 am not a/a$e of a 'uilt&in met!od to du#licate a $eco$d /!ile ente$in% ne/ data, so 4 decided to /$ite a sim#le mac$o to do t!is( 9i$st, use t!e fo$m /i5a$d to c$eate a fo$m to edit t!e DL+LLR ta'le( "lic. on t!e 9o$ms icon ,see *igure %-(

Figure 8: Forms icon Ce6t, clic. on Ise Ei5a$d to "$eate 9o$m to sta$t t!e 9o$m Ei5a$d( 8elect t!e DL+LLR ta'le and t!en co#y all +vaila'le fields to t!e 9ields in t!e fo$m and clic. Next t/ice(

*igure $: +dd all fields from the 4-+L-2 table to the form. "!oose a layout fo$ t!e fo$m and clic. Next t!$ee times(

*igure 15: 6se Columnar : Labels Left Came t!e fo$m DL+LLRM+dd and clic. Finish to e6it t!e 9o$m Ei5a$d( Ise File > Close to close t!e ne/ly c$eated fo$m( Ri%!t clic. on t!e ne/ly c$eated fo$m and c!oose Edit( Ise View > Toolbars to ena'le t!e For Controls and For Design tool'a$s( 4f a tool'a$ is dis#layed, t!e$e is a c!ec. ma$. ne6t to t!e tool'a$ name( Ise Tools > +acros > ,rgani*e +acros > ,'en,$$ice-org #asic to o#en t!e 7#en7ffice(o$% Mac$os dialo%( "lic. on t!e ,rgani*er 'utton to o#en t!e 7$%ani5e$ dialo%( 8elect t!e Modules ta', if it is not al$eady selected( 9ind t!e DL+LLRM+dd document in t!e Module list ,see *igure 11-( 8elect t!e 8tanda$d li'$a$y, /!ic! al$eady e6ists, and clic. t!e New 'utton( "lic. ," to use t!e default ne/ module name of Module>(

OpenOffice.org Base

$9

Forms

*igure 11: +dd a new module to the 4-+L-2>+dd *orm. 9inally, !i%!li%!t Module> and clic. t!e Edit 'utton, /!ic! /ill o#en t!e Jasic 4nte%$ated De'u%%in% Lnvi$onment ,4DL-( Re#lace t!e te6t /it! Listing "'D t!e included comments indicate !o/ t!e mac$o /o$.s( Ise File > Save to save t!e mac$o into t!e DL+LLRM+dd fo$m(
TIP
E!en you save a mac$o in a fo$m, t!e mac$o is sto$ed in t!e fo$m document( E!en a fo$m document is saved, it is saved in t!e Jase document( 8avin% t!e fo$m document, #e$sists t!e fo$m into t!e Jase document, 'ut it does not #e$sist t!e Jase document to dis.( Je ce$tain to save t!e Jase document afte$ you save a fo$m to t!e Jase document(

Listing "': Macro to duplicate a 4-+L-2 record.


REM ***** BASIC Option Explicit Sub Main End Sub Sub DuplicateRecord(oEvent) Dim oForm 'Reference to the form containing the primary record. Dim lNameCol 'Column used to hold the NAME in the DEALER table. Dim sDealer$ 'Value stored in the current NAME field. REM Get REM Get REM Get oForm = the button's view model from the event Source. the button's data model from the view model. the form from the data model. oEvent.Source.getModel().getParent() *****

REM Find the column that contains the NAME field. lNameCol = oForm.findColumn("NAME") REM Not likely to happen, but check for it anyway. OpenOffice.org Base 4"

Forms If oForm.isAfterLast() Then Print "Hey, you are after the last element" Exit Sub End If REM Not likely to happen, but check for it anyway. If oForm.isBeforeFirst() Then Print "Hey, you are before the first element" Exit Sub End If REM Get the data for the current record. REM This is a simple table with an ID and a NAME. REM The ID is an autovalue, so we only need to save the NAME. sDealer = oForm.getString(lNameCol) REM If new data has been entered into the form, REM when I change records, I lose the data. REM Avoid this by updating the row. oForm.updateRow() REM Now, move to the "Insert row" to add a new record. oForm.moveToInsertRow() REM Update all of the data from the original record that you stored. REM If I only updated the control, then the form would not know REM about it, but if I update the column in the row, then the control REM is automatically updated. oForm.updateString(lNameCol, sDealer) End Sub

Isin% t!e fo$m a%ain, clic. on t!e command 'utton icon , - in t!e "ont$ols tool'a$ and t!e mouse cu$so$ /ill c!an%e to c$oss&!ai$s( D$a% a $ectan%le /!e$e you /ant t!e 'utton to 'e #laced ,see *igure 1"-(

*igure 1": Completed 4-+L-2>+dd form. Dou'le clic. on t!e ne/ly added 'utton to o#en t!e 'utton #$o#e$ties dialo%( 4n t!e =ene$al ta', name t!e 'utton Pus!JuttonDu#licate, and set t!e la'el to Du#licate Deale$( 8elect t!e events ta'( + cont$ol 'utton su##o$ts many events( 4t is #ossi'le to diffe$entiate 'et/een a mouse clic., and a .ey #$ess( +ll /e ca$e a'out is t!at t!e 'utton !as 'een clic.ed( "lic. on t!e t!$ee dots , - ne6t to t!e E!en initiatin% 'o6 to o#en t!e +ssi%n Mac$o dialo%( +lt!ou%! t!e$e is an icon ne6t to eve$y su##o$ted event, you can assi%n any event ,o$ multi#le events- to a mac$o( <i%!li%!t t!e E!en initiatin% event and clic. on t!e +ssi%n mac$o( 9ind t!e Du#licateReco$d mac$o in t!e DL+LLRM+dd fo$m, !i%!li%!t it, and clic. ,"(
OpenOffice.org Base 4!

Forms

*igure 1': 6se the 4uplicate2ecord macro in the 4-+L-2>+dd form. "lic. ," in t!e +ssi%n Mac$o dialo%, and t!e fo$m is $eady to test( Ise File > Save to save t!e fo$m into t!e Jase document( Ise t!e Desi%n Mode 7n*7ff icon , off and test t!e fo$m( - to to%%le desi%n mode

%.3. -how one item and the corresponding dealer


E!ile dis#layin% items one $eco$d at a time, t!e deale$ is difficult to identify 'ecause t!e deale$Ks nume$ic identifie$ is not desc$i#tive and easy to $emem'e$( 4t is, t!e$efo$e, ty#ical to s!o/ values f$om 'ot! ta'les( T!e fo$m /i5a$d can easily c$eate t!e a##$o#$iate fo$m( "lic. on t!e 9o$ms icon in t!e left column of t!e Jase document( 4n t!e Tas.s section, select 6se ;i)ard to Create *orm to sta$t t!e 9o$m /i5a$d( 7n t!e fi$st #a%e of t!e /i5a$d, select t!e 4TLM ta'le as t!e #$ima$y sou$ce of data fo$ t!e main fo$m( + 3ue$y can also 'e used as t!e #$ima$y sou$ce of data( Ce6t, move all of t!e fields in t!e F+vaila'le fieldsG list 'o6 to t!e F9ields in t!e fo$mG list 'o6( Ise t!e >> 'utton to move all of t!e fields at one time( "lic. t!e Ce6t 'utton to add a su'&fo$m(

*igure 1/: (elect the table and fields for the main form. + su'&fo$m is a fo$m t!at is inse$ted into anot!e$ fo$m( Ise a su'&fo$m to s!o/ data f$om ta'les o$ 3ue$ies /it! a one&to&many $elations!i#( Ise t!e e6istin% $elations!i#( 4f you do not use an e6istin% $elations!i#, t!en you /ill 'e as.ed to e6#licitly s#ecify t!e co$$es#ondin% fields( "lic. t!e Next 'utton to select /!ic! fields /ill 'e dis#layed f$om t!e DL+LLR ta'le(

OpenOffice.org Base

4#

Forms

*igure 1#: Create a sub:form for the 4-+L-2 record. 8elect all of t!e fields f$om t!e DL+LLR ta'le to 'e included in t!e su'&fo$m( "lic. t!e Next 'utton to c!oose !o/ t!e cont$ols /ill 'e a$$an%ed( "!oose t!e Columnar ? Labels Left fo$mat fo$ 'ot! t!e fo$m and t!e su'&fo$m( "lic. t!e Next 'utton to select t!e data ent$y mode( T!e default is to dis#lay all data and to allo/ modifications, deletions, and additions( "lic. t!e Next 'utton to s#ecify t!e loo., use t!e default D loo. and colo$( "lic. t!e Next 'utton to name t!e fo$m( 8et t!e name to 4TLMMEi5a$dM8im#le( "lic. t!e Finish 'utton to save t!e fo$m ,see *igure 13-( ,TT Cote t!at 4 !ad to use a develo#ment 'uild 'ecause 77o ve$sion 2(0 failed /it! t!is-( +fte$ o#enin% t!e fo$m, you can move 'ac. and fo$t! 'et/een t!e $eco$ds usin% t!e fi$st, #$evious , -, ne6t , -, and last , - $eco$d icons( +s you move t!$ou%! t!e diffe$ent item $eco$ds, t!e co$$es#ondin% deale$ $eco$d is dis#layed( 4f you move #ast t!e end of t!e last $eco$d, an em#ty $eco$d is dis#layed( T!is is t!e same as usin% t!e ne/ $eco$d icon , -( 4f you accidentally move #ast t!e last $eco$d and, use t!e #$evious $eco$d 'utton to %ot 'ac.D a ne/ $eco$d /ill not 'e added to t!e ta'le( 4f you accidentally add a ne/ $eco$d, use t!e delete $eco$d icon , -(

*igure 13: The form contains all fields from both tables. +lt!ou%! t!e deale$ info$mation is dis#layed in t!e su'&fo$m, you can not move t!$ou%! t!e deale$ $eco$ds( Lven /o$se, you can not use t!e data in t!e su'&fo$m to set t!e deale$ identifie$ in t!e 4TLM ta'le( T!e 'est solution to t!is #$o'lem de#ends on you, and t!e use$(

OpenOffice.org Base

4$

Forms

%.%. .se a combo bo/ with the dealer id


4f t!e deale$ identifie$ /e$e desc$i#tive, and sim#le, t!en a com'o 'o6 can 'e easily used to c!oose t!e deale$( Ise t!e fo$m /i5a$d to c$eate a fo$m fo$ t!e 4TLM ta'leD do not include t!e DL+LLR field( Came t!e fo$m 4TLMMDeale$M4DM"om'o( +fte$ c$eatin% t!e sim#le fo$m, $i%!t clic. on t!e fo$m and c!oose Edit( Ise View > Toolbars to ena'le t!e For Controls and For Design tool'a$s( 4f a tool'a$ is dis#layed, t!e$e is a c!ec. ma$. ne6t to t!e tool'a$ name( 7n t!e 9o$m "ont$ols tool'a$, clic. on t!e La'el 9ield icon , -( T!e cu$so$ /ill c!an%e to a c$oss&!ai$s s!a#e( D$a/ a $ectan%le /!e$e you /ant t!e Deale$ la'elD t!e si5e is not im#o$tant 'ecause you can c!an%e t!e si5e late$( Dou'le clic. on t!e ne/ la'el field to o#en t!e cont$ol #$o#e$ties /indo/( 4n t!e cont$ol #$o#e$ties /indo/, set t!e Came to La'el9ieldDeale$ and set t!e La'el to Deale$(
TIP
4f you clic. on ,select- a cont$ol, %$een 'o6es a$e dis#layed a$ound t!e cont$ol( + selected cont$ol can 'e moved, $esi5ed, co#ied, o$ deleted(

"lic. on t!e "om'o Jo6 icon , - in t!e 9o$m "ont$ols tool'a$ and t!en d$a/ a $ectan%le /!e$e you /ant t!e com'o 'o6( T!e "om'o Jo6 /i5a$d is immediately dis#layed( 9i$st, you must c!oose f$om /!ic! ta'le t!e com'o 'o6 s!ould o'tain its valuesD c!oose t!e DL+LLR ta'le and clic. Next( +lt!ou%! t!e Came field is mo$e desc$i#tive t!an t!e 4D field, c!oose to dis#lay t!e 4D field and clic. Next( 4ndicate t!at you /ant to save t!e value in t!e DL+LLR data'ase field( )ou can only save t!e data in fields in t!e 4TLM ta'le, 'ecause t!e com'o 'o6 is in t!e main fo$m ,t!e$e is only one fo$m $i%!t no/- and it is attac!ed to t!e 4TLM ta'le( "lic. Finish to c$eate t!e cont$ol( )ou can test t!e fo$m immediately 'y clic.in% on t!e Desi%n Mode 7n*7ff icon( +s you move t!$ou%! t!e fo$m, t!e com'o 'o6 dis#lays t!e co$$ect value and you can di$ectly set t!e deale$ identifie$ 'y c!oosin% a diffe$ent value in t!e com'o 'o6( Info$tunately, t!is !as not im#$oved t!in%sD t!e deale$ identifie$ is not desc$i#tive(

OpenOffice.org Base

44

Forms

*igure 1&: (imple form with a combo bo7

%.&. .se a list bo/ with the dealer name


+ list 'o6 #$ovides mo$e ca#a'ilities t!an a com'o 'o6( 8ufficient ca#a'ilities, in fact, t!at t!is #$o'lem can 'e solved /it!out /$itin% a sin%le mac$o( Ri%!t clic. on t!e 4TLMMDeale$M4DM"om'o fo$m and c!oose Co'!( Ce6t, use Edit > Paste to c$eate a ne/ fo$mD name t!e ne/ fo$m 4TLMMDeale$MCameMList( Ri%!t clic. on t!e ne/ fo$m and c!oose Edit( Ise View > Toolbars to ena'le t!e For Controls and For Design tool'a$s( 4f a tool'a$ is dis#layed, t!e$e is a c!ec. ma$. ne6t to t!e tool'a$ name(
TIP
4n 77o ve$sion 2(0, t!e tool'a$s seem to move a$ound a lot( 8ometimes 4 find my tool'a$s floatin% a$ound t!e sc$een in $andom locations, and sometimes t!ey a$e doc.ed to t!e to#, 'ottom, o$ side of my cu$$ent /indo/( )ou can al/ays doc a floatin% tool'a$ 'y d$a%%in% it /!e$e you /ant it(

Remove t!e e6istin% com'o 'o6, it is no lon%e$ needed( 4n its #lace, inse$t a ne/ list 'o6 , cont$ol( +fte$ you d$a/ out t!e desi$ed location, t!e ta'le selection dialo% o#ensD select t!e DL+LLR ta'le as t!e sou$ce of t!e dis#layed data and clic. t!e Next 'utton( 8elect C+ML as t!e dis#layed field and clic. t!e Next 'utton( T!e list 'o6 allo/s you to dis#lay one field and lin. it to anot!e$ field( 8et t!e DL+LLR field f$om t!e FSalueG ta'le and t!e 4D field f$om t!e FListG ta'le ,see *igure 1%-( "lic. t!e Finish 'utton to c$eate t!e cont$ol(

*igure 1%: Lin8 1T-M.4-+L-2 to 4-+L-2.14. To em#!asi5e /!at /as Hust accom#lis!ed:

+ list 'o6 /as c$eated to dis#lay t!e C+ML field f$om t!e DL+LLR ta'le( T!e DL+LLR field in t!e 4TLM ta'le /as lin.ed to t!e 4D field in t!e DL+LLR ta'le(

T!e same info$mation can 'e seen in t!e list 'o6 #$o#e$ties dialo%( Dou'le clic. on t!e ne/ly c$eated list 'o6 and loo. at t!e Data ta'(

OpenOffice.org Base

45

Forms

Table %: 4ata properties for the list bo7 control.


Data Property
Data 9ield Ty#e "ontent Jound 9ield +ssociate t!e list 'o6 to t!e DL+LLR field in t!e 4TLM ta'le( Ise an 8PL statement to fill t!e list 'o6 /it! data( 8PL statement to use: 8LLL"T QC+MLQ, Q4DQ 9R7M QDL+LLRQ( Cotice t!at t!e name and t!e id a$e $et$ieved( T!e fi$st field is 'ound, /!ic! means t!at t!e name is dis#layed( Cotice t!at t!e name is t!e fi$st field in t!e select statement(

"lic. on t!e =ene$al ta'( +ssociate t!e Deale$ la'el to t!e list 'o6 'y clic.in% on t!e t!$ee dots to t!e $i%!t of t!e La'el 9ield #$o#e$ty and c!oosin% t!e deale$ la'el( 7t!e$ nota'le #$o#e$ties include t!e D$o#do/n #$o#e$ty, /!ic! causes t!e list 'o6 to 'e dis#layed as a Fd$o# do/nG $at!e$ t!an a list 'o6, and t!e multi&selection #$o#e$ty, /!ic! #$events mo$e t!an on item f$om 'ein% selected at a time(

*igure 1$: The dealer name displayed in a list bo7. 8ave t!e fo$m and test it( +s you move t!$ou%! t!e item $eco$ds, t!e co$$ect deale$ name is automatically dis#layed( "!an%in% t!e deale$ name in t!e d$o# do/n automatically u#dates t!e deale$ id in t!e 4TLM ta'le( T!is is #$o'a'ly t!e solution of c!oice( T!e$e a$e a fe/ #oints to .ee# in mind: >- T!e list is sto$ed in t!e same fo$m as t!e $elated data( 4n ot!e$ /o$ds, alt!ou%! t!e list 'o6 dis#lays t!e deale$ name, it is contained in t!e fo$m dis#layin% t!e item data( )ou can, t!e$efo$e, select t!e item fo$m and t!en inse$t t!e list 'o6( 2- 4f /i5a$ds a$e ena'led V t!e$e is a 'utton in t!e cont$ols tool'a$ to ena'le and disa'le /i5a$ds V a /i5a$d /ill %uide you t!$ou%! t!e #$ocess( - 4f you do not use a /i5a$d, you must set t!e cont$ol #$o#e$ties manually( T!e data field is co$$es#ondin% 4D field, t!e contents ty#e is 8PL, and t!e list contents is simila$ to F8LLL"T QC+MLQ, Q4DQ 9R7M QDL+LLRQG( T!e F'ound fieldG ent$y $efe$s to t!e data t!at is dis#layed f$om t!e 3ue$y( Eit! t!e #$ovided 8PL, t!e data to dis#lay is t!e C+ML field, /!ic! co$$es#onds to t!e fi$st fi$st column $etu$ned( Isin% a list'o6 #o#ulated usin% a 3ue$y #$ovides a lot of cont$ol( )ou can $eally dis#lay almost anyt!in%(

OpenOffice.org Base

46

Forms

%.0. )elations in a single table


+ssume t!at you !ave Ta'le> /it! t!e follo/in% fields:

4D V 4nte%e$ auto&value as t!e .ey field( Title V Te6t field( Desc$i#tion V Te6t field(

"$eate a com'o&'o6 containin% t!e values f$om t!e Title column t!at causes t!e co$$es#ondin% Desc$i#tion te6t to 'e dis#layed in a te6t field(

+...1. !olution
"$eate a fo$m in desi%n vie/( Co/, add cont$ols to t!e fo$m( >- 7#en t!e fo$m navi%ato$( 2- 4n t!e fo$m navi%ato$, $i%!t clic. on 9o$ms and c!oose New > For ( 9o$ me t!e fo$m /as automatically named 8tanda$d( - 4n t!e fo$m navi%ato$, $i%!t clic. on t!e 8tanda$d fo$m and c!oose P$o#e$ties( 4- 4n t!e fo$m #$o#e$ties dialo%, c!oose t!e Data ta'( 5- 8et t!e "ontent #$o#e$ty to Ta'le>, o$ /!at eve$ you named you$ ta'le( ?- Eit! t!e 8tanda$d fo$m !i%!li%!ted in t!e fo$m navi%ato$, clic. on t!e com'o&'o6 'utton in t!e "ont$ols tool&'a$( D$a/ a com'o&'o6 on t!e fo$m( T!e com'o&'o6 /i5a$d /ill o#en( B- 8elect Ta'le> in t!e com'o&'o6 /i5a$d and clic. Ce6t( 8- 9o$ t!e dis#lay field, c!oose Title and clic. Ce6t( 9- "!oose FCo, 4 only /ant to save t!e value in t!e fo$m(G and clic. 9inis!( 4f you to%%le t!e desi%n mode off to test you$ fo$m, t!e com'o&'o6 contains values f$om t!e Title column( To%%le desi%n mode on and t!en continue( Loo. at t!e #$o#e$ties fo$ t!e com'o&'o6, it o'tains content usin% t!e follo/in% 8PL:
SELECT DISTINCT "Title" FROM "Table1"

Co/, add a te6t 'o6 to dis#lay t!e Desc$i#tion( >0-Eit! t!e 8tanda$d fo$m selected, add a te6t field( >>-4n t!e Data ta' of t!e #$o#e$ties dialo% fo$ t!e te6t field, set t!e Data field to Desc$i#tion( +t t!is #oint, t!e te6t field dis#lays t!e Desc$i#tion fo$ t!e cu$$ent $eco$d( 4t is Hust a matte$ of tellin% t!e fo$m /!ic! $eco$d to dis#lay( +dd t!e follo/in% mac$o to t!e fo$m: Listing 24: *ilter a form based on te7t in a combo:bo7.
Sub NewTitleSelected(oEvent) Dim oForm oForm = oEvent.Source.getModel().getParent() oForm.Filter = "Title='" & oEvent.Source.getText() & "'"

OpenOffice.org Base

47

Forms oForm.ApplyFilter = True oForm.reload() End Sub

4 tied t!e mac$o to t!e item status c!an%ed event, /!ic! is only called if a ne/ item is selected usin% t!e mouse V modifyin% te6t usin% t!e .ey'oa$d does not cause an item status c!an%ed event( +not!e$ o#tion is t!e te6t c!an%ed event, /!ic! is called /!en eve$ t!e te6t is modified, includin% f$om t!e .ey'oa$d( TTT 4 t!in. t!at 4 tied t!is to t!e com'o&'o6( Se$ify(

+... . !olution c%aracteristics


Lac! fo$m is associated /it! a $eco$d in a ta'le( T!e fo$m containin% t!e solution is associated /it! Ta'le>( T!e te6t field is $elated to t!e cu$$ent $eco$d( Movin% t!$ou%! t!e $eco$ds causes t!e te6t field to dis#lay t!e Desc$i#tion fo$ t!e cu$$ent $eco$d( T!e com'o&'o6 is filled usin% a 8PL statement and is not $elated to t!e cu$$ent $eco$d( + mac$o filte$s t!e $eco$ds t!at t!e fo$m can visit 'ased on t!e value in t!e com'o&'o6( 4t is #ossi'le,/it! a 'it mo$e /o$., to disassociate t!e te6t field f$om t!e cu$$ent $eco$d( 7n t!e Data ta', do not associate t!e field to t!e ta'le( T!e mac$o must no/ do all of t!e /o$.( Listing 25: (et te7t field based on te7t in a combo:bo7.
Sub NewTitleSelected(oEvent) Dim s$ Dim oForm Dim oDoc Dim oContext 'Global database context. Dim oDataSource 'Data source for the specified database. Dim oCon 'Connection to a database. Dim sSQL$ 'SQL that is executed. Dim oResult 'Result from an SQL statement. Dim oStatement 'A created statement that can execute SQL. Dim sQuote$ oForm = oEvent.Source.getModel().getParent() oDoc = oForm REM Walk up the form component tree looking for REM the containing text document. s = "com.sun.star.text.TextDocument" Do While NOT oDoc.supportsService(s) oDoc = oDoc.getParent() Loop REM Now, get the containing database. s = "com.sun.star.sdb.OfficeDatabaseDocument" oDoc = oDoc.getParent() If IsNull(oDoc) OR IsEmpty(oDoc) Then Print "The form is not embedded in a Base document"

OpenOffice.org Base

48

Forms Exit Sub ElseIf Not oDoc.supportsService(s) Then Print "The form is not embedded in a Base document" Exit Sub End If oContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataSource = oContext.getByName(oDoc.getURL()) oCon = oDataSource.getConnection("", "") sQuote = oCon.getMetaData().getIdentifierQuoteString() oStatement = oCon.CreateStatement() sSQL = "SELECT " & sQuote & "Description" & sQuote & " FROM " & _ sQuote & "Table1" & sQuote & " WHERE " & _ sQuote & "Title" & sQuote & "='" & _ oEvent.Source.getText() & "'" oResult = oStatement.executeQuery(sSQL) s = "" If NOT IsNull(oResult) AND NOT IsEmpty(oResult) Then If oResult.next() Then s = oResult.getString(1) End If End If oCon.close() oForm.getByName("TextBox").setString(s) End sub

%.1. .se a 2help and !ill3 button


+ ty#ical solution to t!is #$o'lem is to #$ovide a 'utton o$ .ey'oa$d s!o$tcut to dis#lay t!e values f$om anot!e$ ta'le( T!e selected value is t!en u#dated in t!e o$i%inal ta'le( 4 can t!in. of a fe/ #ossi'ilities on !o/ to im#lement t!is( 7ne solution, includes c$eatin% a fo$m to dis#lay t!e DL+LLR ent$ies( +fte$ c!oosin% t!e deale$, an u#date item 'utton is #$essed on t!e deale$ fo$m( Pa$ado6 !ad a ve$y nice featu$e fo$ t!is, 'ut 4 am too la5y to c$eate an im#lementation $i%!t no/( 4 use a d$o# do/n list 'o6 in my e6am#le s!o/n in +##endi6 +( 8tuff 4 7/n( Ta.e a loo. at section +(2(2( 4tem 7ne Ta'le(

OpenOffice.org Base

49

-. Many2to2many relations%ips
Ce6t, setu# a many to many $elations!i# and discuss /!at to do /it! it in a manne$ simila$ to t!e one to many $elations!i#( TT Time, 4 lac. time(((

OpenOffice.org Base

5"

.. 3atabase fields
+ data'ase ta'le is a collection of $eco$ds( Lac! $eco$d contains individual #ieces of data called fields( T!is c!a#te$ discusses t!e ty#es of data t!at can 'e sto$ed in a data'ase field, #$ima$ily as it $elates to mac$o #$o%$amme$s( Most maHo$ data'ases a$e 'uilt to confo$m to an 8PL standa$d, /!ic! dictates nume$ous t!in%s, includin% t!e data ty#es su##o$ted 'y t!e data'ase( T!e #$ima$y standa$ds a$e 8PL89, 8PL92, 8PL99, and 8PL200 Ot!e num'e$ indicates t!e yea$ t!at t!e standa$d /as ado#ted( T!e data ty#es defined 'y t!ese standa$ds a$e outlined in Table $( Table $. =eneral field types supported by (@L.
When
8PL99 8PL200 8PL200 8PL92 8PL92 8PL92 8PL99 8PL89 8PL92 8PL99 8PL89 8PL92 8PL92 8PL92 8PL99 8PL99 8PL99 8PL99 8PL99 8PL99

Type
+RR+) +RR+) ICJ7ICDLD J4=4CT J4C+R) J4T ,D$o##ed 8PL200 J4T S+R)4C= ,D$o##ed 8PL200 J77LL+C "<+R D+TL DL"4M+L D7IJLL 9L7+T 4CTL=LR 4CTLRS+L 4CTLRS+LMD+) 4CTLRS+LMD+)MT7M<7IR 4CTLRS+LMD+)MT7MM4CITL 4CTLRS+LMD+)MT7M8L"7CD 4CTLRS+LM<7IR 4CTLRS+LM<7IRMT7MM4CITL

Description
"ollection ty#e( "ollection ty#e( L6act nume$ic value /it! #$ecision >9( Jina$y data of fi6ed len%t! /it! a ma6imum len%t! 255( 9i6ed len%t! n&len%t! 'it st$in%( Sa$ia'le len%t! 'it st$in% ,u# to n&'its-( + sin%le t$ue o$ false value( "!a$acte$ st$in% of fi6ed st$in% len%t! /it! a ma6imum len%t! 255( )ea$, mont!, and day fields, confo$min% to t!e $ules of t!e =$e%o$ian calenda$ ( 8i%ned, e6act, nume$ic value /it! a #$ecision and scale( 8i%ned, a##$o6imate, nume$ic value /it! a 'ina$y #$ecision 5 ( 8i%ned, a##$o6imate, nume$ic value( L6act nume$ic value /it! #$ecision >0 and scale 0( 8#ecify a time inte$val( Cum'e$ of days 'et/een t/o dates( Cum'e$ of days and !ou$s 'et/een t/o dates and times( Cum'e$ of days, !ou$s, and minutes 'et/een t/o date and times( Cum'e$ of days, !ou$s, minutes, and seconds 'et/een t/o dates and times( Cum'e$ of !ou$s 'et/een t/o dates and times( Cum'e$ of !ou$s and minutes 'et/een t/o dates and times(

OpenOffice.org Base

5!

Database fields

When
8PL99 8PL99 8PL99 8PL99 8PL99 8PL99 8PL99 8PL92 8PL92 8PL200 8PL99 8PL89 8PL89 8PL92 8PL92 8PL92 8PL92 8PL92 8PL200

Type
4CTLRS+LM<7IRMT7M8L"7CD 4CTLRS+LMM4CITL 4CTLRS+LMM4CITLMT7M8L"7CD 4CTLRS+LMM7CT< 4CTLRS+LM8L"7CD 4CTLRS+LM)L+R 4CTLRS+LM)L+RMT7MM7CT< L7C= S+RJ4C+R) L7C= S+R"<+R MILT48LT CIMLR4" RL+L 8M+LL4CT T4ML T4ML8T+MP T4C)4CT S+RJ4C+R) S+R"<+R NML

Description
Cum'e$ of !ou$s, minutes, and seconds 'et/een t/o dates and times( Cum'e$ of minutes 'et/een t/o dates and times( Cum'e$ of minutes and seconds 'et/een t/o dates and times( Cum'e$ of mont!s 'et/een t/o dates Cum'e$ of seconds 'et/een t/o dates and times( Cum'e$ of yea$s 'et/een t/o dates( Cum'e$ of yea$s and mont!s 'et/een t/o dates( Sa$ia'le len%t! 'ina$y data( Sa$ia'le len%t! c!a$acte$ dataD ty#ically called a memo field( "ollection ty#e( 8i%ned, e6act, nume$ic value /it! a #$ecision and scale( 8i%ned, a##$o6imate, nume$ic value /it! a 'ina$y #$ecision 24( L6act nume$ic value /it! #$ecision 5 and scale 0( <ou$, minute, and second fields( )ea$, mont!, day, !ou$, minute, and second fields( L6act nume$ic value /it! #$ecision and scale 0( Sa$ia'le len%t! 'ina$y data /it! a ma6imum len%t! 255( Sa$ia'le len%t! c!a$acte$ data /it! a ma6imum len%t! 255( Cative NML sto$a%e(

T!e diffe$ent 8PL standa$ds 'uild on eac! ot!e$( T!e$e a$e instances, !o/eve$, /!e$e a data ty#e is d$o##edD J4T /as d$o##ed 'y 8PL200 ( T!e most commonly su##o$ted and used data ty#es a$e defined 'y 8PL92( T!e data ty#es su##o$ted 'y 7#en7ffice(o$% a$e s!o/n in Table 15( T!e Ty#e column contains a nume$ic value used inte$nally 'y 7#en7ffice(o$% and is useful /!en modifyin% a data'ase usin% mac$os( T!e Len%t! column indicates t!e len%t! values su##o$ted 'y 7#en7ffice(o$%( Many of t!e ty#es defined 'y t!e 8PL standa$d do not s#ecify t!e ma6imum #$ecision and len%t!D t!e values a$e im#lementation s#ecific( P$ecision and len%t! info$mation mentioned in Table 15 is s#ecific to t!e <8PLDJ data'ase im#lemented in 7#en7ffice(o$%( Table 15. *ield types supported by !pen!ffice.org using H(@L4B.
Type Name
Jit Tiny4nt Ji%4nt &5
OpenOffice.org Base

#
&B &?

Len th
>

Comment
Joolean yes and no values( 8 'it si%ned inte%e$ f$om &>28 to >2B( ?4 'it si%ned inte%e$ f$om &9,22 , B2,0 ?,854,BB5,808 to
5#

>9

Database fields

Type Name
Lon%Sa$Jina$y Sa$Jina$y Jina$y Lon%Sa$"!a$

#
&4 & &2 &>

Len th
2>4B48 ?4B 2>4B48 ?4B 2>4B48 ?4B 2>4B48 ?4B 0 > to 2>4B48 ?4B > to ?4?45?99

Comment
9,22 , B2,0 ?,854,BB5,80B( Sa$ia'le&len%t! 'ina$y data suc! as an ima%e( Sa$ia'le&len%t! 'ina$y data /it! a ma6imum len%t!( 9i6ed&len%t! 'ina$y data( Sa$ia'le len%t! c!a$acte$ data, also .no/n as a Memo field( Cull value( 9i6ed len%t! te6t( 8i%ned, e6act nume$ic value /it! a s#ecified #$ecision and scale( 8i%ned, e6act nume$ic value /it! a s#ecified #$ecision and scale( 2 'it si%ned inte%e$ f$om &2,>4B,48 ,?48 to 2,>4B,48 ,?4B( >? 'it si%ned inte%e$ f$om & 2,B?8 to 2,B?B( Dou'le #$ecision ,8 'yte- floatin% #oint num'e$( Dou'le #$ecision ,8 'yte- floatin% #oint num'e$( Dou'le #$ecision ,8 'yte- floatin% #oint num'e$( Sa$ia'le len%t! te6t data( Sa$ia'le len%t! te6t data t!at is not case sensitive( T!is is not a standa$d ty#e( + nume$ic 0 is 9alse and any ot!e$ num'e$ is T$ue( )ea$, mont!, and day fields, confo$min% to t!e $ules of t!e =$e%o$ian calenda$( <ou$, minute, and second fields( Date and time /it! a one second time $esolution( T!e 8PL ty#e is data'ase&s#ecific and is ma##ed to an o'Hect t!at can 'e accessed usin% t!e met!od NRo/::%et7'Hect,- (

8PLCILL "<+R Cume$ic

0 > 2

Decimal 4nte%e$ 4 8mall4nt 9loat Real Dou'le Sa$"!a$ Sa$"!a$M4%no$e"ase Joolean Date 9> Time Time8tam# 7t!e$ >>> 92 9 5 ? B 8 >2 >2 >?

> to ?4?45?99

>0 5 >B >B >B > to 2>4B48 ?4B > to 2>4B48 ?4B > C*+ C*+ C*+

2>4B4 8 ?4B

7f t!e fou$ data ty#esOst$in%, num'e$, date&time, and inte$valOnum'e$s !ave t!e most availa'le data ty#es and t!e %$eatest const$aints on im#lementation( T!e 8PL92 standa$d defines fundamental data ty#es t!at mold t!e ty#es found in t!e va$ious 8PL&'ased data'ase im#lementations( Cum'e$s #ose t!e %$eatest $is. /!en movin% data 'et/een diffe$ent data'ase im#lementations 'ecause it is common to offe$ non&standa$d e6tensions( 9o$ e6am#le, t!e same ty#e may !ave diffe$ent default si5e limits in 7$acle and 8PL 8e$ve$( 4t is, t!e$efo$e, im#o$tant t!at you unde$stand t!e idiosync$asies of t!e unde$lyin% data'ase(

OpenOffice.org Base

5$

Database fields

0.1. -toring numbers


+ll num'e$s !ave a #$ecision, /!ic! indicates t!e num'e$ of si%nificant di%its( 8ome nume$ic ty#es contain a scale value t!at indicates t!e #osition of t!e least si%nificant di%it to t!e $i%!t of t!e decimal( 9o$ e6am#le, t!e num'e$ >2 4(5? !as a #$ecision of ? and a scale of 2( T!e 8PL92 standa$d #$ovides fo$ 'uilt&in o#e$ations, suc! as addition, su't$action, multi#lication, and division, in addition to functions t!at dete$mine t!e len%t! and ot!e$ att$i'utes $e3ui$ed fo$ value !andlin%( T!e diffe$ent nume$ic data ty#es can 'e mi6ed du$in% com#a$isons and nume$ic o#e$ations( 4n most data'ase im#lementations, t!e $esult uses t!e data ty#e /it! t!e %$eatest #$ecision(
TIP
Cume$ic data ty#es a$e t!e most difficult to move 'et/een diffe$ent data'ase im#lementations 'ecause it is common to offe$ non&standa$d e6tensions( 9o$ e6am#le, su##o$t fo$ unsi%ned inte%e$s o$ su##o$t fo$ e6tended #$ecision(

..1.1. Integer numbers


T!e inte%e$ data ty#es a$e used to sto$e num'e$s /it! no decimal #o$tion( +ll of t!e inte%e$ ty#es use t!e same $adi6 ,nume$ic 'ase and inte$nal $e#$esentation-, $ound usin% t!e same $ules, and a$e e6act( T!e 8PL standa$d s#ecifies t!e follo/in% #$o#e$ties:

4s an e6act ty#e, /!ic! sto$e a lite$al $e#$esentation of t!e num'e$( "an uses decimal #$ecision o$ 'ina$y #$ecision, /!ic! is 'ased on t!e num'e$ of 'its used to $e#$esent t!e value( T!e $e#$esented $an%e is im#lementation&s#ecific( <as a scale of 0Ono decimal di%its( <as an im#lementation s#ecific minimum and ma6imum #$ecision( May !ave a vendo$&su##lied default value fo$ t!e #$ecision if no e6#licit value is s#ecified(

T!e 8PL92 standa$d defined t!e ty#es 4CTL=LR, 8M+LL4CT, and T4C)4CTD J4=4CT /as int$oduced 'y 8PL200 ( +lt!ou%! eac! im#lementation is a'le to state t!e #$ecision of t!e inte%e$ ty#es, t!e follo/in% must 'e t$ue: T4C)4CT @U 8M+LL4CT @U 4CTL=LR @U J4=4CT( Table 11 summa$i5es t!e diffe$ences 'et/een t!e inte%e$ data ty#es im#lemented 'y t!e data'ase used in 7#en7ffice(o$%( Table 11. 1nteger types supported by H(@L4B.
Type
T4C)4CT 8M+LL4CT 4CTL=LR J4=4CT

Si!e
> 'yte 2 'ytes 4 'ytes 8 'ytes

Minim"m val"e
&>28 & 2,B?B &2,>4B,48 ,?48 &9,22 , B2,0 ?,854,BB5,808

Ma#im"m val"e
>2B 2,B?B 2,>4B,48 ,?4B 9,22 , B2,0 ?,854,BB5,80B

OpenOffice.org Base

54

Database fields

..1. . 4loating point numbers


9loatin% #oint num'e$s a$e num'e$s t!at can !ave num'e$s to t!e $i%!t of t!e decimal #ointO unli.e an inte%e$ ty#e, /!ic! can not( 9loatin% #oint num'e$s a$e inte$nally $e#$esented in scientific notation, fo$ e6am#le, >(2 e&45( T!e 4nstitute of Llect$ical and Llect$onics Ln%inee$s ,4LLL- defined a fo$mat fo$ sto$in% floatin% #oint num'e$s( T!e 4LLL standa$ds a$e used 'y almost eve$y com#ute$ t!at utili5es floatin% #oint num'e$s( P$o'a'ly t!e most im#o$tant t!in% to .no/ a'out a #a$ticula$ floatin% #oint num'e$ is t!e num'e$ of $elevant di%its( 9o$ e6am#le, a dou'le #$ecision 4LLL floatin% #oint num'e$ is accu$ate to $ou%!ly fifteen di%its( 9loatin% #oint num'e$s a$e defined to use 'ina$y #$ecision /!en $oundin% and a$e not e6act( + fo$mat is not e6act if some num'e$s a$e not $e#$esented e6actly 'ecause t!e inte$nal $e#$esentation is not a'le to do so( +t t!e !ea$t of t!e #$o'lem is t!at num'e$s a$e usually $e#$esented in 'ase 2, 'ut t!e e6te$nal $e#$esentation is 'ase >0( +lt!ou%! it is /ell unde$stood t!at >* may not 'e e6actly $e#$esenta'le, it is unintuitive t!at 0(0> is not( 4n 4LLL sin%le& #$ecision fo$mat, 0(0> is $e#$esented as a##$o6imately 0(009999999BB?482582Ot!e num'e$ t!at is sto$ed is e6actly >0B B4>8*>0B B4>824( 4t is not #ossi'le to e6actly $e#$esent 0(0> usin% t!e 4LLL floatin% #oint fo$mats ty#ically used 'y com#ute$s( T!e 8PL standa$d s#ecifies t!at t!e floatin% #oint ty#es !ave t!e follo/in% #$o#e$ties:

4s an a##$o6imate nume$ic ty#e, meanin% t!at it $e#$esents an e6#onential fo$mat fo$ a %iven value, fo$ e6am#le, >(2 e&45( +lt!ou%! $oundin% and t$uncatin% fo$ t!is ty#e a$e defined la$%ely 'y t!e manufactu$e$, t!e 4LLL standa$ds a$e almost al/ays used( Ises 'ina$y #$ecision /!en $oundin%(

TIP

4n 7#en7ffice(o$%, usin% <8PLDJ, t!e t!$ee floatin% #oint ty#es RL+L, D7IJLL PRL"4847C, and 9L7+T use t!e 4LLL 8 'yte dou'le #$ecision $e#$esentation su##o$tin% values X*& >(B9B?9 > 48?2 2 6 >0L 08(

T!e 8PL standa$d defines t!$ee #$ima$y floatin% #oint data ty#es RL+L, D7IJLL PRL"4847C, and 9L7+T( +lt!ou%! eac! im#lementation is a'le to state t!e #$ecision of t!e floatin% #oint ty#es, t!e #$ecision of t!e RL+L ty#e must 'e less t!an o$ e3ual to t!e #$ecision of t!e D7IJLL PRL"4847C ty#e( 4n t!e 8PL s#ecification, t!e 9L7+T ty#e #$ovides a mec!anism to $ecommend t!e #$ecision, t!e im#lementation can t!en c!oose t!e $e#$esentation( 4n a ty#ical im#lementation, t!e 9L7+T ty#e /ill 'e assi%ned to eit!e$ t!e RL+L o$ t!e D7IJL PRL"4847C ty#e de#endin% on t!e $e3uested #$ecision( T!e <8PLDJ data'ase used inte$nally 'y 7#en7ffice(o$% $e#$esents all t!$ee ty#es as an 4LLL 8 'yte dou'le #$ecision num'e$(
TIP
4n most im#lementations, includin% <8PLDJ, t!e D7IJLL PRL"4847C ty#e can 'e a''$eviated as D7IJLL(

OpenOffice.org Base

55

Database fields

..1.'. 9$M0,IC and 30CIMA* types


T!e CIMLR4" and DL"4M+L ty#es define e6act nume$ic ty#es t!at contain decimals( E!en definin% a CIMLR4" o$ a DL"4M+L column, t!e total column len%t! and t!e num'e$ of decimal di%its is s#ecifiedOt!e num'e$ of decimal di%its is usually $efe$$ed to as t!e scale( T!e 8PL standa$d defines t!e ty#es to !ave t!e follo/in% #$o#e$ties:

4s an e6act ty#e, /!ic! sto$e a lite$al $e#$esentation of t!e num'e$( Pe$fo$m $oundin% in 'ase >0 $at!e$ t!an t!e usual 'ase 2( + ty#ical im#lementation accom#lis!es t!is 'y sto$in% t!e num'e$s as st$in%s o$ in t!e 'ina$y coded decimal fo$mat( <as a total len%t! e3ual to t!e defined #$ecision, #lus > if t!e scale is %$eate$ t!an 0(

Jased on t!e 8PL standa$d, t!e CIMLR4" and DL"4M+L ty#es diffe$ in t!ei$ t$eatment of decimals( + CIMLR4" ty#e must use t!e num'e$ of decimal di%its as s#ecified 'y t!e scale( T!e DL"4M+L ty#e, !o/eve$, must use at least as many decimal di%its as s#ecified 'y t!e scale, 'ut may use mo$e( T!e 8PL definition allo/s t!e t/o ty#es to 'e identical(
TIP
T!e 8PL standa$d uses t!e ty#e CIMLR4"( <8PLDJ documentation and 77o f$e3uently uses t!e /o$d CIMJLR $at!e$ t!an CIMLR4"D t!ey a$e t!e same ty#e(

T!e =I4 s!o$tens nume$ic values, #$o'a'ly 'y mani#ulatin% t!em as Dou'les( 4 tested t!e CIMLR4" ty#e /it! 77o ve$sion 2(0 $elease candidate 2( 4 c$eated a CIMLR4" column /it! a #$ecision of 50 and a scale of 4( Isin% t!e =I4, 4 ente$ed a >9 di%it num'e$, /!ic! t!e =I4 s!o$tened to >B di%its( Isin% 8PL ,see Listing "3-, 4 /as a'le to sto$e and $et$ieve a lon% CIMLR4" num'e$, 'ut t!e =I4 al/ays dis#layed t!e num'e$ to >B si%nificant di%its( Listing "3: (et and retrie9e the 9alue in a N6M-21C field.
s = "update ""Numbers"" Set ""Number2""=1234567890123456789.1234 Where ID=3" oStmt.executeQuery(s) s = "select ""Number2"" from ""Numbers"" Where ID=3" oResultSet = oStatement.executeQuery(s) If Not IsNull(oResultSet) Then oResultSet.next Print "Return = " & oResultSet.getString(1) End If

Caution

+s of ve$sion 2(0, t!e 77o =I4 does not #$o#e$ly u#date and dis#lay CIMLR4" ty#es( T!ey data is a##ea$s to 'e t$eated as a dou'le, /!ic! !as a #$ecision of >B decimal di%its( 4 tested t!is usin% 'ot! t!e Pue$y desi%ne$ and 'y editin% a ta'le di$ectly( Je ce$tain to /$a# access to t!ese ta'les in #$o#e$ly tested fo$ms(

0.2. $it and $oolean *ypes


<8PLDJ su##o$ts t!e J77LL+C ty#e, /!ic! sto$es t!e values KyesK and KnoK( E!en initiali5ed /it! a nume$ic value, a 5e$o value is t$anslated to no and any ot!e$ value is t$anslated to yes( +lt!ou%! 7#en7ffice(o$% does not di$ectly list t!e J4T data ty#e, use t!e Fyes*noG J77LL+C ty#e instead(

OpenOffice.org Base

56

Database fields

TT dJase you can c!ec. usin% yes*no, usually, you use t$ue*false, 4 t!in. t!at you can use 0*&>(

0.3. Date and time


Ise t!e D+TL ty#e to sto$e a date /it! no time( use t!e T4ML ty#e to sto$e a time /it! no date( +lt!ou%! 'ot! t!e D+TL and T4ML ty#e allo/ a dis#lay fo$mat t!at s!o/s 'ot! a date and time, t!is is ve$y confusin% 'ecause neit!e$ ty#e !as 'ot! values( Ise t!e T4ML8T+MP ty#e to sto$e a date and time value( T!e T4ML8T+MP ty#e sto$es and $etu$ns values in !und$edt!s of a second( +lt!ou%! 4 could not set !und$edt!s of a second usin% t!e standa$d =I4, 4 /as a'le to use 8PL to do t!is ,see Listing "&-( Eit! 77o 2(0 R" 2, /!en t!e time stam# is o'tained as a st$in%, t!e value includes <und$edt!8econds, 'ut /!en o'tained as a Time8tam#, it does not( Listing 27: (et a T1M-(T+M0 to include hundredths of a second.
s = "update NUM Set TS='1965-03-13 01:02:03.123456789' Where ID=0" oStmt.executeQuery(s) oResultSet = oStatement.executeQuery("select TS from NUM Where ID=0") If Not IsNull(oResultSet) Then oResultSet.next() oTS = oResultSet.getTimestamp(1) s = s & "TS1 = " & oTS.Year & "-" & oTS.Month & "-" & oTS.Day & " " & _ oTS.Hours & ":" & oTS.Minutes & ":" & _ oTS.Seconds & "." & oTS.HundredthSeconds & CHR$(10) & _ "TS2 = " & oResultSet.getString(1) & CHR$(10) Msgbox s End If

T!e $eal su$#$ise fo$ me is t!at 4 can not set TT TT "omment on can not use t!e ot!e$ ty#e to o'tain milliseconds( TT "omment on default values and definin% usin% DDL so t!at can set ce$tain default values(

0.%. *e/t data


Ise t!e "<+R ty#e to sto$e data /it! a fi6ed len%t!( T!e advanta%e of a "<+R ty#e is t!at it is efficient to sto$e, inde6, and access( T!e disadvanta%e of t!e "<+R ty#e, is t!at t!e ma6imum len%t! is al/ays used and is t!e$efo$e /asteful of s#ace( T!e S+R"<+R ty#e, !o/eve$, is ty#ically mo$e efficient in sto$a%e, usin% only as muc! s#ace as is $e3ui$ed( T!e S+R"<+RM4=C7RL"+8L is a s#ecial case&insensitive non&#o$ta'le ty#e of S+R"<+R(

TIP

4n some im#lementations, it is mo$e s#ace efficient to #lace t!e fi6ed len%t! fields 'efo$e t!e va$ia'le len%t! fields(

OpenOffice.org Base

57

Database fields

Inli.e t!e ot!e$ te6t data ty#es, t!e L7C=S+R"<+R ty#e does not acce#t a len%t!( T!e L7C=S+R"<+R ty#e is f$e3uently called a memo field 'ecause it allo/s fo$ lon% $am'lin% memos of no s#ecific len%t!Ot!e$e is an im#lementation s#ecific u##e$ limit, 'ut t!e limit is usually ve$y la$%e( 4n a ty#ical im#lementation, t!e #$ima$y file contains a #ointe$ to most o$ all of t!e FmemoG, /!ic! is sto$ed in a seconda$y file( T!e <8PLDJ data'ase sto$es all of t!e data in a sin%le file( 8ome data'ase im#lementations !ave difficulty accessin% and usin% memo fields(

TIP

4 e6#e$imentally dete$mined t!at t!e <8PLDJ data'ase uses t!e same amount of sto$a%e $e%a$dless of t!e ty#e used( 4 also sa/ no s#eed advanta%e /!ile sea$c!in% t!e diffe$ent te6t ty#es( Des#ite t!ese t!ese o'se$vations, you s!ould c!oose data ty#es $eali5in% t!at t!e unde$lyin% im#lementation may c!an%e in t!e futu$e(

0.&. $inary data


7#en7ffice(o$% su##o$ts t!$ee #$ima$y 'ina$y ty#es, J4C+R), S+RJ4C+R), and L7C=S+RJ4C+R)( Jased on t!e 8PL standa$ds, t!e 'ina$y ty#es s!ould 'e!ave simila$ly to t!e co$$es#ondin% te6t ty#es "<+R, S+R"<+R, and L7C=S+R"<+R ty#esD'ut 'ina$y data is sto$ed $at!e$ t!an te6t data( T!e <8PLDJ im#lementation used 'y 7#en7ffice(o$%, !o/eve$, im#lements all 'ina$y ty#es simila$ly to a memo$y fieldOyou can not s#ecify t!e len%t!, 'ut t!e len%t! is ve$y la$%e(
TIP
T!e <8PLDJ im#lementation t$eats all t!e 'ina$y ty#es as e3uivalent( )ou can not s#ecify a ma6imum len%t!, so t!e t!$ee 'ina$y ty#es a$e t$eated as a L7C=S+RJ4C+R)(

T!is document contains e6tensive e6am#les of mani#ulations usin% 'ina$y data(

0.0. "ther data type


T!e #u$#ose of t!e 7T<LR data ty#e in <8PLDJ, is to sto$e a se$iali5a'le J+S+ o'Hect( 7'Hects sto$ed as an 7T<LR ty#e a$e al/ays conside$ed e3ual unless one of t!e o'Hects is CILL( 9inally, 7T<LR data can not 'e sea$c!ed o$ Hoined ot!e$ t!an tests fo$ CILL(

0.1. Database se4uences and auto56alue !ields


+ data'ase inde6 is a loo.u# ta'le t!at $elates t!e value of fields to t!ei$ location in t!e data'ase( T!e value of t!e fields on /!ic! an inde6 is 'ased #$ovide is called t!e inde6 .ey( 4t is ty#ically ve$y fast to sea$c! an inde6 fo$ a s#ecific value, and t!en t!e inde6 $etu$ns a #ointe$ into t!e data'ase t!at allo/s t!e co$$es#ondin% $eco$d to 'e o'tained( 4f a la$%e data'ase is f$e3uently accessed 'ased on a #e$sonKs last name, t!en an inde6 s!ould #$o'a'ly 'e c$eated 'ased on t!e last name field( + .ey is a set of columns t!at can 'e used to identify o$ access a #a$ticula$ $o/ o$ $o/s( + uni3ue .ey is a .ey t!at is const$ained so t!at no t/o values a$e e3ual( T!e #$ima$y .ey is a uni3ue .ey t!at is selected to 'e t!e most im#o$tant .ey fo$ a ta'leOeac! ta'le can !ave only one #$ima$y .ey( + #$ima$y inde6 is 'ased on t!e #$ima$y .ey and a seconda$y inde6 is 'ased on columns t!at a$e not t!e #$ima$y .ey(

OpenOffice.org Base

58

Database fields

+lt!ou%! 7#en7ffice(o$% can access a data'ase t!at does not contain a #$ima$y .ey, 77o can not ,in %ene$al- u#date a data'ase /it!out a #$ima$y .ey( Ceit!e$ a "S8 te6t file no$ a "alc document contain a #$ima$y .ey( T!e dJase access code is an e6ce#tion to t!e #$ima$y .ey $uleD dJase files do not contain #$ima$y .eys, yet 77o is a'le to u#date t!ese files( 4t is ve$y im#o$tant, t!e$efo$e, t!at add a #$ima$y .ey field to eve$y ta'le t!at you c$eate( E!en no o'vious #$ima$y .ey e6ists, t!e ty#ical solution is to c$eate an inte%e$ field t!at contains a se3uence of inte%e$s( 7#en7ffice(o$% calls a field an auto&value field, if it can automatically set itself to t!e ne6t availa'le se3uence num'e$ /!en a ne/ $o/ is inse$ted into t!e ta'le(
TIP
T!e auto&inc$ement statement fo$ an inte%e$ field in <8PLDJ is F4DLCT4T)G(

<8PLDJ, included /it! 77o, im#lements an 4dentity statement used to %ene$ate a se3uence of inte%e$s( +n auto&value inte%e$ field can 'e im#licitly set /it! an automatically %ene$ated num'e$Oinse$t a null value into t!e auto&value column to im#licitly inse$t t!e ne6t se3uence num'e$( )ou can e6#licitly set t!e value sto$ed in an auto&value field( 4f t!e e6#licitly ente$ed value is %$eate$ t!an t!e ne6t availa'le se3uence num'e$, t!en t!e se3uence is $eset to t!e e6#licit value( Listing "% demonst$ates im#licitly and e6#licitly settin% an auto&value field /!ile inse$tin% ne/ $o/s in a data'ase( (isting 27. Implicitly and explicitly set an auto-value field.
CALL IDENTITY() INSERT INTO `Table1` INSERT INTO `Table1` INSERT INTO `Table1` INSERT INTO `Table1` INSERT INTO `Table1` INSERT INTO `Table1` VALUES VALUES VALUES VALUES VALUES VALUES (NULL, (137, (130, (130, (NULL, (NULL, 'x0') 'x1') 'x2') 'x3') 'x4') IDENTITY()) ** ** ** ** ** ** ** Assume returns 50 Insert (50, 'x1') Insert (137, 'x2') Insert (130, 'x3') Failure, 130 exists. Insert (138, 'x0') Insert (139, 138)

OpenOffice.org Base

59

7. A few easy database definitions


+lt!ou%! data'ase te$minolo%y is not difficult, some /o$ds !ave a diffe$ent meanin% de#endin% on t!e conte6t and data'ase system( Eo$ds t!at a$e li.ely to 'e used /!ile c$eatin% a ne/ data'ase a$e s!o/n and defined in Table 1" as t!ey a$e used in t!is document( + data'ase #o/e$ use$ /ill al$eady .no/ and 'e comfo$ta'le /it! t!e definitions(
Note
Many of 7#en7ffice(o$%Ks +P4s acce#t a$%uments t!at s#ecify t!e sc!ema and catalo%, /!ic! is /!y 4 c!ose to define t!em( T!e definitions s!o/n in Ta'le 5 a$e intended to #$ovide a '$oad vie/ fo$ an ine6#e$ienced use$( T!e te$ms sc!ema and catalo% a$e %ene$ally not $e3ui$ed /!ile usin% a sim#le data'ase( 4n ot!e$ /o$ds, donKt #anic, and donKt s#end a lot of time memo$i5in% definitions(

+ data'ase ta'le is a collection of $eco$ds( Lac! $eco$d contains individual #ieces of data called fields( T!e 8PL 92 standa$d int$oduces t!e te$ms catalo% and sc!ema, /!ic! $efe$ to t!e o$%ani5ation of data in data'ase systems( 9ields a$e contained in $eco$ds, $eco$ds a$e contained in ta'les, ta'les a$e contained in sc!emas, and sc!emas a$e contained in catalo%s( 9inally, all of t!e elements a$e sto$ed in a data'ase( + sc!ema is also li.ely to contain vie/s, aliases, inde6es, t$i%%e$s, and st$uctu$ed ty#es( Table 1". (implistic database definitions
Term
9ield Reco$d Ta'le 8c!ema "atalo% Data'ase

Simplistic De$inition
4ndividual #iece of data suc! as a fi$st name, o$ date( "ollection of $elated fields, t$eated as a sin%le unitD a $eco$d is a sin%le $o/ of fields( "ollection of $eco$ds( "ollection of ta'les, vie/s, aliases, inde6es, t$i%%e$s, and st$uctu$ed ty#es( 9$e3uently used to mean t!e st$uctu$e of a %$ou# of ta'les( "ollection of sc!emas( Lnca#sulates all of t!e items, includin% catalo%s, sc!emas, ta'les, $eco$ds, and fields(

Many data'ase systems do not su##o$t catalo%s o$ sc!emas, es#ecially smalle$ data'ase systems( La$%e$ data'ase systems a$e mo$e li.ely to su##o$t catalo%s and sc!emas, 'ut t!e names and #$ecise definitions diffe$ 'et/een diffe$ent data'ase systems( 9o$ e6am#le, in some systems a ta'le is called a catalo% and in ot!e$s a ta'le is called a sc!emaOt!e diffe$ent usa%es /e$e in #lace 'efo$e t!e 8PL92 standa$d #$ovided a common definition(
TIP
4nte$nally, t!e <8PLDJ su##o$ts sc!emas, 'ut not catalo%s( 8c!ema su##o$t is ne/, and /as added s!o$tly 'efo$e t!e $elease of of 77o ve$sion 2(0( T!e initial $elease of 77o ve$sion 2(0 does not fully su##o$t sc!emas /!en used /it! t!ei$ inte$nal data'ase due to time const$aintsD 'ette$ su##o$t /ill 'e added late$(

OpenOffice.org Base

6"

A few easy database definitions

1.1. -chema
+cco$din% to t!e dictiona$y, a sc!ema $efe$s to a st$uctu$e t!at $e#$esents some as#ect of t!e /o$ld( T!e 8PL92 definition effectively o$%ani5es o$%ani5es an enti$e data'ase !ie$a$c!y into sc!emas( + common usa%e fo$ a sc!ema is to sto$e ta'le definitions, $elations!i#s, and access $i%!ts in one sc!ema, and t!e %ene$al data ta'les in a diffe$ent sc!ema( E!ile /o$.in% /it! an unfamilia$ data'ase, 4 sometimes sea$c! t!e info$mation sc!ema to dete$mine e6istin% ta'le namesOassumin% t!at 4 !ave access to t!e info$mation sc!ema( Eit! $e%a$ds to data'ase systems, t!e /o$d sc!ema f$e3uently $efe$s to t!e data'ase st$uctu$e, and is f$e3uently $e#$esented as a ta'le o$ a %$a#!ic( +lt!ou%! you must dete$mine t!e meanin% 'ased on t!e conte6t, t!is is usually easy to do(

OpenOffice.org Base

6!

8. 3atabase connections
7.1. "btain a database conte/t
T!e fi$st ste# in accessin% a data'ase, is to o#en t!e data'ase conte6t ,see Listing "$-( T!e data'ase conte6t is used to mani#ulate $e%iste$ed data sou$ces and to o'tain a data sou$ce fo$ a data'ase t!at is not $e%iste$ed( Table 1' #$ovides a '$ief desc$i#tion of met!ods su##o$ted 'y t!e data'ase conte6t( Listing 29. Create a global database context.
oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")

TIP

Do not dis#ose a data'ase conte6tD t!e data'ase conte6t is a %lo'al se$vice and t!e$e is only one instance, /!ic! is al/ays $etu$ned( 4f you dis#ose a data'ase conte6t, t!e dis#osed unusa'le conte6t /ill 'e $etu$ned( )ou must $esta$t 7#en7ffice(o$% 'efo$e you can o'tain anot!e$ data'ase conte6t(

Table 1'. (ome methods supported by a 4atabaseConte7t.


Method
add"ontaine$Listene$,listene$c$eateLnume$ation,dis#ose,%etJyCame,name%etLlementCames,%etRe%iste$ed7'Hect,name!asJyCame,name!asLlements,$e%iste$7'Hect,name, dataMsou$ce$emove"ontaine$Listene$,listene$$evo.e7'Hect,name-

Description
Re%iste$in% a listene$ to 'e notified /!en ne/ data sou$ce is c$eated o$ $emoved( Retu$n an enume$ation of $e%iste$ed data sou$ces( Dis#ose t!is %lo'al o'Hect( Do not use t!is met!od; Ret$ieve a data sou$ce, $e%iste$ed o$ not, 'ased on t!e $e%iste$ed name o$ data'ase IRL( Retu$n an a$$ay of $e%iste$ed data sou$ce names( Retu$n t!e $e%iste$ed data sou$ce( Retu$n T$ue if t!e s#ecified name is a $e%iste$ed data sou$ce( Retu$n T$ue if t!e$e is at least one $e%iste$ed data sou$ce( Re%iste$ t!e su##lied data sou$ce( Remove a $e%iste$ed containe$ listene$( In$e%iste$ t!e named data sou$ce(

OpenOffice.org Base

6#

Database connections

8.1.1. ,egistered data sources


Ise t!e data'ase conte6t to o'tain a data sou$ce fo$ eit!e$ a $e%iste$ed o$ an un$e%iste$ed data sou$ce( 8ome met!ods $elate only to $e%iste$ed data sou$ces( 9o$ e6am#le, t!e met!od !asJyCame,name- $etu$ns T$ue if t!e data'ase conte6t contains a $e%iste$ed a data'ase /it! t!e s#ecified name, 'ut %etJyCame,u$l- $etu$ns a data sou$ce even if it is not $e%iste$ed( T!e mac$o in Listing '5 dis#lays t!e cu$$ently $e%iste$ed data sou$ces and t!en demonst$ates !o/ to enume$ate t!em(,egistere) So-rces Listing 30. List the currently registered database services.
Sub ListRegisteredDataSources() Dim oBaseContext 'Global database context. Dim oEnum 'Enumeration of registered data sources. Dim oDataSource 'Database source oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") If NOT oBaseContext.hasElements() Then Print "There are no registered data sources." Exit Sub End If REM Use hasByName(name) to verify that a data source is registered. REM use getElementNames() to obtain a list of registered data sources. REM Calling oBaseContext.getByName(name) returns a data source. MsgBox Join(oBaseContext.getElementNames(), CHR$(10)),0, _ "Registered Sources" REM Enumerate the currently registered data sources. oEnum = oBaseContext.createEnumeration() Do While oEnum.hasMoreElements() oDataSource = oEnum.nextElement() Loop End Sub

8.1. . $nregistering a data source


E!ile $e%iste$ed, an 77o Jase file is loc.ed, #$eventin% it f$om 'ein% deleted o$ ot!e$/ise mani#ulated( Deletin% a data sou$ce f$om t!e data sou$ce vie/ /ill un$e%iste$ t!e data sou$ceD use F. to o#en t!e data sou$ce vie/( + data sou$ce can also 'e un$e%iste$ed usin% a mac$o ,see Listing '1-( Listing 3 . !nregister a data sources.
oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oBaseContext.revokeObject("MemTest")

OpenOffice.org Base

6$

Database connections

8.1.'. ,egistering a data source


P$io$ to 7#en7ffice(o$% ve$sion 2(0, a data sou$ce needed to 'e $e%iste$ed 'efo$e it could 'e accessedD t!is is no lon%e$ t$ue( + data sou$ce can 'e o'tained 'ased on t!e documentKs IRL, 'ut t!is /ill not $e%iste$ t!e data sou$ce( Listing '" demonst$ates !o/ to o'tain and $e%iste$ a data sou$ce( + data sou$ce can 'e o'tained 'ased on t!e IRL, even if it is al$eady $e%iste$ed 'y anot!e$ nameOnotice t!e use of =et8ou$ce"odeDi$,- f$om Listing #&( Listing 32. "egister a data source.
oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") sName = GetSourceCodeDir() & "MemTest.odb" oDataSource = oBaseContext.getByName(sName) REM Register the object if you want, but this is not required for use. oBaseContext.registerObject("MemTest", oDataSource)

TIP

)ou can mani#ulate a data'ase /it!out a $e%iste$ed data sou$ce( T!e data sou$ce is t!e data'ase document( Listing '" demonst$ates !o/ to o'tain a data sou$ce 'ased on its IRL and !o/ to $e%iste$ t!e data sou$ce(

+ data sou$ce al/ays co$$es#onds to a data'ase documentD even /it! t!e FJi'lio%$a#!yG data sou$ce( T!e data sou$ce is availa'le f$om t!e Data'ase"onte6t usin% t!e IRL of t!e data'ase document( T!e data sou$ce contains a $efe$ence to t!e data'ase document usin% t!e Data'aseDocument #$o#e$ty, /!ic! can 'e o#ened t!e same /as as any ot!e$ 7#en7ffice(o$% document( Listing 3" demonst$ates !o/ to find a cu$$ently o#en document 'ased on t!e documentKs IRL( T!e #$ima$y diffe$ence 'et/een loadin% a document di$ectly, and o'tainin% t!e data sou$ce f$om t!e Data'ase"onte6t ,see Listing '"-, is t!e a'sence of a visi'le use$ inte$face /!en usin% a Data'ase"onte6t(

7.2. Connect to a database


+ data'ase connection $e#$esents a session /it! a s#ecific data'ase( To mani#ulate o$ modify t!e data contained in a data'ase, a data'ase connection is $e3ui$ed( T!e connection #$ovides t!e a'ility to e6ecute 8PL statements to modify and o'tain info$mation( Listing '' demonst$ates !o/ to o#en a connection to t!e Ji'lio%$a#!y data'ase, /!ic! is included /it! 77o( Listing 33. #pen a connection to the $ibliography database.
Dim Dim Dim Dim Dim oBaseContext oDataSource oCon sUser$ sPassword$ 'Global database context. 'Data source for the specified database. 'Connection to a database. 'User name while connecting. 'Password while connections.

REM Set the user name and password for connection. REM There is no user or password required so set to an empty string. sUser = "" sPassword = "" oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext")

OpenOffice.org Base

64

Database connections oDataSource = oBaseContext.getByName("Bibliography") oCon = oDataSource.getConnection(sUser, sPassword) oCon.close()

TIP

+lt!ou%! connections a$e automatically closed /!en t!e mac$o finis!es, it is conside$ed %ood #$actice to close a connection /!en you a$e finis!ed( 4f t!e mac$o e6its a'no$mally, t!e connection may not close(

7.3. Connect using an interaction handler


T!e code in Listin% demonst$ates !o/ to o#en a connection to a data'ase 'y su##lyin% 'ot! t!e use$ name and #ass/o$d( T!e Ji'lio%$a#!y data'ase does not $e3ui$e a use$ name and a #ass/o$d, so em#ty st$in%s a$e used( 7#en7ffice(o$% #$ovides a mec!anism to automatically #$om#t fo$ a #ass/o$d if it is $e3ui$ed ,see Listin% 4-( Listing 3%. !se an interaction handler to open the database.
Dim Dim Dim Dim oBaseContext oDataSource oHandler oCon 'Global database context. 'Data source for the specified database. 'Interaction handler in case a password is required. 'Connection to a database.

oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataSource = oBaseContext.getByName("Bibliography") oHandler = createUnoService("com.sun.star.sdb.InteractionHandler") oCon = oDataSource.ConnectWithCompletion(oHandler) oCon.close()

7.%. Connections
+ connection $e#$esents a session /it! a s#ecific data'ase( + connection is used to e6ecute 8PL statements and o'tain $esults( + data'ase connection is a'le to #$ovide meta data conce$nin% t!e connection( Table 1/. Methods supported by the com.sun.star.sdbc.Connection ser9ice.
Method
c$eate8tatement,#$e#a$e8tatement,s3l#$e#a$e"all,s3lnative8PL,s3l-

Description
Retu$n a ne/ statement o'Hect fo$ e6ecutin% 8PL( 8PL statements t!at a$e e6ecuted many times s!ould use a #$e#a$ed statement instead( Retu$n a #$e#a$ed statement o'Hect fo$ e6ecutin% #a$amete$i5ed 8PL statements( Ise KTK as t!e #a$amete$ #lace !olde$( Retu$n a calla'le statement o'Hect fo$ callin% data'ase sto$ed #$ocedu$es( Ise KTK as t!e #a$amete$ #lace !olde$( + d$ive$ may t$ansfo$m 8PL 'efo$e sendin% it to t!e data'ase, t!e native8PL,- met!od $etu$ns t!e t$ansfo$med 8PL /it!out sendin% it to t!e data'ase( Lna'le ,T$ue- o$ disa'le ,9alse- a connectionKs auto&commit mode( 4n auto& commit mode, all 8PL statements a$e e6ecuted and committed as individual t$ansactions( 7t!e$/ise, 8PL statements a$e %$ou#ed into t$ansactions t!at a$e te$minated 'y a call to eit!e$ commit,- o$ $oll'ac.,-( + commit occu$s /!en a statement com#letes o$ t!e ne6t e6ecute occu$s, /!ic!eve$ comes fi$st( 4f a $esult set is o'tained, t!e statement com#letes /!en t!e last $o/ f$om t!e

set+uto"ommit,'oolean-

OpenOffice.org Base

65

Database connections

Method
%et+uto"ommit,close,commit,-

Description
$esult set is $et$ieved o$ t!e $esult set is closed( Retu$n t!e cu$$ent auto&commit state( Jy default, ne/ connections a$e in auto&commit mode( "lose t!e connection( T!e connection is automatically closed /!en it is no lon%e$ $efe$enced( "ause all c!an%es made since t!e last commit o$ $oll'ac. to 'ecome #e$manent, $eleasin% data'ase loc.s !eld 'y t!e connectionOuse only /!en auto&commit mode is disa'led( Disca$d all c!an%es made since t!e last commit o$ $oll'ac., $eleasin% data'ase loc.s !eld 'y t!e connectionOuse only /!en auto&commit mode is disa'led( Retu$n T$ue if t!e connection is closed( Retu$n t!e meta&data fo$ t!e connectionKs data'ase( Lna'le ,T$ue-, o$ disa'le, $ead&only mode as a !int to ena'le data'ase o#timi5ations( Retu$n T$ue if t!e connection is in $ead&only mode( 8et a catalo% name to select a su's#ace of t!is connectionKs data'ase in /!ic! to /o$.( 4f t!e d$ive$ does not su##o$t catalo%s, t!e $e3uest is i%no$ed( Retu$n t!e name of t!e connectionKs cu$$ent catalo%( "!an%e t!e t$ansaction isolation level( Retu$n t!e connectionKs cu$$ent t$ansaction isolation level( Retu$n t!e ty#e ma#, if any, associated /it! t!is connection( 4nstall t!e %iven ty#e ma# as t!e ty#e ma# fo$ t!is connection( T!e ty#e ma# is used fo$ t!e custom ma##in% of 8PL st$uctu$ed ty#es and distinct ty#es( Cot all d$ive$s su##o$t ty#e ma#s( Retu$n t!e fi$st /a$nin% o$ e$$o$( T!e /a$nin% o'Hect contains a lin. to t!e follo/in% /a$nin%s( "lea$s all /a$nin%s(

$oll'ac.,is"losed,%etMetaData,setRead7nly,'ooleanisRead7nly,set"atalo%,catalo%Mname%et"atalo%,setT$ansaction4solation,lon%%etT$ansaction4solation,%etTy#eMa#,setTy#eMa#,ma#-

%etEa$nin%s,clea$Ea$nin%s,-

T$ansactions #$event data f$om 'ein% $ead in an inconsistent state( 9o$ e6am#le, $eadin% a $o/ c!an%ed 'y one t$ansaction t!at is late$ $olled 'ac.( Table 1# lists t!e t!$ee #$ima$y ty#es of F'adG $eads t!at a$e #$eventa'le usin% t$ansactions( Table 1#. 2ead types that produce inconsistent data.
%ead
Di$ty Con&$e#eata'le P!antom

Description
Readin% a $o/ /it! uncommitted c!an%es( Readin% a $o/ 'efo$e and afte$ a second t$ansaction modifies t!e $o/( + #!antom $ead $e3ui$es t!e follo/in% se3uence of events: + t$ansaction usin% a E<LRL clause $eads $o/s 'efo$e and afte$, a second t$ansaction inse$ts a $o/ t!at matc!es t!e E<LRL clause( T!e e6t$a $o/s $ead afte$ t!e inse$tion a$e called #!antom $o/s(

OpenOffice.org Base

66

Database connections

T!e t$ansaction isolation level is set 'ased on t!e T$ansaction4solation constantsD not all d$ive$s su##o$t all t$ansaction isolation level( Table 13. Constants in the com.sun.star.sdbc.Transaction1solation constant group.
Name
C7CL RL+DMIC"7MM4TTLD RL+DM"7MM4TTLD RLPL+T+JLLMRL+D 8LR4+L4Y+JLL

#
0 > 2 4 8

Description
T$ansactions a$e not su##o$ted( Ro/s t!at a$e not yet committed can 'e $eadD allo/s di$ty, non& $e#eata'le, and #!antom $eads( P$event di$ty $eads 'ut allo/s non&$e#eata'le and #!antom $eads( P$events di$ty and non&$e#eata'le $eads, 'ut allo/s #!antom $eads( P$events di$ty, non&$e#eata'le and #!antom $eads(

8.+.1. 01tended !3B connections


Lve$y connection su##o$ts t!e com(sun(sta$(sd'c("onnection se$vice( 8ome connections su##o$t t!e com(sun(sta$(sd'("onnection se$vice, /!ic! #$ovides access to t!e data definitions of a connected data'ase( T!e e6tended connection can 'e used to cont$ol t!e access $i%!ts on data'ase o'Hects( +ccess to t!e ta'les, usin% %etTa'les,- is al/ays su##o$ted and o#tionally, t!e met!ods %etSie/s,-, %etIse$s,-, and %et=$ou#s,- may also 'e #$esent( T!e 8DJ connection im#lements t!e #$e#a$e"ommand,s3lZ, "ommandTy#e- met!od ,see Ta'le >9-, /!ic! $etu$ns a P$e#a$ed8tatement o'Hect fo$ sendin% #a$amete$i5ed 8PL statements to t!e data'ase( + 8PL statement /it! o$ /it!out 4C #a$amete$s can 'e #$e&com#iled and sto$ed in a P$e#a$ed8tatement o'Hect( T!is o'Hect can t!en 'e used to efficiently e6ecute t!e statement multi#le times( Table 1&. ,alues for the com.sun.star.sdb.CommandType constant group.
&al"e
0 > 2

Name
T+JLL PILR) "7MM+CD

Description
T!e command contains a ta'le name, /!ic! can 'e used to #$ocess a command li.e Q8LLL"T [ 9R7M ta'lenameQ( T!e command contains a name of a 3ue$y com#onent, /!ic! contains a ce$tain statement( T!e command is an 8PL statement(

8.+. . Meta2data
Ise a connectionKs %etMetaData,- met!od to o'tain com#$e!ensive info$mation a'out t!e data'ase as a /!ole( 8ome meta&data o'Hect met!ods $etu$n sim#le data ty#es, and ot!e$s $etu$n a $esult set /it! multi#le $o/s( Diffe$ent $esult set ty#es e6ist( 8ome met!ods su##o$ted 'y t!e meta&data o'Hect acce#t a $esult set ty#e as an a$%umentD inse$ts+$eDetected,- fo$ e6am#le( Table 1%. ,alues for the com.sun.star.sdbc.2esult(etType constant group.
&al"e
>00

Name
97RE+RDM7CL)

Description
T!e $o/ set cu$so$ can move only fo$/a$d(

OpenOffice.org Base

67

Database connections

&al"e
>004 >005

Name
8"R7LLM4C8LC84T4SL 8"R7LLM8LC84T4SL

Description
T!e $o/ set cu$so$ is sc$olla'le 'ut %ene$ally not sensitive to c!an%es made 'y ot!e$s( T!e $o/ set cu$so$ is sc$olla'le and %ene$ally sensitive to c!an%es made 'y ot!e$s(

Table 1$. ,alues for the com.sun.star.sdbc.2esult(etConcurrency constant group.


&al"e
>00B >008

Name
RL+DM7CL) IPD+T+JLL

Description
"oncu$$ency mode fo$ a $esult set t!at may not 'e u#dated( "oncu$$ency mode fo$ a $esult set t!at may 'e u#dated(

Routines t!at acce#t st$in% #atte$ns, suc! as a ta'le name, su##o$t sim#le $e%ula$ e6#$essions( T!e st$in%, F\G means matc! any su'st$in% of 0 o$ mo$e c!a$acte$s, and FMG means matc! any one c!a$acte$(
Caution
T!e +P4 documentation indicates t!at a CILL $efe$ence fo$ a sea$c! #atte$n causes t!at a$%umentKs c$ite$ia to 'e d$o##ed f$om t!e sea$c!( Info$tunately, it is not valid to #ass a CILL $efe$ence usin% IC7( 8ome #latfo$ms %ene$ate a $un time e$$o$ and some #latfo$ms silently allo/ it( Do not allo/ assume t!at a CILL value is valid(

Table "5. Methods supported by the com.sun.star.sdbc.A4atabaseMeta4ata interface.


Method
allP$ocedu$es+$e"alla'le,allTa'les+$e8electa'le,dataDefinition"ausesT$ansaction"ommit,dataDefinition4%no$ed4nT$ansactions,deletes+$eDetected,Result8etTy#edoesMa6Ro/8i5e4ncludeJlo's,%etJestRo/4dentifie$,catalo%, sc!ema, ta'le, sco#e, nulla'le%et"atalo%s,%et"atalo%8e#a$ato$,%et"atalo%Te$m,%et"olumnP$ivile%es,catalo%, sc!ema, ta'le, column-

Description
T$ue, if t!e cu$$ent use$ can call eve$y #$ocedu$e $etu$ned 'y t!e %etP$ocedu$es,- met!od( T$ue, if t!e cu$$ent use$ can 8LLL"T eve$y ta'le $etu$ned 'y t!e %etTa'les,- met!od( T$ue, if a data definition statement /it!in a t$ansaction can fo$ce t!e t$ansaction to commit( T$ue, if a data definition statement /it!in a t$ansaction is i%no$ed( T$ue, if t!e $o/Deleted,- met!od of t!e $esult set can detect a $o/ deletion( T$ue if %etMa6Ro/8i5e,- includes L7C=S+R"<+R and L7C=S+RJ4C+R) 'lo's( Result set desc$i'in% a ta'leKs o#timal set of columns t!at uni3uely identify a $o/( Result set of t!e availa'le catalo% names( T!e se#a$ato$ 'et/een a catalo% and ta'le name( T!e data'ase vendo$Ks #$efe$$ed te$m fo$ Fcatalo%G( Result set /it! a desc$i#tion of t!e access $i%!ts fo$ a ta'leKs columns(

OpenOffice.org Base

68

Database connections

Method
%et"olumns,catalo%,sc!ema, ta'le, column%et"onnection,%et"$ossRefe$ence,#$ima$y"atalo%, #$ima$y8c!ema, #$ima$yTa'le, fo$ei%n"atalo%, fo$ei%n8c!ema, fo$ei%nTa'le%etData'aseP$oductCame,%etData'aseP$oductSe$sion,%etDefaultT$ansaction4solation,%etD$ive$MaHo$Se$sion,%etD$ive$Mino$Se$sion,%etD$ive$Came,%etD$ive$Se$sion,%etL6#o$tedWeys,catalo%, sc!ema, ta'le-

Description
Result set /it! a desc$i#tion of t!e ta'le columns( 4 used t!is to find ta'le names as /ell( "onnection t!at #$oduced t!is meta&data o'Hect( Result set /it! a desc$i#tion of t!e fo$ei%n .ey columns in t!e fo$ei%n .ey ta'le t!at $efe$ence t!e #$ima$y .ey columns of t!e #$ima$y .ey ta'leOdesc$i'e !o/ one ta'le im#o$ts anot!e$Ks .ey( Came of t!e data'ase #$oduct( Se$sion of t!e data'ase #$oduct( Default data'ase t$ansaction isolation level( MaHo$ ve$sion num'e$ of t!e 8DJ" d$ive$( Mino$ ve$sion num'e$ of t!e 8DJ" d$ive$( Came of t!e 8DJ" d$ive$( Se$sion num'e$ of t!e 8DJ" d$ive$( + $o/ set t!at desc$i'es t!e fo$ei%n .ey columns t!at $efe$ence a ta'leKs #$ima$y .ey columnsOt!e fo$ei%n .eys e6#o$ted 'y a ta'le( +ll t!e Qe6t$aQ c!a$acte$s t!at can 'e used in un3uoted identifie$ names ,t!ose 'eyond a&5, +&Y, 0&9 and M-( T!e st$in% used to 3uote 8PL identifie$s( + s#ace Q Q is $etu$ned if identifie$ 3uotin% is not su##o$ted( + $o/ set t!at desc$i'es t!e #$ima$y .ey columns t!at a$e $efe$enced 'y a ta'leKs fo$ei%n .ey columnsOt!e #$ima$y .eys im#o$ted 'y a ta'le( + $o/ set t!at desc$i'es a ta'leKs inde6es and statistics( Ma6imum num'e$ of !e6 c!a$acte$s in a 'ina$y lite$al( Ma6imum len%t! of a catalo% name( Ma6imum len%t! fo$ a c!a$acte$ lite$al( Ma6imum len%t! of a column name( Ma6imum num'e$ of columns in a Q=R7IP J)Q clause( Ma6imum num'e$ of columns allo/ed in an inde6( Ma6imum num'e$ of columns in an Q7RDLR J)Q clause( Ma6imum num'e$ of columns in a Q8LLL"TQ list( Ma6imum num'e$ of columns in a ta'le( Ma6imum num'e$ of concu$$ent active connections( Ma6imum len%t! of a cu$so$ name( Ma6imum inde6 len%t! ,in 'ytes-( Ma6imum len%t! of a #$ocedu$e name( Ma6imum len%t! of a sin%le $o/(
69

%etL6t$aCame"!a$acte$s,%et4dentifie$Puote8t$in%,%et4m#o$tedWeys,catalo%, sc!ema, ta'le-

%et4nde64nfo,catalo%, sc!ema, ta'le, uni3ue, a##$o6imate%etMa6Jina$yLite$alLen%t!,%etMa6"atalo%CameLen%t!,%etMa6"!a$Lite$alLen%t!,%etMa6"olumnCameLen%t!,%etMa6"olumns4n=$ou#Jy,%etMa6"olumns4n4nde6,%etMa6"olumns4n7$de$Jy,%etMa6"olumns4n8elect,%etMa6"olumns4nTa'le,%etMa6"onnections,%etMa6"u$so$CameLen%t!,%etMa64nde6Len%t!,%etMa6P$ocedu$eCameLen%t!,%etMa6Ro/8i5e,OpenOffice.org Base

Database connections

Method
%etMa68c!emaCameLen%t!,%etMa68tatementLen%t!,%etMa68tatements,%etMa6Ta'leCameLen%t!,%etMa6Ta'les4n8elect,%etMa6Ise$CameLen%t!,%etCume$ic9unctions,%etP$ima$yWeys,catalo%, sc!ema, ta'le%etP$ocedu$e"olumns,catalo%, sc!ema, #$ocedu$e, column%etP$ocedu$es,catalo%, sc!ema, #$ocedu$e%etP$ocedu$eTe$m,%et8c!emas,%et8c!emaTe$m,%et8ea$c!8t$in%Lsca#e,%et8PLWey/o$ds,%et8t$in%9unctions,%et8ystem9unctions,%etTa'leP$ivile%es,catalo%, sc!ema, ta'le%etTa'les,catalo%, sc!ema, ta'le, ty#es,-%etTa'leTy#es,catalo%, sc!ema, ta'le, column%etTimeDate9unctions,%etTy#e4nfo,%etIDTs,catalo%, sc!ema, ty#eMname, ty#es,--

Description
Ma6imum len%t! allo/ed fo$ a sc!ema name( Ma6imum len%t! of an 8PL statement( Ma6imal num'e$ of o#en concu$$ent active statements( Ma6imum len%t! of a ta'le name( Ma6imum num'e$ of ta'les in a 8LLL"T statement( Ma6imum len%t! of a use$ name( "omma&se#a$ated list of mat! functions( + $o/ set t!at desc$i'es a ta'leKs #$ima$y .ey columns( + $o/ set t!at desc$i'es t!e sto$ed #$ocedu$eKs #a$amete$s and $esult columns( + $o/ set t!at desc$i'es t!e sto$ed #$ocedu$es in a catalo%( T!e data'ase vendo$Ks #$efe$$ed te$m fo$ F#$ocedu$eG( + $o/ set t!at desc$i'es t!e availa'le sc!ema names( T!e data'ase vendo$Ks #$efe$$ed te$m fo$ Qsc!emaQ( T!e st$in% used to esca#e /ild&ca$d c!a$acte$s KMK o$ K\K( "omma&se#a$ated list of 8PL .ey/o$ds not in 8PL92( "omma&se#a$ated list of st$in% functions( "omma&se#a$ated list of system functions( + $o/ set t!at desc$i'es t!e access $i%!ts fo$ eac! ta'le( + $o/ set t!at desc$i'es t!e availa'le ta'les( + $o/ set /it! one column /it! t!e availa'le ta'le ty#es( "omma&se#a$ated list of time and date functions( + $o/ set t!at desc$i'es t!e su##o$ted standa$d 8PL ty#es( + $o/ set t!at desc$i'es t!e use$&defined ty#es( 8u##o$ted ty#es include 7JJL"T, 8TRI"T, and D48T4C"T( Di$ecto$y and filename of t!e data'ase( Ise$ name fo$ t!e connection( + $o/ set t!at desc$i'es a ta'leKs columns t!at a$e automatically u#dated /!en any value in a $o/ is u#dated( T$ue, if t!e $o/4nse$ted,- met!od of t!e $esult set can detect a $o/ inse$tion( T$ue, if a catalo% a##ea$s at t!e sta$t of a 3ualified ta'le nameD ot!e$/ise it a##ea$s at t!e end( T$ue, if t!e data'ase is in $ead&only mode( T$ue, if concatenations 'et/een CILL and non&CILL values a$e CILL(
7"

%etIRL,%etIse$Came,%etSe$sion"olumns,catalo%, sc!ema, ta'le-

inse$ts+$eDetected,Result8etTy#eis"atalo%+t8ta$t,isRead7nly,nullPlusConCull4sCull,-

OpenOffice.org Base

Database connections

Method
nulls+$e8o$ted+tLnd,nulls+$e8o$ted+t8ta$t,nulls+$e8o$ted<i%!,nulls+$e8o$tedLo/,ot!e$sDeletes+$eSisi'le,Result8etTy#eot!e$s4nse$ts+$eSisi'le,Result8etTy#eot!e$sI#dates+$eSisi'le,Result8etTy#eo/nDeletes+$eSisi'le,Result8etTy#eo/n4nse$ts+$eSisi'le,Result8etTy#eo/nI#dates+$eSisi'le,Result8etTy#esto$esLo/e$"ase4dentifie$s,-

Description
T$ue, if CILL values a$e so$ted at t!e end( T$ue, if CILL values a$e so$ted at t!e sta$t( T$ue, if CILL values a$e so$ted !i%!( T$ue, if CILL values a$e so$ted lo/( T$ue, if deletes made 'y ot!e$s a$e visi'le( T$ue, if inse$ts made 'y ot!e$s a$e visi'le( T$ue, if u#dates made 'y ot!e$s a$e visi'le( T$ue, if a $esult setKs o/n deletes a$e visi'le( T$ue, if a $esult setKs o/n inse$ts a$e visi'le( T$ue, if a $esult setKs o/n u#dates a$e visi'le( T$ue, if t!e data'ase t$eats mi6ed case un3uoted 8PL identifie$s as case insensitive and sto$es t!em in lo/e$ case( T$ue, if t!e data'ase t$eats mi6ed case 3uoted 8PL identifie$s as case insensitive and sto$es t!em in lo/e$ case( T$ue, if t!e data'ase t$eats mi6ed case un3uoted 8PL identifie$s as case insensitive and sto$es t!em in mi6ed case( T$ue, if t!e data'ase t$eats mi6ed case 3uoted 8PL identifie$s as case insensitive and sto$es t!em in mi6ed case( T$ue, if t!e data'ase t$eats mi6ed case un3uoted 8PL identifie$s as case insensitive and sto$es t!em in u##e$ case( T$ue, if t!e data'ase t$eats mi6ed case 3uoted 8PL identifie$s as case insensitive and sto$es t!em in u##e$ case( T$ue, if t!e Data'ase su##o$ts Q+LTLR T+JLLQ /it! add column( T$ue, if t!e Data'ase su##o$ts Q+LTLR T+JLLQ /it! d$o# column( T$ue, if t!e data'ase su##o$ts +C8492 ent$y level 8PL %$amma$( T$ue, if t!e data'ase su##o$ts +C8492 full 8PL %$amma$( T$ue, if t!e data'ase su##o$ts +C8492 inte$mediate 8PL %$amma$( T$ue, if t!e d$ive$ su##o$ts 'atc! u#dates( T$ue, if a catalo% name can 'e used in a data mani#ulation statement( T$ue, if a catalo% name can 'e used in an inde6 definition statement( T$ue, if a catalo% name can 'e used in a #$ivile%e
7!

sto$esLo/e$"asePuoted4dentifie$s,-

sto$esMi6ed"ase4dentifie$s,-

sto$esMi6ed"asePuoted4dentifie$s,-

sto$esI##e$"ase4dentifie$s,-

sto$esI##e$"asePuoted4dentifie$s,-

su##o$ts+lte$Ta'leEit!+dd"olumn,su##o$ts+lte$Ta'leEit!D$o#"olumn,su##o$ts+C8492Lnt$yLevel8PL,su##o$ts+C84929ull8PL,su##o$ts+C84924nte$mediate8PL,su##o$tsJatc!I#dates,su##o$ts"atalo%s4nDataMani#ulation,su##o$ts"atalo%s4n4nde6Definitions,su##o$ts"atalo%s4nP$ivile%eDefinitions,OpenOffice.org Base

Database connections

Method
su##o$ts"atalo%s4nP$ocedu$e"alls,su##o$ts"atalo%s4nTa'leDefinitions,su##o$ts"olumn+liasin%,su##o$ts"onve$t,f$omTy#e, toTy#esu##o$ts"o$e8PL=$amma$,su##o$ts"o$$elated8u'3ue$ies,su##o$tsDataDefinition+ndDataMani#ulationT$ansa ctions,su##o$tsDataMani#ulationT$ansactions7nly,su##o$tsDiffe$entTa'le"o$$elationCames,su##o$tsL6#$essions4n7$de$Jy,su##o$tsL6tended8PL=$amma$,su##o$ts9ull7ute$Joins,su##o$ts=$ou#Jy,su##o$ts=$ou#JyJeyond8elect,-

Description
definition statement( T$ue, if a catalo% name 'e used in a #$ocedu$e call statement( T$ue, if a catalo% name 'e used in a ta'le definition statement( T$ue, if t!e Data'ase su##o$ts column aliasin%( T$ue, if t!e Data'ase can conve$t 'et/een t!e t/o 8PL ty#es( T!e ty#es a$e $e#$esented as an inte%e$( T$ue, if t!e data'ase su##o$ts 7DJ" "o$e 8PL %$amma$( T$ue, if co$$elated su'&3ue$ies a$e su##o$ted( T$ue, if t!e Data'ase su##o$ts 'ot! data definition and data mani#ulation statements /it!in t!e same t$ansaction( T$ue, if only data mani#ulation statements /it!in a t$ansaction a$e su##o$ted( T$ue, if ta'le co$$elation names a$e $est$icted to names diffe$ent f$om t!e actual ta'le names( T$ue, if e6#$essions in Q7RDLR J)Q lists a$e su##o$ted( T$ue, if t!e 7DJ" L6tended 8PL %$amma$ is su##o$ted( T$ue, if full oute$ Hoins a$e su##o$ted( T$ue, if some fo$m of t!e Q=R7IP J)Q clause is su##o$ted( T$ue, if a Q=R7IP J)Q clause can add columns not in t!e 8LLL"TOassumin% it s#ecifies all columns in t!e 8LLL"T( T$ue, if a Q=R7IP J)Q clause can use columns not in t!e 8LLL"T( T$ue, if t!e 8PL 4nte%$ity Ln!ancement 9acility is su##o$ted( T$ue, if t!e esca#e c!a$acte$ is su##o$ted in QL4WLQ clauses( T$ue, if limited oute$ Hoins a$e su##o$ted( T$ue, if t!e 7DJ" Minimum 8PL %$amma$ is su##o$ted( T$ue, if un3uoted 8PL identifie$s a$e case sensitive( T$ue, if 3uoted 8PL identifie$s a$e case sensitive( T$ue, if multi#le $esult sets f$om a sin%le e6ecute a$e su##o$ted( T$ue, if multi#le t$ansactions on diffe$ent connections can 'e o#en at once( T$ue, if columns 'e defined as not nulla'le( T$ue, if cu$so$s can $emain o#en ac$oss commits(

su##o$ts=$ou#JyIn$elated,su##o$ts4nte%$ityLn!ancement9acility,su##o$tsLi.eLsca#e"lause,su##o$tsLimited7ute$Joins,su##o$tsMinimum8PL=$amma$,su##o$tsMi6ed"ase4dentifie$s,su##o$tsMi6ed"asePuoted4dentifie$s,su##o$tsMulti#leResult8ets,su##o$tsMulti#leT$ansactions,su##o$tsConCulla'le"olumns,su##o$ts7#en"u$so$s+c$oss"ommit,-

OpenOffice.org Base

7#

Database connections

Method
su##o$ts7#en"u$so$s+c$ossRoll'ac.,su##o$ts7#en8tatements+c$oss"ommit,su##o$ts7#en8tatements+c$ossRoll'ac.,su##o$ts7$de$JyIn$elated,su##o$ts7ute$Joins,su##o$tsPositionedDelete,su##o$tsPositionedI#date,su##o$tsResult8et"oncu$$ency,Result8etTy#e, concu$$encysu##o$tsResult8etTy#e,Result8etTy#esu##o$ts8c!emas4nDataMani#ulation,su##o$ts8c!emas4n4nde6Definitions,su##o$ts8c!emas4nP$ivile%eDefinitions,su##o$ts8c!emas4nP$ocedu$e"alls,su##o$ts8c!emas4nTa'leDefinitions,su##o$ts8elect9o$I#date,su##o$ts8to$edP$ocedu$es,su##o$ts8u'3ue$ies4n"om#a$isons,su##o$ts8u'3ue$ies4nL6ists,su##o$ts8u'3ue$ies4n4ns,su##o$ts8u'3ue$ies4nPuantifieds,su##o$tsTa'le"o$$elationCames,su##o$tsT$ansaction4solationLevel,levelsu##o$tsT$ansactions,su##o$tsTy#e"onve$sion,su##o$tsInion,su##o$tsInion+ll,u#dates+$eDetected,Result8etTy#eusesLocal9ilePe$Ta'le,usesLocal9iles,-

Description
T$ue, if cu$so$s can $emain o#en ac$oss $oll'ac.s( T$ue, if statements can $emain o#en ac$oss commits( T$ue, if statements can $emain o#en ac$oss $oll'ac.s( T$ue, if an Q7RDLR J)Q clause use columns not in t!e 8LLL"T statement( T$ue, if oute$ Hoins a$e su##o$ted( T$ue, if #ositioned DLLLTL is su##o$ted( T$ue, if #ositioned IPD+TL is su##o$ted( Does t!e data'ase su##o$t t!e concu$$ency ty#e in com'ination /it! t!e %iven $esult set ty#e( T$ue, if t!e %iven $esult set ty#e is su##o$ted( T$ue, if a sc!ema name can 'e used in a data mani#ulation statement( T$ue, if a sc!ema name can 'e used in an inde6 definition statement( T$ue, if a sc!ema name can 'e used in a #$ivile%e definition statement( T$ue, if a sc!ema name can 'e used in a #$ocedu$e call statement( T$ue, if a sc!ema name 'e used in a ta'le definition statement( T$ue, if 8LLL"T fo$ IPD+TL is su##o$ted( T$ue, if sto$ed #$ocedu$e calls usin% t!e sto$ed #$ocedu$e esca#e synta6 a$e su##o$ted( T$ue, if su'&3ue$ies in com#a$ison e6#$essions a$e su##o$ted( T$ue, if su'&3ue$ies in Ke6istsK e6#$essions a$e su##o$ted( T$ue, if su'&3ue$ies in KinK statements a$e su##o$ted( T$ue, if su'&3ue$ies in 3uantified e6#$essions a$e su##o$ted( T$ue, if ta'le co$$elation names a$e su##o$ted( T$ue, if t!e %iven t$ansaction isolation level is su##o$ted( T$ue, if t$ansactions a$e su##o$ted( T$ue, if t!e "7CSLRT function 'et/een 8PL ty#es is su##o$ted( T$ue, if t!e 8PL IC47C statement is su##o$ted( T$ue, if t!e 8PL IC47C +LL statement is su##o$ted( T$ue, if a $o/ u#date can 'e detected 'y callin% t!e met!od $o/I#dated,- on t!e $esult set o'Hect( T$ue, if one local file is used fo$ eac! ta'le( T$ue, if t!e local files a$e used to save t!e ta'les(

OpenOffice.org Base

7$

Database connections

8.+.'. Inspecting t%e meta2data


To demonst$ate !o/ to access t!e meta data, 4 /$ote a mac$o t!at $et$ieves t!e meta&data 'y callin% t!e met!ods in Listing '#, and t!en sto$es t!e data in a "alc document( 9i$st, a ne/ "alc document is c$eated to contain t!e $esultin% data( Listing 3&. Inspect the meta data from a connection.
Function InspectMetaData(ByVal oMeta) Dim s$ 'Utility string variable. Dim oResult 'Result from an SQL statement. Dim i As Long 'General index variable. Dim j As Long 'General index variable. Dim k As Long 'General index variable. Dim oDoc 'Calc document that will contain the presentation data. Dim sNewUrl$ 'URL for a new calc document. Dim oTables() 'Contains the primary data tables. Dim oData1() 'Generic data variable. Dim oData2() 'Generic data variable. Dim oData3() 'Generic data variable. Dim oData4() 'Generic data variable. Dim oNull As Object If IsNull(oMeta) OR IsEmpty(oMeta) Then Print "The meta-data is null or empty" Exit Function End If REM Open a new calc document to hold the data! sNewUrl = "private:factory/scalc" oDoc = StarDesktop.loadComponentFromURL(sNewUrl,"_blank", 0, Array()) REM Start by obtaining the list of regular tables. oResult = oMeta.getTables(oNull, "%", "%", Array("TABLE")) Redim oTables() Do While oResult.next() AppendToArray(oTables(), oResult.getString(3)) Loop RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("allProceduresAreCallable", _ "allTablesAreSelectable", _ "dataDefinitionCausesTransactionCommit", _ "dataDefinitionIgnoredInTransactions", _ "doesMaxRowSizeIncludeBlobs")) REM The arguments are (catalog, schema, table, scope, nullable) REM The scope can be any value from the com.sun.star.sdbc.BestRowScope REM constants including TEMPORARY (0), TRANSACTION (1), REM and SESSION (2). For i = LBound(oTables()) To UBound(oTables()) oResult = oMeta.getBestRowIdentifier(oNull, "%", oTables(i), _ com.sun.star.sdbc.BestRowScope.SESSION, True) AddResultSetToDoc(oResult, oDoc, _ OpenOffice.org Base 74

Database connections "getBestRowIdentifier(" & oTables(i) & ")") Next REM There is a single column CATALOG returned. oResult = oMeta.getCatalogs() AddResultSetToDoc(oResult, oDoc, "getCatalogs") RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getCatalogSeparator", "getCatalogTerm")) REM getColumnPrivileges(catalog,schema, table, columnPattern) oResult = oMeta.getColumnPrivileges(oNull, "%", "%", "%") AddResultSetToDoc(oResult, oDoc, "getColumnPrivileges") REM The NULL reference can not be replaced with REM "%" as with getColumnPrivileges(). oResult = oMeta.getColumns(oNull, "%", "%", "%") ResultSetToData(oResult, oDoc, "getColumns", oData1()) SafeArrayColumns(11, oData1(), _ Array("NO_NULLS", "NULLABLE", "NULLABLE_UNKNOWN"), True) AppendDataToCalcDoc(oDoc, oData1()) RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getDatabaseProductName", "getDatabaseProductVersion")) oData2() = Array("getDefaultTransactionIsolation", "unknown") Select Case oMeta.getDefaultTransactionIsolation() Case com.sun.star.sdbc.TransactionIsolation.NONE oData2(1) = "0 = None" Case com.sun.star.sdbc.TransactionIsolation.READ_UNCOMMITTED oData2(1) = "1 = Read Uncommitted" Case com.sun.star.sdbc.TransactionIsolation.READ_COMMITTED oData2(1) = "2 = Read Committed" Case com.sun.star.sdbc.TransactionIsolation.REPEATABLE_READ oData2(1) = "4 = Repeatable Read" Case com.sun.star.sdbc.TransactionIsolation.SERIALIZABLE oData2(1) = "8 = Serializable" Case Else oData2(1) = "invalid" End Select AppendDataToCalcDoc(oDoc, Array(oData2())) RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getDriverMajorVersion", "getDriverMinorVersion", _ "getDriverName", "getDriverVersion")) ReDim oData3(5 To 7) oData3(5) = "INITIALLY_DEFERRED" oData3(6) = "INITIALLY_IMMEDIATE" oData3(7) = "NONE" For i = LBound(oTables()) To UBound(oTables())

OpenOffice.org Base

75

Database connections oResult = oMeta.getExportedKeys(oNull, "%", oTables(i)) ResultSetToData(oResult, oDoc, _ "getExportedKeys(" & oTables(i) & ")", _ oData1()) SafeArrayColumns(10, oData1(), Array("CASCADE", "RESTRICT", _ "SET_NULL", "NO_ACTION", _ "SET_DEFAULT"), True) SafeArrayColumns(11, oData1(), Array("CASCADE", "RESTRICT", _ "SET_NULL", "NO_ACTION", _ "SET_DEFAULT"), True) SafeArrayColumns(14, oData1(), oData3(), True) AppendDataToCalcDoc(oDoc, oData1()) Next For i = LBound(oTables()) To UBound(oTables()) oResult = oMeta.getIndexInfo(oNull, "%", oTables(i), False, True) ResultSetToData(oResult, oDoc, "getIndexInfo(" & oTables(i) & ")", _ oData1()) SafeArrayColumns(7, oData1(), _ Array("STATISTIC", "CLUSTERED", "HASHED", "OTHER"), True) AppendDataToCalcDoc(oDoc, oData1()) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getMaxBinaryLiteralLength", "getMaxCatalogNameLength", _ "getMaxCharLiteralLength", "getMaxColumnNameLength", _ "getMaxColumnsInGroupBy", "getMaxColumnsInIndex", _ "getMaxColumnsInOrderBy", "getMaxColumnsInSelect", _ "getMaxColumnsInTable", "getMaxConnections", _ "getMaxCursorNameLength", _ "getMaxIndexLength", "getMaxProcedureNameLength", "getMaxRowSize", _ "getMaxSchemaNameLength", "getMaxStatementLength", _ "getMaxStatements", _ "getMaxTableNameLength", "getMaxTablesInSelect", _ "getMaxUserNameLength")) AppendDataToCalcDoc(oDoc, _ Array(Split("getNumericFunctions," & _ oMeta.getNumericFunctions(), ","))) For i = LBound(oTables()) To UBound(oTables()) oResult = oMeta.getPrimaryKeys(oNull, "%", oTables(i)) AddResultSetToDoc(oResult, oDoc, "getPrimaryKeys(" & _ oTables(i) & ")") Next RunMultipleCallsAppendToDoc(oDoc, oMeta, Array("getProcedureTerm")) oResult = oMeta.getSchemas() AddResultSetToDoc(oResult, oDoc, "getSchemas")

OpenOffice.org Base

76

Database connections RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getSchemaTerm", "getSearchStringEscape")) AppendDataToCalcDoc(oDoc, _ Array(Split("getSQLKeywords," & oMeta.getSQLKeywords(), ","))) AppendDataToCalcDoc(oDoc, _ Array(Split("getStringFunctions," & oMeta.getStringFunctions(), _ ","))) AppendDataToCalcDoc(oDoc, _ Array(Split("getSystemFunctions," & _ oMeta.getSystemFunctions(), ","))) REM Obtain the following columns: REM TABLE_CAT, TABLE_SCHEM, TABLE_NAME, GRANTOR, GRANTEE, PRIVILEGE oResult = oMeta.getTablePrivileges(oNull, "%", "%") AddResultSetToDoc(oResult, oDoc, "getTablePrivileges") oResult = oMeta.getTables(oNull, "%", "%", Array()) AddResultSetToDoc(oResult, oDoc, "getTables") REM One column with the supported table types oResult = oMeta.getTableTypes(oNull, "%", "%") AddResultSetToDoc(oResult, oDoc, "getTableTypes") AppendDataToCalcDoc(oDoc, _ Array(Split("getTimeDateFunctions," & _ oMeta.getTimeDateFunctions(), ","))) oResult = oMeta.getTypeInfo() ResultSetToData(oResult, oDoc, "getTypeInfo", oData1()) SafeArrayColumns(7, oData1(), _ Array("NO_NULLS", "NULLABLE", "NULLABLE_UNKNOWN"), True) SafeArrayColumns(9, oData1(), _ Array("NONE", "CHAR", "BASIC", "FULL"), True) AppendDataToCalcDoc(oDoc, oData1()) REM The outlook driver generates an exception with a call to getUDTS() 'oResult = oMeta.getUDTS(oNull, "%", "%", _ ' Array(com.sun.star.sdbc.DataType.OBJECT, _ ' com.sun.star.sdbc.DataType.STRUCT , _ ' com.sun.star.sdbc.DataType.DISTINCT )) 'AddResultSetToDoc(oResult, oDoc, "getUDTS") RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("getURL", "getUserName")) For i = LBound(oTables()) To UBound(oTables()) oResult = oMeta.getVersionColumns(oNull, "%", oTables(i)) ResultSetToData(oResult, oDoc, "getVersionColumns(" & _ oTables(i) & ")", _ oData1()) SafeArrayColumns(8, oData1(), _ Array("UNKNOWN", "NOT_PSEUDO", "PSEUDO"), True)

OpenOffice.org Base

77

Database connections AppendDataToCalcDoc(oDoc, oData1()) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("isCatalogAtStart", "isReadOnly", "nullPlusNonNullIsNull", _ "nullsAreSortedAtEnd", "nullsAreSortedAtStart", _ "nullsAreSortedHigh", "nullsAreSortedLow")) For i = 1003 To 1005 RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("insertsAreDetected", _ "othersDeletesAreVisible", "othersInsertsAreVisible", _ "othersUpdatesAreVisible", "ownDeletesAreVisible", _ "ownInsertsAreVisible", "ownUpdatesAreVisible"), True, i) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("storesLowerCaseIdentifiers", _ "storesLowerCaseQuotedIdentifiers", _ "storesMixedCaseIdentifiers", _ "storesMixedCaseQuotedIdentifiers", _ "storesUpperCaseIdentifiers", _ "storesUpperCaseQuotedIdentifiers", _ "supportsAlterTableWithAddColumn", _ "supportsAlterTableWithDropColumn", _ "supportsANSI92EntryLevelSQL", "supportsANSI92FullSQL", _ "supportsANSI92IntermediateSQL", "supportsBatchUpdates", _ "supportsCatalogsInDataManipulation", _ "supportsCatalogsInIndexDefinitions", _ "supportsCatalogsInPrivilegeDefinitions", _ "supportsCatalogsInProcedureCalls", _ "supportsCatalogsInTableDefinitions", "supportsColumnAliasing")) oData1() = Array(-7, -6, -5, -5, -4, -3, -2, -1, 0,_ 1, 2, 3, 4, 6, 7, 8, 12, 91, 92, 93, 111, _ 2000, 2001, 2002, 2003, 2004, 2005, 2006) oData2() = Array("supportsConvert", "BIT", "TINYINT", "BIGINT", _ "LONGVARBINARY", "VARBINARY", "BINARY", "LONGVARCHAR", _ "SQLNULL", "CHAR", "NUMERIC", "DECIMAL", "INTEGER", _ "SMALLINT", "FLOAT", "REAL", "DOUBLE", "VARCHAR", "DATE", _ "TIME", "TIMESTAMP", "OTHER", "OBJECT", "DISTINCT", _ "STRUCT", "ARRAY", "BLOB", "CLOB", "REF") oData3() = DimArray(UBound(oData2())) oData3(0) = oData2() For i = LBound(oData1()) to UBound(oData1()) oData4() = DimArray(UBound(oData2())) oData4(0) = "supportsConvert(" & oData2(i+1) & ", ...)" For j = LBound(oData1()) to UBound(oData1()) oData4(j+1) = CStr(oMeta.supportsConvert(oData1(i), oData1(j))) Next

OpenOffice.org Base

78

Database connections oData3(i+1) = oData4() Next AppendDataToCalcDoc(oDoc, oData3()) RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("supportsCoreSQLGrammar", "supportsCorrelatedSubqueries",_ "supportsDataDefinitionAndDataManipulationTransactions", _ "supportsDataManipulationTransactionsOnly", _ "supportsDifferentTableCorrelationNames", _ "supportsExpressionsInOrderBy", "supportsExtendedSQLGrammar",_ "supportsFullOuterJoins", "supportsGroupBy", _ "supportsGroupByBeyondSelect", "supportsGroupByUnrelated", _ "supportsIntegrityEnhancementFacility", _ "supportsLikeEscapeClause", _ "supportsLimitedOuterJoins", "supportsMinimumSQLGrammar", _ "supportsMixedCaseIdentifiers", _ "supportsMixedCaseQuotedIdentifiers", _ "supportsMultipleResultSets", "supportsMultipleTransactions", _ "supportsNonNullableColumns", _ "supportsOpenCursorsAcrossCommit", _ "supportsOpenCursorsAcrossRollback", _ "supportsOpenStatementsAcrossCommit", _ "supportsOpenStatementsAcrossRollback", _ "supportsOrderByUnrelated", _ "supportsOuterJoins", "supportsPositionedDelete", _ "supportsPositionedUpdate")) For i = 1003 To 1005 RunMultipleCallsAppendToDoc(oDoc, oMeta, Array("supportsResultSetConcurrency"), RunMultipleCallsAppendToDoc(oDoc, oMeta, Array("supportsResultSetConcurrency"), Next

_ True, i, 1007) _ True, i, 1008)

For i = 1003 To 1005 RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("supportsResultSetType"), True, i) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("supportsSchemasInDataManipulation", _ "supportsSchemasInIndexDefinitions", _ "supportsSchemasInPrivilegeDefinitions", _ "supportsSchemasInProcedureCalls", _ "supportsSchemasInTableDefinitions", "supportsSelectForUpdate", _ "supportsStoredProcedures", "supportsSubqueriesInComparisons", _ "supportsSubqueriesInExists", "supportsSubqueriesInIns", _ "supportsSubqueriesInQuantifieds", _ "supportsTableCorrelationNames")) REM com.sun.star.sdbc.TransactionIsolation constants oData1() = Array(0, 1, 2, 4, 8)

OpenOffice.org Base

79

Database connections For i = Lbound(oData1()) to UBound(oData1()) RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("supportsTransactionIsolationLevel"), True, oData1(i)) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("supportsTransactions", "supportsTypeConversion", _ "supportsUnion", "supportsUnionAll")) For i = 1003 To 1005 RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("updatesAreDetected"), True, i) Next RunMultipleCallsAppendToDoc(oDoc, oMeta, _ Array("usesLocalFilePerTable", "usesLocalFiles")) InspectMetaData() = oDoc End Function

T!e mac$o in Listing '3 demonst$ates !o/ to ins#ect t!e meta&data f$om a connection( DB /eta Data Ise t!e D# +eta Data 'utton to select a Jase document and dis#lay t!e associated meta data in a "alc document( Listing 3'. Inspect()*L+eta,ata is contained in )C0%.
Sub InspectDBMetaData() Dim oBaseContext 'Global database context service. Dim oDataBase 'Database obtained from the database context. Dim oCon 'Database connection. Dim sURL$ LoadDBLibs() sURL = ChooseAFile$(OOoBaseFilters(), True) If sURL = "" Then Exit Sub oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataBase = oBaseContext.getByName(sURL) oCon = oDataBase.getConnection("", "") InspectMetaData(oCon.getMetaData()) oCon.close() End Sub

T!e mac$o in Listing '& demonst$ates !o/ to ins#ect t!e meta&data f$om a connection( .SQ DB /eta Data Ise t!e /S%&D# +eta Data 'utton to use t!e 'ina$y data'ase document c$eated at t!e 'e%innin% of t!is document( T!is mac$o may ta.e a little /!ile to $un; Listing 3-. Inspect()*L+eta,ata is contained in )C0%.
Sub InspectHSQLMetaData() Dim oBaseContext 'Global database context service. Dim oDataBase 'Database obtained from the database context. Dim oCon 'Database connection. Dim sDBUrl$ LoadDBLibs() OpenOffice.org Base 8"

Database connections

sDBUrl = GetSourceCodeDir() & sDBBaseName oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDataBase = oBaseContext.getByName(sDBUrl) oCon = oDataBase.getConnection("", "") InspectMetaData(oCon.getMetaData()) oCon.close() End Sub

8.+.+. &etBest,owIdentifier
T!e met!od %etJestRo/4dentifie$,- $etu$ns a desc$i#tion of t!e o#timal set of columns t!at uni3uely identify a $o/( 4n ot!e$ /o$ds, use t!e columns identified 'y t!e met!od %etJestRo/4dentifie$,- to most 3uic.ly access a $o/ in a ta'le( T!e a$%uments a$e desc$i'ed in Table "1( Table "1. +rguments for getBest2ow1dentifierBC.
Ar "ment
catalo% sc!ema ta'le sco#e

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD an em#ty st$in% ,QQ- $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD an em#ty st$in% ,QQ- $et$ieves $o/s /it!out a sc!ema( Ret$ieve $o/s t!at use t!e s#ecified ta'le nameD /ild&ca$ds a$e not su##o$ted( Ret$ieve $o/s /it! t!e s#ecified sco#e( Ise t!e com(sun(sta$(sd'c(JestRo/8co#e constant %$ou#, /!ic! su##o$ts values of TLMP7R+R) ,0-, TR+C8+"T47C ,>-, and 8L8847C ,2-( 4f T$ue, $etu$n columns t!at a$e allo/ed to 'e null(

nulla'le

Many data'ases su##o$t s#ecial F!iddenG columns t!at a$e not e6#licitly defined 'y t!e use$ in t!e ta'le definition( T!ese #seudo&columns %ene$ally #$ovide t!e fastest access to t!e data 'ecause t!ey ty#ically a$e #ointe$s to t!e e6act location of t!e $eco$d( Table "" contains t!e constants used to identify a column as a #seudo&column( Table "". ,alues for the com.sun.star.sdbc.Best2owType constant group.
&al"e
0 > 2

Name
ICWC7EC C7TMP8LID7 P8LID7

Description
T!e 'est $o/ identifie$ may o$ may not 'e a #seudo&column( T!e 'est $o/ identifie$ is not a #seudo&column( T!e 'est $o/ identifie$ is a #seudo&column(

T!e %etJestRo/4dentifie$,- met!od $etu$ns a $esult set /it! t!e columns s!o/n in Table "'( Table "'. Columns returned by getBest2ow1dentifierBC.
#
> 2

Col"mn
8"7PL "7LIMCMC+ML

Typ e
s!o$t st$in%

Description
8co#e, 'ased on t!e JestRo/8co#e constant %$ou# ,see t!e sco#e a$%ument in Table "1-( "olumn name(
8!

OpenOffice.org Base

Database connections

Col"mn
D+T+MT)PL

Typ e
s!o$t st$in% lon% lon% s!o$t s!o$t

Description
8PL data ty#e 'ased on t!e Hava(s3l(Ty#es ,see Table 15-( Data sou$ce de#endent ty#e name( T!e #$ecision ,len%t!- of t!e column( Len%t! of column value in 'ytes( 8caleD fo$ nume$ical columns( 4dentify t!e column as a #seudo&column ,see Table ""-(

4 5 ? B 8

T)PLMC+ML "7LIMCM84YL JI99LRMLLC=T< DL"4M+LMD4=4T8 P8LID7M"7LIM

Listing '# calls %etJestRo/4dentifie$,-( 8ome d$ive$s $etu$n a CILL $esult set $at!e$ t!an a $esult set t!at contains no $o/s( 4n my testin% usin% 77o 2(0 #$e&'eta,TT $etest-, a flat file $etu$ned a $esult set t!at contained no $o/s and an <8PLDJ data'ase $etu$ned CILL(

8.+.-. &etColumnPri5ileges
T!e $esult set f$om %et"olumnP$ivile%es,- desc$i'es t!e access $i%!ts fo$ a ta'leKs columnsD t!e su##o$ted a$%uments a$e s!o/n in Table "/( Table "/. +rguments for getColumn0ri9ilegesBC.
Ar "ment
catalo% sc!ema ta'le column

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD FG $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD QQ $et$ieves $o/s /it!out a sc!ema( Ret$ieve $o/s t!at use t!e s#ecified ta'le nameD use F\G to $et$ieve all ta'les( Ret$ieve $o/s t!at use t!e s#ecified column nameD use F\G to $et$ieve all columns(

T!e met!od %et"olumnP$ivile%es,- $etu$ns a $esult set /it! t!e columns as s!o/n in Table "#. 8ystem ta'les a$e also $etu$ned, so !und$eds of $o/s may 'e $etu$ned, even on a small data'ase( Table "#. Columns returned by getColumn0ri9ilegesBC.
#
> 2 4 5 ? B 8

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML "7LIMCMC+ML =R+CT7R =R+CTLL PR4S4LL=L 48M=R+CT+JLL

Type
st$in% st$in% st$in% st$in% st$in% st$in% st$in% st$in%

Description
Ta'le catalo% name ,may 'e CILL-( Ta'le sc!ema ,may 'e CILL-( Ta'le name( "olumn name( =$ante$ of access ,may 'e CILL-( =$antee of access( Came of access ,8LLL"T, 4C8LRT, IPD+TL, RL9LRLC"L8, (((-( Q)L8Q if %$antee is #e$mitted to %$ant to ot!e$sD QC7Q if notD CILL if un.no/n(

OpenOffice.org Base

8#

Database connections

8.+... &etColumns
T!e %et"olumns,- met!od $etu$ns a desc$i#tion of t!e availa'le columns( T!e a$%uments to %et"olumns,-, catalo%, sc!ema, ta'le, and column, a$e s!o/n in Table "/( T!e $etu$ned $o/ set uses t!e "olumnSalue constant %$ou# ,see Table "3- to identify if a column can contain a CILL value( Table "3. ,alues for the com.sun.star.sdbc.Column,alue constant group
&al"e
0 > 2

Name
C7MCILL8 CILL+JLL CILL+JLLMICWC7EC

Description
+ column does not allo/ CILL values( + column allo/s CILL values( T!e null&a'ility of t!e column is un.no/n(

T!e %et"olumns,- met!od $etu$ns a $esult set /it! t!e columns s!o/n in Table "&( Table "&. Columns returned by getColumnsBC.
#
> 2 4 5 ? B 8 9 >0 >> >2 >

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML "7LIMCMC+ML D+T+MT)PL T)PLMC+ML "7LIMCM84YL JI99LRMLLC=T< DL"4M+LMD4=4T8 CIMMPRL"MR+D4N CILL+JLL RLM+RW8 "7LIMCMDL9 8PLMD+T+MT)PL

Type
st$in% st$in% st$in% st$in% s!o$t st$in% lon% lon% lon% lon% lon% st$in% st$in% lon%

Description
Ta'le catalo% name( Ta'le sc!ema name( Ta'le name( "olumn name( 8PL data ty#e 'ased on t!e Hava(s3l(Ty#es ,see Table 15-( Data sou$ce de#endent ty#e name( T!e #$ecision ,len%t!- of t!e column( Len%t! of column value in 'ytes( Cot used fo$ all d$ive$s( 8cale fo$ nume$ical columns( Radi6 ,ty#ically eit!e$ >0 o$ 2-( "an t!e column contain a CILL value ,see Table "3-( "omment desc$i'in% column ,may 'e CILL-( Default value fo$ t!e column ,may 'e CILL-( T!e value of t!e 8PL data ty#e as it a##ea$s in t!e 8PLMDL8"MT)PL field of t!e desc$i#to$( T!is is f$e3uently t!e same as t!e data ty#e and it may 'e CILL( 9o$ a date&time o$ inte$val ty#e, t!is contains t!e date&time*inte$val su'&code( T!is may 'e CILL( Ma6imum num'e$ of 'ytes in t!e column ,fo$ c!a$ columns-( "olumnKs 4nde6 in t!e ta'le ,sta$tin% /it! >-( FC7G means no, F)L8G means may'e, and FG

>4 >5 >? >B >8 8PLMD+TLT4MLM8IJ "<+RM7"TLTMLLC=T< 7RD4C+LMP784T47C 48MCILL+JLL lon% lon% int st$in%

OpenOffice.org Base

8$

Database connections

Col"mn

Type

Description
means un.no/n(

Most data'ase systems sto$e info$mation in system ta'les( 9o$ e6am#le, it is ty#ical to !ave a ta'le t!at lists use$s, and anot!e$ t!at lists t!e defined ta'les( E!en $un a%ainst a sim#le data'ase usin% t!e <8PLDJ fo$mat, t!e %et"olumns,- met!od $etu$ned $ou%!ly 400 $o/s f$om nume$ous system ta'les( Ise %et"olumns,- to investi%ate t!e availa'le columns and $o/s, 'ut in #$actice, you /ill #$o'a'ly /ant to limit t!e $etu$ned values to t!e ta'les of inte$est(

8.+.7. &et01ported:eys
T!e met!od %etL6#o$tedWeys,- $etu$ns a $esult set desc$i'in% t!e fo$ei%n .ey columns t!at $efe$ence a ta'leKs #$ima$y .ey columns ,t!e fo$ei%n .eys e6#o$ted 'y a ta'le-( Lac! fo$ei%n .ey contains an u#date and delete $ule desc$i'ed 'y t!e WeyRule constant %$ou# ,see Table "%-( T!e 'e!avio$ may 'e diffe$ent 'ased on /!et!e$ t!e $ule is used as an u#date $ule o$ a delete $ule( Table "%. ,alues for the com.sun.star.sdbc.Dey2ule constant group.
&al"e
0

Name
"+8"+DL

Description
+s an u#date $ule, /!en t!e #$ima$y .ey is u#dated, t!e fo$ei%n .ey ,im#o$ted .ey- is also c!an%ed( +s a delete $ule, /!en t!e #$ima$y .ey is deleted, $o/s t!at im#o$ted t!at .ey a$e deleted( +s an u#date $ule, a #$ima$y .ey may not 'e u#dated if it is im#o$ted 'y anot!e$ ta'le as a fo$ei%n .ey( +s a delete $ule, a #$ima$y .ey may not 'e deleted if it is im#o$ted 'y anot!e$ ta'le as a fo$ei%n .ey( 4f t!e #$ima$y .ey is u#dated o$ deleted, t!e fo$ei%n .ey ,im#o$ted .eyis c!an%ed to CILL( +n im#o$ted #$ima$y .ey cannot 'e u#dated o$ deleted( 4f t!e #$ima$y .ey is u#dated o$ deleted, t!e fo$ei%n .ey ,im#o$ted .eyis set to t!e default value(

>

RL8TR4"T

8LTMCILL C7M+"T47C

8LTMDL9+ILT

T!e Defe$$a'ility constant %$ou# ,see Table "$- cont$ols /!et!e$ a const$aint can 'e defe$$ed( + const$aint t!at is not defe$$a'le is c!ec.ed immediately afte$ eve$y command( + defe$$ed const$aint may 'e #ost#oned until t!e end of t!e t$ansaction( Table "$. ,alues for the com.sun.star.sdbc.4eferrability constant group.
&al"e
5 ? B

Name
4C4T4+LL)MDL9LRRLD 4C4T4+LL)M4MMLD4+TL C7CL

Description
9o$ei%n .ey ve$ification may 'e defe$$ed( 9o$ei%n .ey ve$ification is done afte$ eac! command( 9o$ei%n .ey ve$ification is not #e$fo$med(

T!e columns $etu$ned 'y t!e %etL6#o$tedWeys,- met!od a$e s!o/n in Table '5(

OpenOffice.org Base

84

Database connections

Table '5. Columns returned by get-7portedDeysBC.


#
> 2 4 5 ? B 8 9 >0 >> >2 > >4

Col"mn
PWT+JLLM"+T PWT+JLLM8"<LM PWT+JLLMC+ML PW"7LIMCMC+ML 9WT+JLLM"+T 9WT+JLLM8"<LM 9WT+JLLMC+ML 9W"7LIMCMC+ML WL)M8LP IPD+TLMRILL DLLLTLMRILL 9WMC+ML PWMC+ML DL9LRR+J4L4T)

Type
st$in% st$in% st$in% st$in% st$in% st$in% st$in% st$in% s!o$t s!o$t s!o$t st$in% st$in% s!o$t

Description
P$ima$y .ey ta'le catalo% ,may 'e CILL-( P$ima$y .ey ta'le sc!ema ,may 'e CILL-( P$ima$y .ey ta'le name( P$ima$y .ey column name( 9o$ei%n .ey ta'le catalo% 'ein% e6#o$ted ,may 'e CILL-( 9o$ei%n .ey ta'le sc!ema 'ein% e6#o$ted ,may 'e CILL-( 9o$ei%n .ey ta'le name 'ein% e6#o$ted( 9o$ei%n .ey column name 'ein% e6#o$ted( 8e3uence num'e$ in t!e fo$ei%n .ey( E!at !a##ens to t!e fo$ei%n .ey /!en t!e #$ima$y is u#dated ,see WeyRule in Table "%-( E!at !a##ens to t!e fo$ei%n .ey /!en t!e #$ima$y is deleted ,see WeyRule in Table "%-( 9o$ei%n .ey name ,may 'e CILL-( P$ima$y .ey name ,may 'e CILL-( E!en a$e fo$ei%n .ey const$aints evaluated ,see Table "$-T

T!e a$%uments fo$ %etL6#o$tedWeys,- a$e s!o/n in Table '1( Table '1. +rguments for get-7portedDeysBC.
Ar "ment
catalo% sc!ema ta'le

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD FG $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD QQ $et$ieves $o/s /it!out a sc!ema( Ret$ieve $o/s t!at use t!e s#ecified ta'le nameD /ild&ca$ds a$e not su##o$ted(

8.+.8. &etInde1Info
T!e %et4nde64nfo,- met!od $etu$ns a $o/ set t!at #$ovides info$mation $elated to eac! inde6 fo$ t!e data'ase( Lac! inde6 !as a ty#e ,see Table '"-( + cluste$ed inde6 is usually used /!en t!e$e a$e a limited num'e$ of uni3ue values, suc! as a state column t!at contains only 50 uni3ue state codes( + cluste$ed inde6 is also f$e3uently used if 3ue$ies usin% o#e$ato$s suc! as JLTELLC, A, AU, @, and @U a$e used( + !as!ed 'ased inde6 is o#timi5ed fo$ e3uality 'ased sea$c!es( Table '". ,alues for the com.sun.star.sdbc.1nde7Type constant group.
&al"e
0

Name
8T+T48T4"

Description
Ta'le statistics t!at a$e $etu$ned in conHunction /it! a ta'leKs inde6
85

OpenOffice.org Base

Database connections

&al"e
> 2

Name
"LI8TLRLD <+8<LD 7T<LR

Description
desc$i#tion( T!e inde6 is a cluste$ed inde6( T!e inde6 is a !as!ed inde6( T!is inde6 some ot!e$ ty#e(

+ll of t!e ent$ies in Table '" define a ty#e of inde6 e6ce#t fo$ 8T+T48T4", /!ic! c!an%es t!e meanin% of ce$tain $o/s( 9o$ e6am#le, t!e P+=L8 column $efe$s to t!e num'e$ of #a%es used fo$ t!e inde6 unless t!e ty#e is 8T+T48T4", in /!ic! case it is t!e num'e$ of #a%es used fo$ t!e ta'le ,see Table ''-( Table ''. Columns returned by get1nde71nfoBC.
#
> 2 4 5 ? B 8 9 >0

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML C7CMIC4PIL 4CDLNMPI+L494LR 4CDLNMC+ML T)PL 7RD4C+LMP784T47C "7LIMCMC+ML +8"M7RMDL8"

Type
st$in% st$in% st$in% 'oolean st$in% st$in% s!o$t s!o$t st$in% st$in%

Description
Ta'le catalo% ,may 'e CILL-( Ta'le sc!ema ,may 'e CILL-( Ta'le name( T$ue, if t!e inde6 values can 'e non&uni3ue, 9alse ot!e$/iseD t!is is al/ays 9alse fo$ t!e statistic ty#e( 4nde6 catalo% ,may 'e CILL -D CILL fo$ ty#e statistic( 4nde6 name( T!is is al/ays CILL /!en t!e ty#e is statistic( 4nde6 ty#e ,see Table '"-( "olumn se3uence num'e$ in t!e inde6D 5e$o fo$ ty#e statistic( "olumn nameD CILL fo$ ty#e statistic( "olumn so$t se3uenceD F+G means ascendin% and FDG means descendin%( T!is is CILL if a so$t se3uence is not su##o$ted and fo$ ty#e statistic( Cum'e$ of uni3ue values in t!e inde6( 4f t!e ty#e is statistic, t!en t!is is t!e num'e$ of $o/s in t!e ta'le( Cum'e$ of #a%es used fo$ t!e inde6( 4f t!e ty#e is statistic, t!en t!is is t!e num'e$ of #a%es used fo$ t!e ta'le( 9ilte$ condition, if any ,may 'e CILL-(

>> >2

"+RD4C+L4T) P+=L8

lon% lon%

>

94LTLRM"7CD4T47C

st$in%

T!e a$%uments fo$ %et4nde64nfo,- a$e s!o/n in Table '/( Table '/. +rguments for get1nde71nfoBC.
Ar "ment
catalo% sc!ema
OpenOffice.org Base

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD QQ $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD QQ $et$ieves $o/s /it!out a sc!ema(
86

Database connections

Ar "ment
ta'le uni3ue a##$o6imate

Description
Ret$ieve $o/s t!at use t!e s#ecified ta'le nameD /ild&ca$ds a$e not su##o$ted( 4f T$ue, $etu$n only inde6es fo$ uni3ue values, ot!e$/ise, $etu$n all inde6es( 4f T$ue, t!e $etu$ned values may contain a##$o6imate o$ out of data values( 4f 9alse, $esults must 'e accu$ate(

8.+.;. &etPrimary:eys
T!e %etP$ima$yWeys,- met!od $etu$ns a $esult set t!at desc$i'es a ta'leKs #$ima$y .ey columns( T!e $etu$ned $o/s a$e o$de$ed 'y t!e column name( T!e acce#ted a$%umentsOcatalo%, sc!ema, and ta'leOa$e desc$i'ed in Table "3 and t!e $etu$ned $o/s a$e s!o/n in Table '#( Table '#. Columns returned by get0rimaryDeysBC.
#
> 2 4 5 ?

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML "7LIMCMC+ML WL)M8LP PWMC+ML

Type
st$in% st$in% st$in% st$in% s!o$t st$in%

Description
"atalo% name ,may 'e CILL-( Ta'le sc!ema ,may 'e CILL-( Ta'le name( "olumn name( 8e3uence num'e$ /it!in #$ima$y .ey( Came of t!e #$ima$y .ey ,may 'e CILL-(

8.+.1<. &etTablePri5ileges
T!e met!od %etTa'leP$ivile%es,- $etu$ns a $esult set t!at desc$i'es t!e access $i%!ts fo$ eac! ta'le in t!e catalo%( Lac! ta'le #$ivile%e a##lies to one o$ mo$e columns in t!e ta'le, 'ut not necessa$ily to all of t!e columns in t!e ta'le( T!e acce#ted a$%uments a$e desc$i'ed in Table "3 and t!e $etu$ned columns a$e desc$i'ed in Table '3O/ild&ca$ds a$e su##o$ted fo$ t!e ta'le name( Table '3. Columns returned by getTable0ri9ilegesBC.
#
> 2 4 5 ? B

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML =R+CT7R =R+CTLL PR4S4LL=L 48M=R+CT+JLL

Type
st$in% st$in% st$in% st$in% st$in% st$in% st$in%

Description
"atalo% name ,may 'e CILL-( Ta'le sc!ema ,may 'e CILL-( Ta'le name( Pe$son /!o %$anted access ,may 'e CILL-( Pe$son to /!om access /as %$anted( +ccess ty#e ,8LLL"T, 4C8LRT, IPD+TL, RL9LRLC"L8, (((-( Q)L8Q if %$antee is #e$mitted to %$ant to ot!e$sD QC7Q if notD CILL if un.no/n

OpenOffice.org Base

87

Database connections

8.+.11. &etTables
T!e %etTa'les,- met!od $etu$ns a $o/ set t!at desc$i'es t!e ta'les contained in t!e data'ase( T!e columns $etu$ned 'y t!e $o/ set a$e desc$i'ed in Table '&( Table '&. Columns returned by getTablesBC.
#
> 2 4

Col"mn
T+JLLM"+T T+JLLM8"<LM T+JLLMC+ML T+JLLMT)PL

Type
st$in% st$in% st$in% st$in%

Description
"atalo% name ,may 'e CILL-( Ta'le sc!ema ,may 'e CILL-( Ta'le name( Ta'le ty#eD ty#ical values include T+JLL, S4LE, 8)8TLM T+JLL, =L7J+L TLMP7R+R), L7"+L TLMP7R+R), +L4+8, and 8)C7C)M( "omment t!at e6#lains t!e ta'le(

RLM+RW8

st$in%

T!e a$%uments fo$ %etTa'les,- a$e s!o/n in Table '%( Table '%. +rguments for getTablesBC.
Ar "ment
catalo% sc!ema ta'le ty#es,-

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD QQ $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD QQ $et$ieves $o/s /it!out a sc!ema( Ret$ieve $o/s t!at use t!e s#ecified ta'le nameD use F\G to $et$ieve all ta'les( +$$ay of ta'le ty#es to $etu$nD +lt!ou%! CILL $etu$ns all ty#es, t!is is not su##o$ted on some systemsD use an em#ty a$$ay instead(

8.+.1 . &etTypeInfo"#
T!e %etTy#e4nfo,- met!od $etu$ns a $o/ set t!at desc$i'es t!e standa$d 8PL ty#es su##o$ted 'y t!is data'ase( Lac! column su##o$ts diffe$ent ty#es of sea$c!es 'ased on t!e data ty#e and t!e data'ase im#lementation ,see Table 15-( Table '$. ,alues for the com.sun.star.sdbc.Column(earch constant group.
&al"e
0 > 2

Name
C7CL "<+R J+84" 9ILL

Description
E<LRL sea$c! clauses a$e not su##o$ted fo$ t!is ty#e( T!e only su##o$ted sea$c! clause is E<LRL(((L4WL( 8u##o$ts all su##o$ted sea$c! clauses e6ce#t E<LRL(((L4WL( +ll E<LRL sea$c! clauses can 'e 'ased on t!is ty#e(

T!e columns $etu$ned 'y t!e $o/ set a$e s!o/n in Table /5(

OpenOffice.org Base

88

Database connections

Table /5. Columns returned by getType1nfoBC.


#
> 2 4 5 ? B 8 9 >> >2 > >4 >5 >?

Col"mn
T)PLMC+ML D+T+MT)PL PRL"4847C L4TLR+LMPRL94N L4TLR+LM8I994N "RL+TLMP+R+M8 CILL+JLL "+8LM8LC84T4SL 8L+R"<+JLL 94NLDMPRL"M8"+LL +IT7M4C"RLMLCT L7"+LMT)PLMC+ML M4C4MIMM8"+LL M+N4MIMM8"+LL 8PLMD+T+MT)PL

Type
st$in% s!o$t lon% st$in% st$in% st$in% s!o$t 'oolean s!o$t 'oolean 'oolean st$in% s!o$t s!o$t lon%

Description
Ty#e name( 8PL data ty#e f$om Hava(s3l(Ty#es ,see Table 15-( Ma6imum #$ecision( P$efi6 used to 3uote a lite$al ,may 'e CILL-( 8uffi6 used to 3uote a lite$al ,may 'e CILL-( Pa$amete$s used in c$eatin% t!e ty#e ,may 'e CILL-( 4ndicates if t!is ty#e su##o$ts CILL values ,see Table "3-( T$ue if t!is ty#e is case sensitive( 4ndicates t!e sea$c!es su##o$ted 'y t!is ty#e: Table '$( 4f T$ue, t!is ty#e can $e#$esent a moneta$y value( 4f T$ue, t!is ty#e can 'e used fo$ an auto&inc$ement value( Locali5ed ve$sion of ty#e name ,may 'e CILL-( Minimum scale su##o$ted( Ma6imum scale su##o$ted( T!e value of t!e 8PL data ty#e as it a##ea$s in t!e 8PLMDL8"MT)PL field of t!e desc$i#to$( T!is is f$e3uently t!e same as t!e data ty#e and it may 'e CILL( 9o$ a date&time o$ inte$val ty#e, t!is contains t!e date& time*inte$val su'&code( T!is may 'e CILL fo$ many d$ive$s( Radi6 ,ty#ically eit!e$ >0 o$ 2-(

>B

8PLMD+TLT4MLM8IJ

lon%

>8

CIMMPRL"MR+D4N

lon%

8.+.1'. &et$3T!
T!e %etIDT8,- met!od $etu$ns a $o/ set t!at desc$i'es t!e use$&defined ty#es contained in t!e data'ase( T!e a$%uments fo$ %etIDT8,- a$e s!o/n in Table /1( 4n my testin%, callin% t!e %etIDT8,- met!od causes a $untime e$$o$ fo$ some connection ty#esD 7utloo., fo$ e6am#le( Table /1. +rguments for get64T(BC.
Ar "ment
catalo% sc!ema ty#e name ty#es,-

Description
Ret$ieve $o/s t!at use t!e s#ecified catalo% nameD FG $et$ieves $o/s /it!out a catalo% and CILL means i%no$e t!e catalo% name( Ret$ieve $o/s t!at use t!e s#ecified sc!ema nameD QQ $et$ieves $o/s /it!out a sc!ema( Ret$ieve $o/s t!at use t!e s#ecified fully 3ualified nameD use F\G to $et$ieve all IDTs( +$$ay of IDT ty#es to $etu$nD su##o$ted ty#es include st$in%s /it! values of 7JJL"T, 8TRI"T, and D48T4C"T(

OpenOffice.org Base

89

Database connections

T!e columns $etu$ned 'y t!e $o/ set a$e s!o/n in Table /"( Table /". Columns returned by get64T(BC.
#
> 2 4 5 ?

Col"mn
T)PLM"+T T)PLM8"<LM T)PLMC+ML "L+88MC+ML D+T+MT)PL RLM+RW8

Type
st$in% st$in% st$in% st$in% st$in% st$in%

Description
Ty#eKs catalo% ,may 'e CILL-( Ty#eKs sc!ema ,may 'e CILL-( Ty#e name( Java class name o$ se$vice name( Ty#e value( 7ne of 7JJL"T, 8TRI"T, o$ D48T4C"T( L6#lanato$y comment on t!e ty#e(

8.+.1+. &et=ersionColumns
T!e met!od %etSe$sion"olumns,- $etu$ns a $o/ set t!at desc$i'es a ta'leKs columns t!at a$e automatically u#dated /!en any value in a $o/ is u#dated( Many data'ases su##o$t s#ecial F!iddenG columns t!at a$e not e6#licitly defined 'y t!e use$ in t!e ta'le definition( T!ese #seudo& columns %ene$ally #$ovide t!e fastest access to t!e data 'ecause t!ey ty#ically a$e #ointe$s to t!e e6act location of t!e $eco$d( Table /' contains t!e constants used to identify a column as a #seudo&column( Table /'. ,alues for the com.sun.star.sdbc.ColumnType constant group.
&al"e
0 > 2

Name
ICWC7EC C7TMP8LID7 P8LID7

Description
T!e 'est $o/ identifie$ may o$ may not 'e a #seudo&column( T!e 'est $o/ identifie$ is not a #seudo&column( T!e 'est $o/ identifie$ is a #seudo&column(

T!e a$%uments acce#ted 'y %etSe$sion"olumns,-Ocatalo%, sc!ema, and ta'leOa$e desc$i'ed in Table '1O/ild&ca$ds a$e not su##o$ted fo$ t!e ta'le a$%umentOand t!e $etu$ned $o/s a$e s!o/n in Table //( Table //. Columns returned by get,ersionColumnsBC.
#
> 2 4 5 ? B 8

Col"mn
8"7PL "7LIMCMC+ML D+T+MT)PL T)PLMC+ML "7LIMCM84YL JI99LRMLLC=T< DL"4M+LMD4=4T8 P8LID7M"7LIMC

Type
s!o$t st$in% s!o$t st$in% lon% lon% s!o$t s!o$t

Description
Inused( "olumn name( 8PL data ty#e 'ased on t!e Hava(s3l(Ty#es ,see Table 15-( Data sou$ce de#endent ty#e name( T!e #$ecision ,len%t!- of t!e column( Len%t! of column value in 'ytes( 8caleD fo$ nume$ical columns( 4dentify t!e column as a #seudo&column ,see Table /'-(

OpenOffice.org Base

9"

Database connections

7.&. Connections
+ met!od is usually o'tained as a t!$ee ste# #$ocess ,see Listing '%-: >( =et a $efe$ence to t!e Data'ase"onte6t se$vice( 2( =et*load t!e data'ase f$om t!e Data'ase"onte6t( ( =et a connection f$om t!e data'ase( Listing 3.. )tandard method to obtain a database connection.
oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(dbURL) oCon = oDB.getConnection("", "")

T!e getConnection met!od $etu$ns a #$o6y o'Hect fo$ t!e connection( Lve$y #$o6y o'Hect o'tained in t!is /ay s!a$e t!e same #!ysical connection( T!e$efo$e, o#e$ations done on one #$o6y s!ould cause side effects on all t!e ot!e$s( +not!e$ met!od, getIsolatedConnection, $etu$ns an isolated connection t!at is not s!a$ed( +lt!ou%! an isolated connection uses mo$e $esou$ces, t!is is $e3ui$ed if a se#a$ate connection is $e3ui$ed to t!e data'ase( 77o is not a multi&use$ a##lication so a standa$d connection is usually /!at you /ant( 4f an e6istin% connection al$eady !as e6clusive access to t!e data'ase, t!e $etu$ned connection /ill 'e ,4 t!in. it /ill 'e- $ead&only( 9o$ e6am#le, if you o#en t/o isolated connections, t!e second connection is li.ely to 'e $ead&only(
TIP
4f you fo$%et to close a connection, t!e ne6t connection may 'e $ead&only, even if t!e connection is isolated( 8o, if you o'tain a $ead&only connection t!at you did not e6#ect, c!ec. you$ code fo$ a connection lea8(

7.0. Connections without a data source


+lt!ou%! t!e ne/ data'ase document ty#e, /!ic! co$$es#onds to a data sou$ce, is desi$a'le, sometimes t!e e6t$a functionality of #$e#a$ed 3ue$ies, fo$ms, and $e#o$ts is not $e3ui$ed( 4t is #ossi'le to connect to a data'ase 'y usin% an a##$o#$iate data'ase d$ive$ $at!e$ t!an a data sou$ceOso an e6te$nal Jase file is not $e3ui$ed( 7#en7ffice(o$% contains a d$ive$ mana%e$ t!at mana%es t!e data'ase d$ive$s su##o$ted 'y 77o( Listing '$ demonst$ates !o/ to $et$ieve t!e data'ase d$ive$ mana%e$( Listing 39. "etrieve the global database driver manager.
oManager = CreateUnoService("com.sun.star.sdbc.DriverManager")

T!e d$ive$ mana%e$ identifies t!e d$ive$ ty#es 'ased on a IRL ,see Table /#-( T!e st$uctu$e of t!e IRL consists of a #$otocol name, follo/ed 'y t!e d$ive$ s#ecific su'&#$otocol( T!e data sou$ce administ$ation dialo% s!o/s t!e latest su##o$ted #$otocols( 8ome #$otocols a$e #latfo$m de#endent( 9o$ e6am#le, +D7 is only su##o$ted on Eindo/s(

OpenOffice.org Base

9!

Database connections

Table /#. 4atabase 62L types supported by !pen!ffice.org.


Driver
JDJ" 7DJ" (5 +da'as D +D7 dJase 9lat file fo$mat ,csv7#en7ffice(o$% "alc +dd$ess Joo.

'%L
Hd'c:su'#$otocol: sd'c:od'c:datasou$ce name sd'c:ada'as:data'ase name sd'c:ado:+D7 s#ecific sd'c:d'ase:Location of folde$ o$ file sd'c:flat:Location of folde$ o$ file sd'c:calc:Location of 7#en7ffice(o$% "alc file sd'c:add$ess:Wind of add$ess 'oo.(

Comment
JDJ" connections( 7DJ" connections( +da'as connections( +vaila'le only on Eindo/s( Read&only access to dJase files( Read&only access to delimited te6t files ,see Listing /"-( Read&only access to "alc documents ,see Listing /&-( Mo5illa, 7utloo., and LD+P add$ess 'oo.s ,see Listing /%-(

T!e d$ive$ mana%e$ su##o$ts met!ods to o'tain connections, 'ased on a IRL and to enume$ate t!e su##o$ted d$ive$s ,see Table /3-( Table /3. (ome methods supported the dri9er manager.
Method
c$eateLnume$ation,%et"onnection,u$l%et"onnectionEit!4nfo,u$l, a$%s,-%etD$ive$JyIRL,u$l%etLo%inTimeout,!asLlements,setLo%inTimeout,seconds-

Description
Retu$n an enume$ation of t!e availa'le d$ive$s( Retu$n a connection to t!e %iven data'ase IRL( T!e mana%e$ selects an a##$o#$iate d$ive$ f$om t!e $e%iste$ed d$ive$s( Retu$n a connection to t!e %iven data'ase IRL( T!e mana%e$ selects an a##$o#$iate d$ive$ f$om t!e $e%iste$ed d$ive$s( Retu$n a d$ive$ t!at can !andle t!e s#ecified IRL( =et t!e ma6imum time, in seconds, t!at a d$ive$ /ill /ait /!ile attem#tin% to connect to a data'ase( Retu$n T$ue if t!e$e a$e any availa'le d$ive$s( 8et t!e ma6imum time, in seconds, t!at a d$ive$ /ill /ait /!ile attem#tin% to connect to a data'ase(

Listing /5 demonst$ates !o/ to enume$ate t!e d$ive$s su##o$ted 'y 7#en7ffice(o$% and is s!o/n in *igure "5< my Linu6 com#ute$ !as all of t!e d$ive$s s!o/n in *igure "5, and it also !as a d$ive$ fo$ evolution( S-pporte) DB Dri0ers Ise t!e Su''orted D# Drivers 'utton to dis#lay a list of d$ive$s su##o$ted on t!is com#ute$( (isting %#. ,atabase drivers supported by ##o.
Sub SupportedDBDrivers() Dim oManager 'Connection driver manager. Dim oEnum 'Enumeration of supported drivers. Dim oDriver 'An indiviual driver. Dim s$ 'Utility string variable.

OpenOffice.org Base

9#

Database connections oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") oEnum = oManager.createEnumeration() Do While oEnum.hasMoreElements() oDriver = oEnum.nextElement() s = s & oDriver.getImplementationName() & CHR$(10) Loop MsgBox s, 0, "Supported Database Drivers" End Sub

*igure "5. 4ri9ers supported on a ;indows computer. Ise %etD$ive$JyIRL,- to o'tain t!e d$ive$ used to o#en a s#ecific data'ase( )ou can also ve$ify t!at a suita'le d$ive$ e6ists fo$ a s#ecific data'ase ty#e( +fte$ o'tainin% a s#ecific d$ive$, use t!e met!ods in Table /&( Table /&. Methods supported by a database dri9er.
Method
connect,u$l, a$%s,-acce#tsIRL,u$l%etP$o#e$ty4nfo,u$l, a$%s,-%etMaHo$Se$sion,%etMino$Se$sion,-

Description
Retu$n a connection to t!e %iven data'ase IRL( CILL is $etu$ned if t!e d$ive$ can not connect to t!e s#ecified data'ase( Retu$n T$ue if t!e d$ive$ t!in.s t!at it can o#en a connection to t!e %iven IRLD d$ive$s $etu$n T$ue if t!ey unde$stand t!e su'&#$otocol in t!e IRL( Retu$n t!e #$o#e$ties su##o$ted 'y t!is d$ive$( Retu$n t!e d$ive$Ks maHo$ ve$sion num'e$( 4nitially t!is s!ould 'e >( Retu$n t!e d$ive$Ks mino$ ve$sion num'e$( 4nitially t!is s!ould 'e 0(

OpenOffice.org Base

9$

Database connections

T!e connect,- met!od fo$ a d$ive$ ,see Table /&- and %et"onnectionEit!4nfo,- fo$ t!e d$ive$ mana%e$ ,see Table /3- 'ot! acce#t a IRL to t!e data'ase and an a$$ay of a$%uments( T!e su##o$ted a$%uments diffe$ 'ased on t!e data'ase and t!e d$ive$ used( Lac! d$ive$ su##o$ts t!e met!od %etP$o#e$ty4nfo,- ,see Table /&- t!at $etu$ns t!e #$o#e$ties su##o$ted 'y a s#ecific d$ive$( T!e %etP$o#e$ty4nfo,- met!od is intended to allo/ a %ene$ic =I4 tool to discove$ t!e su##o$ted #$o#e$ties and t!en #$om#t fo$ connection info$mation( T!e $etu$ned list may c!an%e de#endin% on t!e #$o#e$ties, /!ic! is /!y %etP$o#e$ty4nfo,- acce#ts an a$$ay of #$o#e$ties( +s suc!, it may 'e necessa$y to ite$ate t!ou%! seve$al calls to %etP$o#e$ty4nfo,-( T!e mac$o in Listing /1 demonst$ates t!e use of %etP$o#e$ty4nfo,- fo$ a "8S file( &lat Dri0er %rgs Ise t!e Flat Driver Args 'utton to dis#lay t!e su##o$ted a$%uments fo$ a "8S file ,see *igure "1-( Cotice t!at t!e d$ive$ dis#lays a$%uments fo$ t!e file foo(csv, /!ic! does not e6ist( T!e file name is used to find t!e d$ive$( T!e mac$o in Listing /1 does not actually o#en t!e file( Listing % . )ho/ the arguments supported by the C)0 database driver.
Sub ShowFlatDriverArgs() LoadDBLibs() Call DriverArgs("sdbc:flat:" & GetSourceCodeDir() & "foo.csv") End Sub REM The specified database is not required to exist. REM Required arguments are enclosed in parenthesis "()". REM Optional arguments are enclosed in square brackets "[]". Sub DriverArgs(sURL$) Dim oManager 'Connection driver manager. Dim oDriver 'An indiviual driver. Dim oProps() 'Supported properties. Dim oProp 'A specific property. Dim s$ 'Utility string variable. Dim i% 'Utility index variable. oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") REM Obtain a driver that supports the specified URL oDriver = oManager.getDriverByURL(sURL) If IsNull(oDriver) Then Print "Sorry, no driver available for " & sURL Exit Sub End If oProps() = oDriver.getPropertyInfo(sURL, ARRAY()) For i = LBound(oProps()) To UBound(oProps()) oProp = oProps(i) If NOT oProp.IsRequired Then s = s & "[" & oProp.Name & ", " & oProps(i).Value & ", " & _ oProps(i).Description & "]" & CHR$(10) Else s = s & "(" & oProp.Name & ", " & oProps(i).Value & ", " & _ oProps(i).Description & ")" & CHR$(10) End If Next

OpenOffice.org Base

94

Database connections MsgBox s, 0, "Properties for " & oDriver.getImplementationName() End Sub

*igure "1. +rguments for a flat file dri9er. *igure "1 s!o/s t!e #$o#e$ties su##o$ted 'y t!e flat d$ive$ fo$ a "8S file as %ene$ated 'y Listing /1( +lt!ou%! all of t!e listed #$o#e$ties a$e listed as o#tional, t!e default values fo$ some #$o#e$ties a$e not $easona'le( 9o$ e6am#le, t!e te6t se#a$ato$ and field se#a$ato$ a$e not set( T!e su##o$ted #$o#e$ties fo$ t!e data'ase d$ive$s a$e s!o/n in Table /%( Table 48. 4ocumented connection properties.
Property
+utoRet$ievin%8tatement "!a$set DecimalDelimite$ L6tension 9ieldDelimite$ 9i6edLen%t!

Description
8#ecifies t!e statement to e6ecuted /!en as.in% an inse$t statement fo$ t!e N=ene$atedResult8et inte$face( "!a$acte$ set used to fetc! data( + one c!a$acte$ delimite$ to se#a$ate t!e decimal( L6tension of t!e files to 'e usedD t6t, csv, and sdf( + one c!a$acte$ delimite$ to se#a$ate t!e fields( T$ue /!en all occu$$ences of QTQ as a #a$amete$ name /ill 'e $e#laced 'y a valid #a$amete$ name( T!is is necessa$y, 'ecause some d$ive$s mi6 t!e o$de$ of t!e #a$amete$s( T$ue /!en t!e file contains a !eade$ line ot!e$/ise false 4%no$e #$ivile%es f$om t!e data'ase d$ive$( 4f T$ue, t!e statement /ill su##o$t t!e N=ene$atedResult8et inte$face /!en it is su##o$ted in t!e futu$e( J+S+ class fo$ t!e JDJ" d$ive$( 4f T$ue, t!e #a$amete$ KTK in a #$e#a$ed statement is $e#laced /it! a distinct name( Pass/o$d fo$ t!e s#ecified use$ name( T$ue /!en deleted $o/s s!ould 'e s!o/n, ot!e$/ise false 4f T$ue, no use$ inte$action /ill 'e used /!ile c$eatin% t!e connection( + one c!a$acte$ delimite$ to se#a$ate t!e st$in%s(

Driver
JDJ", 7DJ" 7DJ", dJase, 9lat 9lat 9lat 9lat 9lat

<eade$Line 4%no$eD$ive$P$ivile%es 4s+utoRet$ievin%Lna'led JavaD$ive$"lass Pa$amete$Came8u'stitution #ass/o$d 8!o/Deleted 8ilent 8t$in%Delimite$

9lat 7DJ" JDJ" JDJ", 7DJ" JDJ" 7DJ" all dJase 7DJ" 9lat

OpenOffice.org Base

95

Database connections

Property
8ystemD$ive$8ettin%s T!ousandDelimite$ Timeout Ise"atalo% use$

Description
D$ive$ settin%s( + one c!a$acte$ delimite$ to se#a$ate t!e t!ousands( Timeout value, in seconds, to use fo$ t!is connection( 4f T$ue, t!e d$ive$ s!ould su##o$t a catalo%( Ise$ name to access t!e data'ase(

Driver
7DJ" 9lat 7DJ" 7DJ" all

4 ins#ected t!e sou$ce code and found #$o#e$ties t!at a$e not in Table /%:
+dd4nde6+##endi6 +##endTa'le+liasCame +uto4nc$ement"$eation JaseDC Joolean"om#a$isonMode "ont$olPass/o$d "ont$olIse$ Data"ac!e8i5e Data"ac!e8i5e4nc$ement Lna'le8PL92"!ec. 9i6edLen%t! <ostCame Ma6Ro/"ount CoCameLen%t!Limit Po$tCum'e$ Pa$amete$Came8u'stitution 8!utdo/nData'ase 8u##$essSe$sion"olumns Ise8c!ema4n8elect Ise"atalo%4n8elect

8...1. 3elimited te1t files


T!e flat file d$ive$ #$ovides $ead&only connections to te6t files( T!e most #o#ula$ te6t file fo$mat is t!e "8S ,"omma&8e#a$ated Salues- file( + "8S file contains t!e values fo$ a sin%le ta'le as a se$ies of +8"44 te6t lines o$%ani5ed so t!at eac! column value is se#a$ated 'y a delimite$O usually a comma, semicolon, o$ ta'Of$om t!e ne6t columnKs value and eac! $o/ sta$ts a ne/ line( T!e mac$o in Listing /" o#ens a connections to a "8S file, ins#ects t!e connectionKs meta& data, and t!en $eads all of t!e data in t!e file( Listing %2. "ead a C)0 file1 print the meta-data and the data.
REM sDir - Path, as a URL, to the database file. REM sFile - File name without the file extension; also the table name. REM sExt - File extension, probably csv. Sub ReadCSVData(sDir$, sFile$, sExt$) Dim oManager 'Connection driver manager. Dim oDriver 'An indiviual driver. Dim sURL$ 'DB URL including "sdbc:flat:..." Dim oCon 'Connection object. Dim sSQL$ 'SQL that is executed. Dim oResult 'Result from an SQL statement. Dim oStatement 'A created statement that can execute SQL. Dim oDoc 'Calc document that will contain the presentation data. Dim oData1() 'Generic data variable. Dim oParms() As New com.sun.star.beans.PropertyValue sFile = sFile sExt = sExt sURL = "sdbc:flat:" & sDir & sFile & "." & sExt REM Obtain a driver that supports the specified URL oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") oDriver = oManager.getDriverByURL(sURL) OpenOffice.org Base 96

Database connections If IsNull(oDriver) Then Print "Sorry, no driver available for a " & sExt & " file" Exit Sub End If REM Assume that there is AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), a header line! "Extension", sExt) "HeaderLine", True) "FieldDelimiter", ",") "StringDelimiter", """") "DecimalDelimiter", ".") "ThousandDelimiter", ",")

oCon = oManager.getConnectionWithInfo(sURL, oParms()) oDoc = InspectMetaData(oCon.getMetaData()) oStatement = oCon.CreateStatement() sSQL = "SELECT * FROM " & DBQuoteName(sFile, oCon) oResult = oStatement.executeQuery(sSQL) ResultSetToData(oResult, oDoc, "SELECT *", oData1()) AppendDataToCalcDoc(oDoc, oData1()) oCon.close() End Sub

Ise t!e Read CSV Data 'utton to call t!e mac$o in Listing /'( 9i$st, you must select an e6istin% "8S file( T!e mac$o /ill o#en a ne/ "alc document and t!en fill t!e "alc document /it! #$o#e$ties f$om t!e meta data, follo/ed 'y t!e data in t!e "8S file(
,ea) CS1 Data

Listing %3. 2rompt for a C)0 file1 and then display the data.
Sub CallReadCSVData() Dim oFilters() Dim sFile$ Dim sURL$ Dim sExt$ Dim sDir$ REM Load my libraries.y LoadDBLibs() REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If REM List .csv first so it will be used by default. oFilters() = Array("*.csv Flat files", "*.csv", "All Files", "*.*") sURL = ChooseAFile$(oFilters(), True) If sURL = "" Then Exit Sub REM Call methods in the Tools library to parse the path. sExt = GetFileNameExtension(sURL) sFile = GetFileNameWithoutExtension(sURL, "/") OpenOffice.org Base 97

Database connections sDir = DirectoryNameoutofPath(sURL, "/") & "/" REM Now, display the meta-data and the regular data. ReadCSVData(sDir$, sFile$, sExt$) End Sub

T!e data'ase d$ive$ may c!oose to conve$t ta'le and column names to u##e$ case and t!en fail 'ecause t!e names a$e not in mi6ed o$ lo/e$&case( Puote t!e ta'le and column names to avoid t!is #$o'lem( T!e 3uote st$in% may 'e diffe$ent fo$ eac! d$ive$( T!e mac$o in Listing && uses t!e 3uote st$in% f$om t!e connection meta&data to safely 3uote identifie$s( Lac! flat file contains a sin%le ta'le( T!e name of t!e ta'le is t!e name of t!e file /it!out t!e file e6tension( 4f t!e <eade$Line #$o#e$ty is T$ue, t!e column names a$e set 'ased on t!e fi$st $o/ of data( 4f t!e <eade$Line #$o#e$ty is 9alse, !o/eve$, t!e columns names default to t!e lette$ " follo/ed 'y t!e column num'e$D ">, "2, " , "4(
TIP
T!e ta'le name in a flat file is t!e 'ase file name( 4f t!e fi$st $o/ does not contain t!e column names, t!en t!e columns default to ">, "2, " ( 4t is al/ays #ossi'le to $et$ieve columns 'ased on its inde6( 4 dete$mined t!is 'y ins#ectin% t!e meta data f$om t!e connection( T!is is t!e same /ay t!at 4 dete$mined t!e ta'le names in a "alc document( 4ns#ectin% t!e meta data f$om t!e connection is a ve$y enli%!tenin% e6#e$ience(

8... . 4i1ed widt% te1t files


9i6ed /idt! te6t files a$e f$e3uently called 8D9 ,8ystem Data 9o$mat-( +n 8D9 file is an +8"44 te6t file in /!ic! $eco$ds !ave a fi6ed len%t! and end /it! a ca$$ia%e $etu$n and line feed( +lt!ou%! t!e 8D9 file fo$mat is mentioned in t!e develo#e$Ks %uide as a su##o$ted fo$mat, 4 !ave only 'een a'le to $ead fi6ed te6t files 'y usin% t!e "8S file e6tension( 9ields a$e not delimited( Info$tunately, fi6ed /idt! files can not 'e o#ened di$ectly as a data'ase connection(
TIP
77o uses t!e 8D9 e6tension fo$ files out#ut f$om t!e locali5ation tools( T!e locali5ation files a$e also sometimes la'eled =84D =84 is s!o$t fo$ F=utsc!midt inventedG afte$ t!e invento$ of t!e fo$mat( T!e 8D9 locali5ation files a$e not fi6ed /idt! te6t files(

4t is #ossi'le to o#en fi6ed /idt! data into a "alc document usin% t!e FTe6t & t6t & csv ,8ta$"alc-G im#o$t*e6#o$t filte$( T!e "alc document can t!en 'e used as t!e data sou$ce( 9o$ "alc to $eco%ni5e a flat file, t!e file e6tension must 'e "8S( Listing // is a code sni##et t!at /ill im#o$t a fi6ed /idt! te6t file( Listing %%. Import a fixed /idth text file.
Dim args(1) as new com.sun.star.beans.PropertyValue args(0).Name = "FilterName" args(0).Value = "Text - txt - csv (StarCalc)" args(1).Name = "FilterOptions" args(1).Value = "FIX,34,0,1,0/1/10/2/30/10" sURL = GetSourceCodeDir() & "fix_len.csv" oDoc = StarDesktop.LoadComponentFromUrl(sURL, "_blank", 0, args())

OpenOffice.org Base

98

Database connections

T!e 9ilte$7#tions a$%ument di$ects t!e im#o$tin% and e6#o$tin% of data t!$ou%! t!e "alc "8S filte$( T!e fo$mat of t!e a$%ument is s!o/n in Listing /#( Lac! o#tion is se#a$ated 'y a comma( T!e fi$st o#tion dete$mines if t!e "8S file is a fi6ed /idt! file o$ a delimited file ,see Table /$-( Listing %&. 3ilter options for 45ext - txt - csv 6)tarCalc78 filter.
field_separator,text_delimiter,character_set,first_line,field_specifier

Table /$. 1nitial arguments for the ETe7t : t7t : cs9 B(tarCalcCF filter.
#
>

Name
field se#a$ato$ te6t delimite$

Description
T!e +8"44 value of t!e field se#a$ato$( 4f multi#le se#a$ato$s a$e used, se#a$ate t!em /it! a slas!( 9o$ e6am#le, 44*9 indicates t!at a comma o$ a ta' can se#a$ate eac! field( Ise t!e te6t F94NG fo$ fi6ed /idt! fields( +8"44 value of t!e te6t delimite$( 4n a "8S file, t!e te6t #o$tions a$e usually su$$ounded 'y eit!e$ dou'le 3uotation ma$.s ,Q- o$ sin%le 3uotation ma$.s ,K-( To $eco%ni5e multi#le delimite$s, se#a$ate t!em /it! a slas!D fo$ e6am#le 4* 9 s#ecifies 'ot! a dou'le and a sin%le 3uote( Cume$ic inde6 t!at identifies /!ic! c!a$acte$ set to use( T!e value of 0 $e#$esents t!e system c!a$acte$ set( T!is mi%!t also 'e called t!e code #a%e( 9i$st line to im#o$t( T!e value > indicates t!e fi$st line( T!e value 2, causes t!e fi$st column to 'e i%no$ed( T!e field s#ecifie$ identifies t!e columns o$ fields to im#o$t(

c!a$acte$ set 4 5 fi$st line field s#ecifie$

4f t!e filte$ o#tions sta$t /it! a field se#a$ato$, t!en t!e field s#ecifie$ is in t!e fo$mat s!o/n in Listing /3( T!e fieldMnum is an inte%e$ t!at identifies a field, /!e$e > is t!e leftmost field( 9o$ e6am#le, %iven t!e fields FoneG, Ft/oG, and Ft!$eeG, a fieldMnum of 2 $efe$s to Ft/oG( T!e fo$mat is an inte%e$ t!at identifies t!e fo$mat of t!e field ,see Table #5-( Listing %'. ,elimited-text-format string for the C)0 filter.
field_num/format/field_num/format/field_num/format/...

4f t!e filte$ o#tions sta$t /it! t!e te6t F9i6G, as is s!o/n in Listing //, t!en t!e field s#ecifie$ is in t!e fo$mat s!o/n in Listing /&( T!e column value s#ecifies t!e fi$st c!a$acte$ in a field( + column of 0 $efe$s to t!e leftmost c!a$acte$ of t!e te6t( T!e fo$mat is an inte%e$ t!at identifies t!e fo$mat of t!e te6t ,see Table #5-( Listing %-. ,elimited-text-format string for the C)0 filter.
column/format/column/format/column/format/...

Table #5. C(, field format 9alues.


Format
> 2 4 5 9

Description
8tanda$d fo$mat allo/s t!e im#o$t filte$ to %uess t!e ty#e( Te6t MM*DD*)) DD*MM*)) ))*MM*DD Do not im#o$tD i%no$e t!is field(

OpenOffice.org Base

99

Database connections

Format
>0

Description
4m#o$t a num'e$ fo$matted in t!e I8&Ln%lis! locale $e%a$dless of t!e locale(

To access a fi6ed /idt! te6t file usin% a data'ase connection, o#en t!e file as a "alc document and t!en eit!e$ access t!e "alc document as a data'ase, o$ e6#o$t t!e data as a delimited file and t!en o#en t!e connection to t!e delimited te6t file( T!e mac$o in Listing /& demonst$ates !o/ to $ead a fi6ed /idt! te6t file 'y t$ansfo$min% t!e file to a "alc document and a delimited "8S file as follo/s: >- "$eate t!e fi6ed /idt! data file delme>(csv( 2- T!e fi6ed /idt! data is im#o$ted into a "alc document usin% t!e "8S im#o$t filte$( - T!e "alc document is saved as a "alc document ,delme>(ods-( 4- T!e "alc document is e6#o$ted to a delimited "8S file( 5- + connection is c$eated to t!e delimited file( ?- + connection is made to t!e "alc document( B- T!e c$eated files a$e deleted(
,ea) &i+e) 2i)t( &ile

Ise t!e 'utton Read Fixed )idth File to c$eated and $ead t!e

fi6ed /idt! files( Listing %.. Created and read fixed /idth files and a Calc document.
Sub ReadFixedWidthFile() Dim sFileName$ 'The base file name. Dim n As Integer 'The file number. Dim i As Integer 'General index variable. Dim s As String 'Temporary string. Dim sURLInitial$ 'URL of the CSV file. Dim sURLCalc$ 'URL of the Calc document. Dim sOut() 'Output text initially written to the CSV file. Dim oManager 'Connection driver manager. Dim oCon 'Connection object. Dim sSQL$ 'SQL that is executed. Dim oResult 'Result from an SQL statement. Dim oStatement 'A created statement that can execute SQL. Dim oDoc 'Calc document used to read the fixed width data. Dim oParms() As New com.sun.star.beans.PropertyValue REM REM REM REM REM First, create the following text file: Date Name Number 01/01/05Danny Bot 17 12/25/99Shelly Girt13 03/13/65Fred Krank 7

sOut() = Array("Date Name Number", _ "01/01/05Danny Bot 17", _ "12/25/99Shelly Girt13", _

OpenOffice.org Base

!""

Database connections "03/13/65Fred Krank 7 ") sFileName = "delme1" sURLInitial = GetSourceCodeDir() & sFileName & ".csv" n = FreeFile() 'Next free file number REM Open for read/write Open sURLInitial For Output Access Read Write As #n For i = 0 To UBound(sOut()) Print #n, sOut(i) Next Close #n REM Open the fixed width text file into a Calc document. AppendProperty(oParms(), _ "FilterName", "Text - txt - csv (StarCalc)") AppendProperty(oParms(), "FilterOptions", "FIX,34,0,1,0/3/8/2/19/10") oDoc = StarDesktop.LoadComponentFromUrl(sURLInitial, "_blank", _ 0, oParms()) REM Save the document as a Calc document! ReDim oParms() AppendProperty(oParms(), "Overwrite", "True") sURLCalc = GetSourceCodeDir() & sFileName & ".ods" oDoc.storeAsURL(sURLCalc, oParms()) REM Delete the initial fixed width file. Kill(sURLInitial) REM Write the file as a comma delimited text file. Notice that only the REM text columns contain the double quote text delimiter. REM "Date","Name","Number" REM 01/01/2005,"Danny Bot",17 REM 12/25/1999,"Shelly Girt",13 REM 03/13/1965,"Fred Krank",7 ReDim oParms() AppendProperty(oParms(), _ "FilterName", "Text - txt - csv (StarCalc)") AppendProperty(oParms(), "FilterOptions", "44,34,0,1,1/1/2/2/3/10") oDoc.storeAsURL(sURLInitial, oParms()) oDoc.close(True) oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") REM Open the CSV file. REM Notice that I the header line is ignored. REM If the header line is NOT ignored, then all REM columns are recognized as type VarChar. ReDim oParms() AppendProperty(oParms(), "Extension", "csv") AppendProperty(oParms(), "HeaderLine", True)

OpenOffice.org Base

!"!

Database connections AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), AppendProperty(oParms(), "FieldDelimiter", ",") "StringDelimiter", """") "DecimalDelimiter", ".") "ThousandDelimiter", ",")

oCon = oManager.getConnectionWithInfo("sdbc:flat:" & _ sURLInitial, oParms()) oStatement = oCon.CreateStatement() sSQL = "SELECT * FROM " & DBQuoteName(sFileName, oCon) oResult = oStatement.executeQuery(sSQL) Do While oResult.next() s = s & "CSV File: Date = " & _ CStr(UNODateToDate(oResult.getDate(1))) & _ " Name = '" & oResult.getString(2) & "'" & _ " Number = " & CStr(oResult.getLong(3)) & CHR$(10) Loop oCon.close() oCon = oManager.getConnection("sdbc:calc:" & sURLCalc) oStatement = oCon.CreateStatement() sSQL = "SELECT * FROM " & DBQuoteName(sFileName, oCon) oResult = oStatement.executeQuery(sSQL) s = s & CHR$(10) Do While oResult.next() s = s & "Calc File: Date = " & _ CStr(UNODateToDate(oResult.getDate(1))) & _ " Name = '" & oResult.getString(2) & "'" & _ " Number = " & CStr(oResult.getLong(3)) & CHR$(10) Loop oCon.close() MsgBox s, 0, "Data from the flat file" REM Delete the created files. Kill(sURLCalc) Kill(sURLInitial) End Sub

TIP

4t is ve$y im#o$tant t!at you use t!e co$$ect filte$ name( E!en 4 used Fscalc: Te6t & t6t & csv ,8ta$"alc-G, $at!e$ t!an FTe6t & t6t & csv ,8ta$"alc-G( T!e mac$o /o$.ed fine on one com#ute$, 'ut on t!e ot!e$ com#ute$, t!e "8S file loaded into a te6t document $at!e$ t!an a "alc documentOt!an.s to Paolo Mantovani fo$ #$ovidin% t!e co$$ect solution(

*igure "" demonst$ates t!at t!e data $ead f$om t!e "alc document is t!e same as t!e data $ead f$om t!e "8S file(

OpenOffice.org Base

!"#

Database connections

*igure "". The C(, and Calc files contain the same data. 4t is easie$ to im#o$t a "alc document t!an a delimited te6t file( T!e$efo$e, 4 $ecommend t!at you $ead fi6ed /idt! data files as "alc documents $at!e$ t!an delimited files( T!e flat file data'ase connection %uesses t!e column ty#es 'ased on data in t!e fi$st $o/( 4f t!e !eade$ is included /it! t!e "8S file, t!en all fields a$e conside$ed te6t fields( T!e "alc "8S im#o$t filte$ allo/s you to s#ecify t!e data ty#es( +lso, connections to "alc documents do not $e3ui$e connection a$%uments(

8...'. >elp? I still can not import my C!= file


4t can 'e difficult to o'tain t!e co$$ect values to o#en a "8S file( T!e most common #$o'lems a$e: >- T!e file e6tension must 'e F(csvGD you can not o#en a F(t6tG file into a calc document as a comma delimited file( 2- Isin% t!e /$on% filte$ name( - Dete$minin% t!e co$$ect c!a$acte$ set, sometimes $efe$$ed to as t!e code #a%e ,see Table #1-( 4- Dete$minin% t!e co$$ect field /idt!s( 4f you do not .no/ t!e c!a$acte$ set, t$y some of t!e values s!o/n in Table #1( 4 am li.ely to t$y 0, ?55 5, and t!en >252( Table #1. Character sets for use with C(, import.
Character Set
0 ?55 5 4 B 850 85> >252 >250

Comment
T!e system c!a$acte$ set f$e3uently /o$.s ,tested-( Inicode is ve$y #o#ula$ t!ese days ,tested-( 7$i%inal D78 Latin c!a$acte$ set,not tested-( D78 Latin > ,not tested-( Dos Latin 2 ,not tested-( Eindo/s Latin > ,not tested-( Eindo/s Latin 2 ,not tested-(

OpenOffice.org Base

!"$

Database connections

4f you still !ave difficulties, t$y im#o$tin% t!e file usin% t!e =I4 and t!en ins#ect t!e document to see /!ic! im#o$t a$%uments /e$e used( Listing %9. Inspect document arguments.
Sub InspectDocArgs Dim args() Dim x, i%, s$ args() = ThisComponent.getArgs() On Error Resume Next For i = LBound(args()) To UBound(args()) x = args(i) s = s & x.Name & " : " s = s & CStr(x.Value) s = s & CHR$(10) Next MsgBox s End Sub

+fte$ ins#ectin% t!e a$%uments ,see Listing /$-, you can see t!e filte$ and t!e filte$ a$%uments ,see *igure "'-( 4f you can fi%u$e out !o/ to im#o$t t!e document usin% t!e =I4, you s!ould 'e a'le to im#o$t t!e file f$om a mac$o(

*igure "': +rguments from a C(, file.

OpenOffice.org Base

!"4

Database connections

8...+. Address books


T!e add$ess 'oo. connection #$ovides access to Mo5illa, 7utloo., 7utloo. L6#$ess, and LD+P add$ess 'oo.s( T!e mac$o in Listing #5 demonst$ates !o/ to $ead t!e names and email add$esses su##o$ted 'y t!e local 7utloo. add$ess 'oo.( Lac! add$ess 'oo. ty#e ,see Table /#- im#lements a diffe$ent set of ta'les and columns( 4 ins#ect t!e connection meta&data to dete$mine t!e name of t!e ta'les and su##o$ted columns( T!e 7utloo. add$ess 'oo. uses t!e F 7P "ontactsG ta'le, and t!e Mo5illa add$ess 'oo. !as t/o ta'les, FPe$sonal +dd$ess 'oo.G and F"ollected +dd$essesG( 3nspect O-tloo4 %))resses 4 c!ec.ed t!is mac$o on a /indo/s com#ute$ and it dis#layed t!e email add$esses t!at 4 #e$sonally added, not t!e %lo'al add$esses( Listing &0. Inspect an #utloo9 address boo9.
Sub InspectOutlookAddress() Dim oManager 'Connection driver manager. Dim oCon 'Connection object. Dim sSQL$ 'SQL that is executed. Dim oResult 'Result from an SQL statement. Dim oStatement 'A created statement that can execute SQL. Dim s$ 'General string variable. Dim nCount& oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") oCon = oManager.getConnection("sdbc:address:outlook:") oStatement = oCon.CreateStatement() sSQL = "SELECT " & DBQuoteName("First Name", oCon) & ", " &_ DBQuoteName("Last Name", oCon) & ", " & _ DBQuoteName("E-mail", oCon) & " FROM " & _ DBQuoteName("OP Contacts", oCon) oResult = oStatement.executeQuery(sSQL) REM Limit the returned values to 50! nCount = 0 Do While oResult.next() AND nCount < 50 s = s & oResult.getString(1) & " " & oResult.getString(2) & _ " ==> " & oResult.getString(3) & CHR$(10) Loop MsgBox s, 0, "Public e-mail" oCon.close() End Sub

8...-. My!)* using @3BC


"onnectin% to a My8PL data'ase usin% JDJ" is easy if you .no/ #$o#e$ connection IRL( T!e mac$o in Listing #1 connects to a t!e Fstam#sG My8PL data'ase $unnin% on my local com#ute$ ,local !ost- usin% t!e default #o$t , 0?-( 8ettin% t!e Java d$ive$ class #$o#e$ty is o#tional and it defaults to com(mys3l(Hd'c(D$ive$( Listing & . Connect to a +y)*L database using :,$C.
sUser$ = "user" sPass$ = "password"

OpenOffice.org Base

!"5

Database connections sURL$ = "sdbc:mysql:jdbc:localhost:3306/stamps"

oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") AppendProperty(oParms(), "user", sUser) AppendProperty(oParms(), "password", sPass) AppendProperty(oParms(), "JavaDriverClass", "com.mysql.jdbc.Driver") oCon = oManager.getConnectionWithInfo(sURL, oParms())

TIP

Listing #1 assumes t!at Java is installed, t!e JDJ" d$ive$ is installed, and t!e 7#en7ffice(o$% !as 'een #$o#e$ly confi%u$ed to use t!e d$ive$(

8..... Parado1 using O3BC


7DJ" ,7#en DataJase "onnectivity-, #$onounced as se#a$ate lette$s, is a standa$d data'ase access met!od develo#ed in >992 'y t!e 8PL +ccess %$ou#( 7DJ" is a middle laye$ 'et/een a DJM8 ,data'ase mana%ement system- and an a##lication( 7DJ" t$anslates data 3ue$ies into commands t!at t!e DJM8 unde$stands( 8DJ" .no/s !o/ to tal. to an 7DJ" data sou$ce( +n 7DJ" data sou$ce must 'e $e%iste$ed 'efo$e it can 'e used( Ise t!e 7DJ" Data 8ou$ce +dminist$ato$ to add and confi%u$e an 7DJ" data sou$ce on Eindo/s( Ise t!e cont$ol #anel ,8ta$t ] 8ettin%s ] "ont$ol Panel- to o#en t!e "ont$ol Panel( Eit! Mic$osoft Eindo/s 2000 o$ ne/e$, use +dminist$ative Tools ] Data 8ou$ces ,7DJ"- to o#en t!e 7DJ" Data 8ou$ce +dminist$ato$ ,see *igure "/-( 9o$ olde$ ve$sions of Eindo/s, use 2&'it 7DJ" o$ 7DJ"(

OpenOffice.org Base

!"6

Database connections

*igure "/. !4BC data sources on ;indows A0 0rofessional. 4 used 7DJ" to connect to a set of e6istin% Pa$ado6 ta'les( 4 /as ve$y !a##y to find out t!at Eindo/s NP P$ofessional came /it! d$ive$s fo$ Pa$ado6, and many ot!e$ data'ase systems, al$eady installed( T!e mac$o in Listing #" connects to t!e defined PD7N data sou$ce and accesses t!e "7ICTR) ta'le( Listing &2. Connect to a 2aradox database using #,$C.
Sub UsePDoxODBC Dim oManager Dim sURL$ Dim oCon Dim sSQL$ Dim oResult Dim oStatement Dim oDoc Dim oData() Dim s$ 'Connection driver manager. 'DB URL including "sdbc:flat:..." 'Connection object. 'SQL that is executed. 'Result from an SQL statement. 'A created statement that can execute SQL. 'Calc document that will contain the presentation data. 'Generic data variable. 'General utility string.

sURL = "sdbc:odbc:PDOX" oManager = CreateUnoService("com.sun.star.sdbc.DriverManager") oCon = oManager.getConnection(sURL) oStatement = oCon.CreateStatement() sSQL = "SELECT * FROM " & DBQuoteName("COUNTRY", oCon) oResult = oStatement.executeQuery(sSQL) Do While oResult.next() s = s & oResult.getString(1) & " " & oResult.getString(2) & CHR$(10) Loop

OpenOffice.org Base

!"7

Database connections oCon.close() MsgBox s End Sub

8...7. Conclusion
Dete$minin% t!e connection IRL is #$o'a'ly t!e most difficult #a$t of connectin% to an e6te$nal data'ase( 4 f$e3uently c$eate a connection and t!en ins#ect t!e meta data to dete$mine t!e fo$mat of t!e IRL( T!is c!a#te$ #$ovides sufficient info$mation to connect to a data'ase and sets t!e sta%e fo$ mo$e advanced a##lications(

OpenOffice.org Base

!"8

;. Connecting to My!)* using @3BC


To connect to My8PL usin% JDJ", Java must 'e installed on you$ com#ute$( 9$om 77o, use Tools > ,'tions > ,'en,$$ice-org > 0ava to o#en t!e Java ta' of t!e o#tions dialo%( Se$ify t!at a Java $untime envi$onment is confi%u$ed fo$ use /it! 7#en7ffice(o$%( 4f Java is not installed, visit !tt#:**Hava(sun(com* to do/nload and install Java( 4 installed J28L 5(0, /!ic! is sometimes $efe$$ed to as ve$sion >(5( Develo#e$s usually install t!e JDW ,Java Develo#ment Wit- ve$sion so t!at t!ey can c$eate soft/a$e usin% Java( Con&develo#e$s, !o/eve$, usually install t!e JRL ,Java Runtime Lnvi$onment- ve$sion 'ecause it is smalle$ and t!ey do not $e3ui$e t!e develo#e$ tools( +fte$ installin% Java, you may need to $esta$t 77o so t!at it can $eco%ni5e Java( Do/nload t!e latest JDJ" d$ive$ f$om !tt#:**///(mys3l(comD t!e main My8PL /e' #a%e( 9$om t!e main My8PL #a%e, clic. Products > Connectors > +!S%& Connector10 to o#en t!e JDJ" do/nload #a%e( 8elect and do/nload an a##$o#$iate d$ive$( In#ac. t!e d$ive$ usin% a 5i# o$ ta$ utility and ma.e a note of /!e$e you #laced t!e d$ive$( )ou must set t!e class #at! so t!at 77o can find t!e My8PL JDJ" d$ive$s( "lic. t!e "lass Pat! 'utton, f$om t!e Java o#tions #a%e, to o#en t!e "lass Pat! dialo%( "lic. t!e +dd 9olde$ 'utton to add t!e di$ecto$y containin% t!e JDJ" d$ive$( )ou must $esta$t 7#en7ffice(o$% 'efo$e t!e ne/ class #at! /ill 'e $eco%ni5ed( Ise File > New > Database to sta$t t!e Data'ase Ei5a$d( 8elect "onnect to an e6istin% data'ase and c!oose t!e My8PL Data'ase ty#e( "lic. Ce6t to setu# t!e My8PL connection( "!oose t!e JDJ" connecto$ and clic. Ce6t to setu# t!e JDJ" connection( 4n My8PL, you connect to a data'ase, /!ic! is collection of ta'les( T!e JDJ" connection in *igure "# is confi%u$ed to connect to t!e stam#s data'ase on t!e cu$$ent com#ute$ usin% t!e default #o$t(

Figure 25. Configure and test the JDBC connection. T!e default JDJ" d$ive$ is com(mys3l(Hd'c(D$ive$( "lic. t!e Test class 'utton to ve$ify t!at t!e JDJ" d$ive$ can 'e loaded( 4f t!e d$ive$ can not 'e loaded, ve$ify t!at t!e class #at! is #$o#e$ly confi%u$ed in 77o( "lic. Ce6t to setu# use$ aut!entication

OpenOffice.org Base

!"9

onnecting to MyS!" #sing $DB

Lnte$ t!e use$ name and c!oose to use a #ass/o$d if $e3ui$ed( "lic. t!e Test "onnection 'utton to ve$ify t!at a connection can 'e made to t!e data'ase usin% t!e confi%u$ed #a$amete$s( )ou /ill 'e #$om#ted fo$ t!e #ass/o$d, if one is $e3ui$ed( To connect to a My8PL data'ase, t!e My8PL se$ve$ must 'e $unnin%( "lic. Ce6t to move to t!e final dialo% in t!e Data'ase Ei5a$d( )ou do not need to $e%iste$ t!e data'ase unless you /ant to $efe$ence t!e data sou$ce 'ased on a name $at!e$ t!an usin% t!e IRL of t!e Data'ase document( "lic. t!e 9inis! 'utton to finis! and save t!e document( 4 c!ose to save t!e document usin% t!e name 8tam#sJDJ"( 77o contains a dedicated My8PL*JDJ" '$id%e, /!ic! !andles ce$tain My8PL #eculia$ities suc! as #a$amete$ !andlin%( T!e connection $etu$ned f$om t!e =I4 uses t!e s#ecial My8PL connection( E!ile usin% t!e connection mana%e$ in a mac$o, !o/eve$, you must 'e ce$tain to s#ecify t!e co$$ect ty#e ,see Listing #1-( T!e Qsd'c:mys3l:Hd'c:local!ost: 0?*stam#sQ connection st$in% uses t!e 8DJ" My8PL d$ive$, /!ic! is t!e desi$ed connection( Isin% QHd'c:mys3l:**local!ost: 0?*stam#sQ, uses a standa$d JDJ" connection, t!at does not contain t!e Fs#ecial sauceG, so to s#ea.(
TIP
+l/ays use Fsd'c:mys3l:Hd'cG $at!e$ t!an FHd'c:mys3lG(

OpenOffice.org Base

!!"

1<. Mailmerge
TT 4nse$t content f$om c!a#te$ >0 as it is( +lso, use t!e ne/ me$%e to email ca#a'ility in 2(0>(

OpenOffice.org Base

!!!

11. Copying an entire database


T!e$e is an e6am#le !e$e: !tt#:**///(ooofo$um(o$%*fo$um*vie/to#ic(#!tmlT tU22858^vie/U#$evious

OpenOffice.org Base

!!#

1 . &eneral utility macros


T!is section int$oduces %ene$al utility mac$os and esta'lis!es t!e foundation on /!ic! t!e data'ase $elated mac$os a$e 'uilt( Many inte$estin% and useful mac$os t!at a$e not di$ectly $elated to data'ase #$o%$ammin% a$e used in t!is document( T!e mac$os also demonst$ate some useful #$o%$ammin% tec!ni3ues( Mac$os a$e conside$ed an advanced to#ic t!at a$e an a'solute necessity fo$ some and neve$ $e3ui$ed fo$ ot!e$s( T!e mac$o cove$a%e in t!is 'oo. assumes a /o$.in% .no/led%e of mac$os so no #$elimina$y mac$o info$mation is discussed( 9o$ mo$e info$mation on mac$o #$o%$ammin%, see my 'oo. F7#en7ffice(o$% Mac$os L6#lained(G 77o su##o$ts diffe$ent documents ty#es suc! as E$ite$ ,te6t document- and "alc ,s#$eads!eet document-( Lac! uni3ue document ty#e su##o$ts at least one se$vice t!at is su##o$ted only 'y t!at document ty#e ,see Table #"-( )ou can dete$mine t!e ty#e of document 'y c!ec.in% if it su##o$ts one of t!ese se$vices( Table #". *ields in the binary table.
Doc"ment Type
D$a/in% E$ite$ E$ite$*Ee' Maste$ Document "alc Mat! P$esentation ,4m#$essData'ase ,Jase-

Service
com(sun(sta$(d$a/in%(D$a/Document com(sun(sta$(te6t(Te6tDocument com(sun(sta$(te6t(Ee'Document com(sun(sta$(te6t(=lo'alDocument com(sun(sta$(s!eet(8#$eads!eetDocument com(sun(sta$(fo$mula(9o$mulaP$o#e$ties com(sun(sta$(#$esentation(P$esentationDocument com(sun(sta$(sd'(Data'aseDocument

+ Data'ase document im#lements t!e Data'aseDocument se$vice( T!e mac$o in Listing #' c!ec.s to see if t!e va$ia'le oDoc $efe$ences a data'ase document( Listing #': Chec8 if o4oc references a database document.
If oDoc.supportsService("com.sun.star.sdb.DatabaseDocument") Then

Inli.e ot!e$ document ty#es, a data'ase document can not contain mac$os, /!ic! is #$o'a'ly /!y T!is"om#onent is not set to $efe$ence a data'ase document( To o'tain t!e cu$$ently focused com#onent, includin% a data'ase document, use t!e %et"u$$ent"om#onent,- met!od of t!e des.to# o'Hect ,see Listing #/-( T!is"om#onent $efe$ences t!e most $ecently focused document t!at is not a data'ase document( Info$tunately, %et"u$$ent"om#onent,- also $etu$ns com#onents suc! as t!e Jasic 4DL( Listing #/: =et the current component and ThisComponent.
oDoc = ThisComponent oComp = StarDesktop.getCurrentComponent()

TIP

Late$ ve$sions of 7#en7ffice(o$% may allo/ data'ase documents to contain mac$os( +lso, in futu$e ve$sions, T!is"om#onent may 'e set to $efe$ence a data'ase documentD until t!en, you

OpenOffice.org Base

!!$

%eneral #tility macros

need to use %et"u$$ent"om#onent,-(

12.1. Choose a directory


T!e Pat!8ettin%s se$vice #$ovides an easy met!od to %et t!e use$Ks document di$ecto$y( 2or4 Directory Ise t!e )or2 Director! 'utton to #$int you$ /o$.in% di$ecto$y( Listing ##: =et the userGs document directory from the 0ath(ettings ser9ice.
Function GetWorkDir() As String Dim oPathSettings oPathSettings = CreateUnoService("com.sun.star.util.PathSettings") GetWorkDir() = oPathSettings.Work End Function

T!e 9olde$Pic.e$ se$vice $etu$ns a dialo% to select di$ecto$ies( T!e actual se$vice t!at is $etu$ned de#ends on t!e o#e$atin% system and o#tions s#ecified in t!e 7#tions dialo%( Ise C(oose Directory t!e Choose Director! 'utton to call t!e mac$o in Listing #3D t!e sta$tin% di$ecto$y s!ould 'e you$ /o$. di$ecto$y(
Caution
4n 77o ve$sion 2(0, t!e Ein 29olde$Pic.e$ !as a 'u%, /!ic! #$events you f$om settin% t!e initial di$ecto$y( Ise Tools > ,'tions > ,'en,$$ice-org > 3eneral to o#en 7#tions dialo%, and t!en c!ec. t!e 6se !pen!ffice.org 4ialogs c!ec.'o6( Ja$in% t!at, you can e6#licitly use t!e 7ffice9olde$Pic.e$ se$vice $at!e$ t!an t!e 9olde$Pic.e$ se$vice(

Listing #3: (elect a directory.


REM sInPath specifies the initial directory. If the initial directory REM is not specified, then the user's default work directory is used. REM The selected directory is returned as a URL. Function ChooseADirectory(Optional sInPath$) As String Dim oDialog As Object Dim oSFA As Object Dim s As String Rem You can also use com.sun.star.ui.dialogs.OfficeFolderPicker oDialog = CreateUnoService("com.sun.star.ui.dialogs.FolderPicker") oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess") If IsMissing(sInPath) Then oDialog.setDisplayDirectory(GetWorkDir()) ElseIf oSFA.Exists(sInPath) Then oDialog.setDisplayDirectory(sInPath) Else s = "Directory '" & sInPath & "' Does not exist" If MsgBox(s, 33, "Error") = 2 Then Exit Function End If If oDialog.Execute() = 1 Then ChooseADirectory() = oDialog.getDirectory()

OpenOffice.org Base

!!4

%eneral #tility macros End If End Function

12.2. 8et a document9s directory


Many of t!e mac$os in t!is document assume t!at t!e /o$.in% di$ecto$y is t!e di$ecto$y t!at contains t!is document( T!e mac$o in Listing #& demonst$ates !o/ to o'tain t!e di$ecto$y #o$tion of a IRL( 5rint Doc Dir Ise t!e Print Doc Dir 'utton to call t!e mac$o in Listing #&( Listing #&: (elect a directory.
REM Determine the directory used by this document. REM It is assumed that the rest of the interesting data files REM are in the same directory. REM Returns the document's directory as a URL with a trailing "/". Function GetSourceCodeDir(Optional useDoc) As String Dim oDoc 'The document on which to work. Dim s$ 'Temporary string variable. If NOT IsMissing(useDoc) Then oDoc = useDoc End If If IsEmpty(oDoc) OR IsNull(oDoc) Then oDoc = ThisComponent End If If oDoc.hasLocation() Then GlobalScope.BasicLibraries.LoadLibrary("Tools") REM This is assumed to be in URL notation! s = DirectoryNameoutofPath(oDoc.getLocation(), "/") GetSourceCodeDir() = s & "/" Else Print "Warning, current document has no location" End If End Function

12.3. Choose a !ile


Ise t!e 9ilePic.e$ se$vice to select a file( T!e$e a$e many confi%u$a'le o#tions fo$ settin% t!e default 'e!avio$ usin% Tem#lateDesc$i#tion constants( 4f t!e o#tional in#ut #at! is set and contains a file name, t!en t!at file name is selected 'y default( Listing #%: (elect a file.
REM sInPath specifies the initial directory. If the initial directory REM is not specified, then the user's default work directory is used. REM The selected file is returned as a URL. Function ChooseAFile$(sFilters(), bOpen As Boolean, Optional sInPath$) Dim oDialog As Object Dim sPath As String Dim oSFA As Object Dim s As String Dim i As Integer oDialog = CreateUnoService("com.sun.star.ui.dialogs.FilePicker") OpenOffice.org Base !!5

%eneral #tility macros oSFA = createUnoService("com.sun.star.ucb.SimpleFileAccess") REM See the TemplateDescription constants to see what other REM values are supported. If bOpen Then i = com.sun.star.ui.dialogs.TemplateDescription.FILEOPEN_SIMPLE Else REM When choosing a file that already exists, you will be asked REM if you want to overwrite the file. i = com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_SIMPLE End If oDialog.initialize(Array(i)) If IsMissing(sInPath) Then oDialog.setDisplayDirectory(GetWorkDir()) ElseIf oSFA.Exists(sInPath) Then oDialog.setDisplayDirectory(sInPath) Else s = "Directory '" & sInPath & "' Does not exist" If MsgBox(s, 33, "Error") = 2 Then Exit Function End If For i = LBound(sFilters()) To UBound(sFilters()) Step 2 Dim sFilterName$ Dim sFilterValue$ sFilterValue = sFilters(i+1) sFilterName = sFilterValue & " - " & sFilters(i) oDialog.appendFilter(sFilterName, sFilterValue) Next If oDialog.Execute() = 1 Then sPath = oDialog.Files(0) ChooseAFile() = sPath End If End Function

T!e mac$o in Listing #% e6#ects a list of filte$s to limit t!e files dis#layed to t!e use$( T!e mac$os in Listing #$ demonst$ate !o/ to 'uild t!e list( Listing #$: Build filters for selecting graphics files or Base documents.
Function OOoBaseFilters() OOoBaseFilters() = Array("All Files", "*.*", _ "OOo Base", "*.odb") End Function Function GraphicFilters() GraphicFilters() = Array("All Files", "*.*", _ "Graphic Interchange Format", "*.gif", _ "Joint Photographic Experts Group", "*.jpg", _ "Tag Image File Format", "*.tif", _ "Windows Bit Map", "*.bmp", _ "Gimp Files", "*.xcf", _

OpenOffice.org Base

!!6

%eneral #tility macros "Portable Network Graphics", "*.png") End Function

Ise t!e Find File 'utton to call t!e mac$o in Listing 35( T!e initial filename and di$ecto$y a$e not s#ecified, so t!e you$ default /o$.in% di$ecto$y is used(
&in) &ile

Listing 35: !btain a graphic filename for input.


Sub ChooseGraphicFileForOpen() LoadDBLibs() Print "You Chose: " & ChooseAFile$(GraphicFilters(), True) End Sub

+s nice as t!e 9ilePic.e$ is, it can 'e ve$y annoyin%, o$ ve$y f$iendly, de#endin% on you$ desi$es( 4f you c!oose to save a file, t!en you a$e as.ed if you /ant to ove$/$ite t!e file( 7n t!e ot!e$ !and, if you a$e o#enin% a file, t!en you can not s#ecify a file t!at does not e6ist( T!is 'e!avio$ can 'e a cu$se, o$ a 'lessin%, de#endin% on you$ intentions(

12.%. Finding a :loaded; ""o document


4 /ant a $efe$ence to a document t!at is al$eady loaded( To solve t!is #$o'lem, o'tain an enume$ation of o#en com#onents f$om t!e des.to# o'Hect and t!en c!ec. t!e IRL fo$ eac! com#onent( T!e enume$ation includes all o#en com#onents, includin% t!e Jasic 4DL and t!e 77o !el#, /!ic! s!ould 'e i%no$ed( +lso, if a document !as not 'een saved, t!en it does not !ave a IRLOc!ec. t!is 'y callin% t!e !asLocation,- met!od( Listing 31: (afely get the 62L from an !!o component.
REM Care must be taken while enumerating components to only obtain a URL REM from components that support them. Function GetDocURL(oDoc) As String GetDocURL() = "" If NOT HasUNOInterfaces(oDoc, "com.sun.star.frame.XStorable") Then REM The OOo help does not support the XStorable interface, but the REM Basic IDE does. A truely paranoid person, therefore, might check REM for the com.sun.star.document.OfficeDocument service. REM I could also check for the com.sun.star.script.BasicIDE service. ElseIf NOT oDoc.hasLocation() Then REM This document has never been saved, so there is no URL REM to compare against. Else GetDocURL() = oDoc.getURL() End If End Function

4f an 77o document is al$eady loaded, t!e mac$o in Listing 3" /ill find it 'ased on its IRL o$ file name( 4f t!e file name is used $at!e$ t!an t!e full IRL, t!e file e6tension is o#tional 'ut safe$ Ot!e files Itil(od' and Itil(odt loo. t!e same /it!out a file e6tension( 4f a document is not found in t!e enume$ation $etu$ned 'y t!e des.to# o'Hect, t!en it is loaded if t!e second a$%ument is t$ue(
Caution
Ise t!e 8ta$Des.to#(load"om#onent9$omIRL,- to load an 77o document( 4n 77o ve$sion >(6, a CILL value is $etu$ned if t!e document does not e6ist( 4n 77o ve$sion 2(0, !o/eve$, an ille%al a$%ument e6ce#tion is t!$o/n instead(
!!7

OpenOffice.org Base

%eneral #tility macros

Listing 3": *ind an !!o document if it is already loaded.


Function FindComponentWithURL(sName$, bLoadIfNotFound As Boolean) Dim oDocs ' Enumeration of the loaded components. Dim oDoc ' A single enumerated component. Dim sDocURL$ ' URL of the component that we are checking. REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If oDocs = StarDesktop.getComponents().createEnumeration() Do While oDocs.hasMoreElements() oDoc = oDocs.nextElement() sDocURL = GetDocURL(oDoc) REM Just in case the name contains the full URL. REM If the name is an empty string, then return an unsaved document. If sName = sDocURL Then FindComponentWithURL() = oDoc Exit Function End If REM This will only work if the name contains the file extension. If InStr(sDocURL, "/") > 0 Then If FileNameoutofPath(sDocURL, "/") = sName Then FindComponentWithURL() = oDoc Exit Function End If End If Loop REM The document was not found, REM perhaps the name did not contain a file extension. oDocs = StarDesktop.getComponents().createEnumeration() Do While oDocs.hasMoreElements() oDoc = oDocs.nextElement() sDocURL = GetDocURL(oDoc) If InStr(sDocURL, "/") > 0 Then If GetFileNameWithoutExtension(sDocURL, "/") = sName Then FindComponentWithURL() = oDoc Exit Function End If End If Loop

OpenOffice.org Base

!!8

%eneral #tility macros

REM The name was still not found, check to see if a document exists REM with the specified URL. REM In OOo version 1.x, loadComponentFromURL() returned NULL REM if the document did not exist. Starting with version 2.x, REM an illegal argument exception is thrown instead. If bLoadIfNotFound AND FileExists(sName) Then oDoc = StarDesktop.loadComponentFromURL(sName, "_blank", 0, Array()) FindComponentWithURL() = oDoc 'Else ' FindComponentWithURL = NULL End If End Function

12.&. Append to an array


E!ile accumulatin% data, it is convenient to add data to an a$$ay /it!out /o$$yin% a'out t!e si5e of t!e a$$ayOit may not 'e efficient, 'ut it is convenient( T!e mac$o in Listing 3' inc$eases t!e si5e of an a$$ay 'y one, and t!en a##ends data to t!e end of t!e a$$ay( T!is tec!ni3ue is invalua'le /!en s#ace and com#le6ity a$e mo$e im#o$tant t!an $untimeOa##endin% data to an a$$ay is simila$ to #us!in% data onto a stac.( Listing '3. ;ppend data to an array.
Sub AppendToArray(oData(), ByVal x) Dim iUB As Integer 'The upper bound of the array. Dim iLB As Integer 'The lower bound of the array. iUB = UBound(oData()) + 1 iLB = LBound(oData()) ReDim Preserve oData(iLB To iUB) oData(iUB) = x End Sub

TIP

T!e fi$st ve$sion of +##endTo+$$ay,- #assed t!e second a$%ument as a $efe$ence( 4 t!en /$ote a loo# t!at used a tem#o$a$y va$ia'le to collect data( +t eac! ite$ation, t!e $efe$ence to t!e tem#o$a$y va$ia'le /as #us!ed onto t!e end of t!e a$$ay( T!e final $esult /as t!at eve$y value in t!e a$$ay /as t!e same(

12.0. Compare data in an array


4 f$e3uently conve$t data into data a$$ays and t!en co#y t!e data a$$ays di$ectly into a s#$eads!eet( 4 initially /$ote t!is $outine to c!ec. individual a$$ays to see if t!ey contained du#licate data( Listing '%. Chec9 to see if t/o arrays contain the same text.
REM REM REM REM check to see if two arrays contain the same data. Both arrays are assumed to be one dimensional arrays. The data in both arrays are assumed to be directly comparable data.

OpenOffice.org Base

!!9

%eneral #tility macros Function ArraysAreSame(oData1(), oData2(), nMinCol As Long) As Boolean Dim n As Long ArraysAreSame() = False REM First, compare the upper dimension. If UBound(oData1()) <> UBound(oData2()) Then Exit Function If LBound(oData1()) <> LBound(oData2()) Then Exit Function If LBound(oData1()) < nMinCol Then Exit Function For n = LBound(oData1()) To UBound(oData1()) If oData1(n) <> oData2(n) Then Exit Function End If Next ArraysAreSame() = True End Function

12.1. Create a property


4 !ave al/ays found it annoyin% to c$eate an a$$ay of #$o#e$ties to #ass as a$%uments to t!e IC7 +P4D c$eate a #$o#e$ly dimensioned a$$ay, set t!e #$o#e$ty values, $eali5e t!at an e6t$a #$o#e$ty is $e3ui$ed so 4 need to sta$t ove$( T!e "$eateP$o#e$ty,- met!od in Listing 3# sim#lifies t!e c$eation of #$o#e$ties( acce#ts a #$o#e$ty name and a #$o#e$ty valueOa ne/ #$o#e$ty is c$eated and $etu$ned( T!e $eal st$en%t! of t!e "$eateP$o#e$ty,- met!od is seen /!en used in conHunction /it! t!e +##endP$o#e$ty,- met!od, /!ic! c$eates a ne/ #$o#e$ty and a##ends it to an a$$ay ,see Listing 3#-( Listing '&. Create a 2roperty0alue structure and append one to an array.
Function CreateProperty(sName$, oValue) As com.sun.star.beans.PropertyValue Dim oProperty As New com.sun.star.beans.PropertyValue oProperty.Name = sName oProperty.Value = oValue CreateProperty() = oProperty End Function Sub AppendProperty(oProperties(), sName As String, ByVal oValue) AppendToArray(oProperties(), CreateProperty(sName, oValue)) End Sub

12.7. Create a oint and a -ize


Many $outines $e3ui$e a #oint o$ si5e o'Hect( 4t is easie$ to c$eate and $etu$n an item in a function( Listing ''. Create a 2oint and )i<e.
Function CreatePoint(xPos, YPos) as New com.sun.star.awt.Point Dim oPoint as New com.sun.star.awt.Point oPoint.X = xPos oPoint.Y = yPos CreatePoint() = oPoint End Function Function CreateSize(iWidth, iHeight) As New com.sun.star.awt.Size OpenOffice.org Base !#"

%eneral #tility macros Dim oSize As New com.sun.star.awt.Size oSize.Width = iWidth oSize.Height = iHeight CreateSize() = oSize End Function

12.<. Append a data array to a Calc document


4 f$e3uently /$ite test mac$os t!at dis#lay data in a dialo%( + dialo% is not sufficient to dis#lay a la$%e amount of data, so 4 sometimes use a "alc document instead( T!e mac$o in Listing 3& acce#ts a data a$$ay, /!ic! is added to t!e "alc document at t!e cu$$ent cu$so$ #osition( +fte$ inse$tin% t!e data, t!e cu$so$ is moved 'elo/ t!e last inse$ted $o/( Re#eated calls to +##endDataTo"alcDoc,- a##end mo$e data to t!e end of t!e document and $e#osition t!e cu$so$( Listing '-. ;dd data array to a Calc document at the cursor position.
Sub AppendDataToCalcDoc(oDoc, oData()) Dim oSheet 'The first sheet in the document. Dim oAddr 'Address of the current cursor. Dim iNumRows% 'Number of rows to add. Dim iNumCols% 'Number of columns to add. Dim x() 'Utility variable used as a single row. Dim oRange 'Range to add the data and focus the cursor. REM Get the address of the currently selected cell. REM Use the address to obtain the current sheet. oAddr = oDoc.getCurrentSelection().getCellAddress() oSheet = oDoc.getSheets().getByIndex(oAddr.Sheet) REM Determine the number of rows in the data. REM Next, obtain the first row and see how many columns it has. iNumRows = UBound(oData()) - LBound(oData()) x() = oData(lBound(oData())) iNumCols = UBound(x()) - LBound(x()) oRange = oSheet.getCellRangeByPosition(oAddr.Column, oAddr.Row, _ oAddr.Column + iNumCols, oAddr.Row + iNumRows) oRange.setDataArray(oData()) oRange.getColumns().optimalWidth = True oRange = oSheet.getCellByPosition(oAddr.Column, oAddr.Row + iNumRows+1) oDoc.getCurrentController().select(oRange) End Sub

T!e setData+$$ay,- met!od fo$ a "alc s!eet is used 'ecause it is fast and efficient, 'ut t!e data a$$ay must 'e a sin%le dimension a$$ay( Lac! element in t!e data a$$ay co$$es#onds to a sin%le $o/ of data and is $e#$esented 'y a one dimensional a$$ay,see Table #'-(

OpenOffice.org Base

!#!

%eneral #tility macros

Table #'. 4ata arrangement for use in set4ata+rrayBC


Correct( Each ro) is an array
Dim oData, oData,0-U+$$ay,>, 2, oData,>-U+$$ay,4, 5, ?oData,2-U+$$ay,B, 8, 9-

Incorrect( A t)o dimension array


Dim oData, , oData,0, 0-U> : oData,0, >-U2 : oData,0, 2-U oData,>, 0-U4 : oData,>, >-U5 : oData,>, 2-U? oData,2, 0-UB : oData,2, >-U8 : oData,2, 2-U9

12.1#. Dynamically call ob,ect methods


T!e mac$os int$oduced in t!is section a$e ve$y advanced and easily s.i##ed 'y a novice( Jefo$e e6aminin% t!ese mac$os, it is im#o$tant to unde$stand t!e #$o'lem( +ssume t!at you !ave an o'Hect and t!e name of t!e met!od ,as a st$in%- t!at you /ant to call( 4f you .no/ t!e name of t!e met!od /!en you /$ite you$ mac$o, you can di$ectly call t!e met!od( 4f you do not .no/ t!e met!od name a!ead of time, !o/eve$, t!en it is not #ossi'le to di$ectly call t!e met!od on an o'Hect 'ased on its name( 9o$ e6am#le, if you /ant to /$ite a mac$o t!at as.s t!e use$ /!ic! met!od to call( T!e mac$o in Listing 3% demonst$ates a function called FMy4nse$ted9uncG( T!e FMy4nse$ted9uncG function $etu$ns t!e value $etu$ned 'y t!e %etCame,- met!od on t!e o7'H o'Hect(
TIP
+lt!ou%! you can not dynamically call a met!od 'ased on its name, most of an o'Hects #$o#e$ties a$e availa'le t!$ou%! t!e #$o#e$ty set info$mation o'Hect availa'le t!$ou%! t!e met!od %etP$o#e$ty8et4nfo,-( +t $untime, you can discove$ t!e name of an o'Hects #$o#e$ties and t!en o'tain t!e values usin% t!e #$o#e$ty set info$mation o'Hect( )ou can also discove$ t!e names of an o'Hects met!ods at $untime, 'ut you can not call t!em 'ased on t!e name(

(isting 07. Call the get=ame67 function on the ob>ect o#b>.


Option Explicit Function MyInsertedFunc(ByRef oObj) MyInsertedFunc = oObj.getName() End Function

T!e mac$o in Listing 3% is so t$ivial and o'vious t!at it seems su#e$fluous until you $eali5e t!at you can /$ite a mac$o to %ene$ate t!e mac$o in Listing 3% 'ased on t!e met!od name( 4 c$eated a function named Run9$omLi',-( E!en Run9$omLi',- is called as s!o/n in Listing 3$, it #e$fo$ms t!e follo/in% tas.s:

"$eate a li'$a$y named 6li' in t!e %lo'al li'$a$ies o'Hect( "$eate a module named TMod in t!e 6li' li'$a$y( "$eate t!e function named My4nse$ted9unc ,see Listing 3%-, /!ic! calls t!e function %etCame,- on t!e oDoc o'Hect( "all t!e function My4nse$ted9unc,-D t!is /o$.s 'ecause t!e function name My4nse$ted9unc neve$ c!an%es( Pe$fo$m cleanu#(
!##

OpenOffice.org Base

%eneral #tility macros

Listing '9. Call the get=ame67 function on the ob>ect o,oc.


olib = GlobalScope.BasicLibraries RunFromLib(oLib, "xlib", "TMod", oDoc, "getName", True)

T!e a$%uments fo$ Run9$omLi',- a$e s!o/n in Table #/( Table #/. +rguments for the 2un*romLibBC function.
Ar "ment
oLi's sLCame sMCame o7'H s"all '"lean 6 y

Description
JasicLi'a$ies containe$ to contain t!e ne/ly c$eated module( Came of t!e li'$a$y to use, t!is li'$a$y can al$eady e6ist( 4f t!e li'$a$y does not e6ist, it is c$eated( Came of t!e module to useD t!e module is $e#laced if it al$eady e6ists( T!e module is c$eated to contain code simila$ to t!at s!o/n in Listing 3%( 7'Hect t!at contains t!e met!od to call( Came of t!e function to call( 4f T$ue, t!e c$eated li'$a$y and module a$e deleted afte$ t!e call( T!e li'$a$y is not $emoved if it e6isted 'efo$e t!e call( 7#tional a$%ument t!at, if it e6ists, is #assed to t!e called met!od( 7#tional a$%ument t!at, if it e6ists, is #assed to t!e called met!od(

T!e oLi's a$%ument is a JasicLi'a$ies containe$ fo$ eit!e$ a document o$ t!e a##lication( T!e li'$a$y containe$ contains t!e ne/ly c$eated module( 4n my testin%, 4 /as a'le to use t!e JasicLi'$a$ies #$o#e$ty f$om t!e cu$$ent document and f$om t!e a##lication, 'ut not f$om a ne/ly c$eated document( )ou can not c$eate a li'$a$y in a document t!at is not t!e cu$$ent document, 'ecause t!e o'Hect $etu$ned 'y t!e %etLi'$a$y"ontaine$,- met!od is not usa'le fo$ t!is #u$#ose( Listing &5 contains a /o$.in% im#lementation( Listing -0. Call a named method on an ob>ect.
Function RunFromLib(oLibs, sLName$, sMName$, oObj, sCall$, _ bClean As Boolean, Optional x, optional y) Dim oLib 'The library to use to run the new function. Dim s$ 'Generic string variable. Dim bAddedLib As Boolean REM If the library does not exist, then create it. bAddedLib = False If NOT oLibs.hasByName(sLName) Then bAddedLib = True oLibs.createLibrary(sLName) End If oLibs.loadLibrary(sLName) oLib = oLibs.getByName(sLName) If oLib.hasByName(sMName) Then oLib.removeByName(sMName) End If s = "Option Explicit" & CHR$(10) & _ "Function MyInsertedFunc(ByRef oObj"

OpenOffice.org Base

!#$

%eneral #tility macros

If NOT IsMissing(x) Then If NOT IsMissing(y) Then s = s & ")" & CHR$(10) & If NOT IsMissing(x) Then If NOT IsMissing(y) Then s = s & ")" & CHR$(10) &

s = s & ", x" s = s & ", y" "MyInsertedFunc = oObj." & sCall & "(" s = s & "x" s = s & ", y" "End Function"

oLib.insertByName(sMName, s) If IsMissing(x) Then RunFromLib = MyInsertedFunc(oObj) ElseIf IsMissing(y) Then RunFromLib = MyInsertedFunc(oObj, x) Else RunFromLib = MyInsertedFunc(oObj, x, y) End If If bClean Then oLib.removeByName(sMName) If bAddedLib Then oLibs.removeLibrary(sLName) End If End If End Function

E!ile investi%atin% meta&data, 4 /anted to call multi#le met!ods on t!e same o'Hect( To s!o$ten t!e mac$o listin%s, 4 c$eated t!e RunMulti#le"alls,- met!od ,see Listing &1- to call Run9$omLi',- multi#le times( T!e a$%uments fo$ RunMulti#le"alls,- a$e s!o/n in Table ##( Table ##. +rguments to the 2unMultipleCallsBC method.
Ar "ment
o7'H oData,funcs,'P$int7#tional 6 y

Description
7'Hect t!at contains t!e met!ods to call( +s eac! function is called, t!e $etu$n value is added to t!is a$$ay( +$$ay of function names to call( 4f T$ue, o#tional a$%uments a$e #$inted /it! t!e function names( 7#tional a$%ument t!at, if it e6ists, is #assed to t!e called met!od( 7#tional a$%ument t!at, if it e6ists, is #assed to t!e called met!od(

T!e mac$o in Listing &1 acce#ts an a$$ay of function names t!at a$e assumed to $etu$n a sim#le data ty#e and acce#t 5e$o, one, o$ t/o a$%uments( Run9$omLi',- is called once fo$ eac! function name in t!e funcs,- a$$ay( T!e oData,- a$$ay is modified to contain t!e met!od name and t!e $etu$n value in a fo$m suita'le fo$ use in t!e setData+$$ay,- met!od in a "alc s!eet( Listing - . Call multiple named methods on an ob>ect.
Sub RunMultipleCalls(oObj, oData(), funcs(), _ Optional bPrintOptional, Optional x, optional y) Dim i% 'General index variable.

OpenOffice.org Base

!#4

%eneral #tility macros Dim z 'General utility variable.

REM First, dimension the array to hold the data. ReDim oData(LBound(funcs()) To UBound(funcs())) REM For each function, create a module that contains a function, REM which is used to call the requested function on the object oObj. For i = LBound(funcs()) To UBound(funcs()) If IsMissing(x) Then z = RunFromLib(GlobalScope.BasicLibraries, _ "xyzzylib", "TestMod", oObj, funcs(i), True) ElseIf IsMissing(y) Then z = RunFromLib(GlobalScope.BasicLibraries, _ "xyzzylib", "TestMod", oObj, funcs(i), True, x) Else z = RunFromLib(GlobalScope.BasicLibraries, _ "xyzzylib", "TestMod", oObj, funcs(i), True, x, y) End If If IsMissing(bPrintOptional) OR IsMissing(x) Then oData(i) = Array(funcs(i), CStr(z)) ElseIf NOT bPrintOptional Then oData(i) = Array(funcs(i), CStr(z)) ElseIf IsMissing(y) Then oData(i) = Array(funcs(i) & "(" & CStr(x) & ")", CStr(z)) Else oData(i) =Array(funcs(i) & "(" & CStr(x) & ", " & CStr(y) & _ ")", CStr(z)) End If Next End Sub

T!e met!od RunMulti#le"alls+##endToDoc,- ,see Listing &"- is a /$a##e$ to call RunMulti#le"alls,- and a##end t!e $etu$ned data a$$ay to a "alc document( Listing -2. Call named methods and append the output to a document.
Sub RunMultipleCallsAppendToDoc(oDoc, oObj, funcs(), _ Optional bPrintOptional, _ Optional x, optional y) Dim oData() 'Holds the data array that is set. If IsMissing(x) OR IsMissing(bPrintOptional) Then RunMultipleCalls(oObj, oData(), funcs()) ElseIf IsMissing(y) Then RunMultipleCalls(oObj, oData(), funcs(), bPrintOptional, x) Else RunMultipleCalls(oObj, oData(), funcs(), bPrintOptional, x, y) End If AppendDataToCalcDoc(oDoc, oData()) End Sub

OpenOffice.org Base

!#5

%eneral #tility macros

12.11. Display numeric constants as meaning!ul te/t


T!e 77o +P4 contains many constant %$ou#s( T!e constants can 'e $efe$enced as eit!e$ t!e nume$ical value, o$ t!e full name( 9o$ e6am#le, com(sun(sta$(sd'c("olumnSalue(C7MCILL8 is e3uivalent to t!e num'e$ 0( 4t is muc! easie$ to $eco%ni5e t!e te6t name t!an it is to $emem'e$ t!e nume$ical values( Most constant %$ou#s used in 7#en7ffice(o$% IC7 #$o%$ammin% a$e se3uentially num'e$ed( 9o$ e6am#le, t!e com(sun(sta$(sd'c("olumnSalue constant %$ou# contains t!e constants C7MCILL8, CILL+JLL, and CILL+JLLMICWC7EC, /!ic! a$e num'e$ed 0, >, and 2( T!e code sni##et in Listing &' demonst$ates an easy /ay to conve$t se3uentially num'e$ed constants to te6tD t!e constant value is used to inde6 into an a$$ay containin% a te6tual $e#$esentation( Listing -3. Convert the Column0alue constants to text.
x() = Array("NO_NULLS", "NULLABLE", "NULLABLE_UNKNOWN") Print x(com.sun.star.sdbc.ColumnValue.NO_NULLS) Print x(0)

T!e mac$o in Listing &/ %ene$ali5es t!e met!od demonst$ated in Listing &' to conve$t t!e nume$ic value to a use$ f$iendly te6t ent$y( T!e fi$st a$%ument, n, is t!e constant value to conve$t( T!e second a$%ument, 6,-, is an a$$ay of desc$i#tive ent$ies t!at desc$i'e t!e constant values( 4f t!e constants $an%e f$om & to 5, t!en so s!ould 6,-( 4f '4ncC is T$ue, t!en t!e $etu$ned name is #$eceded 'y nume$ic value( T!e final a$%ument is o#tional, and is used as t!e default default desc$i#tive ent$y if t!e constant %$ou# value does not #$o#e$ly inde6 into t!e a$$ay( Listing -%. #btain data from an array /ithout an out-of-bounds error.
Function SafeArray(ByVal n As Long, x(), bIncN As Boolean, _ Optional DValue) Dim s As String If bIncN Then s = CStr(n) & " - " Else s = "" End If If LBound(x()) <= n AND n <= UBound(x()) Then SafeArray() = s & CStr(x(n)) ElseIF NOT IsMissing(DValue) Then SafeArray() = s & CStr(DValue) Else SafeArray() = s & "Invalid" End If End Function

T!e #u$#ose of t!e 8afe+$$ay,- function in Listing &/ is to conve$t a sin%le nume$ic value into a !uman $eada'le te6t $e#$esentation of t!e value( T!e mac$o in Listing &# $e#laces t!e nume$ic values in an enti$e column /it! a !uman $eada'le te6t $e#$esentation( T!e final usa%e of Listing &# $educes t!e amount of code $e3ui$ed to evaluate an enti$e $esult set to a data a$$ay, and t!en $e#lace a sin%le column /it! a nice te6tual $e#$esentation(

OpenOffice.org Base

!#6

%eneral #tility macros

Listing -&. 3ind element in parallel arrays.


Sub SafeArrayColumns(ByVal nCol As Long, oData(), x(), _ bIncN As Boolean, Optional DVal) Dim oRow() Dim i As Long Dim n As Long Dim dValue If IsMissing(dVal) Then dValue = "Invalid" Else dValue = dVal End If For i = LBound(oData()) + 1 To UBound(oData()) oRow() = oData(i) If LBound(oRow()) <= nCol AND nCol <= UBound(oRow()) Then oRow(nCol) = SafeArray(CLng(oRow(nCol)), x(), bIncN, dValue) End If Next i End Sub

12.12. -elect !rom a list in a list bo/


T!e mac$o in Listing &3 c$eates a dialo% containin% a list 'o6( T!e data in t!e oData,- a$$ay is added into t!e list 'o6( T!e use$ t!en c!ooses a sin%le item f$om t!e list 'o6( T!e c!osen item is $etu$ned as a st$in%( 4f not!in% is selected, an em#ty st$in% is $etu$ned( +n inte$estin% t!in%s a'out t!is mac$o, is t!at it dynamically 'uilds t!e dialo% and t!e cont$ols( Listing -'. Create a dialog /ith a list box to select one item.
REM Create a dialog with a list box. REM Populate the list box with the data and return the selected item. Function DialogSelectItem(oData(), sTitle$) As String Dim oDlg 'The created dialog. Dim oDlgModel 'The created dialog's model. Dim oModel 'Model for a control. Dim oControl 'References a control. Dim iTabIndex% 'The current tab index while creating controls. Dim s$ 'Generic temporary string variable. DialogSelectItem() = "" REM Create the dialog's model oDlgModel = CreateUnoService("com.sun.star.awt.UnoControlDialogModel") oDlgModel.PositionX = 50 : oDlgModel.PositionY = 50 oDlgModel.Width = 350 : oDlgModel.Height = 300 oDlgModel.Title = sTitle$ iTabIndex = 0 s = "com.sun.star.awt.UnoControlListBoxModel" oModel = oDlgModel.createInstance(s)

OpenOffice.org Base

!#7

%eneral #tility macros oModel.Name = "ListBox" oModel.TabIndex = iTabIndex oModel.PositionX = Clng(10) : oModel.PositionY = 10 oModel.Width = 350 - 20 : oModel.Height = 300 - 60 oModel.Dropdown = False oModel.MultiSelection = False oDlgModel.insertByName("ListBox", oModel) iTabIndex = iTabIndex + 1 s = "com.sun.star.awt.UnoControlButtonModel" oModel = oDlgModel.createInstance(s) oModel.Name = "OKButton" oModel.TabIndex = iTabIndex oModel.PositionX = Clng(350/ 2 - 75) oModel.PositionY = 300-20 oModel.Width = 50 oModel.Height = 15 oModel.Label = "OK" oModel.PushButtonType = com.sun.star.awt.PushButtonType.OK oDlgModel.insertByName("OKButton", oModel) iTabIndex = iTabIndex + 1 oModel = oDlgModel.createInstance(s) oModel.Name = "CANCELButton" oModel.TabIndex = iTabIndex oModel.PositionX = Clng(350/ 2 + 25) oModel.PositionY = 300-20 oModel.Width = 50 oModel.Height = 15 oModel.Label = "Cancel" oModel.PushButtonType = com.sun.star.awt.PushButtonType.CANCEL oDlgModel.insertByName("CANCELButton", oModel) iTabIndex = iTabIndex + 1 REM Create the dialog and set the model oDlg = CreateUnoService("com.sun.star.awt.UnoControlDialog") oDlg.setModel(oDlgModel) REM Add the items. oDlg.getControl("ListBox").addItems(oData(), 0) REM Create a window and then tell the dialog to use the created window. Dim oWindow oWindow = CreateUnoService("com.sun.star.awt.Toolkit") oDlg.createPeer(oWindow, null) Dim i% REM Finally, execute the dialog. i = oDlg.execute() If i = 0 Then Exit Function End If

OpenOffice.org Base

!#8

%eneral #tility macros DialogSelectItem() = oDlg.getControl("ListBox").getSelectedItem() End Function

OpenOffice.org Base

!#9

1'. 3atabase utility macros

13.1. =uoting table and !ield names


4f a field name contains a s#ace o$ lo/e$ case lette$s, t!en t!e field name must 'e 3uoted( T!e c!a$acte$ used fo$ 3uotin% c!an%es de#endin% on t!e data'ase in 3uestion( "ommon 3uote c!a$acte$s include a 'ac.&tic ,R-, sin%le 3uote ,K-, o$ dou'le 3uote ,Q-( T!e #$ecise c!a$acte$ to use is o'taina'le f$om t!e connection meta&data( Listing &&: @uote a table or field name in a (@L statement.
REM The quote charcter changes based on the database that is accessed. Function DBQuoteName(sName As String, oCon) As String Dim sQuote As String sQuote = oCon.getMetaData().getIdentifierQuoteString() DBQuoteName = sQuote & sName & sQuote End Function

13.2. Con6ert between an .>" Date and a $asic Date


T!e 77o data'ase en%ine $etu$ns date o'Hects as an IC7 Date st$uctu$e ,see Table #"-( Jasic, on t!e ot!e$ !and, !as a date ty#e 'ased on a floatin% #oint num'e$ so t!e ty#es a$e not di$ectly com#ati'le( Table #3. 0roperties of the com.sun.star.util.4ate structure.
Type
unsi%ned s!o$t unsi%ned s!o$t unsi%ned s!o$t

Property
)ea$ Mont! Day

Description
yea$( Mont! of yea$ ,>&>2 o$ 0 fo$ a void date-( Day of mont! ,>& > o$ 0 fo$ a void date-(

Listing &% demonst$ates !o/ to conve$t 'et/een t!e Date ty#e used inte$nally 'y Jasic, and t!e IC7 st$uctu$e $etu$ned 'y data'ase calls( Listing -.. 5he date routines are contained in the document )C 3.
Function UNODateToDate(ByVal x) As Date If IsNull(x) OR IsEmpty(x) Then UNODateToDate = cDate(0.0) ElseIf x.Day = 0 OR x.Month = 0 Then UNODateToDate = cDate(0.0) Else UNODateToDate = DateSerial(x.Year, x.Month, x.Day) End If End Function Function DateToUNODate(ByVal x As Date) OpenOffice.org Base !$"

Database #tility macros Dim oDate As New com.sun.star.util.Date SetUnoDate(x, oDate) DateToUNODate = oDate End Function Sub SetUnoDate(ByVal x As Date, oDate) oDate.Day = Day(x) oDate.Month = Month(x) oDate.Year = Year(x) End Sub

T!e 77o data'ase en%ine $etu$ns time data as an IC7 Time st$uctu$e ,see Table #&-( T!e Time st$uctu$e contains values accu$ate to !und$edt!s of a second( Jasic is a'le to sto$e times accu$ate !und$edt!s of a second, 'ut does not #$ovide a function to e6t$act t!e value ,see Listing &$-( Table #&. 0roperties of the com.sun.star.util.Time structure.
Type
unsi%ned s!o$t unsi%ned s!o$t unsi%ned s!o$t unsi%ned s!o$t

Property
<ou$s Minutes 8econds <und$edt!8econds

Description
<ou$s ,0&2 -( Minutes ,0&59-( 8econds ,0&59-( <und$edt! seconds ,0&99-(

Listing -9. Convert !=# 5ime to a $asic ,ate


Function UNOTimeToDate(ByVal x) As Date If IsNull(x) OR IsEmpty(x) Then UNOTimeToDate = cDate(0.0) Else UNOTimeToDate = TimeSerial(x.Hours, x.Minutes, x.Seconds) + _ x.HundredthSeconds / 8640000 End If End Function Function DateToUNOTime(ByVal x As Date) Dim oDate As New com.sun.star.util.Time SetUNOTime(x, oDate) DateToUNOTime = oDate End Function Sub SetUNOTime(ByVal x As Date, oDate) Dim d As Double dim i As Integer oDate.Hours = Hour(x) oDate.Minutes = Minute(x) oDate.Seconds = Second(x) REM Remove any date portion. Int() rounds towards negative infinity, REM which works properyly, even for dates prior to December 29,1899. d = x - Int(x)

OpenOffice.org Base

!$!

Database #tility macros REM Now, convert to seconds. There are 86,400 seconds in a day. d = d * 86400 d = d - Int(d) REM Now, convert to hundredths of seconds. Use CInt to round to the REM nearest integer rather than round towards negative infinity. i = CInt(d * 100) If i > 99 Then i = 99 oDate.HundredthSeconds = i End Sub

+ data'ase time stam# is $etu$ned as a DateTime st$uctu$e, t!at contains t!e #$o#e$ties in Table #3 and Table #&( T!e fle6i'ility offe$ed 'y Jasic allo/s t!e use of t!e $outines in Listing &% and Listing &$, /!ic! #$ovides fo$ ve$y sim#le $outines to conve$t 'et/een t!e Jasic Date ty#e and t!e IC7 DateTime st$uctu$e ,see Listing %5-( Listing .0. Convert !=# ,ate5ime to a $asic ,ate
Function UNODateTimeToDate(ByVal x) As Date UNODateTimeToDate = UNODateToDate(x) + UNOTimeToDate(x) End Function Function DateToUNODateTime(ByVal x As Date) Dim oDate As New com.sun.star.util.DateTime SetUNOTime(x, oDate) SetUNODate(x, oDate) DateToUNODateTime = oDate End Function

13.3. Con6ert a result set to an array o! data


+ $esult set contains $o/s of data( Lac! $o/ of data contains columns /it! data( + $esult set allo/s a la$%e dataset to 'e $etu$ned, even if it /ill not all fit into memo$y at one timeOt!e mac$o #$esented in t!is section assumes t!at t!e data $etu$ned 'y t!e $esult set is not too la$%e to fit into memo$y( T!e #u$#ose is to #$ovide a sim#le met!od to o'tain all of t!e data f$om a 3ue$y, fo$matted fo$ use 'y +##endDataTo"alcDoc,- in Listing 3&D com#lete /it! column !eade$s( + $esult set #$ovides meta&data, /!ic! desc$i'es t!e data t!at it contains( T!e $esult set meta&data indicates t!e num'e$ of columns in t!e $esult set alon% /it! a desc$i#tion of eac! column( T!e meta&data is used to dete$mine t!e num'e$ of columns and t!e column titles( T!e mac$o in Listing %1 %ene$ates a data a$$ay t!at enca#sulates t!e data 'ased on its ty#e( Listing . . ,ump the results from a "esult)et into an array.
Sub ResultSetToData(oResult, oDoc, sFunc$, oData()) Dim oData2() 'Temporary row data array. Dim oMeta 'Each result set also has meta-data. Dim n As Long 'Number of columns returned by a result set. Dim i As Long 'General index variable. Dim nRowCount& 'Count of the number of rows. Dim x 'Generic work variable. If IsNull(oResult) OR IsEmpty(oResult) Then oData() = Array(Array(sFunc, "NULL result set returned"))

OpenOffice.org Base

!$#

Database #tility macros Exit Sub End If oData() = Array() Do While oResult.next() If n = 0 Then REM Add column titles. oMeta = oResult.getMetaData() n = oMeta.getColumnCount() oData2() = DimArray(n) oData2(0) = sFunc For i = 1 To n oData2(i) = oMeta.getColumnName(i) Next REM Advanced programming concept.... REM Do not replace the next two lines with: REM oData() = Array(oData2()) REM because it would use a reference to oData2(). REM AppendToArray() copies the array by value. AppendToArray(oData(), oData2()) End If REM The first column is always the function name. oData2() = Array() oData2() = DimArray(n) REM Although the row number should be available using REM oResult.getRow(), this is not always the case. nRowCount = nRowCount + 1 oData2(0) = sFunc & " " & nRowCount For i = 1 To n Select Case oMeta.getColumnType(i) Case com.sun.star.sdbc.DataType.DATE oData2(i) = CStr(UNODateToDate(oResult.getDate(i))) Case com.sun.star.sdbc.DataType.TIME x = oResult.getTime(i) oData2(i) = Format(x.Hours, "00") & ":" & _ Format(x.Minutes, "00") & ":" & _ Format(x.Seconds, "00") & "." & x.HundredthSeconds Case com.sun.star.sdbc.DataType.TIMESTAMP x = oResult.getTimestamp(i) oData2(i) = CStr(UNODateToDate(x)) & " " & _ Format(x.Hours, "00") & ":" & Format(x.Minutes, "00") & _ ":" & Format(x.Seconds, "00") & "." & x.HundredthSeconds Case Else oData2(i) = oResult.getString(i) End Select Next AppendToArray(oData(), oData2()) Loop REM In case no rows are returned...

OpenOffice.org Base

!$$

Database #tility macros If n = 0 AND nRowCount = 0 Then oData() = Array(Array(sFunc, "No rows returned")) End If End Sub

T!e mac$o in Listing %1 ins#ects t!e data ty#e 'y usin% t!e DataTy#e constants, /!ic! a$e 'ased on t!e Hava(s3l(Ty#es constants ,see Table #%-( Table #%. Column types defined by the com.sun.star.sdbc.4ataType constants.
&al"e
&B &? &5 &4 & &2 &> 0 > 2 4 5 ? B 8 >2 9> 92

Name
J4T T4C)4CT J4=4CT L7C=S+RJ4C+R) S+RJ4C+R) J4C+R) L7C=S+R"<+R 8PLCILL "<+R CIMLR4" DL"4M+L 4CTL=LR 8M+LL4CT 9L7+T RL+L D7IJLL S+R"<+R D+TL T4ML T4ML8T+MP

Comment
7ne o$ mo$e 'its( Ty#ically an 8 'it si%ned inte%e$( Ty#ically a ?4 'it si%ned inte%e$( Sa$ia'le len%t! 'ina$y data, suc! as an ima%e( Sa$ia'le len%t! 'ina$y data, suc! as an ima%e( 9i6ed len%t! 'ina$y data( Sa$ia'le len%t! c!a$acte$ data( CILL value( 9i6ed len%t! c!a$acte$ data( Lon% inte%e$ /it! a s#ecified #$ecision( Lon% inte%e$ /it! a s#ecified #$ecision( Ty#ically a 2 'it si%ned inte%e$( Ty#ically a >? 'it si%ned inte%e$( Ty#ically a sin%le o$ dou'le #$ecision floatin% #oint num'e$( Ty#ically a sin%le o$ dou'le #$ecision floatin% #oint num'e$( Ty#ically a sin%le o$ dou'le #$ecision floatin% #oint num'e$( Sa$ia'le len%t! c!a$acte$ data( Date( Time( Date and time accu$ate to seconds o$ milliseconds de#endin% on t!e data'ase( <8PLDJ is accu$ate to milliseconds(( Data'ase&s#ecific ty#e, ma##ed to an o'Hect t!at is accessed usin% t!e met!od NRo/::%et7'Hect,- ( + ty#e $e#$esented 'y an o'Hect /!ic! im#lements t!is ty#e( Desc$i'es a ty#e 'ased on a 'uilt&in ty#eD a use$&defined data ty#e ,IDT-( +tt$i'utes t!at may 'e any ty#eD a use$&defined data ty#e ,IDT-( 8PL +RR+)(

9 >>> 2000 200> 8TRI"T 2002 200 +RR+) 7T<LR 7JJL"T D48T4C"T

OpenOffice.org Base

!$4

Database #tility macros

&al"e
2004 2005 200?

Name
JL7J "L7J RL9

Comment
8PL Jina$y La$%e 7'Hect( 8PL "!a$acte$ La$%e 7'Hect( 8PL $efe$encin% ty#e(

T!e +ddResult8etToDoc,- met!od in Listing %" co#ies a $esult set to a data a$$ay and t!en a##ends t!e data to a "alc document usin% t!e mac$os in Listing 3& and Listing %1( 4t is assumed t!at t!e data'ase is not e6ceedin%ly la$%e and t!at all of t!e data /ill fit in memo$y( Listing .2. ;dd"esult)et5o,oc is found in the document )C 3.
Sub AddResultSetToDoc(oResult, oDoc, sFunc$) Dim oData() 'Primary data array added to the Calc document. ResultSetToData(oResult, oDoc, sFunc$, oData()) AppendDataToCalcDoc(oDoc, oData()) End Sub

13.%. Create and populate a dialog !rom a result set


T!e mac$o in Listing %' acce#ts a $esult set, a column num'e$ and a ma6imum num'e$ of $o/s( + dialo% /it! a list 'o6 dis#lays t!e data f$om t!e s#ecified column ,see Listing &3-( T!e sin%le selected item is $etu$ned as a st$in%( T!e list 'o6 is a standa$d IC7 cont$ol is not actually tied to t!e data'ase( 4n ot!e$ /o$ds, t!e data is e6t$acted manually( Listing .3. 2opulate and use a list box from a result set.
Function SelItemFromResult(oResult, nCol%, nMaxRows&) As String Dim nCount As Long Dim oData() As String Dim s$ SelItemFromResult = "" REM First, check to see if there is data to read. If nMaxRows < 1 Then Exit Function If IsNull(oResult) OR IsEmpty(oResult) Then Exit Function End If REM Now read the data from the database. nCount = 0 ReDim oData(0 To nMaxRows - 1) As String Do While oResult.next() AND nCount < nMaxRows oData(nCount) = oResult.getString(nCol) nCount = nCount + 1 Loop ReDim Preserve oData(0 To nCount - 1) As String SelItemFromResult() = DialogSelectItem(oData(), "Select Item") End Function

OpenOffice.org Base

!$5

Database #tility macros

OpenOffice.org Base

!$6

1+. Tips and tricks


+t least initially, ti#s and t$ic.s $eally means Ft!in%s t!at +nd$e/ al/ays fo$%etsG(

1%.1. (imit the number o! returned records


Lve$y data'ase does t!is diffe$ently( 4n a native Jase document, use t!e follo/in% synta6:
!select limit 0 100 <cols> from <tables> select limit 0 4 * from TABLE1 'Rows 0, 1, 2, and 3 select limit 4 4 * from TABLE1 'Rows 4, 5, 6, and 7

Cotice t!at t!e $o/s a$e num'e$ed sta$tin% /it! 5e$o( Je ca$eful, o$ you /ill miss a $o/( 8econd, you can not use t!is synta6 in t!e =I4 'ecause t!e #a$se$ /ill not $eco%ni5e t!e 8PL( T!is synta6 is s#ecific to t!e data'ase em'edded in an 77o Jase document(
Use Select i'it T!e (se Select &i it 'utton as.s you to c!oose a data'ase( T!e D+T+ ta'le is c$eated in t!is data'ase and data is added( T!e L4M4T statement is t!en used in t/o 3ue$ies to dis#lay t!e $esult(

Listing .%. Create a simple database and then use LI+I5.


Sub UseSelectLimit(Optional dbURL$ = "") Dim sTableName$ 'The name of the table to creat. Dim oTable 'A table in the database. Dim oTables 'Tables in the document Dim oTableDescriptor 'Defines a table and how it looks. Dim oCols 'The columns for a table. Dim oCol 'A single column descriptor. Dim oCon 'Database connection. Dim oBaseContext 'Database context service. Dim oDB 'Database data source. Dim oStatement Dim sSQL$ If dbURL = "" Then dbURL = ChooseAFile(OOoBaseFilters(), False) If dbURL = "" Then Exit Sub CreateBinaryDB(dbURL$, False) REM Use the DatabaseContext to get a reference to the database. oBaseContext = CreateUnoService("com.sun.star.sdb.DatabaseContext") oDB = oBaseContext.getByName(dbURL) oCon = oDB.getConnection("", "") oTables = oCon.getTables() sTableName$ = "DATA" If oTables.hasByName(sTableName$) Then oTables.dropByName(sTableName) oDB.DatabaseDocument.store() End If

OpenOffice.org Base

!$7

Tips and tric&s REM For now, this should always be True If NOT oTables.hasByName(sTableName$) Then oTableDescriptor = oTables.createDataDescriptor() oTableDescriptor.Name = sTableName$ oCols = oTableDescriptor.getColumns() oCol = oCols.createDataDescriptor() oCol.Name = "ID" oCol.Type = com.sun.star.sdbc.DataType.INTEGER oCol.IsNullable = com.sun.star.sdbc.ColumnValue.NO_NULLS oCol.IsAutoIncrement = True oCol.Precision = 10 oCol.Description = "Primary Key" oCols.appendByDescriptor(oCol) oCol.Name = "NAME" oCol.Type = com.sun.star.sdbc.DataType.VARCHAR oCol.Description = "Filename" oCol.Precision = 255 oCol.IsAutoIncrement = False oCols.appendByDescriptor(oCol) oTables.appendByDescriptor(oTableDescriptor) End If sSQL = "insert into DATA (NAME) values (?)" oStatement = oCon.PrepareStatement(sSQL) Dim x() Dim i% x() = Array("zero", "one", "two", "three", "four", _ "five", "six", "seven", "eight", "nine", "ten") For i = LBound(x()) To UBound(x()) oStatement.SetString( 1, x(i)) oStatement.ExecuteUpdate() Next oStatement = oCon.CreateStatement() Dim s$ Dim oResult For i = 0 To 4 Step 4 sSQL = "select LIMIT " & i & " 4 * from DATA" oResult = oStatement.executeQuery(sSQL) Do While oResult.next() s = s & "LIMIT " & i & " 4 Yields " & oResult.getString(1) & _ " " & oResult.getString(2) & CHR$(10) Loop Next MsgBox s REM Do not dispose the database context or you will NOT be able to REM get it back without restarting OpenOffice.org. REM Store the associated document to persist the changes to disk.

OpenOffice.org Base

!$8

Tips and tric&s oDB.DatabaseDocument.store() oCon.close() End Sub

OpenOffice.org Base

!$9

1-. Connect to a Base document using @3BC


+ Jase document can connect to an e6te$nal data'ase o$ it can c$eate an <8PLDJ data'ase t!at is sto$ed inside of t!e Jase document( 77o documents a$e sto$ed as 5i# files and Jase documents a$e no e6ce#tion( Jo!n Ea$d c$eated a solution in Java t!at e6t$acts t!e <8PLDJ files f$om t!e Jase document ,/!ic! means 5i# file- into a tem#o$a$y di$ecto$y and t!en connects to it usin% JDJ"( +ll of Jo!nKs comments and code a$e availa'le in !is Jlo%( !tt#:**di%iassn('lo%s#ot(com*200?*0B*Hava&c$eatin%&Hd'c&connection&to(!tml Listing .&. ;ccess a $ase document using :,$C.
import import import import import java.sql.*; java.util.zip.*; java.io.*; org.hsqldb.jdbcDriver; java.util.*;

public class Test { public static void main(String[] args) { //Instantiate the jdbcDriver from HSQL jdbcDriver j = new jdbcDriver(); Connection con = null; //Database objects Statement com = null; ResultSet rec = null; ZipFile file = null; //For handeling zip files ZipEntry ent = null; Enumeration en = null; //For the entries in the zip file BufferedOutputStream out = null; //For output from zip class InputStream in = null; //for reading buffers from the zip file File f = null; //Get temporary file name, not used for anything int len; //General length counter for loops //Stores list of unzipped file for deletion at end of program List v = new ArrayList(); //Unzip zip file, via info from //http://www.devx.com/getHelpOn/10MinuteSolution/20447 try { //Open the zip file that holds the OO.Org Base file file = new ZipFile("/home/digiassn/OODatabase/employeeDatabase.odb"); //Create a generic temp file. I only need to get the filename from //the tempfile to prefix the extracted files for OO Base f = File.createTempFile("ooTempDatabase", "tmp"); f.deleteOnExit(); //Get file entries from the zipfile and loop through all of them en = file.entries(); while (en.hasMoreElements()) { OpenOffice.org Base !4"

onnect to a Base doc#ment #sing $DB //Get the current element ent = (ZipEntry)en.nextElement(); //If the file is in the database directory, extract it to our //temp folder using the temp filename above as a prefix if (ent.getName().startsWith("database/")) { System.out.println("Extracting File: " + ent.getName()); byte[] buffer = new byte[1024]; //Create an input stream file the file entry in = file.getInputStream(ent); //Create a output stream to write out the entry to, using the //temp filename created above out = new BufferedOutputStream(new FileOutputStream("/tmp/" + f.getName() + "." + ent.getName().substring(9))); //Add newly created temp file to tempfile vector for deleting //later v.add("/tmp/"+f.getName() + "." + ent.getName().substring(9)); //Read the input file into the buffer, then write out to //the output file while((len = in.read(buffer)) >= 0) out.write(buffer, 0, len); //close both the input stream and the output stream out.close(); in.close(); } } //Close the zip file since the temp files have been created file.close(); //Create our JDBC connection based on the temp filename used above con = DriverManager.getConnection("jdbc:hsqldb:file:/tmp/" + f.getName(), "SA", ""); //Create a command object and execute, // storing the results in the rec object com = con.createStatement(); rec = com.executeQuery("select * from \"employees\""); //GO through the resultset, and output the results while (rec.next()) System.out.println("Last Name: " + rec.getString("nm_emp_last") + " First Name: " + rec.getString("nm_emp_first")); //Close all the database objects rec.close(); com.close();

OpenOffice.org Base

!4!

onnect to a Base doc#ment #sing $DB con.close(); //Delete temporary files, // the file names are stored in the v vector for (len = 0; len <> v.size(); len++) (new File((String)v.get(len))).delete(); } catch (Exception e) { e.printStackTrace(); } } }

Jo!nKs code does t!e follo/in%:

L6t$act t!e <8PLDJ files to a tem# location ,/!ic! you must c!an%e so t!at t!is /ill /o$. fo$ you"$eate a JDJ" connection to t!e tem#o$a$y files( L6t$act values f$om t!e nm>emp>first and nm>emp>last columns( Delete t!e tem#o$a$y files(

OpenOffice.org Base

!4#

Appendi1 A. !tuff I Own


4 decided to c$eate a data'ase of stuff t!at 4 o/n( T!e data'ase !as c!an%ed ove$ time( 4 !ave added ne/ fields, and t!e$e a$e some t!at 4 s!ould #$o'a'ly $emove( T!e end $esult is so$t of a collection of stuff t!at /o$.s 'ut is not #olis!ed( My intention is not to demonst$ate a #olis!ed a##lication, 'ut $at!e$, to s!o/ a fe/ tec!ni3ues t!at /o$.ed fo$ me(

A.1. *ables

*igure "3. ,ague schema of stuff 1 own. Cotice t!at ta'le names and field names a$e in u##e$ caseD t!is is safe$ and avoids #$o'lems /it! ce$tain ty#es of data'ase 'ac.&ends(

A.1.1. Category
4 c$eated a$'it$a$y cate%o$i5ations suc! as com#ute$s, elect$onics, and tools( 4t /ould 'e nice to !ave a !ie$a$c!y of cate%o$ies V allo/ eac! cate%o$y to !ave a #a$ent( 4f 4 stated t!at /ood /o$.in% tools !ad a #a$ent called tools, 4 /ould find !and /ood /o$.in% tools /!en 4 sea$c!ed fo$ tools( Info$tunately, t!is is noto$iously difficult ,and inefficient- to code in 8PL( T!e usual su'stitute is to use a !ie$a$c!ical namin% convention( 8o$$y, no solutions on t!is today, 4 sim#ly i%no$e t!e #$o'lem in my desi%n(

A.1. . 3ealer
T!e deale$ ta'le tells me f$om /!om 4 #u$c!ased an item( Se$y sim#le contact info$mation and a comment field a$e used(

143

A.1.'. Images
+ scanned ima%e of a $ecei#t, o$ a #ictu$e of t!e item( T!e Came field contains Hust t!e file name and does not include t!e #at! to t!e ima%e( T!is is $e3ui$ed 'ecause t!e$e is no ot!e$ /ay to $eally unde$stand t!e file ty#e, ot!e$ t!an loo.in% at t!e file e6tension( +s a 'ina$y field, it could contain Hust a'out any data( T!e "omment field ty#ically contains sim#le te6t suc! as F$ecei#tG, so 4 .no/ /!at t!e ima%e is(

A.1.+. Item
E!at /as 4 t!in.in% /!en 4 c$eated t!e 4tem ta'leT
Field
Ma.e Model 8e$ial Date "ost Deale$4D Desc$i#tion "omment

Description
Manufactu$e$ suc! as Panasonic, JME, o$ Eilson "om'at( Model name and num'e$( 8e$ial num'e$ of t!e unit( E!en did 4 'uy itT <o/ muc! did 4 #ayT 9$om /!om did 4 'uy itT E!at is itT +nyt!in% else suc! as F4 li.e itG

4t tu$ns out t!at 4 !ave not follo/ed my convention fo$ ma.e and model( 4t is usually Hust easie$ to ente$ t!e full ma.e and model into a sin%le field( 4 use t!e desc$i#tion and comment fields fo$ most anyt!in% V so #e$!a#s 4 s!ould !ave Hust one field( Isually, 4 mention t!e /a$$anty, so 4 can Hust loo. in t!e data'ase to see if t!e item is still unde$ /a$$anty(

A.2. Forms
T!e data'ase evolved ove$ time, so fo$ms t!at 4 no lon%e$ use a$e still in t!e DJ(

A. .1. Item Two Tables


4 t!in. t!at 4 c$eated t!e 4tem /it! t/o ta'les fo$m usin% t!e /i5a$d /it! t!e items ta'le in t!e main fo$m, and t!e ima%es ta'le in a t!e su'&fo$m( T!e fo$m contains %a$'a%e c!a$acte$s to t!e $i%!t of t!e fi$st ta'le, t!is is a 'u% in eit!e$ 77o, o$ in my video d$ive$(

144

*igure "&. 1tems with two tables form. T!e title&'a$ indicates t!e data'ase, t!e ta'le name, and t!e te6t ,$ead&only-( Read&only indicates t!at you can not edit t!e fo$m in t!e cu$$ent mode( )ou can, !o/eve$, edit t!e data in t!e fo$m(

T!e st$uctu$e and $elations!i# of t!e fo$ms is ve$y sim#le:

*igure "%. *orm hierarchy. T!e Main9o$m !as content ty#e Ta'le, and t!e contents is 4TLM8( T!e 8u'9o$m !as ty#e Ta'le, and t!e contents is 4M+=L8( Lin. Maste$ 9ields, and Lin. 8lave 9ields a$e 'ot! set to 4TLM4D, since t!at is t!e name in 'ot! ta'les( T!e stated lin.s a$e clea$ly s!o/n in 9i%u$e 2?( + fe/ annoyances e6ist /it! t!is fo$m( 145

>( 4ma%es a$e not s!o/n, 'ut you .no/ t!at t!ey a$e t!e$e( 2( )ou must set t!e cate%o$y and deale$ 'ased on t!ei$ nume$ic 4D afte$ manually findin% an a##$o#$iate value( T!e ne6t fo$m sta$ts to deal /it! one issue(

A. . . Item One Table


T!e #u$#ose fo$ t!e item vie/ /it! one ta'le, /as to fi%u$e out !o/ to associate eac! $eco$d to t!e deale$ and cate%o$y( T!is fo$m includes t!e item ta'le in a %$id simila$ to 9i%u$e 2B( Jelo/ t!e %$id a$e t/o list 'o6es(

*igure "$. Two list bo7es. T!is $e#o$t !as only one fo$m( T!e cate%o$y list 'o6, t!e$efo$e, is in t!e fo$m, /!ic! is set to loo. at t!e item ta'le( T!e cont$ol !as t!e follo/in% %ene$al #$o#e$ties of inte$est:

8et t!e D$o#do/n #$o#e$ty to yes( 8et Line count to 5 to limit t!e si5e( 8et Multiselection to Co( 8et t!e Data field to "+TL=7R)4D ,f$om t!e item ta'le-( 8et Ty#e of list contents to 83l( Ise t!e 8PL in Listin% 8? fo$ t!e List content( T!is loads t!e list /it! t!e data f$om t!e "ate%o$y ta'le( +lt!ou%! t!e data is #o#ulated f$om t!e cate%o$y ta'le, t!e cont$ol is associated /it! a field f$om t!e items ta'le( 8et t!e 'ound field to >(

T!e Data ta' fo$ t!e cont$ol #$o#e$ites is a 'it mo$e inte$estin%(

Listing .'. )*L for the Category list box.


SELECT "DESCRIPTION", "CATEGORYID" FROM "CATEGORY" ORDER BY "DESCRIPTION"

146

+s you select diffe$ent $o/s in t!e %$id, t!e values in t!e d$o# do/n list c!an%e to $e#$esent t!e data in t!e item ta'le fo$ t!e cu$$ent $eco$d( +lso, c!oosin% a ne/ value in t!e d$o# do/n, sets t!e associated cate%o$y 4D in t!e item ta'le(

A. .'. Item 4ields


T!is fo$m adds t!e ima%e field, and 'uttons fo$ addin%, c!an%in%, and e6t$actin% ima%es(

*igure '5. 1tems with indi9idual fields. T!e$e a$e t/o inte$nal fo$ms, t!e main fo$m contains t!e item info$mation( T!e t/o d$o#& do/n list 'o6es a$e in t!e main item fo$m, and t!ey /o$. and a$e confi%u$ed in t!e same /ay as t!e 4tem 7ne Ta'le fo$m( 4n ot!e$ /o$ds, t!ey #e$fo$m a !el# and fill( T!e ve$y 'ottom line contains a navi%ation 'a$ fo$ t!e fi$st fo$m( T!e 'uttons to +dd, Delete, Re#lace, and L6t$act an ima%e a$e also in t!e main fo$m( T!e second fo$m contains t!e ima%e $elated fields( T!e ima%e fo$m also contains a navi%ation 'a$, /!ic! is used to navi%ate t!$ou%! t!e ima%es(

147

A.3. Add an image macro


T!e +dd 4ma%e 'utton is associated to t!e +dd4ma%eJutton mac$o( 9i$st, va$ia'les a$e decla$ed, and $e3ui$ed li'$a$ies a$e loaded( Cotice t!at an event a$%ument is #assed( Listing .-. ;dd an image to a form and database.
Sub AddImageButton(oEvent) Dim oImagesForm Dim oMainForm Dim nImage As Long Dim nImageName As Long Dim sFileName$ Dim sNameOnly$ REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If

T!e 'utton is contained in t!e main fo$m( T!e fo$m is, t!e$efo$e, t!e 'uttonKs #a$ent( T!e follo/in% ste#s occu$: ,>- =et t!e main fo$m, /!ic! is t!e 'uttonKs #a$ent( ,2- =et t!e contained 4ma%es fo$m, /!ic! is contained in t!e main fo$m(
oMainForm = oEvent.Source.getModel().getParent() oImagesForm = oMainForm.getByName("Images")

+s. t!e ima%e fo$m fo$ t!e column num'e$ of t!e ima%e field, and t!e name field(
nImage = oImagesForm.findColumn("IMAGE") nImageName = oImagesForm.findColumn("NAME")

4 /ant to inse$t an ima%e into t!e data'ase, 'ut 4 can not do t!is unless t!e main fo$m, /!ic! contains items, actually !as a $eco$d( E!en you use t!e fo$m to add a ne/ item, t!e fo$m moves to t!e inse$t $o/( 4 do not .no/ !o/ to tell if t!e cu$so$ is on t!e inse$t $o/, 'ut it loo.s li.e %etRo/,- $etu$ns 5e$o /!en t!is is t!e case( T!e follo/in% code c!ec.s t!e main fields in t!e fo$m to see if any data !as 'een ente$ed( 4f no data e6ists, t!en t!e mac$o e6its /it! a /a$nin%( 4f data is dete$mined to 'e #$esent ,and /e 'elieve t!at /e a$e on t!e Finse$tG $o/-, t!en /e call inse$tRo/,- to add t!e cu$$ent data to t!e data'ase(
If oMainForm.getRow() = 0 Then If IsEmpty(oMainForm.getByName("fmtITEMID").getCurrentValue()) AND _ IsEmpty(oMainForm.getByName("datDATE").getCurrentValue()) AND _ Len(oMainForm.getByName("txtCOMMENT").getCurrentValue()) = 0 AND _ Len(oMainForm.getByName("txtDESCRIPTION").getCurrentValue()) = 0 AND _ Len(oMainForm.getByName("txtSERIAL").getCurrentValue()) = 0 AND _ Len(oMainForm.getByName("txtMODEL").getCurrentValue()) = 0 Then MsgBox ("The current row contains no data") Exit Sub End If oMainForm.insertRow()

148

End If

+lt!ou%! it may ma.e sense to c!ec. fo$ u#dated data and t!en u#date t!e $o/, 4 do not( Ce6t, use t!e "!oose+9ile mac$o ,see Listing #%C, to select t!e file to in#ut( T!e file /it!out t!e #ass is sto$ed in sCame7nly, and it /ill 'e saved into t!e filename field(
sFileName = ChooseAFile$(GraphicFilters(), True) if Len(sFileName) < 1 Then Exit Sub End If sNameOnly$ = FileNameoutofPath(sFileName, "/")

4f t!e ima%es fo$m is on a cu$$ent $eco$d, call u#dateRo/,- Hust in case a field !as 'een u#dated in t!e fo$m( 4n ot!e$ /o$ds, save t!e data in case t!e$e is data to save( 4f 4 ne/ !o/ to c!ec. if t!e data /as c!an%ed, 4 /ould(
If oImagesForm.isAfterLast() OR oImagesForm.isBeforeFirst() Then Rem No need to save! Else Rem Save the current data oImagesForm.updateRow() End If

7#en t!e 'ina$y file(


Dim s$ Dim oSimpleFileAccess Dim oStream s$ = "com.sun.star.ucb.SimpleFileAccess" oSimpleFileAccess = createUnoService(s$) oStream = oSimpleFileAccess.openFileRead(sFileName)

9inally, use moveTo4nse$tRo/,- to inse$t a ne/ ima%e $eco$d, u#date t!e ima%e column usin% t!e st$eam to t!e ima%e, u#date t!e file name /it!out #at! fo$ t!e ima%e name column, and t!en tell t!e fo$m to inse$t t!e $o/(
oImagesForm.moveToInsertRow() oImagesForm.updateBinaryStream(nImage, oStream, oStream.getLength()) oImagesForm.updateString(nImageName, sNameOnly) oImagesForm.insertRow() End Sub

A.%. Delete an image macro


T!e Delete 4ma%e 'utton is associated to t!e Delete4ma%eJutton mac$o( T!e fi$st #o$tion is e6actly li.e addin% an ima%e( Sa$ia'les a$e decla$ed, $e3ui$ed li'$a$ies a$e loaded, and $efe$ences to fo$ms and columns a$e o'tained( Listing ... ,elete an image.
Sub DeleteImageButton(oEvent)

149

Dim Dim Dim Dim Dim Dim

oImagesForm oMainForm nImage As Long nImageName As Long sFileName$ sNameOnly$

REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If REM Inspect oEvent.Source oMainForm = oEvent.Source.getModel().getParent() oImagesForm = oMainForm.getByName("Images") nImage = oImagesForm.findColumn("IMAGE") nImageName = oImagesForm.findColumn("NAME")

4f t!e$e does not a##ea$ to 'e a $eco$d to delete, t!en e6it( 7t!e$/ise, as. if t!e ima%e s!ould 'e deleted(
If oImagesForm.isAfterLast() OR oImagesForm.isBeforeFirst() Then Exit Sub End If Dim i% i = MsgBox ("Delete current image?", 4, "Delete Image") If i <> 6 Then Exit Sub End If

Delete the current row, and then move to the next or previous record. Finally, reload the form.
oImagesForm.deleteRow() If oImagesForm.isLast() Then oImagesForm.previous() ElseIf NOT oImagesForm.next() Then oImagesForm.previous() End If oImagesForm.reload() End Sub

A.&. )eplace an image macro


T!e Re#lace 4ma%e 'utton is associated to t!e Re#lace4ma%eJutton mac$o( T!e fi$st #o$tion is e6actly li.e deletin% an ima%e( Sa$ia'les a$e decla$ed, $e3ui$ed li'$a$ies a$e loaded, $efe$ences to fo$ms and columns a$e o'tained, and if it loo.s li.e t!e$e is no ima%e to delete, t!en e6it t!e mac$o( 150

Listing .9. "eplace an image.


Sub ReplaceImageButton(oEvent) Dim oImagesForm Dim oMainForm Dim nImage As Long Dim nImageName As Long Dim sFileName$ Dim sNameOnly$ REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If REM Inspect oEvent.Source oMainForm = oEvent.Source.getModel().getParent() oImagesForm = oMainForm.getByName("Images") nImage = oImagesForm.findColumn("IMAGE") nImageName = oImagesForm.findColumn("NAME") If oImagesForm.isAfterLast() OR oImagesForm.isBeforeFirst() Then Exit Sub End If

8elect a file t!at /ill $e#lace t!e e6istin% ima%e( 4f no ima%e is c!osen, t!en e6it t!e mac$o( 4f a file is selected, o#en a st$eam to t!e file, u#date t!e ima%e, u#date t!e ima%e name, and t!en u#date t!e $o/( T!e only diffe$ence 'et/een u#datin% an ima%e and addin% a ne/ ima%e ,fo$ t!ese ste#s-, is t!at t!e $o/ is u#dated $at!e$ t!an inse$ted(
sFileName = ChooseAFile$(GraphicFilters(), True) if Len(sFileName) < 1 Then Exit Sub End If sNameOnly$ = FileNameoutofPath(sFileName, "/") Dim s$ Dim oSimpleFileAccess Dim oStream s$ = "com.sun.star.ucb.SimpleFileAccess" oSimpleFileAccess = createUnoService(s$) oStream = oSimpleFileAccess.openFileRead(sFileName) oImagesForm.updateBinaryStream(nImage, oStream, oStream.getLength()) oImagesForm.updateString(nImageName, sNameOnly) oImagesForm.updateRow() End Sub

151

A.0. '/tract an image macro


T!e L6t$act 4ma%e 'utton is associated to t!e L6t$act4ma%eJutton mac$o( T!e fi$st #o$tion is e6actly li.e deletin% o$ u#datin% an ima%e( Sa$ia'les a$e decla$ed, $e3ui$ed li'$a$ies a$e loaded, $efe$ences to fo$ms and columns a$e o'tained, and if it loo.s li.e t!e$e is no ima%e to delete, t!en e6it t!e mac$o( Listing 90. "eplace an image.
Sub ExtractImageButton(oEvent) Dim oImagesForm Dim oMainForm Dim nImage As Long Dim nImageName As Long Dim sFileName$ Dim sNameOnly$ REM Use some methods from the Tools library. If NOT GlobalScope.BasicLibraries.isLibraryLoaded("Tools") Then GlobalScope.BasicLibraries.LoadLibrary("Tools") End If REM Inspect oEvent.Source oMainForm = oEvent.Source.getModel().getParent() oImagesForm = oMainForm.getByName("Images") nImage = oImagesForm.findColumn("IMAGE") nImageName = oImagesForm.findColumn("NAME") If oImagesForm.isAfterLast() OR oImagesForm.isBeforeFirst() Then Exit Sub End If

T!e ima%e name is o'tained f$om t!e data'ase( T!e name /as saved so t!at t!e file name and, #e$!a#s mo$e im#o$tantly, so t!at t!e file e6tension /ould 'e .no/n( 4f t!e$e a##ea$s to 'e no #at! info$mation in t!e file name, t!en use t!e /o$.in% di$ecto$y(
sFileName = oImagesForm.getString(nImageName) If InStr(sFileName, "/") = 0 AND InStr(sFileName, "\") = 0 Then REM Does not contain any path components sFileName = GetWorkDir() & "/" & sFileName End If

8elect a ta$%et file name to save t!e file( T!e o$i%inal name is used as t!e default value( 4f no file is selected, t!en e6it t!e mac$o(
sFileName = ChooseAFile$(GraphicFilters(), False, sFileName) if Len(sFileName) < 1 Then Exit Sub End If

152

7'tain a st$eam f$om t!e data'ase, and st$eam t!e file to dis.(
Dim s$ Dim oSimpleFileAccess Dim oStream s$ = "com.sun.star.ucb.SimpleFileAccess" oSimpleFileAccess = createUnoService(s$) oStream = oImagesForm.getBinaryStream(nImage) oSimpleFileAccess.writeFile(sFileName, oStream) End Sub

A.1. Clean the database


4 co#ied my o$i%inal data'ase and 4 /anted to #lace a sam#le on my /e' site( 9i$st, !o/eve$, 4 /anted to ma.e ce$tain t!at deleted $eco$ds /e$e $eally $emoved( Ise Tools > S%& to o#en t!e 8PL /indo/( 4ssue t!e command F"<L"WP74CT DL9R+=G and t!en save and close t!e data'ase file(

A.7. *hings to do
T!e$e a$e so many t!in%s to do, 4 Hust do not !ave t!e time( +dd t!e a'ility to u#date t!e deale$ and cate%o$y usin% a fo$m( T!is s!ould 'e calla'le f$om t!e main fo$m( 9o$ no/, 4 manually edit t!e ta'le V yuc.;

153

You might also like