• Tidak ada hasil yang ditemukan

Directory listing of http: uap.unnes.ac.id ebook biblebook Visual Basic 6 com & Library Books

N/A
N/A
Protected

Academic year: 2017

Membagikan "Directory listing of http: uap.unnes.ac.id ebook biblebook Visual Basic 6 com & Library Books"

Copied!
28
0
0

Teks penuh

(1)

Working with

Recordsets —

Part I I

I

n this c hapter, I’ll c o ntinue my disc ussio n o f the ADO Recordseto bjec t by c o vering ho w to ac c ess the info rma-tio n c o ntained in the vario us fields. Then I’ll explain ho w to mo ve aro und and lo c ate rec o rds in the Recordset.

M ore About Recordsets

As yo u kno w, a Recordseto bjec t c o ntains a c o llec tio n o f ro ws returned fro m the database. Rather than make all o f the ro ws available to yo u at o ne time, it maintains a po inter to the c urrent ro w that yo u c an mo ve thro ugh the rec o rdset using vario us metho ds and pro perties. The info rmatio n c o ntained in the ro w’s c o lumns is made available thro ugh the Fields c o llec tio n. Depending o n yo ur c urso r type, yo u c an c hange the values lo c ally and then c o mmit the values to the database using the appro priate metho ds.

The Field Object

The Fieldo bjec t c o ntains info rmatio n abo ut a spec ific c o l-umn in a Recordset. It is part o f the Fieldsc o llec tio n, whic h c o ntains the set o f c o lumns retrieved fro m the database.

1 5

1 5

In This Cha pter

Accessing fields in a reco rdset

Mo ving aro und in a reco rdset

So rting and filtering ro ws

Co llecting reco rdset info rmatio n

G etting info rmatio n fro m fields

W o rking with larg e values

(2)

Field object properties

Table 15-1 lists the pro perties asso c iated with the Fieldo bjec t. Tables 15-2 and 15-3 c o ntain additio nal info rmatio n abo ut spec ific pro perties listed in Table 15-1.

Values, values and more values:Each field has three properties that describe its value. Value contains the current value of the field. OriginalValue contains the value as it w as originally retrieved from the database. UnderlyingValue

contains the current value for the field, w hich m ay reflect changes m ade by other transactions.

Table 15-1

Properties of the Field Object

Property Description

ActualSize A Longvalue containing the actual length of a field’s value.

Attributes An enum erated type describing the characteristics of the colum n (see Table 15-2).

DataFormat An object reference to a StdDataFormatobject containing inform ation about how to form at the data value.

DefinedSize A Longcontaining the m axim um length of a field’s value.

Name A Stringvalue containing the nam e of the field.

NumericScale A Bytevalue containing the num ber of digits to the right of the decim al point for a num eric field.

OriginalValue A Variantcontaining the original value of the field before any m odifications w ere m ade.

Precision A Bytevalue containing the total num ber of digits in a num eric field.

Properties An object reference to a Propertiescollection containing provider-specific inform ation about a field.

Type An enum erated type containing the OLE DB data type of the field (see Table 15-3).

UnderlyingValue A Variantcontaining the current value of the field in the database as it exists on the database server.

Value A Variantcontaining the current value of the field.

(3)

Table 15-2

Values for Attributes

Constant Value Description

adFldUnspecified -1 The provider doesn’t supply field attributes.

adFldMayDefer 2 The field value is not retrieved w ith the w hole record, but only w hen you explicitly access the field.

adFldUpdateable 4 The field’s value m ay be changed.

adFldUnknownUpdateable 8 The provider can’t determ ine if you can change the field’s value.

adFldFixed 16 The field contains fixed-length data.

adFldIsNullable 32 The field w ill accept Nullvalues.

adFldMayBeNull 64 The field m ay contain a Nullvalue.

adFldLong 128 The field contains a long binary value and you should use the AppendChunkand GetChunk

m ethods to access its data.

adFldRowID 256 The field contains an identity value w hich can’t be changed.

adFldRowVersion 512 The field contains a tim e stam p value that is used to track updates.

adFldCacheDeferred 4096 This field is cached by the provider and subsequent reads and w rites are done from cache.

adFldIsChapter 8192 The field contains a chapter value, w hich specifies a specific child Recordsetrelated to this parent field.

adFldNegativeScale 16384 The field contains a num eric colum n that supports negative scale values.

adFldKeyColumn 32768 The field is (or at least part of) the prim ary key for the table.

adFldIsRowURL 65536 The field contains the URL that nam es the resource from the data store represented by the record.

(4)

Table 15-2

(continued)

Constant Value Description

adFldIsDefaultStream 131072 The field contains the default stream for the resource represented by the record.

adFldIsCollection 262144 The field contains a collection of another resource such as a folder rather than a sim ple resource such as a file.

Table 15-3

Values for Type

Constant Value Description

adEmpty 0 This field has no value (OLE DB data type value:

DBTYPE_EMPTY).

adSmallInt 2 This field has an Integervalue (OLE DB data type value: DBTYPE_I2).

adInteger 3 This field has a Longvalue (OLE DB data type value:

DBTYPE_I4).

adSingle 4 This field has a Singlevalue (OLE DB data type value: DBTYPE_R4).

adDouble 5 This field has a Doublevalue (OLE DB data type value: DBTYPE_R8).

adCurrency 6 This field has a Currencyvalue (OLE DB data type value: DBTYPE_CY).

adDate 7 This field has a Datevalue (OLE DB data type value:

DBTYPE_DATE).

adBSTR 8 This field has a null-term inated Unicode string (OLE DB data type value: DBTYPE_BSTR).

adIDispatch 9 This field has a pointer to an IDispatchinterface in a COM object (OLE DB data type value:

DBTYPE_IDISPATCH).

adError 10 This field has a 32-bit error code (OLE DB data type value: DBTYPE_ERROR).

(5)

