Tải bản đầy đủ - 0 (trang)
Hack 47. Don't Let Nulls Ruin Data Summaries

Hack 47. Don't Let Nulls Ruin Data Summaries

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

Blank.



5.9.1.NullsinNumberFields

Let'sassumeyouhaveatablewithafieldcalledAmount.You

aretryingtodeterminetheaverageofthatfield(assumealso

thattheaveragedoesn'tneedtobeweighted).Ifyouwritea

querythatattemptstodeterminetheaveragevalue,theSQL

mightlooklikethis:







SELECTAvg(tbl_Amount.Amount)ASAvgOfAmount

FROMtbl_Amount;



Thisgivesyoutheaverageamountofthevaluesinthatfield.

However,ifyouhavenullsforanyofthevalues,thequerywill

ignorethem.So,ifyourvaluesare8,null,8,null,8,null,the

averageis8.Ifyourvaluesare8,0,8,0,8,0,theaverageis4.

Dependingonthepurposeofthequery,youmightwanttosee

4insteadof8.

Ifyouwanttosubstitute0fornull,youcantrytodoitwiththe

ISNULLfunctionbywritingalinesuchasthis:





IIF(ISNULL([Amount]),0,[Amount])



Thereisamucheasierway,though.TheNZfunctionavailablein

Accessrequirestwoparameters:oneforthevalueandthe

otherforthevalueifitisnull.Youcanusethisforbothnumber

andstringfunctions.HereiswhattheSQLofthequerylooks

likeusingtheNZfunction:





SELECTAvg(NZ([Amount],0))ASAverageofAmount







FROMtbl_Amount;



Asyoucansee,thisismorecompactthanwritingoutIIF

statementstoperformthesamefunction.

Next,let'slookatanexampleofastringfunction.Assumeyou

liveinanareawherepinetreesarepopular,andyouhavea

surveyinwhichyouinputthetypeoftreeonlyifitissomething

otherthanpine;otherwise,youjustinputthenumberoftrees

(baddesign,butI'veseenworse)andleavethetreetypefield

null.

Now,assumethatyouhaveinheritedthisapplication,andyou

wanttouseitinotherareasofthecountry.Youwanttoupdate

allthenullTree_TypefieldswithPineTree.Youcandosowith

theNZfunction.HereiswhattheSQLforthisquerylookslike:







UPDATEtbl_TreeTypesSETtbl_TreeTypes.Tree_Type=

nz([Tree_Type],"PineTree");



Thiswillwork,butyouhavetoupdateeveryrecord.So,ifyou

can'tusetree_Type=Null,youmightaskifyoucanusenullfor

criteriainaquery.Youcan,usingoneoftwomethods.The

easiestwayistouseISNULLforthecriteria.Thepreviousquery

lookslikethisusingISNULL:







UPDATEtbl_TreeTypesSETtbl_TreeTypes.Tree_Type="Pin

WHERE(((tbl_TreeTypes.Tree_Type)IsNull));.



5.9.2.PreventingNulls



Itmightbenecessaryforyoutopreventnullsandzero-length

stringsinyourdatabaseinthefirstplace.Agoodexamplefor

thismightbeanamefieldoraZIPcodefield.Youcandothis

througheitheryourtabledesignoryourdataentryforms.



5.9.2.1Tabledesigntopreventnullsandzero-length

strings.

Whenyoudesignyourtable,youcansetseveralpropertiesto

helpyouhandleblankfields,asshowninFigure5-32.



Figure5-32.Settingfieldpropertiestocontrol

nullsandzero-lengthstrings



ThefirstisapropertycalledRequired.IfyouenterYesforthe



Requiredproperty,youaretellingAccessavaluemustbeentered



inthisfieldforittobesaved.Thiswon'tpreventsomeonefilling

itwithazero-lengthstring.SettingtheAllowZeroLengthproperty

toNoforcesanentryotherthanazero-lengthstring.Ifyousay

Yes,andyoujustwanttoeliminatenulls(testforblankby

writing[Field]=""),youcansettheDefaultValuepropertyto"".

Ifyousetthesetwopropertiescorrectly,youwillhaveavalue

ineachfield,andyouwon'thavetodealwithnullsinyour

application.Thesamethingappliestonumberfields:thereisa

RequiredpropertyyoucansettoYes,andthereisalsoaDefault

Valueproperty.Normally,theDefaultValuepropertyissetto0ina

numberfield.However,ifyouwanttoensurethatusersentera

valueinthisfieldanddon'tsimplyskipoverit,youcanremove

the0inthedefaultvaluefieldandsettheRequiredpropertyto

Yes.Thisensuresthattherecordisn'tsaveduntiltheuserputs

avalueinthefield(0canbeenteredunlessyouhavea

validationruleinplace).



5.9.2.2Formdesigntopreventnullsandzero-length

strings.

Ifyoudon'thavecontroloverthetabledesign,butyouwantto

ensurethedataenteredisaccurate,youcandosothrough

Accessforms.WhenyoucreateaforminAccess,several

textboxpropertiesareavailablethatcanhelpyouensure

meaningfuldata,asshowninFigure5-33.



Figure5-33.Controllingnullsthroughform

controlproperties



YoucansettheDefaultValuepropertytoallowazero-length

stringifallyouwantisavoidanull.

YoucanalsowritecodeintheLostFocusevent.Itisimportantto

dothisintheLostFocuseventbecausetheBeforeUpdateevent

won'tfireifthefieldisjusttabbedthrough,andtheAfterUpdate

eventfiresafterthefieldhasactuallybeenchanged.Hereis

whatthatcodemightlooklikeforatextboxcalledTextBox1:





PrivateSubTextBox1_LostFocus()



IfIsNull(Me.TextBox1.Value)Then

MsgBox"Youmustenteravalueinthisfield",vbOKOnly,



Me.TextBox2.SetFocus



Me.TextBox1.SetFocus



EndIf



EndSub



YoumightbewonderingwhytheSetFocuseventiscalledtwice.

Youmustsetthefocusoffofthetextboxandthenbackontoit;

otherwise,itwon'tletyousetthefocustothebox.Youmight

alsobewonderingwhythecodedoesn'tusetheValidationRule

property.Thevalidationrulerunonlyswhenthefieldis



changed,soifyousimplyskipafield,itwon'trun.

ThereisalimitationtousingtheLostFocuseventifauseruses

thmouseanddoesn'tclickeachfield.Youcangetaroundthis

limitationbysettingtheCyclepropertyontheOthertabofthe

FormPropertiesdialogboxtoCurrentRecord(asshowninFigure

5-34)andthensettingtheNavigationButtonspropertytoNoon

theFormattabofthesamedialogbox(asshowninFigure535).



Figure5-34.SettingtheCyclepropertytoCurrent

Record



Figure5-35.SettingtheNavigationButtons

propertytoNo



Onceyouhavedonethis,youcancreateyourownbuttonsto

allowuserstomovetothenextrecord,andyoucanputyour

validationtextinthere.Inallcases,itismucheasiertoassign

thesesettingsduringtabledesign,butmanytimesyoudon't

havethatcontrol.

MichaelSchmalz



Hack48.UseaCustomFunctioninaQuery



Writeacustomfunctiontomanipulatemultipledata

formats.

Whenyouneedtoperformcomplexmanipulationofdataina

query,itisofteneasiertowriteafunctiontoperformthe

manipulation.Youcanavoidusingcomplexfunctionsinsidea

queryandalwayswriteauserfunction.However,itisbestto

useyourjudgment.Ifyouhavearathersimpleconcatenation

ofafewfields,Isuggestyouwriteauserfunctionwithinyour

query.Butifyouneedtoperformsomethingcomplexanditis

likelythatyouwillneedtodoitinotherplacesinthe

application,creatinganewfunctionwillsaveyoualotoftime.



5.10.1.CreatingaNewFunction

Tocreateafunction,gototheModulestabinAccess,and

createanewmodule.Onceyouareinthenewmodule(youcan

alsogointoDesignviewinanexistingmodule),selectInsert

Procedure.Giveitaname,selectFunctionastheType,and

selectPublicastheScope.Onceyouhaveyourfunction,you

canplacevariablesbetweentheparentheses.Afterthe

parentheses,giveyourfunctionatypebytypingAsdatatype;

thisensuresthatyourfunctionisreturnedinthedatatypethat

youexpect.



5.10.2.ManipulatingDates

Datescomefromdifferentsystemsinmanydifferentformats,



includingYYYYMMDD,MM/DD/YYYY,andMMDDYYYY.The

problemcomeswhenyouneedtohavethedateinanother

format,ashappenswhenyouimportdatafromamainframeor

afixed-lengthtextfileinwhichthedateisactuallyimportedas

text.Thisfirstexampleassumestheformatbeingimportedis

YYYYMMDDorYYMMDD.Inthisfunction,thestringisbroughtin

asanargumentandtheLeft,Right,andMidfunctionsareused

withtheCDatefunctiontocreatethedate:



PublicFunctionGetDate(DtAsVariant)AsDate



DimMMAsString



DimDDAsString



DimYYYYAsString



IfVBA.InStr(1,Dt,"/")>0ThenDt=""



SelectCaseVBA.Len(Access.Nz(Dt,""))

Case8



YYYY=VBA.Left(Dt,4)



MM=VBA.Mid(Dt,5,2)



DD=VBA.Right(Dt,2)



GetDate=VBA.CDate(MM&"/"&DD&"/"&YYYY)

Case6



YYYY=VBA.Left(Dt,2)



MM=VBA.Mid(Dt,3,2)



DD=Right(Dt,2)



GetDate=VBA.CDate(MM&"/"&DD&"/"&YYYY)



CaseElse



GetDate=#1/1/1900#

EndSelect

EndFunction



Noticethatthisfunctionpassesthestringasavariant;this

allowsittotestforanullvalueortrapanactualdate.Ifthe

variableisdeclaredasastring,anullvalueresultsinanerror.

Inthiscase,ifarealdate,nullvalue,oranythingotherthan

YYMMDDorYYYYMMDDispassed,itreturnsadateof1/1/1900.



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

Hack 47. Don't Let Nulls Ruin Data Summaries

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

×