Tải bản đầy đủ - 0 (trang)
Hack 44. Sort Any Arbitrary String of Characters

Hack 44. Sort Any Arbitrary String of Characters

Tải bản đầy đủ - 0trang

ThedateisOctober23,2004.

Theamountis$45.95.

Let'ssayyouneedtosorttherecordsbydate.Asshownin

Figure5-12,ineachrecord,thedatestartsinposition3and

takesupsixplaces.

Haveyoueverworkedwithdatasuchasthis?Youneeda

recordlayouttogowiththedata;otherwise,youcan'ttellwhat

kindofdataitis.Whatifyouhadtoguesswhichcharacters

makeupthedate?Garbagein,garbageout,asthesaying

goes.

ThebestwaytotackleaproblemsuchasthisistousetheMid

function.Midisoneofthefunctionsthatletyoumanipulate

textualdata.Itworksbyisolatingapartofalargertextstring.

YouhavetotellMidtHReethings:thestringofdata,theposition

youwanttostartfrom,andhowmanycharacterstoinclude.

Thesyntaxlookslikethis:





Mid(string,startingposition,length)



Eventhoughweareconceptuallyworkingwithdatesinthisexample,

thestoredinformationisintextformat.Therefore,it'seasyto

manipulatethedatewithstandardstringfunctions.



Figure5-13showsaquerydesigninwhichtheMidfunctionis

used.ThefirstcolumnistheSalesDatafielditself,andthe

secondcolumnisacalculatedfieldusingtheMidfunction.Within

thefunction,SalesDataisenclosedinbrackets.Thisisthe



standardwaytoputafieldnameinafunction.Mid'sparameters

aresettoisolatesixcharactersstartingatposition3(thedate,

inotherwords).



Figure5-12.Avendorcode,date,andamount,

combinedinonefield



Whenthequeryruns,thesecondcolumnhasjustthedateinit



becauseMiddoesthejobofgrabbingthecharactersfrom

positions3through8.Thesecondcolumnreceivesthesort

because,afterall,thedateiswhatweneedtosorton.So,

wheretheSortrowandthesecondcolumnmeet,setthechoice

tosortinascendingorderbyselectingAscendingfromthe

drop-downmenu.

NoteinFigure5-13thattheShowcheckboxforthecalculated

fieldisunchecked.Youdon'thavetoactuallydisplaythecolumn

whenthequeryisrun.Itisusedjusttomakethesorthappen,

butitdoesn'tnecessarilyhavetoappearintheresults.



Figure5-13.UsingtheMidfunctiontoisolatethe

dateforsorting



Figure5-14showstheresultofrunningthequery.Nowthe

salesrecordsaresortedbydate.Thefirstreturnedrecord

(MR0104047011)contains010404,theequivalentofJanuary4,



2004.



Figure5-14.Recordssortedbydate



5.6.2.SortingonMixedFixedPositions

Whatifyouhavetosortonboththedateandtheamount?

Whatifthesorthastoshowthedateinascendingorderand

theamountindescendingorder?Thisisacommon

requirement:toseemoneyamountssortedfromhightolow.

Canyoudothis?

Butofcourse!Inthiscase,thetechniqueistohavetwo

columnswithexpressions,oneeachforthedateandthe

amount.Figure5-15showshowyoudothis,withtheamount

startingintheninthposition.ThelengthparameterfortheMid



functionthatprocessestheamountissetto5.Usually,alength

isknown,butnotalways.Inthisexample,theamountsamong

therecordsmightbefourorfivedigitslong,sosettingthe

lengthto5worksforallrecords.



Figure5-15.Aquerydesignforsortingontwo

subsectionsofthefield



Inthisexample,asbefore,onlytheactualSalesDatafieldis

shownwhenthequeryruns.Therefore,thesecondandthird

columnsbothhaveuncheckedShowboxes.Thesecondand

thirdcolumnsbothuseMidtoworkondifferentsubstringswithin

thesamefullSalesDatastring.

Nowtheresultisslightlydifferent.Figure5-16displaysthe

returneddata.Comparingthisresulttotheresultshownin

Figure5-14,youcanseethatrecords6through8havebeen

reordered.TheserecordssharethesamedateofJanuary16,

2004(011604),butnowtheamountsarereorderedbasedon

thequeryspecification.



Figure5-16.Sortingondateandamount,which

returnsadifferentorder



5.6.3.SortingonCharactersWhenTheirPosition

IsUnknown

Often,youneedtomanipulatedataimportedfromexternal

systemsbeforeyoucanuseitinyourapplication.Thisisa

commonissuewithnames.Yourdatabasetablemighthave

separatefieldsforfirstandlastnames.Thisofcoursemakesit

ano-brainertosortonlastname.Butimaginethedifficulty