Constant Value Description

adVariant 12 This field has a Variantvalue (OLE DB data type value: DBTYPE_VARIANT). Note that w hile this type is supported by OLE DB, but it is not supported by ADO. Using it m ay cause unpredictable results.

adIUnknown 13 This field has a pointer to an IUnknowninterface in a COM object (OLE DB data type value:

DBTYPE_IUNKNOWN).

adDecimal 14 This field has an exact num eric value w ith a fixed precision and scale (OLE DB data type value:

DBTYPE_DECIMAL).

adTinyInt 16 This field has a one byte signed integer (OLE DB data type value: DBTYPE_I1).

adUnsignedTinyInt 17 This field has a one byte unsigned integer (OLE DB data type value: DBTYPE_UI1).

adUnsignedInt 18 This field has a tw o byte unsigned integer (OLE DB data type value: DBTYPE_UI2).

adUnsignedInt 19 This field has a four byte unsigned integer (OLE DB data type value: DBTYPE_UI4).

adBigInt 20 This field has an 8-byte signed integer (OLE DB data type value: DBTYPE_I8).

adUnsignedBigInt 21 This field has an 8-byte unsigned integer (OLE DB data type value: DBTYPE_UI8).

adFileTime 64 This field has a 64-bit date-tim e value represented as the num ber of 100-nanosecond intervals since 1 January 1601 (OLE DB data type value: DBTYPE_ FILETIME).

adGUID 72 This field has a globally unique identifier value (OLE DB data type value: DBTYPE_GUID).

adBinary 128 This field has a Binaryvalue (OLE DB data type value: DBTYPE_BYTES).

adChar 129 This field has a Stringvalue (OLE DB data type value: DBTYPE_STR).

adWChar 130 This field contains a null-term inated Unicode character string (OLE DB data type value: DBTYPE_ WSTR).

adNumeric 131 This field contains an exact num eric value w ith a fixed precision and scale (OLE DB data type value:

DBTYPE_NUMERIC).

(6)

Table 15-3

(continued)

Constant Value Description

adUserDefined 132 This field contains a user-defined value (DBTYPE_UDT).

adDBDate 133 This field has a date value using the YYYYMMDD

form at (OLE DB data type value: DBTYPE_DBDATE).

adDBTime 134 This field has a tim e value using the HHMMSSform at (OLE DB data type value: DBTYPE_DBTIME).

adDBTimeStamp 135 This field has a date-tim e stam p in the YYYYMMDDHH MMSSform at (OLE DB data type value: DBTYPE_ DBTIMESTAMP).

adChapter 136 This field has a 4-byte chapter value that identifies the row s in a child row set (OLE DB data type value:

DBTYPE_HCHAPTER).

adPropVariant 138 This field has an Autom ation PROPVARIANT(OLE DB data type value: DBTYPE_PROP_VARIANT).

adVarNumeric 139 This field contains a num eric value. (Available for

Parameterobjects only.)

adVarChar 200 This field contains a String. (Available for

Parameterobjects only.)

adLongVarChar 201 This field has a long character value. (Available for

Parameterobjects only.)

adVarWChar 202 This field has a null-term inated Unicode character string value. (Available for Parameterobjects only.)

adLongVarWChar 203 This field has a long null-term inated character string value. (Available for Parameterobjects only.)

adVarBinary 204 This field has a binary value. (Available for

Parameterobjects only.)

adLongVarBinary 205 This field has a long binary value. (Available for

Parameterobjects only.)

Field object methods

(7)

Sub AppendChunk (Data as Variant)

The AppendChunkmetho d is used to add data to a large text o r b inary field. The first time the AppendChunkmetho d is used, the value in Datawill o verwrite any existing data in the field. Fo r sub seq uent c alls, simply append data to the end o f the existing data.

Datais a Variantc o ntaining the data to be appended to the end o f the field.

Function GetChunk (Length as Long) as Variant

The GetChunkmetho d is used to retrieve data fro m a large text o r binary field. The first time GetChunkis c alled, the data will be retrieved fro m the start o f the field. Only the number o f bytes (o r Unic o de c harac ters) spec ified will be retrieved. Subsequent c alls will retrieve data fro m where the previo us c all left o ff. If yo u spec ify a length greater than the remaining data, o nly the remaining data will be returned witho ut padding.

A long, long chunk ago:You can only use the GetChunkand the AppendChunk

m ethods w hen the adFldLongbit is set in the Attributesproperty.

Lengthis a Longc o ntaining the number o f bytes o r c harac ters o f data to be retrieved.

The Fields Collection

The Fieldsc o llec tio n c o ntains the set o f c o lumns being returned in a Recordset o bjec t.

Fields collection properties

Table 15-4 lists the pro perties asso c iated with the Fieldsc o llec tio n.

Table 15-4

Properties of the Fields Collection

Property Description

Count A Longvalue containing the num ber of Fieldobjects in the collection.

Item(index) An object reference to a Fieldobject containing inform ation about a particular field in the Recordset. To locate a field, specify a value in the range of 0 to Count–1 or the nam e of the Field.

(8)

Special fields: The tw o special fields that are defined for a Recordobject are the default Streamobject (index = adDefaultStream) and the absolute URL for the Record(index = adRecordURL).

Fields collection methods

The Fieldsc o llec tio n c o ntains metho ds that are used to maintain the set o f Field o bjec ts.

Sub Append (Name As String, Type As DataTypeEnum, [DefinedSize As

Long], [Attrib As FieldAttributeEnum = adFldUnspecified], [FieldValue

As Variant])

The Appendmetho d c reates a new Fieldo bjec t and adds it to the Fieldsc o llec tio n.

Nameis a Stringvalue c o ntaining the name o f the field.

Typeis the data type that will be asso c iated with the new field.

DefinedSizeis a Longc o ntaining the size o f the new field.

Attribis a bit pattern c o ntaining values that determine the c harac teristic s o f the field ( see Table 15-2 fo r the po ssible values fo r this pro perty) .

FieldValueis a Variantthat c o ntains the value fo r the new field. If this value isn’t spec ified, then the field will be Null.

Sub Delete (Index As Variant)

The Deletemetho d remo ves a Fieldfro m the c o llec tio n. Indexis either a String c o ntaining the name o f the field o r a Longvalue c o ntaining the o rdinal po sitio n o f the Fieldo bjec t to be deleted.

Sub Refresh( )

The Refreshmetho d has no real effec t o n the Fieldsc o llec tio n. To see a c hange in the underlying database struc tures, yo u need to issue a Requerymetho d o f the Recordseto bjec t.

Sub Update( )

The Updatemetho d is used to save the c hanges yo u make to the Fieldsc o llec tio n.

(9)

M oving Around a Recordset

Yo u c an use the Recordseto bjec t to gain ac c ess to the set o f ro ws selec ted fro m the database. Yo u c an o nly ac c ess o ne ro w at a time with the curre nt re co rd po inte r, whic h allo ws yo u to use vario us metho ds and pro perties to c hange the rec o rd that the c urrent rec o rd po inter is po inting to .

The Recordset M ovement Demo program

To demo nstrate the different ways to mo ve aro und in a Recordset, I wro te the Rec o rdset Mo vement Demo pro gram ( see Figure 15-1) . This pro gram might no t win the award fo r the Wo rld’s Mo st Cluttered windo w, but it wo uld c ertainly plac e in the to p five. Ho wever, it do es ac c o mplish its go al o f presenting the maximum amo unt o f info rmatio n abo ut what happens when yo u mo ve aro und in a Recordset.

Figure 15-1: Running the Recordset Movem ent Dem o program

This program can be found on the CD-ROM in the \VB6DB\Chapter15\ RecordsetMovementDemodirectory.

(10)

Running the program

In o rder to try mo ving aro und in a rec o rdset with this pro gram, yo u must first c o nnec t to yo ur database. Enter yo ur user name and passwo rd info rmatio n in the appro -priate blanks in the Co nnec tio n frame and press the Co nnec t butto n. Respo nd Yes to the message bo x that asks “Do yo u really want to c o nnec t?”. If yo u were able to suc -c essfully -c o nne-c t to the database server, the message “Co nne-c ted” will be displayed in the status bar at the bo tto m o f the fo rm.

Onc e yo u’re c o nnec ted to the database server, yo u c an o pen the Recordsetin the Open Rec o rdset frame. Yo u may enter a two -c harac ter state name in the field c alled Selec t State to restric t the Recordsetso that it o nly c o ntains c usto mers fro m the spec ified state. Otherwise, the rec o rdset will c o ntain all o f the c usto mers fro m the database.

Yo u c an also spec ify the number o f rec o rds yo u want per page in the Page Size field. The default value is ten. Then yo u c an c ho o se values fo r Curso r Lo c atio n, Curso r Type, and Lo c k Type pro perties. Pressing Open Rec o rdset will o pen the rec o rdset. Yo u c an c hange any o f these values and press the Open Rec o rdset butto n to c lo se the c urrent rec o rdset and o pen it again with the new parameters.

The c urrent status o f the Recordseto bjec t is rec o rded in the Rec o rdset Status frame. The values fro m three fields are displayed, alo ng with the c urrent status o f the BOFand EOFpro perties. No rmally the BOF o r EOF bo xes will be blac k, indic ating that the c urrent rec o rd po inter isn’t po inting to either extreme. When yo u read either BOF o r EOF, the appro priate bo x will be displayed in yello w. If yo u are already o n BOF o r EOF and attempt to mo ve beyo nd the end o f the rec o rdset a sec o nd time, the bo x will be displayed in red. Also displayed are the values fro m the AbsolutePosition, RecordCount, AbsolutePage, PageCount,and Bookmarkpro perties.

Onc e yo u have o pened the Recordset, yo u c an mo ve aro und using the c o ntro ls in the Mo ve Demo , Filter, Find, and So rt frames o f the fo rm. No te that yo u c an’t update any o f the fields in the database. I’ll disc uss updating info rmatio n in a rec o rdset in Chapter 16.

Check before you click: I don’t check m ost of the input param eters before using them , so don’t be surprised if the program gets a fatal error or does som ething unpredictable if you enter the w rong value.

M odule level declarations

The Rec o rdset Mo vement Demo pro gram inc ludes a few variables dec lared at the mo dule level, making them glo bal to the entire mo dule ( see Listing 15-1) . These inc lude the Customers Recordseto bjec t, the db Connectiono bjec t and the SaveBookmarkvariable. No te that I dec lared bo th the Recordsetand Connection o bjec ts WithEvents, whic h allo w me to mo nito r the status o f bo th o bjec ts with the appro priate events to trac k their status.

(11)

Listing 15-1:

M odule level declarations for Recordset

M ovement Demo

Option Explicit

Dim WithEvents Customers As ADODB.Recordset Dim WithEvents db As ADODB.Connection Dim SaveBookmark As Variant

M oving sequentially

The c urrent rec o rd is a po inter to o ne o f the ro ws in the Recordset. Assume that yo u retrieve a Recordsetfro m yo ur datab ase with seven ro ws. Befo re the first ro w in the rec o rdset is a spec ial marker kno wn as the BOF, while the EOF marker is b eyo nd the end o f the last ro w. The c urrent rec o rd po inter c an po int to any o f these lo c atio ns ( see Figure 15-2) .

Figure 15-2: A logical view of the current record pointer

Absolutely addressed: The record num bers show n in Figure 15-2 correspond to the values of the AbsolutePositionproperty, except for BOF and EOF, w hich don’t have a corresponding value for AbsolutePosition.