whenyouaregivenfullnamesinonefield.Whatifthenames

areintheorderoffirstandthenlastname,withaspaceinthe

middle,andyouneedtosortonthelastname?Thedifference

here,comparedtotheprevioussalesinformationexample,is



thatyoucan'tknow,recordbyrecord,inwhichpositionthelast

namestarts.

Thetricktosortingbylastnameistofirstdeterminethe

positionofthespace.Inthiscase,youusetheInStrfunction

withtheMidfunction.Insteadofhard-codingthepositionofthe

space,InStrreturnsthepositionofthespace.

TheInStrfunctiontellsyouthestartingpositionofthefirst

occurrenceofasubstringinsidealargerstring.Inthisexample,

thestringbeingsearchedistheClientfield,andthesubstringis

aspace.Byitself,InStrlookslikethis:





InStr([Client],"")



HereweusetheInStrfunctiontotelltheMidfunctionthe

positionfromwhichitshouldstartcounting.InStrisembedded

insidetheMidfunction.Together,theylooklikethis:





Mid([Client],InStr([Client],"")+1,10)



NotethatalthoughtheInStrfunctionreturnsthepositionofthe

space,weareinterestedinthestartingpositionofthelast

name.Thisisonepositiontotherightofthespace,andforthis

reason,1isaddedaftertheInStrfunction.Thereturnedvalueof

InStrplusthevalue1isusedasthestartingpositionparameter

intheMidfunction.

Figure5-17showshowtosetupaqueryusingthesenested

functions.Thevalueof10isarbitrarilyusedhereasthelength

ofthelastname.Lastnamesvaryinlength,butusing10

characterstosortonallbutguaranteesthesortwillbeinthe

rightorder.



Figure5-17.Usingnestedfunctionsinasort



Figure5-18showstheresultofthequery.Clientsaresortedby

lastname,withinasinglefieldthatcontainsfullfirstandlast

names.Neat!



5.6.4.HackingtheHack

Sortingonnamesisn'tdifficultwhenfirstandlastnamesareall

youhavetoworkwith.Butwhataboutmiddlenames,titles,

andsuffixes?Howcanyouhandlethese?Let'suptheanteon

thishackandincludeacustomfunctioninthequery.



Figure5-18.Clientssortedbylastname



ThefunctionweneedwillexaminethenamesintheClientfield

todeterminethepositionofthespace.Here'sthecatch:now

therecouldbemorethanonespace.MynameisKenS.

Bluttman;that'stwospacesoneoneachsideofthemiddle

initial.Somenameshavethree,four,orevenfivespaces.The

functionismeanttosimplyfigureoutthebestspacetouse;it

figuresoutthepositionofthatspaceandtellstheMidfunction

whereitis.

First,youwritethefunctioninaVBAcodemodule.Todothis,

fromthedatabasewindow,gototheModulestab,andselectto

createanewmodule.Enterthiscode:

Functionfind_space(client_nameAsString)

Dimname_lengthAsInteger

Dimspace_loopAsInteger



Dimspace_countAsInteger

Dimpartial_nameAsString

Dimfirst_space_positionAsInteger

'countspacesinfullname

space_count=0

name_length=Len(client_name)

Forspace_loop=1Toname_length

IfMid(client_name,space_loop,1)=""Then

space_count=space_count+1

EndIf

Nextspace_loop

'parsethefullnameusingassumptionsineachCase

SelectCasespace_count

Case0

'nospacesfound!

'return1astheposition

find_space=1

Case1

'afirstnameandlastname

'splitafterfirstspace

find_space=InStr(client_name,"")

Case2,3

'assumeafirstname,Middlename,andlastname(2spaces

'orafirstname,Middlename,lastname,andsuffix(3sp

'splitaftersecondspace

find_space=InStr(client_name,"")

first_space_position=find_space

partial_name=_

Mid(client_name,find_space,name_length-find_space)

find_space=InStr(partial_name,"")+first_space_positi

CaseElse

'difficulttomakeassumptiononnamestructure

'splitafterfirstspace

find_space=InStr(client_name,"")

EndSelect

EndFunction



Inanutshell,thefunctiontakesaclientname,countshow

manyspacesareinit,andthendetermineswhichspaceisbest.

ThepositionofthatspaceisusedintheMidfunctionasbefore.

Inthequerygrid,thecalltothefunction,namedfind_space,is

embeddedintheMidfunction,likethis:





Mid([Client],find_space([Client])+1,10)



Figure5-19showshowtosetupthequery.



Figure5-19.TheMidfunction,usingthe

find_spacefunction



Whenthequeryruns,eachclientnameisexaminedinthe

find_spacefunction.Thefunctionreturnsthebestspaceposition,



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Hack 44. Sort Any Arbitrary String of Characters

Tải bản đầy đủ ngay(0 tr)

×