When yo u first o pen a Recordset,the c urrent rec o rd po inter is po inting to the first rec o rd (assuming o f c o urse that there is at least o ne rec o rd in the rec o rdset). Fro m this lo c atio n, yo u c an mo ve to the next rec o rd (rec o rd number 2) in sequenc e using the MoveNextmetho d. Using the MoveLastmetho d will take yo u to rec o rd number 7, whic h is the last rec o rd in the rec o rdset. Yo u c an return to the first rec o rd by using the MoveFirstmetho d, and yo u c an mo ve to the previo us rec o rd using the MovePreviousmetho d.

Note

(12)

M oving beyond the ends

One pro blem with the MoveNextmetho d is that if yo u are at the last rec o rd in the rec o rdset, there is no thing to prevent yo u fro m trying to mo ve beyo nd the end. When this happens, the c urrent rec o rd po inter is mo ved to EOF. While the c urrent rec o rd po inter po ints to EOF, any attempt to ac c ess c o lumn info rmatio n results in an erro r. The same pro blem o c c urs with the MovePreviousmetho d and the begin-ning o f the Recordset.

The so lutio n to this pro blem is to no t leave the c urrent rec o rd po inter po inting to EOF o r BOF. This c o nditio n c an be detec ted by using the EOF and BOF pro perties. The EOFpro perty is TRUEo nly when the c urrent rec o rd po inter is po inting beyo nd the last rec o rd, while the BOFpro perty is o nly TRUEif the c urrent rec o rd po inter is po inting befo re the first rec o rd. No te that if bo th pro perties are TRUE, the Recordset do esn’t c o ntain any rec o rds.

Using the M oveNext method

Using these metho ds is very straightfo rward. All yo u really need to do is to c all the desired metho d; ho wever, this isn’t really prac tic al sinc e it do esn’t do any erro r c hec king. A mo re prac tic al example is sho wn in Listing 15-2. This ro utine verifies that the Recordsetisn’t already at the end o f file marker befo re it c alls the MoveNextmetho d. This ensures that yo u c an’t mo ve beyo nd EOF.

Listing 15-2:

The M oveNextDemo routine

Sub MoveNextDemo()

If Not Customers.EOF Then Customers.MoveNext

End If

End Sub

An alternate M oveNext

(13)

Listing 15-3:

The Command5_Click event in Recordset

M ovement Demo

Private Sub Command5_Click()

On Error Resume Next

StatusBar1.SimpleText = “” Err.Clear

Customers.MoveNext If Err.Number <> 0 Then

WriteError

End If

End Sub

Ho wever, to make the Co mmand5_Clic k event wo rk pro perly, I also have to c o de the WillMoveevent to detec t and c anc el any attempt to mo ve beyo nd the BOF o r EOF ( see Listing 15-4) . This ro utine detec ts when yo u are at EOF o r BOF and are abo ut to perfo rm a metho d that wo uld trigger an erro r, and sets the adStatusparameter to adStatusCancelto return an erro r c o nditio n.

Listing 15-4:

The Customers_WillM ove event in Recordset

M ovement Demo

Private Sub Customers_WillMove( _

ByVal adReason As ADODB.EventReasonEnum, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset)

If Customers.BOF And adReason = adRsnMovePrevious Then adStatus = adStatusCancel

End If

If Customers.EOF And adReason = adRsnMoveNext Then adStatus = adStatusCancel

End If

(14)

M oving randomly

There are several ways to mo ve aro und the Recordsetrando mly. The o ne yo u sho uld use depends o n what yo u are trying to ac c o mplish. The Bookmarkpro perty allo ws yo u to save the lo c atio n o f a ro w and be able to return to that ro w at so me future po int in time. The Movemetho d allo ws yo u to mo ve fo rward o r bac kward the spec ified number o f ro ws. The AbsolutePagepro perty allo ws yo u to jump to the spec ified page number in the Recordset. If yo ur rec o rdset suppo rts it, yo u c an also use the AbsolutePositionpro perty to po sitio n the c urso r at a spec ific lo c a-tio n in the rec o rdset.

Using bookmarks

The Bookmarkpro perty c o ntains the c urrent lo c atio n o f a rec o rd in a Recordset. It is a Variantvalue that is highly dependent o n the data pro vider. It is po ssible to have multiple bo o kmarks that po int to the same rec o rd, but eac h bo o kmark is a dif-ferent value. The o nly way to c o mpare bo o kmarks is to use the CompareBookmarks metho d. Also , a Bookmarkis spec ific to the Recordsetthat it c ame fro m. Yo u c an’t use it with any o ther rec o rdsets, even if they were c reated with the same c o mmand.

Cloned again: A Bookmarkcan be used w ith any copy of a Recordsetthat w as created using the Clonem ethod.

To save a bo o kmark, simply dec lare a Variantvariable and save the value o f the Bookmarkpro perty to it, as sho wn belo w.

SaveBookmark = Customers.Bookmark

This saves the lo c atio n o f the c urrent rec o rd. Then after mo ving to a different rec o rd, yo u c an mo ve the c urrent rec o rd po inter bac k to the bo o kmarked lo c atio n by assigning the value yo u saved bac k to the Bookmarkpro perty. When yo u add so me erro r-handling lo gic , yo u end up with c o de like yo u see in Listing 15-5.

Listing 15-5:

The Command8_Click of Recordset M ovement

Demo

Private Sub Command8_Click()

On Error Resume Next

StatusBar1.SimpleText = “” Err.Clear

Customers.Bookmark = SaveBookmark

(15)

If Err.Number <> 0 Then WriteError

End If

End Sub

M oving forward and backward

The Movemetho d takes two parameters: the number o f ro ws to mo ve and an o ptio nal Bookmarkthat will be used as the starting lo c atio n. The number o f ro ws may be either po sitive o r negative. A po sitive value will mo ve the spec ified number o f ro ws to ward the last ro w o f the Recordset, while a negative value will mo ve to ward the first ro w. If yo u spec ify a value o f zero , the c urrent rec o rd will be refreshed.

Spec ifying the bo o kmark c o mputes the o ffset relative to that rec o rd rather than the c urrent rec o rd. Of c o urse, the Recordsetmust suppo rt bo o kmarks in o rder to use this parameter.

Listing 15-6 sho ws ho w easy it is to c all the Movemetho d. While yo u might think that the erro r c hec king in this ro utine isn’t nec essary, think again. If yo u spec ify to o large o f a value ( fo r example, o ne that wo uld take yo u beyo nd the end o f the rec o rd-set) , a run-time erro r will be triggered.

Listing 15-6:

The Command7_Click event of Recordset

M ovement Demo

Private Sub Command7_Click()

On Error Resume Next

StatusBar1.SimpleText = “” Err.Clear

Customers.Move CLng(Text14.Text) If Err.Number <> 0 Then

WriteError

End If

(16)

Reading pages

One o f the mo re interesting features o f ADO is its ability to manage data in terms o f pages. A page is a gro up o f rec o rds fro m the database. The PageSizepro perty determines the number o f rec o rds in a page, while the PageCountpro perty tells yo u the number o f pages in yo ur Recordset. The AbsolutePagepro perty c o ntains the relative number o f the c urrent in the rec o rdset.

Yo u c an repo sitio n the c urrent rec o rd po inter by setting the AbsolutePagepro p-erty to a partic ular page, as sho wn belo w:

Customers.AbsolutePage = CLng(Text18.Text)

This will mo ve the c urrent rec o rd po inter to the first rec o rd o n that page. Yo u c an even c hange the PageSizepro perty while the Recordseto bjec t is o pen, whic h makes it easy to c hange the number o f rec o rds displayed per page o n the fly.

Internet ready: The page properties are often useful in an Internet or transaction-oriented environm ent w here a user scrolls though a recordset one page at a tim e. You can use the AbsolutePageproperty to determ ine w hich page needs to be displayed, and then use the MoveNextm ethod to retrieve the rem aining row s on the page.

Absolute positioning

If yo ur rec o rdset suppo rts the AbsolutePositionand RecordCountpro perties, yo u c an determine the c urrent rec o rd numb er and the to tal rec o rds in yo ur Recordset. The AbsolutePositionpro perty will also allo w yo u to mo ve the c urso r to the spec ified lo c atio n.

Absolute ain’t accurate: You should not use the AbsolutePositionproperty in place of bookm arks. Depending on the options you select w hen you open your recordset, the actual record pointed to by the AbsolutePositionm ay change as other records are added and deleted from the recordset. Don’t assum e that if you haven’t added or deleted a record, this value w on’t change. Rem em ber —depend-ing on the type of cursor you select, changes m ade by other database users m ay affect the value of AbsolutePositionassociated w ith a particular row.

Searching, Sorting, and Filtering

Ano ther c o mmo n need is the ability to find and o rganize the info rmatio n within a rec o rdset. The Recordseto bjec t inc ludes a metho d to find a partic ular ro w by searc hing fo r a value, and a metho d to so rt the rec o rds c o ntained in the rec o rdset by a spec ified list o f fields.

(17)

Finding a row

One c o mmo n pro blem with retrieving a large number o f rec o rds is trying to find a partic ular value in the Recordset. The easiest way to address this pro blem is to use the Findmetho d.

The Findmetho d allo ws yo u to spec ify a searc h string c o nsisting o f a c o lumn name, a relatio nal o perato r, and a value. If the value is a string, it must be enc lo sed in either single quo tes ( ‘ ) o r po und signs ( # ) . Do uble quo tes ( “ ) may no t be used. Po und signs must enc lo se date values.

If yo u use the Likeo perato r, yo u may also use an asterisk ( * ) as a wild c ard c harac -ter in any stringvalue. Ho wever, the asterisk must be the last c harac ter in the value o r the o nly c harac ter in the value. Otherwise a run-time erro r will o c c ur.

The Findmetho d has several arguments in additio n to the searc h c o nditio n. Spec ify the number o f ro ws to skip befo re beginning yo ur searc h; o therwise, the searc h will begin with the c urrent ro w. So , yo u sho uld spec ify a value o f o ne if yo u want to find the next o c c urrenc e o f a value.

Yo u c an also spec ify whether yo u want to searc h bac kwards ( to ward the beginning) o r fo rwards ( to ward the end) o f the rec o rdset, and yo u may spec ify a bo o kmark fro m where the searc h will begin.

Like mo st o f the Recordsetmetho ds I’ve talked abo ut so far, yo u simply c all the metho d with the list o f arguments yo u wish to use, and inc lude the appro priate erro r c hec king to prevent a run-time erro r fro m o c c urring if yo u c an’t find the rec o rd o r yo ur searc h c o nditio n c o ntains an erro r ( see Listing 15-7) .

Listing 15-7:

The Command10_Click event of Recordset

M ovement Demo

Private Sub Command10_Click()

On Error Resume Next

StatusBar1.SimpleText = “” Err.Clear

Customers.Find Text17.Text, 1 If Err.Number <> 0 Then

WriteError

End If

(18)

For client-side cursors only: The Seek m ethod provides an alternative to the

Find m ethod, but is only available w hen you are using client-side cursors (dis-cussed in Chapter 14). You begin by specifying the nam e of an index in the Index

property and then supplying a list of values to search for that corresponds to the colum ns in the index (i.e., if your index has only one colum n, only one value m ay be supplied). Note that not all providers support this feature, including the one for SQL Server, so you m ay w ant to use the Supportsm ethod to determ ine if the

Seekm ethod is supported.

Sorting rows

The Sortpro perty c o ntains the list o f c o lumns that are used to so rt yo ur rec o rd-set. Thus, o ne way yo u c an so rt the rec o rdset in the sample pro gram is by setting the Sortpro perty to the fo llo wing value:

State, Name Desc

This so rt key will so rt the ro ws by State in asc ending o rder and then by the Name c o lumn in desc ending o rder.

The Sortpro perty is available o nly fo r c lient-side rec o rdsets, whic h means yo u may want to do a little extra erro r c hec king, espec ially if yo u use multiple c urso r types. The erro r message that wo uld no rmally be issued ( “Objec t o r pro vider is no t c apable o f perfo rming requested o peratio n”) do esn’t fully desc ribe what c aused the erro r.

Listing 15-8 c o ntains so me sample c o de that will so rt the info rmatio n in a rec o rdset. The ro utine begins by getting the so rt key fro m the fo rm and assigning it to the Sortpro perty. Then I c hec k fo r erro rs and display the appro priate erro r message. An erro r c o de o f 3251 implies that the user attempted to so rt the rec o rdset witho ut using a c lient-side c urso r.

Listing 15-8:

The Command13_Click event in Recordset

M ovement Demo

Private Sub Command13_Click()

On Error Resume Next

Err.Clear

Customers.Sort = Text19.Text If Err.Number = 3251 And _

Customers.CursorLocation = adUseServer Then StatusBar1.SimpleText = _

(19)

“Can’t sort while using server cursors.”

ElseIf Err.Number <> 0 Then WriteError

End If

End Sub

Filtering rows

One o f my favo rite to o ls available in a Recordseto bjec t — o ne that will help yo u lo c ate a partic ular rec o rd — is the Filterpro perty. Only tho se ro ws that meet the filter c riteria yo u spec ify will be visible in the rec o rdset.

Yo u c an filter yo ur rec o rdset using a string whic h is similar to the c o nditio n yo u wo uld spec ify in the Whe re c lause o f a Se le ctstatement. A co nditio nis c o mpo sed o f o ne o r mo re simple expressio ns c o mpo sed o f c o lumn names, relatio nal o pera-to rs, and values that c an be gro uped pera-to gether, as in this example:

State = ‘MD’ And CustomerId > 100

To remo ve a filter, simply set the Bookmarkpro perty to zero o r the c o nstant adFilterNone. The o riginal c o ntents o f the rec o rdset will no w be ac c essible.

If yo u c reate an array o f bo o kmark values and assign it to the Filterpro perty, o nly the ro ws in the array will be visible in the rec o rdset. Yo u c an also assign the Filter pro perty a value fro m the FilterGroupEnumdata type. Aside fro m adFilterNone, these values are used primarily fo r reviewing the results o f batc h updates, whic h I’ll talk abo ut in the next c hapter.

Why did it change?: Using the Filterproperty w ill change the values in the

AbsolutePosition, AbsolutePage, RecordCount,and PageCount proper-ties for a specific row. If you need to rem em ber w here a particular row is located, you should use the Bookmarkproperty, w hich w ill rem ain unchanged no m atter w hat the value of the Filterproperty.

Listing 15-9 desc ribes a ro utine that applies the value spec ified in the Text16text bo x as a filter to the Customersrec o rdset. If the length o f the text is zero , then I explic itly remo ve the filter by assigning the Filterpro perty the value

adFilterNone.

(20)

Listing 15-9:

The Command9_Click event in Recordset

M ovement Demo

Private Sub Command9_Click()

On Error Resume Next

StatusBar1.SimpleText = “” Err.Clear

If Len(Text16.Text) = 0 Then Customers.Filter = adFilterNone

Else

Customers.Filter = Text16.Text

End If

If Err.Number <> 0 Then WriteError

End If

End Sub

Collecting recordset information

There are two events asso c iated with c hanging the po sitio n o f the c urrent rec o rd po inter in the Recordseto bjec t. I talked abo ut the WillMoveevent earlier in this c hapter ( see Listing 15-4) , and no w I want to talk abo ut the MoveCompleteevent. This is an exc ellent plac e to display the c urrent status o f a rec o rdset.

You don’t need to do this: In this sam ple program , I w anted to dem onstrate clearly how the various status fields change w hile you perform various tasks using a Recordset. The easiest w ay for m e to do this w as to trap the state of the object using the MoveCompleteevent. How ever, this isn’t som ething you need to do in your ow n program s. You can easily test the various properties directly after you perform a task. Thus, you don’t need to use the MoveCompleteevent.

Listing 15-10:

The Customers_M oveComplete event in

Recordset M ovement Demo

Private Sub Customers_MoveComplete( _

ByVal adReason As ADODB.EventReasonEnum, _ ByVal pError As ADODB.Error, _

adStatus As ADODB.EventStatusEnum, _

(21)

ByVal pRecordset As ADODB.Recordset)

On Error Resume Next

If Customers.BOF And adStatus = adStatusErrorsOccurred Then Text5.BackColor = RGB(255, 0, 0)

ElseIf Customers.BOF Then

Text5.BackColor = RGB(255, 255, 0)

Else

Text5.BackColor = RGB(0, 0, 0)

End If

If Customers.EOF And adStatus = adStatusErrorsOccurred Then Text6.BackColor = RGB(255, 0, 0)

ElseIf Customers.EOF Then

Text6.BackColor = RGB(255, 255, 0)

Else

Text6.BackColor = RGB(0, 0, 0)

End If

Text9.Text = FormatNumber(Customers.AbsolutePosition, 0) Text10.Text = FormatNumber(Customers.RecordCount, 0) Text11.Text = FormatNumber(Customers.AbsolutePage, 0) Text12.Text = FormatNumber(Customers.PageCount, 0)

Err.Clear

Text13.Text = Customers.Bookmark If Err.Number <> 0 Then

Text13.Text = “The bookmark isn’t available.”

End If

End Sub

(22)

This means that the user attempted to mo ve past the BOF o r EOF marker. The easi-est way to implement this in c o de is to start with the last c o nditio n ( bec ause it’s the mo st restric tive) and wo rk my way bac kwards.

After I set the BOF and EOF flags, I display the pro perties fo r AbsolutePosition, RecordCount, AbsolutePage,and PageCount. Then I attempt to grab the c urrent bo o kmark. If the Bookmarkisn’t available, I’ll trigger a run-time erro r and display a message that indic ates this.

Getting Information From Fields

Mo ving aro und a rec o rdset is impo rtant, but retrieving info rmatio n fro m a field is equally impo rtant. Eac h o f the sample pro grams in Part III o f this bo o k has used the Fieldsc o llec tio n and so me Fieldo bjec ts to display data. In so me c ases, this was do ne explic itly thro ugh statements like this:

Text1.Text = FormatNumber(rs.Fields(0).Value, 0)

while o ther pro grams used the Recordseto bjec t as the data so urc e and bo und vario us c o ntro ls o n the fo rm to the individual Fieldo bjec ts.

Binding a field to a control

The same pro perties that yo u use to bind a c o ntro l to the ADO Data Co ntro l are also used to bind to a Recordset. Ho wever, unlike the ADO Data Co ntro l, yo u c an’t bind the c o ntro ls at design time, sinc e the Recordseto bjec t do esn’t exist. So yo u need to set these pro perties at runtime. In fac t, yo u c an o nly set these pro perties while the Recordseto bjec t is o pen. This means that if yo u c lo se a rec o rdset and reo pen it, yo u need to rebind all o f yo ur c o ntro ls.

Sho wn belo w is a c o de fragment that c o ntains the key pro perties yo u need to set in o rder to bind a field to a c o ntro l. The DataFieldpro perty c o ntains the name o f the c o lumn yo u want to bind the c o ntro l to , while the DataSourcepro perty c o ntains an o bjec t referenc e to the Recordseto bjec t. No te that yo u must use the Set state-ment to make this assignstate-ment.

Text3.DataField = “Name”

Set Text3.DataSource = Customers

Accessing field values

(23)

Referencing a field’s value

Visual Basic pro vides many different ways fo r yo u to retrieve a value fro m a Field o bjec t. Yo u c an use the traditio nal o bjec t-o riented way by spec ifying the Recordset o bjec t and wo rking yo ur way do wn to the lo west level o bjec t. The fo llo wing expres-sio ns take advantage o f the default pro perties o f the Recordseto bjec t and the Fieldsand Itemsc o llec tio ns to return the value o f the “Name” field. No te that yo u c an replac e the value “Name”with the numeric po sitio n o f the field in the Fields c o llec tio n.

Customers.Fields.Items(“Name”).Value Recordset.Fields.Items(“Name”) Recordset.Fields(“Name”).Value Recordset.Fields(“Name”) Recordset(“Name”)

Fewer is faster: The few er periods (.) included in an object reference, the faster it w ill run. Each period m eans that a call m ust be m ade to the object to determ ine if the follow ing property is valid and to get a reference to the code that w ill process it. The inform ation needed to call the object’s default property is autom atically retrieved w hen the object is created.

An alternate way to retrieve a value is by using an exc lamatio n mark ( !) , as sho wn belo w.

Recordset!Name

No te that in this fo rmat, the field name must be spec ified witho ut single quo tes ( ‘) and spac es. Yo u also c an’t use a numeric referenc e to the field. Ho wever, if yo u enc lo se the field name using square brac kets ( [ ] ) , yo u c an use any o f these values as sho wn belo w.

Recordset![First Name]

Other field values

There are two o ther value pro perties asso c iated with a Fieldo bjec t: the

OriginalValueand the UnderlyingValue. The OriginalValuefield c o ntains the value o f the Fieldo bjec t as it was when it was retrieved fro m the database. This value is useful when yo u want to resto re the o riginal value after yo u c hange it. The UnderlyingValuec o ntains the value fo r this field in this ro w, as it c urrently exists in the database when yo u ac c ess this pro perty.

Working with large values

When yo u dec lare a c o lumn as NTe xt, Te xt,o r Image, yo u c an’t use the Valuepro p-erty to ac c ess the data. Instead, yo u must use the GetChunkmetho d to retrieve

(24)

info rmatio n fro m the field, and the AppendChunkmetho d to save values to the field. These metho ds wo rk basic ally the same fo r all three types o f data, so I’m just go ing to talk abo ut Imagefields in this sec tio n. Mo st peo ple are go ing to use them fo r graphic images, binary do c uments ( suc h as RTF files, Exc el Wo rksheets, and so o n) o r o ther fo rms o f binary data.

Bound controls

Chanc es are, the reaso n yo u’re using large c o lumns is that yo u want to ho ld an image o r a large text do c ument. If that’s true, then yo u sho uld take advantage o f c o ntro ls like the Image, Picture,and the Rich Text Boxthat are c apable o f being bo und to a field in a rec o rdset and c an handle large vo lumes o f data.

Imperfect images: Changing the im age in either the Picture control or the

Imagecontrol w ill not update the field in the recordset. You m ust explicitly load the im age into the field. Even if you w ere able to save the im age in the control, you w ould be better off storing the im age in either .GIF or .JPGform at in the database, rather than storing the uncom pressed bit m ap im age used by the

Pictureand Imagecontrols.

Loading images

One o f the mo st c o mmo n questio ns I’ve heard peo ple ask is ho w to lo ad an image into an Imagedatabase field fro m a Visual Basic pro gram. The answer is sho wn in Listing 15-11. The real tric k is to use a Bytearray and Redimthe size so that the array has the same number o f bytes as the image file. Then it’s merely a matter o f o pening the file fo r binary ac c ess and using the Getstatement to read the image into the array in a single c hunk. Onc e yo u’ve lo aded the image into memo ry, yo u c an use the AppendChunkmetho d to c o py it into the Fieldo bjec t, and then Updateto save it to the database.

You can find the Recordset Update Dem o program on the CD-ROM in the

\VB6DB\Chapter16\RecordsetUpdateDemo directory.

Listing 15-11:

The Command14_Click event in Recordset

Update Demo

Private Sub Command14_Click()

Dim f As String Dim img() As Byte

f = InputBox(“Enter image file name:”)

On the CD-ROM

(25)

f = App.Path & “\” & f

If Len(Dir(f)) > 0 Then

Open f For Binary Access Read As #1 ReDim img(FileLen(f) - 1)

Get #1, , img() Close #1

Images(“Image”).AppendChunk img Image1.Picture = LoadPicture(f)

Else

Image1.Picture = LoadPicture()

End If

End Sub

Zero counts, too:When m oving data from a file to a Bytearray, rem em ber that the array w ill start w ith zero, so the size of the array m ust be one byte less than size of the file to allow for the zeroth byte in the array.

While it is po ssib le to use a lo o p like the o ne sho wn b elo w to lo ad an image, I feel that it isn’t wo rth the effo rt fo r files smaller than a megab yte o r so . Ho wever, yo u c an use the fo llo wing c o de to replac e the statements in Listing 15-11 fro m the Open statement to the Closestatement to perfo rm a lo o p. No te that this ro utine b egins b y c o pying the o dd size b lo c k first and then c o pying c hunks in a fixed b lo c k size. Otherwise, yo u’d have to keep trac k o f the numb er o f b ytes transferred to deter-mine when yo u are ab o ut to read the last b lo c k so yo u may ReDimthe Bytearray in o rder to transfer o nly the appro priate amo unt o f data.

Open f For Binary Access Read As #1 ReDim img(FileLen(f) Mod 1024 - 1) Get #1, , img()

Do While Not EOF(1)

Images.Fields(“Image”).AppendChunk img ReDim img(1023)

Get #1, , img

Loop Close #1

Saving images

The c o de to save the value in a lo ng field isn’t very different than it is to lo ad the data into the field. If po ssible, it’s best to try to deal with the data in a single c hunk, as sho wn in Listing 15-12.

(26)

Listing 15-12:

The Command15_Click event in Recordset

Update Demo

Private Sub Command15_Click()

Dim f As String Dim img() As Byte

f = InputBox(“Enter image file name:”) f = App.Path & “\” & f

ReDim img(Images.Fields(“Image”).ActualSize - 1) Open f For Binary Access Write As #1

img = Images.Fields(“Image”).GetChunk(UBound(img) + 1) Put #1, , img

Close #1

End Sub

Thoughts on Designing Database Applications

There are tw o basic w ays to design a database application. One w ay is to perm it the user to scroll through from one record to another through the entire recordset. The second w ay is to ask the user for a key value, w hich w ill return only the records related to the key. Both approaches have strengths and w eaknesses, and you can build effective program s using either technique.

The first m ethod w orks w ell if you w ant to use the ADO Data Control. The ADO Data Control opens a connection to the database and its Recordsetobject as soon as the form con-taining it is show n. How ever, this isn’t practical for large, m ulti-user applications. It can be difficult for a user to find a particular row in the data, w hile at the sam e tim e consum ing a lot of database resources. How ever, this approach is ideal for sm all databases, w here the num ber of records is sm all enough that the scrolling ability is appreciated and you have a sufficiently sm all num ber of users that w on’t overw helm the database server.

(27)

Summary

In this c hapter yo u learned the fo llo wing:

✦Yo u c an use the Fieldsc o llec tio n to ac c ess the c o llec tio n o f c o lumns retrieved fro m the database.

✦Yo u c an use the Fieldo b jec t to ac c ess the info rmatio n asso c iated with a single c o lumn.

✦Yo u c an use many different metho ds to selec t a rec o rd fro m the rec o rdset, inc luding MoveFirst, MoveNext, MovePrev, MoveLast, Move, Bookmark, AbsoluteRecordand AbsolutePage.

✦Yo u c an use the Sortpro perty to so rt the info rmatio n in a rec o rdset and the Findmetho d to lo c ate a partic ular ro w in a rec o rdset.

✦Yo u c an use the GetChunkand AppendChunkmetho ds to retrieve and sto re info rmatio n in large values in yo ur rec o rdset, suc h as images.

(28)

Gambar

Table 15-1Properties of the Field Object
Table 15-2Values for Attributes
Table 15-3Values for Type
Table 15-3 (continued)
+4

Referensi

Dokumen terkait

Adapun tujuan diadakannya indeks saham syariah sebagaiman Jakarta Islamic Index yang melibatkan 30 saham terpilih, yaitu sebagai tolak ukur untuk mengukur kinerja

You can download and install the soft file of this incredible book Time Mends (Timber Wolves, Book 2) By Tammy Blackwell currently and in the link offered.. Yeah, different with

Indonesia merupakan negara dengan orang muslim terbesar didunia, akan tetapi setiap ormas muslim sendiri tentunya berbeda dalam memutuskan suatu masalah baru yang muncul

54 Tahun 2010 tentang Pengadaan Barang/Jasa Pemerintah serta menindaklanjuti proses seleksi untuk Paket Pekerjaan Pengadaan Meubelair (985 Unit) , bersama ini kami

Additionally, Aaron developed a wide variety of exercises and stretches specific for posture and alignment based on the personal needs and desires of the many clients he has served

Uang merupakan uang milik masyarakat atau uang beredar di masyarakat (di luar Bank Sentral seperti Bank Indonesia dan perbankan atau semua bank), yang terdiri dari :.. Uang Kertas

Puji syukur kami panjatkan kepada Tuhan Yang Maha Esa atas limpahan rahmat dan hidayah-Nya sehingga Prosiding Seminar Nasional MIPA Universitas Negeri Yogyakarta

As everybody recognizes, book Carr: Five Years Of Rape And Murder By Edna Buchanan is very popular as the window to open up the globe. It implies that reading publication Carr: