Documentos de Académico
Documentos de Profesional
Documentos de Cultura
DrAlexanderJTurner2007 1
BabySteps
Dedicatedto:ProfessorI.H.Williams.
Forhistirelesssupportandguidanceofmyselfandmany
othersinoursearchforagreaterunderstandingof
nature'screation.
2 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Table of Contents
Forward:RunTheWorldFromExcel!........................................7
A Dream No Reality......................................................................7
Who can benefit from Excel Scripting Macros?..............................8
Where Does This Idea Come From?................................................8
Why 'Baby Steps'.............................................................................9
Introduction:Whatisthisallaboutthen?...............................10
Do I Need To Be A Programmer?...................................................10
Using This Book............................................................................10
Lesson1:BasicConcepts.........................................................11
'Take Home' Ideas from Lesson 1..................................................14
Lesson2:BuildingBlockConcepts..........................................15
Collections:....................................................................................15
Variables:.......................................................................................17
More On Variables.........................................................................18
With Statements............................................................................20
'Take Home' Ideas from Lesson 2..................................................21
Lesson3:Loops.......................................................................23
Finally we start to make things easier:.........................................23
Drag And Drop Scripting, An Introduction....................................24
For Loops.......................................................................................27
For Each Loops..............................................................................28
'Take Home' Ideas from Lesson 3..................................................29
Lesson4:GettingTooledUp....................................................31
A Quick Note.................................................................................31
Get A Good Text Editor..................................................................31
Recording Macros.........................................................................32
Translating Recorded Macros.......................................................36
Keyboard and Mouse to Script Translation..........................................................36
Translating Excel Constants.................................................................................37
Using The Object Browser.............................................................39
Finding And Removing Bugs.........................................................41
'Take Home' Ideas from Lesson 4..................................................44
Lesson5:StartingToWorkWithData.....................................45
Special Folders..............................................................................45
Using 'SendTo' As A Really Easy Way To Run Scripts..........................................46
Saving And Opening From Special Folders..........................................................47
Merging Between Workbooks........................................................48
Merging Data By Example....................................................................................48
Dictionary Objects.................................................................................................49
Simple Merge Script.............................................................................................51
Working Merge Script...........................................................................................53
Merging Multiple Columns...................................................................................56
'Take Home' Ideas from Lesson 5..................................................57
Lesson6:Reading&WritingFiles...........................................59
What Is A File?..............................................................................59
Writing To A Text File....................................................................60
DrAlexanderJTurner2007 3
BabySteps
4 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
AppendixB:HowThisBookWasWritten..............................157
AppendixC:WhyScriptWhenExcelHasMacros?................159
One Final Thing...................................................................................................160
AppendixD:VBScriptBuiltInFunctions&Constants...........161
Built In Functions........................................................................161
The Functions Enumerated And Explained........................................................161
Built In Constants................................................................................................170
Built In String Constants.....................................................................................170
AppendixE:NamedArgumentsAndThe:=Symbol.............173
Why This Is Here.........................................................................173
The Where, Why And When Of :=...............................................173
How To Translate From Named Arguments................................174
Errata....................................................................................176
Index.....................................................................................177
DrAlexanderJTurner2007 5
BabySteps
6 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 7
BabySteps
8 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 9
BabySteps
10 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
NowwehavestartedwritingaScriptingMacro. Tomakethisabit
morerealisticweneedtosplitouttheconceptof'aglassofwine'from
'myglassofwine'.Afterall,youwanttoknowwhichglassyourare
drinking(atleastatthestartoftheevening).
Todothis,wemightwritesomethinglikethis:
set my-glass-of-wine to be a-glass-of-wine
set my-person to be a-person
my-person.drink(the-glass-of-wine)
YoucanprobablytellthatIamgoingsomewherewiththelayoutof
these'pseudoscripts';Iamtransformingeverydayspeakintotheway
wetellthecomputertodostuff.Alotofthetime,itisfairlystraight
forwardtodoso.Sometimes,however,historyandconventiongetin
theway.But,fornow,letuscontinuealongthispath.
Key Concept:
Incomputerspeak,wecall'myglassofwine'anObjectandwecall'a
glassofwine'aclassofobjects,orsimplyaClass.
Onereallynicethingaboutcomputingisthatmakingglassesofwine
isverysimpleandjustaboutfree.Ifwewantanewglassofwine,we
just say something like 'Create myglassofwine which is from the
Classof'aglassofwine'.
Makingglassesofwineinascriptmightlooksomethinglikethis:
set my-glass-of-wine = CreateObject(a-glass-of-wine)
Butactually,hyphensbetweenwordsarenotallowedsoweput:
DrAlexanderJTurner2007 11
BabySteps
Thatdoesnotlookverymuchlikeeverydayspeakanylonger,but
thereisaclearlineagetobeseen! Onequestionthatcomesupis
whatdoesthe'='signmean?Therearetwothings'='canmeanin
ScriptingMacros:
1) Does x equal y, as in:
if x = y then
2) Make x equal to y, i.e. load the value of y into
x, as in:
Set x = y
or:
set myExcel=CreateObject(Excel.Application)
Nowwecanputallthistogethertomakeanearlycompleteprogram:
' Create the Objects which we require
set myself = CreateObject(People.Person)
set myGlass = CreateObject(Wine.Glass)
mySelf.drink(myGlass)
12 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Thispieceofcodecanbedescribedinwordslikethis:
SettheVariable myExcel tobeannewlycreated Object
which is from the Class Excel.Application. Make the
visible Property of that Object be true. Get the
Workbooks Property ofthatObjectandrunitsMethod
Add,whichwillcauseanewWorkbooktobecreated.
DrAlexanderJTurner2007 13
BabySteps
Whenwritingscripts,werepresentreal,tangiblethings(like
glassesofwineorworkbooks)asObjects.Theobject
'myGlassOfWine'comesfromtheClassofObjects'aGlassOfWine'.
MacroScriptsaresimpletextfiles.Theyareeditedusingatext
editor(likenotepad)andsavedwiththe'.vbs'fileextension.
WhenwritingaScriptingMacro,beforewedoanythingwith
Excel,weneedtocreateanExcel.ApplicationObject.
14 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Fig1:AdigramshowinghowinExcelObjectsoftenhave
CollectionsofObjectsinsidethem.ACollectionholdsalistof
zeroormoreObjectsinsideitandallowsyoutofindthose
Objectsbyindex(e.g.0,1,2etc.,orsometimes:1,2,3etc.)or
name(e.g.sheet1,sheet2etc.).Thisdiagramshowsyouhow
tostartoffwithExcel.Applicationand'drill'allthewaydownto
individualCellsinaSheet.
DrAlexanderJTurner2007 15
BabySteps
Inlessononewelookedathowthings,likeglassesofwineandExcel
Applications,arecalled Objects.'myGlassOfWine'isanObjectwhilst
'aGlassOfWine'definesaClassofObjectsandsowecallitaClass.
WhenworkingwithExcel,weuseObjectsalot;also,wetendtousea
lotofthesameClassofObjectatonce.WhenyoucreateaWorkbook
Object(likewedidwithwithoursimplescript)youseethreeSheets,
notone.Indeed,anExcel.ApplicationcanhavemanyWorkbooksand
eachWorkbookcanhavemanySheetsandeachSheetwillhavemany
Cells.
To handle all these groups of Objects, Microsoft use what it calls
'Collections'. These are numbered, and sometimes named, lists of
Objects. A Collection is also an Object its self. For example, a
CollectionofWorkbooksisanObjectfromtheClassofCollections.
All Collections have the Property .count (note, because it is a
Property,notaMethod,thereisnoparenthesis).Thistellsyouhow
manythingsareinsidetheCollection.SomespecialCollectionshave
other properties and/or Methods. For example, Excel's Workbooks
Collection has .Add() to create a new Workbook and .Open(file
name)toopenanexistingWorkbook.
If we draw out the relationships of Excel.Application, Workbook,
SheetandCell,wegetsomethinglikeFigure1.
TofindtheObjectforaCell,wemightdosomethinglikethis:
' Create an Excel.Application Object
Set myExcel = CreateObject(Excel.Application)
' Cause Excel to create a Workbook (it starts
' with none). This is done by 'adding' one to
' the Collections of Workbooks
myExcel.Workbooks.Add()
16 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
' the Cell at the top left hand corner of the first
' Sheet.
'
' We can use this Object to
' write the value of the contents of the Cell.
myCell.Value = Hello World
KeyConcept:
CollectionsareawayofstoringzeroormoreObjectssothattheycan
beeasilyfoundandused.
Variables:
Whenweput:
Set myExcel= CreateObject(Excel.Application)
Wearesaying:
SetaVariablecalledmyExceltorefertoanewlycreated
Excel.ApplicationObject.
WhenworkingwithObjectsinExcel,weoftensetVariablestoreferto
ObjectstomakeiteasytousetheseObjects.Hereisanexampleasto
why:
' Try to set a Cell's contents without using Variables
' Step 1: Open up Excel and create a new Workbook
' in it
CreateObject(Excel.Application).Workbooks.Add()
' Are, now I am unstuck, because I no longer have a
' way of 'getting to' to the Excel.Application
' Object.
Thesolution,aswesawbefore,istosetaVariabletorefertothe
Excel.Application Object. This approach has other benefits as well.
Oncewegetthehangofitwecan:
1. Saveourselvesalotoftyping.
2. Savethecomputeralotof'thinking'.
3. Make developing (adding to, editing, improving) scripts
mucheasier.
Theseadvantagescomefromtheabilitytostore'working'information
inVariablesjustlikewemightstorenotesonpostits.Ifyouhadto
work out what the square root of 23456 was each morning, you
mightwellwritedowntheanswertosavetheeffort! Variablesare
usedforthispurposeinscripting.
DrAlexanderJTurner2007 17
BabySteps
KeyConcept:
Variablesarelike'postitnotes'forscripts;theyallowustostorethings
sowedonothavetokeeprecreatingthem.
Letusseethis'postitnote'conceptinusebyaddingtoourprevious
script:
' Create an Excel.Application Object
set myExcel = CreateObject(Excel.Application)
HerewehavereusedthevalueofmySheetratherthanhavingtore
findtheSheetObject. ThisuseofaVariablehassavedusrewring
andrerunningallthecodewhichfindstheSheet.
More On Variables
VariablesdonotonlyrefertoObjects;theycanholdotherstufflike
Numbers,DatesandStrings(piecesoftextarecalled'Strings'asin'a
stringofcharacters').
When working with Excel Scripting Macros we are using a
programming language called VBScript. VBScript, just like any
programminglanguagethathasbeenaroundforawhile,hashistory;
ithasaccumulatedafewoddities.Whilstthesecanbeexplained,itis
18 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
oftenbettertojustacceptthem. Oneoftheseisthewaywework
withVariablesandthingswhicharenotObjects.
Strings,Numbers,DatesandBooleans(logicalvalues,true/false)are
notObjectsin VBScript. Thisisnotforanyparticularreasonother
thanhistory. Variablesare almostexactly the samewhen working
withObjectsandnonObjects,appartfromonelittlething:wedonot
'set'Variablestononobjects.So:
Set Cell = mySheet.Cells(1,1) ' OK
myString = Hello World ' OK
myNumber = 1.0 ' OK
Set myNumber = 2 ' WRONG (2 is not an object)
myObject = CreateObject(Excel.Application) ' WRONG
DrAlexanderJTurner2007 19
BabySteps
With Statements
Withstatements areanotherwayofworkingwithObjectwhichcan
behandyasanadditiontousingVariables.Thisisespeciallysoifwe
wanttodoseveralthingswiththesameObjectintightsequence.It
iseasiesttoshowthisbyanexample;herewewillsetthevaluesof
severalCellsinsequence.
Set myExcel = CreateObject(Excel.Application)
myExcel.Workbooks.Add()
Set myWorkbook = myExcel.Workbooks(1)
KeyConcept:
NotehowanythinginsidetheWith(betweentheWithand EndWith)
whichbegins.istreatedasaMethodorpropertyoftheObjecttowhich
theWithstatementrefers.
20 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
InExcel,manyObjectshaveaCollectionofObjectsasoneoftheir
Properties.Thisallowsusto'drilldown'fromatoplevelObject
likeExcel.ApplicationallthewaydowntoCells.
VariablesarenamedcontainersforObjectsornonObjectdata
likeStrings,Booleans,DatesandNumbers.
VariablesareahandywayofbeingabletofindanObjectonce
butuseitseveraltimes.
AnotherhandywayofusingthesameObjectseveraltimesisto
useaWithstatement.
DrAlexanderJTurner2007 21
BabySteps
22 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Lesson 3: Loops
Finally we start to make things easier:
Iamnotyou,butifItrytoimaginebeingyou,rightnowIwouldbe
thinking:
Thisisallverywell,butIhavejusttakenanagetodosomethingI
couldhavedoin30secondswithExcelusingjustformulaeorfills.
Thatsentimentisperfectlycorrect!So,itistimetostartdoingsome
stuffwhichiseasierandfastertodowithscriptsthanitisbyhand,
andthatusuallyinvolvesloops.
Fig2:Thelooptapemodelofcomputerloops.Hereweare
makingaloopwhichsays'Add2And2'overandoveragain,for
ever!
People do not normally like doing the same thing over and over
again;computersloveit. Loopsareawayoftellingacomputerto
'loopover'thesamesetofactionsrepeatedly.Youcanthinkofloops
DrAlexanderJTurner2007 23
BabySteps
24 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure4:HereistheWorkbookfileBabyStepsExamples.xlsbeing
'draganddropped'ontoaMacroScriptfile.Whenthescriptruns,
thefilenameoftheWorkbookwillbebeplacedinthe
WScript.ArgumentsCollectionofthescriptatindex0.
Now that we have figured out how to tell a script which Excel
Workbooktoopen,weneedtoactuallyopenit.Thispieceofcode
willopenanExcelWorkbookwhichisdroppedontoit:
' Create an Excel application Object and make it
' become visible
Set myExcel = CreateObject("Excel.Application")
myExcel.visible=true
DrAlexanderJTurner2007 25
BabySteps
Note:ifyouendaline_itmeansthatthelineiscontinuedon
thenextline.i.e.:
a = _
b
Isthesameas:
a = b
TotestthisscriptweshouldcreateanExcelWorkbookinwhichthe
firstSheethasvaluessomethinglikethis:
Price Price $
1.5
2.3
0.5
26 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
OncethescripthasrunthefirstSheetwilllooklikethis:
Price Price $
1.5 3.0
2.3 4.6
0.5 1.0
DrAlexanderJTurner2007 27
BabySteps
Because,inExcelscripting,wearemoreoftenthannotloopingover
data until some data related condition is met, For loops are less
commonthanWhileloops.However,asyoucanseefromtheabove
example,whenyoucanusethemtheytakeuplessspaceanditis
moreobviouswhatishappening.
For Each Loops
WehavejustseenhowForloopsareaneasywayofperformingaset
ofactionsforasetnumberofrepetitions.Howaboutifwewantto
performanactiononeachofthecontentsofaCollection?Inother
wordsForEachelementintheCollection.Happily,VBScriptprovides
uswithareallysimplewayofdoingthis.
WecouldmakethishappenusingaForloop:
For index = 1 To myWorkbook.Sheets.Count
mySheet = myWorkbook.Sheets(index)
mySheet.Cells(1,1).Value = Hello World
Next
28 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
TheeasiestwayofsettingupaScriptingMacrotoopenpre
existingWorkbooksistouseDragAndDropScripting.
WScriptisapreexistingObjectwhichisavailablefromall
scripts.Italowsus,amongstmanyotherthings,togetthefile
nameofaWorkbookwhichhasbeen'dropped'ontoourscript.
AlotofthetimewewillwanttoprocessCellsuntilwefindonor
moreemptyones.Thiscanbeachievedusingthehandy
IsEmpty()methodinconjunctionwithaWhileloop.
DrAlexanderJTurner2007 29
BabySteps
30 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 31
BabySteps
Figure4:ThisisascreenshotofNotepad++beingusedtoeditone
oftheexamplefilesfromBabySteps.
Todownloadacopy,pleasegotothisURL:
http://www.sourceforge.net/project/showfiles.php?
group_id=95717&package_id=102072.
Alternativelyyoucandotothepackagehomepageandfollowthe
linkstodownloadthebinaryexecutablefiles:
http://notepad-plus.sourceforge.net/uk/download.php
Recording Macros
ItwouldbeahugetasktolearnandrememberhowtogetExceltodo
everythingviaScriptsthatwecangetittodoviatheuserinterface.
Wow, that is scary. Fortunately, we do not have to learn and
rememberallthat!Excelhas(asyoumaywellalreadyknow)areally
handyfeaturecalledthe'MacroRecorder'.
The Macro Recorder records 'Internal' Macros; those being ones
which are embedded into a Workbook. However, Internal Macros
andScriptingMacrosasverysimilar.WecanrecordInternalMacros
andtheneasilytranslatethemintoScriptingMacrosorintopieces
whichcanbeaddedintoScriptingMacros.
First,IwillbrieflydescriberecordingMacrosforthispurpose.Then,
inthenextsection,IwillexplainhowtotranslatetheInternalMacros
intopiecesofScriptingMacro.
32 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure5:HowtostartrecordingaMacro.
Theusualuseofthe MacroRecorder istocreateanInternalMacro
whichwillautomateatask.Usingitrequiresthreesimplesteps:
1. Startrecording.
2. Performthetask.
3. Stoprecording.
Startingtherecording,inmostversionsofExcel,isdoneviatheTools
menuoption. Figure5showsthisbeingdoneandAppendixAhas
detailsofhowtodoitinExcel2007.
Figure6:WhenchoosingaMacroname,youmayaswellusethe
oneExcelsuggestsbecauseyouarenotgoingtokeeptheMacro,
itisgoingtobetranslatedintoyourScript.
DrAlexanderJTurner2007 33
BabySteps
Figure7:ThisscreenshotshowsasetofCellsbeingcoloured
whilsttheMacroRecorderisrunning.
RememberthatwearenotwantingtokeeptheMacro.Wearegoing
totranslateitintopartofaMacroScript.Becauseofthis,itismuch
easiertorecordaseparateshortMacroforeachstepofaprocessthan
torecordahugeMacroofanentire,complexprocess.Infigure7we
canseeaMacrobeingrecorded.Thisoneconsistsofselectingsome
Cellsandthencolouringthem.Thisisaboutthelevelofcomplexity
we should be aiming for in any one recording. There are some
34 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
exceptionswhereitisnotpossibletomakereallyshortrecordings.
Forexample,whenwecreatePivotTablesinlesson8.
Figure8:Thisscreenshotshowshow,oncetheactionswewant
recordinghavebeencompletedandtheMacroRecorderstopped,
wecanopentheVisualBasicEditorandviewtheMacrocode.
Figure9:HerewecanseehowthecodefortheMacrohasbeen
writtenintoaModuleofname'Module1'.Byexpandingthe
Modulesnodeinthelefthandtreeviewandthendoubleclicking
on'Module1'wecanseetherecordedcode.
DrAlexanderJTurner2007 35
BabySteps
Is100%thesameas:
mySheet.Range(A1:A1).Value = Hello World
OncetheCellshavebeenselected,theRecorderrecordsthechanges
tothatselection.Weshouldremovethisuseofaselectionandwork
withtheCellsdirectly:
Range(A1:I1).Select
With Selection.Interior
Becomes:
36 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
With mySheet.Range(A1:I1).Interior
Figure10:TostarttheprocessoffindingthevalueofanExcel
constantrightclickontheconstantintheVisualBasicviewofthe
Macro.
ExcelhasatoolcalledtheObjectBrowser.Wearegoingtolookinto
usingthisinmoredetailinthenextsection.Usingitforfindingthe
valueofExcelconstantsisverysimpleindeed.Thatisexactlywhat
wewilldonow.
DrAlexanderJTurner2007 37
BabySteps
Figure11:ThesecondsteptofindingoutthevalueofanExcel
constantistoclickon'Definition'whencontextmenucomesup.
AllthatisrequiredistoviewthecodeofourrecordedMacro.From
thisview,wecanrightclickonthetextoftheconstantitsself.Inour
example,ifwerightclickonthetext'xlAutomatic'acontextmenu
appears.Allweneedtodoisclickon'Definition'.
Figure12:Oncewehavechosen'Definition'fromthecontextmenu
overanExcelconstant,theObjectBrowserwillopen.Inthebottom
paneoftheObjectBrowser,wecanseethedefinitionoftheExcel
Constant.Inthiscase,xlAutomaticisdefined
as4105.
38 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Oncewehaveclickedon'Definition'Excelwillautomaticallystartup
the Object Browser showing details of the constant on which we
clicked. Constantsareshownasthenumberinournormaldecimal
numbersystemandtheninbracketsusingthemorecomputercentric
hexadecimalsystem.Weonlyneedtoconsiderthedecimalversion.
ForourScriptingMacrotousetheconstantswehavetodefinethem
in the Scripting Macro. Hereis an example of thefinished Script
segment(thisisnotafullscript):
xlAutomatic = -4105
xlSolid = 1
With mySheet.Range(A1:I1).Interior
.ColorIndex = 36
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With
DrAlexanderJTurner2007 39
BabySteps
Figure13:WecanstarttheObjectBrowsermanuallyfromthe
Viewmenu.
OncewehavestartedtheBrowserwecanstartlookingaroundinside
theprogrammaticinterfacetoExcelandsolearnalittlemoreabout
justwhatwecandowithScriptingMacros.
Figure14:ThisscreenshotshowswhattheObjectBrowserlooks
likewhenithasbeenopened.AlsohereIhavetyped'xlsolid'
(notethatthesearchisnotcasesensitive)intothesearchbox
andclickedthesearchbutton(ithasbinocularsonit).Inthe
paneatthebottomoftheBowserwecanseetheresultofmy
search.InthemiddlepaneswecanseethatxlSolidisamember
ofConstants.
40 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure15:NotonlycanwesearchusingtheObjectBrowserwe
canbrowsewithit.Thebottomtwopanesallowustomove
aroundtheClassesandCollectionsofExcelandseewhatis
available.
Finding And Removing Bugs
Bugsareafactoflifeinanythingcomputerbased.Basically,abugis
whenourscriptdoesnotdowhatwewantorexpect. Thereisno
simplecureorremedyforbugs.Whenweseetheeffectofabugin
thewayascriptisrunningwemust'findthebug'. Thisisjustlike
fixinganymachine;thefirststepistofindoutwhyitisnotworking
properly.Fixingtheproblemalwayscomessecond.
Thebestadviceforfindinganythingistodevelopthebestpossible
wayoflookingforit.Ifwearelookingforaneedleonacarpet,we
mightuseamagnet. Ifwearelookingforastar,wemightusea
telescope.So,weneedtoolstohelpusfindbugsinScriptingMacros.
Fortunatelyforustherearethree:
1) Ourbrains!Wemustnotmakeanyassumptions.Thehuman
brainisamazingpowerfulattheartoffiguringoutwhatis
goingon,aslongaswedonotassumewealreadyknowwhat
isgoingon.Findingbugsrequiresanopenmindandlotsof
concentration.
2) Wscript.Echo:ThisMethodpopsupalertboxesthatletussee
theinnerworkingsofascript.Onewayoflookingforabug
istoimagineallthevaluesofVariablesasthescriptruns.An
alternativeistoimaginewhichpiecesofcodewillberunning
atwhichpointintime. Placing Wscript.Echo statementsin
DrAlexanderJTurner2007 41
BabySteps
thescriptsallowsusto'see'ifourimaginingsarecorrect.If
they are not, maybe that points to the bug. For example,
whatvalueswillmyNumbertakeon?
For row = 1 To 10
myNumber = (row * row) / (row * 0.25)
Next
Tofindout,simplyjustgetthescripttotellus:
For row = 1 To 10
myNumber = (row * row) / (row * 0.25)
Wscript.Echo myNumber
Next
Ifhavingtenpopupboxesisjusttooannoyingthenthisisan
alternative:
myList =
for row = 1 to 10
myNumber = (row * row) / (row * 0.25)
myList = myList & myNumber & ,
next
Wscript.Echo myList
3) OptionExplicit:Thissasimpledirectivethatwecanputat
the top of scripts. It forces the VBScript interpretor (the
thingthatactuallyrunsourScriptingMacro)tocheckthat
youhaveexplicitlyuseDimtocreateallVariablesbeforeyou
usethem.
Here is an example of the use of Option Explicit to help debug a
script:
Inthisexample,thescriptwillproducemeaninglessresults:
' Create Excel Etc
...
' Populate a Spreadsheet
for row=1 to 100
value=row * 10
mySheet.Cells(row,1).Value=valeu
next i
Amistakelikethisisalargescriptcantakeaverylongtimetospot
usingjustthehumaneye.Thesolutionistodothis:
Option Explicit
Dim mySheet,row,value
' Create Excel Etc
42 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
...
' Populate a Spreadsheet
for row=1 to 100
value=row * 10
mySheet.Cells(row,1).Value=valeu
next i
The'OptionExplicit'atthetopofthescripttellsVBScriptnottousea
Variable unlessit has beencreated witha Dimstatement. In this
case,wehavenotcreatedaVariablevaleusothescriptwillnotrun;
insteaditwillgiveusawarningtellingusthattheVariableisnot
definedandthelineonwhichthebugis.
DrAlexanderJTurner2007 43
BabySteps
Scriptsaretextandsoarebesteditedwithatexteditorlike
notepad++.
Excel'sInternalMacrosandScriptingMacrosareverysimilar.A
goodapproachtofiguringouthowtodosomethingwithascript
istorecordanExcelInternalMacroandthentranslateitintoa
ScriptingMacro.
Scripttranslationrequires3steps:
1) Covertfromthekeyboardandmousebasedapproachto
asimplerdirectmethodology.
2) Translateconstants.
3) Integrate.
Totranslateconstants,wecanrightclickontheminExcel'scode
viewandgotoDefinition.
FindingdefinitionsusestheObjectBrowser.TheObjectBrowser
isveryusefulforlookingatotherpartsofExcel'sprogrammatic
interface.
Gettingridofbugstakes3techniques:Keepingandopenmind,
usingWscript.Echoto'see'whatisreallyhappeningandalways
usingOptionExplicit.
44 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 45
BabySteps
ThewaytousetheSpecialFolderfeatureofaWScript.Shellobjectis
via the .SpeciaFolders.Item() Method. The script below finds the
locationoftheMyDocumentsspecialfolderanddisplaysittous.
Option Explicit
Dim myShell, myPath
Set myShell = WScript.CreateObject("WScript.Shell")
myPath = myShell.SpecialFolders.Item("MyDocuments")
WScript.Echo "MyDocuments='" & myPath & "'"
46 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 47
BabySteps
Figure16:ThisscreenshotisresultofthefirstofthetwoDesktop
scripts.ThisistheExcelWorkbookthatIopenedfromdouble
clickingonAutoSaved.xlsonthedesktop.
' This script opens the Workbook saved by the
' previous one
Dim myShell, myExcel,myShell
Set myExcel = CreateObject("Excel.Application")
Set myShell=CreateObject("WScript.Shell")
myExcel.Open myShell.SpecialFolders("Desktop") &
"\AutoSaved.xls"
48 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
the road collecting orders. They report the orders back to head
officeonspreadsheetslikethis:
OurfirstchallengeistowriteaScriptingMacrowhichwilloutputa
Sheettosendtofulfilment.ThisscriptwilltakeeachorderRowfrom
a sales person and match the customer name against the Name
column in the Customer Contact Details Sheet. The output of this
process should have the customer name, address, part number,
quantityandorderdate.
Dictionary Objects
Dictionary Objects are very useful things indeed. They let us just
lookupvaluesratherthanhavingtogoandsearchforthem.Inthe
case of our example, we can storeall the customer addresses and
'lookthemup'bycustomername.Thethingwearelookingupisa
valueandwelookitupbyakey.Hereisadescriptionofallthe
PropertiesandMethodsofaDictionaryObject.
DictionaryObjectProperties:
DrAlexanderJTurner2007 49
BabySteps
ignore this.
Count The number of key/value pairs in this
Dictionary.
Item(key) Return the value looked up by key. We can
also set the value for an existing key:
myDictionary.item(fred-wife)= wimla
Key(key) Allows us to change a key. Consider that
Wilma remarried Barny then we could put:
myDictionary.key(fred-wife)=barny-wife
DictionaryObjectMethods:
Thereverseofthisistolookupthevalueassociatedwithanalready
stored key. We can demonstrate this with a continuation of the
previousscript.
50 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Dim address
address = myDictionary.Item(hack and slash)
Wscript.Echo address
Theabovescriptwillecho123FakeStreet
Simple Merge Script
Tomakeamergescriptworkitwillhaveto:
1) Loadtheordersheet.
2) Loadthecustomerinformationsheet.
3) Createanewsheet.
4) Populatethenewsheetwithamergeddataset.
5) Savethenewsheet.
TomakethisniceandsimpleIwillsaythatthecustomerinformation
WorkbookisalreadyonmyDesktop.Thismeansthatwecanusethe
'specialfolders'wehavealreadylookedattolocatetheWorkbook.To
continuewiththeeasyconcept,IwillputtheoutputWorkbookon
the Desktop aswell. Finally,using'draganddrop'seemsasensible
choiceforloadingthesalesWorkbookintomyScriptingMacro.
Todothedatamergethescriptwillhavetolookupaddressesby
customer name. So it will load a Dictionary; the keys will be
customernamesandthevalueswillbecustomeraddresses.Nextthe
scriptwillworkitswaydownthesalesSpreadsheet(fromthesales
Workbook that was dropped onto it). For each Row on the sales
Spreadsheetthescriptwillreadinthecustomersnameandlookup
theaddress.
Onceithasfoundtheaddressitwillwritethename,address,order
quantityanddateintotheordersSheetintheoutputWorkbook.The
followingscriptperformsthissimplemerge:
Option Explicit
Dim myShell,myExcel,ordersWB
Dim customersWB,outputWB,myDict
Dim desktop,row,ordersSh,customersSh,outputSh
Set myExcel=CreateObject("Excel.Application")
Set myDict =CreateObject("Scripting.Dictionary")
Set myShell=CreateObject("WScript.Shell")
desktop=myShell.SpecialFolders("Desktop")
myExcel.Visible=TRUE
DrAlexanderJTurner2007 51
BabySteps
Set ordersSh=ordersWB.Sheets(1)
Set customersSh=customersWB.Sheets(1)
Set outputSh=outputWB.Sheets(1)
'Clean up output
outputSh.Columns("D:D").NumberFormat = _
"[$-F800]dddd, mmmm dd, yyyy"
outputSh.Columns("A:E").AutoFit
outputSh.Rows("1:1").Font.FontStyle = "Bold"
Thisscriptproducesthisoutputwhenoneoftheordersisforabc
engineering:
52 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Thisscriptisallwellandgoodbutitwillbenouseintherealworld.
Forexample,thecustomerinformationWorkbookmaywellhavea
customer names as ABC Engineering; however, a sales person
(maybeinarush)mightputabcengineering(seetheabovetable).
Thesalespersonmightevenputabcengineering.Howcanwedeal
withthesesituations?
Thesolution isto this realworld situation isabit ofpragmatism.
Step one is to remove all unnecessary information. ABC
Engineering and abc engineering are clearly the same company.
Wecanchangethescripttoignorethecaseofnamestoreflectthis
reality. Thiscanbedonebymakingallthekeysinthe Dictionary
lowercaseviatheLCase()functionwhichisbuiltintoVBScript.The
other built in Function to use here is Trim() which removed any
unwantedspacesfromthestartorendofaString.
Dim MyString
myString = "VBSCript "
myString = LCase(Trim(myString))
' We can see here that the output is all lower case
' and the trailing space has gone.
Wscript.Echo "'" & myString "'"
DrAlexanderJTurner2007 53
BabySteps
Dim
myShell,myExcel,ordersWB,customersWB,outputWB,myDict
Dim desktop,row,ordersSh,customersSh,outputSh,key
Dim errorSh,errorRow,okRow
Set myExcel=CreateObject("Excel.Application")
Set myDict =CreateObject("Scripting.Dictionary")
Set myShell=CreateObject("WScript.Shell")
desktop=myShell.SpecialFolders("Desktop")
myExcel.Visible=TRUE
Set ordersWB=myExcel.Workbooks.Open(desktop &
"\orders.xls")
Set customersWB=myExcel.Workbooks.Open(desktop &
"\customers.xls")
Set outputWB=myExcel.Workbooks.Add()
Set ordersSh=ordersWB.Sheets(1)
Set customersSh=customersWB.Sheets(1)
Set outputSh=outputWB.Sheets(1)
Set errorSh=outputWB.Sheets(2)
errorSh.Cells(1,1).Value="Customer Name"
errorSh.Cells(1,2).Value="Part Number"
errorSh.Cells(1,3).Value="Quantity"
errorSh.Cells(1,4).Value="Date"
errorSh.Cells(1,5).Value="Address"
54 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
errorRow=2
okRow=2
While(NOT IsEmpty(ordersSh.Cells(row,1)))
key=Trim(LCase(ordersSh.Cells(row,1).Value))
' Here is the decision if the address can be looked
up or not
If myDict.Exists(key) Then
' Yes it can - so put the Row into the ouput Sheet
outputSh.Cells(okRow,1).Value= _
ordersSh.Cells(row,1)
outputSh.Cells(okRow,2).Value= _
ordersSh.Cells(row,2)
outputSh.Cells(okRow,3).Value= _
ordersSh.Cells(row,3)
outputSh.Cells(okRow,4).Value= _
ordersSh.Cells(row,4)
outputSh.Cells(okRow,5).Value= _
myDict.Item(key)
okRow=okRow+1
Else
' No it cannot - so put the Row into
' the error Sheet
errorSh.Cells(errorRow,1).Value= _
ordersSh.Cells(row,1)
errorSh.Cells(errorRow,2).Value= _
ordersSh.Cells(row,2)
errorSh.Cells(errorRow,3).Value= _
ordersSh.Cells(row,3)
errorSh.Cells(errorRow,4).Value= _
ordersSh.Cells(row,4)
errorRow=errorRow+1
End If
row=row+1
Wend
'Clean up output
outputSh.Columns("D:D").NumberFormat = "[$-F800]dddd,
mmmm dd, yyyy"
outputSh.Columns("A:E").AutoFit
outputSh.Rows("1:1").Font.FontStyle = "Bold"
outputSh.Name="Orders To Process"
errorSh.Columns("D:D").NumberFormat = "[$-F800]dddd,
mmmm dd, yyyy"
errorSh.Columns("A:D").AutoFit
errorSh.Rows("1:1").Font.FontStyle = "Bold"
errorSh.Name="Errors"
Hereisastepbystepapproachtogettingdatamergingtowork:
DrAlexanderJTurner2007 55
BabySteps
1) FindaColumnwhichisinbothSheets
2) WorkoutwhichSheethasthemasterrecordsandwhich
theslave.InourexamplethecustomerinformationSheet
wasthemaster. Donotworryifitisnotobviouswhichis
which;youcanalwaystryitbothwaysandseewhichworks
better.
3) FindtheColumninthemasterwhichissharedwiththeslave
(e.g.customername).
4) Figureoutallthevariabilitywhichcanberemovedfromthe
shared column data. Examples are capitals, spaces,
punctuation.
5) Loadthedatayouwantfromthemasterintoa Dictionary
Object.KeytheDictionarybythesharecolumn.
6) Foreachrowintheslave,lookupthedataintheDictionary.
7) Ifamatchingentryinthe Dictionary isfound,putthedata
fromtheslaveandtheDictionaryintotheoutputSheet.
8) Ifnomatchisfound,putthedatafromtheslaveintothe
'errors'Sheet.
Merging Multiple Columns
Sofarwehavelookedatmergingmultiplecolumnsfromtheslave
Sheet with a single column (e.g. address) from the master. How
couldwe mergemultiple columns frombothSheets? Itwouldbe
quite hard to load more than one Column into the Value of a
key/valuepairintheDictionaryObjectsothatisprobablynotthe
solution.
Asitturnsout,thesolutionisverysimple. Doeverythingthesame
wayasforthesinglemasterColumnmerge,butthistimestorethe
RownumberinthemasternottheColumndata.Eachtimeamatch
isfoundintheDictionary,theRownumbercanbeusedtoextractthe
datafortheoutputdirectlyfromthemasterSheet.
56 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
TheSpecialFolderCollectionisveryusefulindeedforfindingeasy
touseplacesonthecomputer'sharddriveliketheDesktop.
DictionaryObjectsletusstorevaluesandthenlookthesevalues
bykeys.
Mergingdatafrommultiplespreadsheetsisaverycommonand
importantScriptingMacrotask.
Mergingcanbedonequickandeasilywiththehelpof
Dictionaries.
DrAlexanderJTurner2007 57
BabySteps
58 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 59
BabySteps
Fileformatscanbecomeverycomplexindeed. InBabyStepswe
arenotinterestedincomplexsowewillkeepthingssimple. Itis
amazingwhatcanbedonesimplywithfilesandExcel.
Formostoftherestifthisbookwewillonlydealwithwhatarecalled
textfiles.Thesehavedirecttranslationsofthenumbersinthefile
to characters,punctuationandafewlayoutrules. Textfilesareso
simplethattheycanbereadandconvertedtohumanreadablefrom
using Notepad. Notepad (or Notepad++) reads in each number
fromthetextfileandconvertsitintoahumanreadablecharacteretc.
When we write text in Notepad, every so often we will press the
'enterkey'todroptothenextline.Yearsagosomecomputerscalled
the enter key 'newline'. This is because in text file editors like
Notepad,pressingitproducesaspeciallayoutcharacterwhichmeans
start a newline. This is an example ofone of the hand full of
speciallayoutcharactersintextfiles.
Newline characters are stored in the text file as the number 13.
Spaceisanotherexamplewithitsnumberbeing32.Thenumeral1
isrepresentedbythenumber48andtheletterAby64.So123A
is4849503264.
Whenweworkwithtextfileswetendtoletthecomputerprograms
weworkwithdoallthetranslationbetweenthefiles'numbersand
thetextweareworkingwith.Inotherwords,wereadtextfilesinto
StringsandwewriteStringstotextfiles. Towardstheendofthe
book I discuss what are called binary files. These are where the
actualnumbersarereadandwrittendirectly.Wealmostneverneed
todirectlyhandlebinaryfilesinExcelMacroScripting.
Writing To A Text File
MacroScriptingusesaspecialObjecttoaccessfilesdirectly.Towrite
toafilewecreatea System.FileSystemObject. WegivethisObject
informationonwheretoputthefilethatwewillbewriting,itsname
andifitshouldreplaceanypreexistingfilewiththesamenamein
thesamefolder.FromthisinformationtheFileSystemObjectcreates
aTextStreamObject.ItisthisTextStreamObjectwhichactuallydoes
thewriting.
TheexamplebelowwillcreateatextfileontheDesktopadinside
thatfileitwillplacetwolinesoftext.
Option Explicit
Dim myFSO, myTSO,myShell,myName,forWriting
forWriting=2
60 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure17:ThisiswhatNotepadshowsifweuseittoopenthefile
example.txtcreatedbyourfilefilewritingscript.
Thepreviousscriptwillalwaysreplaceanexistingfilewithanew
one.Thismeansthatit'secretly'performsthefollowingsteps:
1) CheckifafileofthatFolder\Nameexists.
2) Ifitdoes,deleteitpermanently.
3) CreateanewfilewiththesameFolder\Name.
4) Writetothenewfile.
Whathappensifwejustwanttoaddtothefileratherthanreplaceit?
Thisisnotsoodd;wemightwanttowritealineatheendofasfile
everytimeascriptisruntoactasanaudittrailforexample.Todo
DrAlexanderJTurner2007 61
BabySteps
thiswetelltheFileSystemObjectto'Append'ratherthan'Write'when
weopenthefileandcreatetheTextStreamObject.
Thisscriptaddsanewlinegivingthedateandtimethescriptwas
runtoafilescript.log.ThefilewillbecreatedontheDesktopthe
first time the script runs. After that, a line will be added to the
existingfileeachtimeitisrunagain.
Option Explicit
Dim myFSO, myTSO, myShell, myName, forWriting,
forAppending
forWriting = 2
forAppending = 8
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set myShell=CreateObject("WScript.Shell")
' The file location (folder) and name are sent to the
' FSO as a single String: Folder Name \ File Name
myName=myShell.SpecialFolders("Desktop") &
"\script.log"
' The arguments to the OpenTextFile method here
' give the location\name, that we want to write
' and that it is OK to create the file if it does
' not already exist
Set myTSO =
myFSO.OpenTextFile(myName,forAppending,true)
myTSO.WriteLine("Script Run: " & now)
myTSO.Close
Iranthisscriptafewtimeandhereisthecontentsoftheresulting
file:
Script Run: 18/10/2007 13:03:31
Script Run: 18/10/2007 13:04:30
Script Run: 18/10/2007 13:04:31
Script Run: 18/10/2007 13:04:42
Script Run: 18/10/2007 13:04:44
Script Run: 18/10/2007 13:04:45
Script Run: 18/10/2007 13:04:46
62 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Date = 01/07/2007
Action = logon
End
Begin
User = FF
Date = 01/08/2007
Action = logoff
End
InthisfileweknowthatalinewhichsaysBeginstartsablockof
lines and a line which says End ends that block. This extra
informationaboutthemeaningofthecontentsofthefileiswhatwe
callformat.ThisformatisnotonethatExcelunderstandssowehave
toloadthedataintoaspreadsheetusingascript:
Option Explicit
Dim
myFSO,myExcel,myWorkbook,mySheet,myTS,row,line,keyWord,d
atum
Set myExcel=CreateObject("Excel.Application")
Set myWorkbook=myExcel.Workbooks.Add()
Set mySheet=myWorkbook.Sheets(1)
myExcel.Visible=TRUE
With mySheet
.Cells(1,1).Value="User"
.Cells(1,2).Value="Date"
.Cells(1,3).Value="Action"
End With
DrAlexanderJTurner2007 63
BabySteps
' This means keep looping until the end of the file
While NOT myTS.AtEndOfStream
' Read a line of text and put it in
' the Variable line
line=myTS.ReadLine()
' Split the line in two iff it has a = in it
line=Split(line,"=")
'See if there are two parts or one
if UBound(line)=1 Then
datum=Trim(line(1))
end if
' It will always have at least one part once split
' Strip spaces off the beginning and end
' at the same time
keyWord=Trim(line(0))
'Make sure the key word is all lower case
keyWord=LCase(keyWord)
' Choose what to do depending on the line
if keyWord="end" Then
' At the end of a block, move down
' one row in Excel
row=row+1
elseif keyWord="user" Then
mySheet.Cells(row,1).Value=datum
elseif keyWord="date" Then
mySheet.Cells(row,2).Value=datum
elseif keyWord="action" Then
mySheet.Cells(row,3).Value=datum
end if
Wend
' For neatness - close the TextStream
myTS.Close
' Tidy up our spreadsheet
mySheet.Columns(1).Autofit
mySheet.Columns(2).Autofit
mySheet.Columns(2).Autofit
64 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
WhenweusemyTextStream.ReadLine()wegetbackthenextlineof
text from a file. Just like a human reading a page of text, the
TextStreamObjectremembersits'place'inthetextandsocangiveus
thenextlinefromthat.
Thereareafewotherthingswhichwemightwanttodowithatext
file.Thesearenotusefulquiteasoftenasworkingwithonelineata
time,buttheycomeinhandyeverysooften:
1) ReadanentirefileatoncetoaString.
2) WriteanentirefileatoncefromString.
3) Readanexactnumberofcharactersfromafile.
4) WriteaStringtoafilewithoutaddingonthecarriagereturn
linefeed.
Whilstthesearefourdifferentthingsweneedonlylearntwonew
techniquestobeabletodothem! WhenweopenaTextStreamfor
readingwecancallcallmyTextStream.Read(count)wherecountisa
number. This is just like Readline in that the TextStream Object
remembers its 'place' in the file and reads on from that place.
However, rather then reading a whole line, it reads exactly count
charactersandreturnstheseasaString.Anotherslightdifferenceis
thatwhenitencounters carriagereturn or linefeed,itwillactually
put these characters in the returned String. Also note that if it
reachestheendofthefilebeforeithasread countcharactersitjust
givesusthecharactersithasreadsofar.
InExcelMacroScriptingIhaveyettocomeacrossaneedtoread
count characters from a file except in one common special case.
SometimewewanttoreadanentirefileintoaStringallinonego.
Again,tomakethissupereasy,wecanjustmissoutcountaltogether.
InthebelowscriptweopenaTextStreamreadingfromafileandcall
ReadAll()whichislikeusingRead(count)wherecountisthenumber
of characters left which can be read. This slurps the entire file's
contentsintoaStringforus(thisisnotanentirescript,justapieceof
one):
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile _
( _
"myFile.txt", _
forReading, _
FALSE _
)
' Read the entire contents at once
DrAlexanderJTurner2007 65
BabySteps
fileContents=myTS.ReadAll()
myTS.Close
Theexactsamethingcanbedonewithwriting.ByusingtheMethod
Write(myString)onaTextStreamObject(whichwasopenedtowrite
orappend)wesimplywriteoutthenumbersforthecharactersinthe
Stringtothefile. Write(myString)doesnotadd carriagereturn or
newline.Ifwecallitmanytimeswecanaddtothefilesonechunk
atatime.IfweopenaTextStreamforoverwriting(notappending)
and we call Write(myString) just the once before closing the
TextStream,wehavewrittentheentirecontentsofthefilefromour
String.
Hereisascriptwhichreadsanentiretextfileinonego. Itthen
replaceseveryinstanceof/with//.Finally,itwritesanewfile
withtheupdatedcontents.Wewillseeinlesson7(thenext)whywe
mightwanttodothis(again,thisisjustasubsectionofascript):
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile _
( _
"myFile.txt", _
forReading, _
FALSE _
)
' Read the entire contents at once
fileContents=myTS.ReadAll()
myTS.Close
Listing Files
I was considering not including this section. Then I suddenly
rememberedaveryimportantsortofapplicationforlistingfiles.Let
us imagine that wehave written a script which takes a 'dragand
66 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
drop'WorkbookandmergesthedatawithasecondWorkbook.This
scriptthencreatesanoutputWorkbookcontainingthemergeddata
(see lesson 5). Whilst this is fine for one, two or even ten input
Workbooks, how about if there were 100 or even 1000. The
alternativetospendingthebalanceofournaturallifedraggingand
droppingistogetourscripttofindtheinputWorkbookfilesitsself.
Thenextscriptdoesexactlythat.Itisabit'dense'inthatitdoesalot
withonlyafewlinesofcode.Ratherthanstuffitfullofcomments,I
havediscussedhowitworksafterthescript.
Option Explicit
Dim fso,myFolder,myFile,myShell,myList
Set myShell=CreateObject("WScript.Shell")
Set fso=CreateObject("Scripting.FileSystemObject")
Set myFolder =
fso.GetFolder(myShell.SpecialFolders.Item("Desktop"))
myList=""
For Each myFile In myFolder.Files
With myFile
If _
LCase(Right(.name,4))=".xls" OR _
LCase(Right(.name,5))=".xlsx" _
Then _
myList=myList & .name & vbcrlf
End IF
End With
Next
WScript.Echo "Excel Files On The Desktop:" & vbcrlf &
myList
ThefirstthingthattheabovescriptdoesistouseSpecialFoldersto
findthepathtotheDesktop.NextitcallstheGetFolder(path)
methodofaFileSystemObjectObject.ThismethodreturnsaFolder
Object.BecausethepathwepasstotheGetFoldermethodisthepath
totheGetFoldermethod,wegetaFolderObejctrepresentingthe
Desktop.
FolderObjectsareusedtoallowustodothingswithFolders.Inthis
case,wewanttofindallthefilesintheFolder.TheFolderObjecthas
aCollectioninitcalled'Files'whichcontainsaFileObject
representingeachoftheFilesintheFolder.ThisbeingaCollectionis
veryusefulbecausewecanuseaForEachlooptoworkthrougheach
ItemintheCollection.
InsidetheForEachloopIhaveplacedanIfstatement.Thisiswhatis
calleda'conditional'.WhatthismeansisthatIfaconditionismet
DrAlexanderJTurner2007 67
BabySteps
Thenapieceofcodeisexecuted.TotryandexplainthisfurtherIcan
takethepieceofscript...
With myFile
If _
LCase(Right(.name,4))=".xls" OR _
LCase(Right(.name,5))=".xlsx" _
Then _
myList=myList & .name & vbcrlf
End If
End With
..andtryanddescribeitasinplainEnglish:
If the name oftheVariable myFileendswith.xlsor
with .xlsx then add that name to the end of the
VariablemyList.Otherwise,donotdoanything.
WehavealreadyseetheVBScriptbuiltinfunction LCase. Another
handybuiltinfunctionisRight.ThisfunctionreturnsjusttheRight
handcharactersfromaString. AppendixDhasadescriptionofall
thesebuiltinfunctions.VBCRLFisabuiltin'Constant'.Itcontainsa
Stringconsistingofcarriagereturn, linefeed. Byaddingthistothe
endofeachFilenameasitisaddedtomyList,itmakesthenames
appearonnewlinesinthepopupboxcreatedattheendofthescript.
Toprocessallthefilesofaparticulartypeinafolderallweneedto
doisreplacethecode...
If _
LCase(Right(.name,4))=".xls" OR _
LCase(Right(.name,5))=".xlsx" _
Then _
myList=myList & .name & vbcrlf
End IF
68 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Byassigningcharacterstothenumberswecanstoretextinfiles.
Wecallthesetextfiles.
TheTextStreamObjectdoestheconversionfromtexttonumbers
(andback)soitletsusreadanwritetextfilesusingStrings.
Byaddingmorerulesabouttheorderofdatainfiles,more
complexinformationcanbestoredinthem.Wecallthese
structurerulesformat.
Whenwritingfileswecanoverwriteolderversionsofthefileor
appendnewstufftothen.
Mostreadingandwritingisdoneonelineatatime.
Beingabletoreadandwritefilesallowsourscriptstoworkwith
fileformatswhichExceldoesnotunderstandbyitsself.
SometimesitishandytoreadawholefileintoaStringorwrite
awholefileoutfromaString.
Wecanlistallthefilesinafoldersothatwecanthenprocess
themall,orasubsetofthem,automatically.
DrAlexanderJTurner2007 69
BabySteps
70 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
BymakingthenameoftheFunctionequaltothethingwewantgiven
back,wecontrolwhatitgivesback. TheaboveFunctioncouldbe
usedlikethis:
Option Explicit
WScript.Echo AddTwoNumbers(2,2)
WScript.Echo AddTwoNumbers(3,4)
Function AddTwoNumbers(a,b)
AddTwoNumbers=a+b
End Function
DrAlexanderJTurner2007 71
BabySteps
Thisscriptwillproducetwopopupboxes;thefirstwillsay4and
thesecond7.
Hereisamoreuseful Function. ItlooksdownaColumnandturns
everyCellValueintouppercase.Itwillstopwhenitfindsanentire
Rowwhichisempty,returningthenumberofalteredRows:
Option Explicit
Dim myExcel, myWorkbook,mySheet,col,row
Set myExcel=CreateObject("Excel.Application")
Set myWorkbook=myExcel.Workbooks.Add()
Set mySheet=myWorkbook.Sheets(1)
myExcel.Visible=true
72 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
End Function
FigureX:HereiswhattheuppercaseaColumnscriptproduces
atthepointwherethefirstpopupappears.
ItisimportanttorememberthatiswecreateaFunctionwhichgives
back(sometimescalled'returns')anObject,wemustuseSet:
' A Function to create a new Excel Object and
' return a new Workbook from it
Function MakeExcelWorkbook()
Dim myExcel
Set myExcel=CreateObject(Excel.Application)
Set MakeExcelWorkbook=myExcel.Workbooks.Add()
End Function
DrAlexanderJTurner2007 73
BabySteps
FigureX:HereiswhattheuppercaseaColumnscriptproduces
onceithasfinishedprocessingtheSheet.
Death By Dates
IhavebeenworkinginITforwhatfeelslikeaverylongtime(over
25 years sob). Over that time, certain patterns have started to
appeartome.Oneoftheseisthatwhenadatasetgoesallweird,it
isusuallybecauseofdates.
Thereasonissimple;dateshavenoconsistentlyappliedstandards.
Wecanillustratethisbycounterexample.Integernumbersdohavea
very consistent standard. Nearly all integer number in data are
representedusingArabicnumeralbasetennotation:
1
11
100
-20
Bywayofcontrast,herearejustafewofthewaysonemightseethe
firstofJulytwothousandandonewritten:
1/7/01
1/7/2001
7/1/01
1-7-01
7/1/2001
1-July-2001
74 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure20:Hereisthelanguageandregionalconfigurationofmy
test(virtual)computerwhilstwriting'BabySteps'.
Toillustratethisissue,IhavecreatedascriptwhichloadsExcelwith
datesfromthe10thtothe20thofJanuary.Italsousesatricktoforce
ExcelnotitinterpretthevaluesIampassingintoit.ThiswayIcan
getExceltoshowwhatthe'raw'valueIputinitandthenalsowhatit
interpretsitas.Thistrickwillbeusedagainlater.
DrAlexanderJTurner2007 75
BabySteps
Option Explicit
Dim myExcel,myWorkbook,mySheet,row
Set myExcel = CreateObject("Excel.Application")
Set myWorkbook = myExcel.Workbooks.Add()
Set mySheet = myWorkbook.Sheets(1)
76 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure21:HerewecanseehowExcelhasmadeacompletemess
ofinterpretingthevalueswhichourscriptasplacedintoit.
DateAdd And DateSerial Fixing The Problem
FirstwecanlookataVBScriptbuiltinfunctioncalled'DateAdd'.We
canusethistobypassthefaultydateinterpretationinExcel.
DateAdd(Interval, Number, Date)
TheNumberargumentisamultiplierfortheIntervalargument(i.e.,
DrAlexanderJTurner2007 77
BabySteps
howmanydays,weeks,months,etc.).Ifthisisapositivenumber,you
willgoforwardintime.Anegativenumberwillgobackintime.
TheDateargumentisanactualDate.ThismeansitisnotaStringin
dateformatlike01/02/2001;itisavalueoftypeDate. Wecan
makeDatevaluesfromstringsusingthe VBScript builtinfunction
CDate.
Option Explicit
Dim
myExcel,myWorkbook,mySheet,year,month,day,myDate,start
Date,row
Set myExcel = CreateObject("Excel.Application")
Set myWorkbook = myExcel.Workbooks.Add()
Set mySheet = myWorkbook.Sheets(1)
For row=1 to 10
' Here we set up the day month and year
myMonth=1
myYear=2001
myDay=row+10
78 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure22:Herewecanseethenewscriptcorrectlycreatesdate
valuesintheExcelCells.
Another(possiblysimpleryetlessinformative)wayofachievingthe
samethingistousethe DateSerial builtinfunction. Thistakes3
arguments,theyear,monthandday.Sothepreviousscriptpiece:
myDate=startDate
myDate=DateAdd("YYYY",myYear-2000,myDate)
myDate=DateAdd("M",myMonth-1,myDate)
myDate=DateAdd("D",myDay-1,myDate)
Becomes:
myDate=DateSerial(year,month,day)
DrAlexanderJTurner2007 79
BabySteps
Iconsideredonlyincludingthissimplerversion.However,themore
complex DateAdd version made such a nice example of date
arithmetic, I chose to include both approaches. Indeed, the the
DateAddmethodisillustrativeofthewayDateSerialactuallyworks.
Forexample,whatdoesthefollowingscriptproduce?
Option Explicit
Dim myDate
myDate=DateSerial(2007,2,32)
WScript.Echo myDate
WhatitcomesupwithisapopupboxgivingthefourthofMarchasa
date.
Figure23:ThisisthepopupshowingthatDateSerialactually
worksjustlikeDateAdd.Here,DateSerial(2007,2,32)yieldsthe
fourthofMarch,i.e.twomonthsand32daysaddedto2007.
ThefourthofMarchbeingtheDateyouwouldgetifyouweretodo
this:
myDate=1/1/2007
myDate=DateAdd("M",2-1,myDate)
myDate=DateAdd("D",32-1,myDate)
WScript.Echo myDate
80 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
relationshipmanagementsystemmustcreateanoutputwhichwecan
readwithExcel,CVSmightbeanexcellentchoice:
Figure24:ThisshowshowadatabaseviewfromaCRM
(CustomerRelationshipManagement)systemcanbeconvertedto
aCSVfileformat.
IntheaboveexampleaviewinaCRMsystemhasbeenexportedtoa
CSVfile. Excelisabletoread CSV filesandconvertthecontents
directlyintoaspreadsheet.Thereareevensomecleaverstandardsto
avoidthingslikecommasinthedatacausingtrouble.Iftherewasa
comma in the data, the field holding thecomma is surrounded in
quotationmarks:
FigureX:Herewecanseehowwhenadatafieldhasacommain
it,theCSVformatplacesthatfieldinquotationmarkstomakeit
clearwhichcommasareseparatingfieldsandwhichare
containedinsidefields.
Unfortunately,CSVtellsusnothingaboutthenatureofthedata,it
justhascolumnsandrows.However,Exceltriestoguessthenature
ofdatafromitsformat.Aswehavealreadyseen,Exceloftentakes
somethinglikethis5/7/01andtreatsitasadate.Butitalsogets
allconfusedbetweenthefifthofJulyandtheseventhofMay.
Becauseoftheseissues,itissometimesnecessaryto'help'Excelalong
abitwhenreadingCSVfiles. Thiscanbedonewithathreestep
strategy:
1) Change the data in the CSV file so that Excel will treat
everythingassimpletext.
2) OpenExcelandtellittoloadthealteredCSVfile.
3) Change thedata in Excel to the format we wantor insert
formulaewhichoutputtheformatwewant(orboth).
DrAlexanderJTurner2007 81
BabySteps
Forstep1wecanusethefilehandlingtechniqueswelookedatthe
previous lesson. We open the original CSV file as a TextStream
Object andopenanemptyoutput CSV fileasanother TextStream.
Wecanthereadtheoriginalin,alterthecontentsandwritethenew
contentout.
ToillustratethissurvivaltrickIwillgothroughtwoexamples;oneis
forworkingwithdatesandtheforworkingwiththingsthatExcel
mightincorrectlythinkarenumbers.Forexample,ifwetype10e24
intoanExcelCell,Excelwillconvertthisto1.00E25;inotherwords,
Excelhasreadthetextandconsideredittorepresent1x1024.
' Create a CSV file with a load of dates in it.
' This script is here
' only to produce the input file for the next
' script it is not really part of the example
Option Explicit
Dim myFSO, myTS,row
Const forWriting = 2
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile("Date-
data.csv",forWriting,TRUE)
myTS.WriteLine "SerialNumber,Date"
For row=0 to 99
' This is a numerical trick to produce realistic
' serial numbers from the row Variable and dates
' in US format which a UK Excel setting will get
' wrong.
myTS.WriteLine (NOT ((row + row * 65536) XOR
&H8888)) & ",8/" & (1+row-(31*Int(row/31))) & "/2006"
Next
myTS.Close
HereiswhatthecontentsofthecreatedCSVfilelooklike:
SerialNumber,Date
30583,8/1/2006
96118,8/2/2006
161653,8/3/2006
227188,8/4/2006
292723,8/5/2006
358258,8/6/2006
82 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure26:ThisishowExcelinterpretstheCSVfilewhichour
scriptcreates.Clearly,ithasreadthedatestotallyincorrectly.
' Change the CSV file innards to force Excel
' to treat them as plain text
Option Explicit
Dim
myExcel,myWorkbook,mySheet,row,myValue,myFSO,myTS,file
Contents,myShell,myDesktop,splitted
Const forReading=1
Const forWriting=2
Set myShell=CreateObject("WScript.Shell")
myDesktop=myShell.SpecialFolders("Desktop")
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile(myDesktop & "/Date-
data.csv",forReading,FALSE)
fileContents=myTS.ReadAll()
myTS.Close
fileContents=Replace(fileContents,"/","//")
Set myTS=myFSO.OpenTextFile(myDesktop & "/Date-data-
fixed.csv",forWriting,TRUE)
myTS.Write(fileContents)
myTS.Close
Theabovescriptworkbyreplacingeveryoccurrenceof/with//.
This means that a date String 1/5/01 will become 1//5//05.
Hereisapieceoftheresultingfile:
SerialNumber,Date
30583,8//1//2006
96118,8//2//2006
DrAlexanderJTurner2007 83
BabySteps
161653,8//3//2006
227188,8//4//2006
292723,8//5//2006
358258,8//6//2006
WhilstthishasstoppedExcelincorrectlyinterpretingdates,ithasnot
performedstep3inourstrategy.Todothatweneedtogothrough
all the fields that should be dates in Excel and convert them into
Excelcorrectdates. Notonlythat,wealsoneedtocorrectalltext
fieldstoundoanychangesthepreviousstepcaused. Forexample,
thechoicewasgreen/bluewillhavebeenchangedtothechoice
wasgreen//blue. Thesefieldsneedchangingback. Thefollowing
script performs this action on our example file. It is actually a
continutationofthepreviousscript. Itmakessensetocombinethe
filecorrectionandloadingintooneScriptingMacro:
' Read the newly updated CSV file into Excel and
' then recreate the dates in a way Excel cannot
' get confused (see previous lesson)
Set myExcel=CreateObject("Excel.Application")
myExcel.Visible=TRUE
' Load the csv usign the Open Method of the
' Workbooks Collection
Set myWorkbook=myExcel.Workbooks.Open(myDesktop &
"/Date-data-fixed.csv")
Set mySheet=myWorkbook.Sheets(1)
' This loop goes down the Rows from the first data
' until the first Row in which the "serial number"
' is blank
For row=2 to 65536
If IsEmpty(mySheet.Cells(row,1).Value) Then Exit For
' Here we use the ever handy Split built in Function
' to split the date String in Excel into
' three bits (0, 1 and 2)
myValue=mySheet.Cells(row,2).Value
splitted=Split(myValue,"//")
' DateSerial can now be used to create a real Date
' value to put back into Excel
myValue=DateSerial _
( _
splitted(2), _
splitted(0), _
splitted(1) _
)
mySheet.Cells(row,2).Value=myValue
' Finally, we correct the other Cell values
myValue=mySheet.Cells(row,1).Value
myValue=Replace(myValue,"//","/")
84 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
mySheet.Cells(row,1).Value=myValue
Next
Hereisthesamesetofscriptsforcorrectingtheproblemscausedby
scientificnotationnumbers:
' The script creates a csv file where the serial
' numbers are interpreted by Excel as scientific
' numbers
Option Explicit
Dim myFSO, myTS,row
Const forWriting = 2
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile("Serial-
data.csv",forWriting,TRUE)
myTS.WriteLine "SerialNumber,Action"
For row=1 to 100
' Here we use the same numerical trick to produce
' realistic looking serial numbers but with an 'e'
' in them so Excel misinterprets them as scientific
' notation
myTS.WriteLine(NOT ((row + row * 65536) XOR &H8888)) &
"e" & row & ",Incomming"
Next
myTS.Close
HereiswhatthecontentsofthecreatedCSVfilelooklike:
SerialNumber,Action
96118e1,Incomming
161653e2,Incomming
227188e3,Incomming
292723e4,Incomming
358258e5,Incomming
423793e6,Incomming
489328e7,Incomming
Hereisthescripttocorrectthisbehaviour:
' Change the CSV file innards to force Excel
' to treat them as plain text
Option Explicit
Dim
myExcel,myWorkbook,mySheet,row,myValue,myFSO,myTS,file
Contents,myShell,myDesktop,fixed
Const forReading=1
Const forWriting=2
Set myShell=CreateObject("WScript.Shell")
myDesktop=myShell.SpecialFolders("Desktop")
DrAlexanderJTurner2007 85
BabySteps
Set myFSO=CreateObject("Scripting.FileSystemObject")
Set myTS=myFSO.OpenTextFile(myDesktop & "/Date-
data.csv",forReading,FALSE)
fileContents=myTS.ReadAll()
myTS.Close
fileContents=Replace(fileContents,"e","ee")
Set myTS=myFSO.OpenTextFile(myDesktop & "/Date-data-
fixed.csv",forWriting,TRUE)
myTS.Write(fileContents)
myTS.Close
' Read the newly updated CSV file into Excel and
' then recreate the dates in a way Excel cannot
' get confused (see previous lesson)
Set myExcel=CreateObject("Excel.Application")
myExcel.Visible=TRUE
' Load the csv usign the Open Method of the
' Workbooks Collection
Set myWorkbook=myExcel.Workbooks.Open(myDesktop &
"/Date-data-fixed.csv")
Set mySheet=myWorkbook.Sheets(1)
' This loop goes down the Rows from the first data
' until the first Row in which the serial number
' is blank
For row=2 to 65536
If IsEmpty(mySheet.Cells(row,1).Value) Then Exit For
' This time we convert ee into e and the use the
' "Formula" techniques to force Excel not to
' interpret the serial number
myValue=mySheet.Cells(row,1).Value
fixed=Replace(myValue,"ee","e")
mySheet.Cells(row,1).Formula = "=""" & fixed & """"
' Finally, we correct the other Cell values
myValue=mySheet.Cells(row,2).Value
myValue=Replace(myValue,"ee","e")
mySheet.Cells(row,2).Value=myValue
Next
PleasenotethatinVBScript"""""actuallymeansaStringcontaining
justaquatationmark.So"""Hello"""isaString"Hello".Thisiswhat
the"="""&Fixed&""""isdoing;itisputtingtheString="nnnn"into
theCell'sformulawherennnnistheserialnumber.
86 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure27:Again,Excelhasincorrectlyinterpretedthecontentsof
ourCSVfile.Ithasreadtheserialnumbers,andbecausethey
haveeinthem,ithasconvertedthemintostandardnotation
scientificnumbers.
Creating Reports
QuiteoftenExcelspreadsheetsthemselvesmakeverygood reports.
However,sometimewewanttowriteoutreportsinMSWordinstead.
Thereareamyriadofdisturbinglycomplexwaysofdoingthis.I,for
one,liketoavoidcomplexwaysofdoinganythingsohereisanice
simple way of creating reports in MS Word from Excel Macro
Scripting.
Thekeytothismethodisusing HTML. HTML beingthewaythat
web pages arecreated. Using HTML we can lay out text without
usinganywizardry.Really,itisveryeasyindeedtomaketablesand
listsetc.Forexample:
<table border=1>
<tr>
<td>Hello</td><td>World</td>
</tr>
</table>
Makessomethinglikethis:
Hello World
Tomakealistwecanput:
DrAlexanderJTurner2007 87
BabySteps
<ul>
<li>This is the first list element.</li>
<li>This is the second list element.</li>
<li>This is the third list element.</li>
</ul>
This'unorderedlist'willcomeoutsomethinglikethis:
Thisisthefirstlistelement.
Thisisthesecondlistelement.
Thisisthethirdlistelement.
Textthisisjustnormalparagraphwritingcanbelaidoutlikethis:
<p>This is paragraph text. We do not want any special
layout for this.</p>
Wecanputallthistogethertomakesomethinglikethis:
<p>Below is a simple table which I have created using HTML</p>
<table border=1>
<tr>
<td>Hello</td><td>World</td>
</tr>
</table>
<p>Things to remember about HTML are:</p>
<ol>
<li>Text is laid out using 'tags'.</li>
<li>A tag is text between < and >.</li>
<li>To avoid confusion, less than and greater than symbols are
replaced with special sequences of characters as seen in the
previous line.</li>
<li>Tags always come in pairs called 'open' and 'close'. Just
like the <li> and </li> pairs used to make this
list.</li>
</ol>
InthiscaseIhavecreatedanorderedlistbyusingolrathertan
theunorderedlistul.Ifwesavetheabovetextinafilewithcalled
text.htmlwecanreaditwithawebbrowser.
88 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure28:Hereiswhatawebbrowserdisplayswhenaskedto
openoursimpletest.htmlfile.Wecanseethatthespecial
charactersequence<hasbeenconvertedto<and>has
beenconvertedto>.Thetagsinsidethetextlike<li></li>etc.
havecausedthetexttobelaidoutinthewaywewant.
Thisisallfineandwonderful,butwearesupposedtobecreatinga
MSWordreport,notanHTMLpage.Wellthisiswherealittleknown
featureofMSWord comesinto play. Bysimply savingthe fileas
test.docinsteadoftest.htmlMSWordwillmagicallyreadsitasa
normaldocument.However,MSWordwillstillapplytheHTMLstyle
layoutrules.
Figure29:Herewecanseetheresultsofopeningoursimple
HTMLtextasaMSWorddocument.IsavedtheHTMLinafile
calledtest.docandthenopenedthefileinMSWord.
DrAlexanderJTurner2007 89
BabySteps
for row = 1 to 10
myReportFile.WriteLine("<TR>")
for column = 1 to 2
myReportFile.WriteLine("<TD STYLE='border-bottom:
1px solid black; border-right: 1px solid black;'>" & row
& "," & column & "</TD>")
next
myReportFile.WriteLine("</TR>")
next
myReportFile.WriteLine("</TBODY></TABLE>")
myReportFile.Close
Whilst this script creates the data which it puts in the MS Word
document,itcouldhaveequallywellretrievedthedatafromanExcel
Sheet.
Figure30:ThisscreenshotisofMSWord2007displayingour
testreport.Theslightlymoresophisticateddescriptionofthe
borderscausesthenicesingleborderratherthanthedefault
doubleborderwhichwehaveseenintheearlierexamples.
90 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure31:ThisscreenshotisofMSWord2003displayingour
testreport.ThisolderversionofMSWorddoesaslightlyless
accuratejobofinterpretingtheHTML;theborderontheleftand
topofthetableisthickerthanitshouldbe.Ihaveincludedthis
imagetoillustratethatthistechniqueisusefulandeasybutnot
100%consistentacrossdifferentversionsofMSOffice.
DrAlexanderJTurner2007 91
BabySteps
SubroutinesandFunctionsletuswriteapieceofscriptoncebut
useitmanytimes.
FunctionsarejustlikeSubroutinesexcepttheygivesomething
back(theyhaveareturnvalue).
Datacontainingdatesisoftenacauseoferrors.
Theseerrorsarebecausedatestandardsareapplied
inconsistently.
Readingafile,changingittostopExcelmakingerrorsand
writingitbackoutagaincanpreventExcelmisinterpretingdata
likedatesorserialnumbers.
ReplaceisaVBScriptbuiltinfunctionwhichreplacesallthe
instancesofonesubstringwithanother.
92 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 93
BabySteps
workoutwhatisgoingwrongwherecomplianceisnotmet? Well,
compliance levels can be worked out directly using a Pivot Table.
Then we can use that table to drilldown to the exact failing jobs
numberstothenfollowthemupwitha'phonecalltoelucidatewhat
ishappening.
Inshort,wewilluseaPivotTableto'see'whatishappeninginthe
businessatbothanoverviewanddetailview.
Creating An Example Pivot Table
Belowisascriptwhich'manufactures'data.Ihavehavedonethisso
thatthereisnoneedtohaveasetofdownloadableWorkbookstogo
with Baby Steps. Using a script like this is also a great way to
develop any Excel Scripting Macro project. We can manufacture
somenicecleandataandworkwiththattocreateourscript. Once
ourscriptworkswithcleandata,wecantryitwithrealworlddata.
Aswehaveseenearlier,realworlddatais'dirty';ithashumanerrors
init.Withthistechnique,wecanaddtheabilitytocopewithdirty
dataintoourExcelScriptingMacrosinthesureknowledgethatthey
workjustfinewithcleandata.
Option Explicit
' Script to make some data for Pivot Table work
Dim myExcel,myWorkbook,mySheet
Dim row,rTime,wOffice,wEquipment, office, equipment
Dim r1,r2
Set myExcel=CreateObject("Excel.Application")
Set myWorkbook=myExcel.WorkBooks.Add()
Set mySheet=myWorkbook.Sheets(1)
myExcel.Visible=TRUE
mySheet.Cells(1,1).Value="Office"
mySheet.Cells(1,2).Value="Equipment"
mySheet.Cells(1,3).Value="Repair Time"
mySheet.Cells(1,4).Value="Job Number"
94 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
wEquipment=Fix(rnd()*6+1)
if wEquipment=1 then
equipment="Modem"
elseif wEquipment=2 then
equipment="Hard Drive"
elseif wEquipment=3 then
equipment="Monitor"
elseif wEquipment=4 then
equipment="Keyboard"
else
equipment="Power Supply"
end if
mySheet.Cells(row,2).Value=equipment
rTime=Fix(rnd()*10+1)+Fix(Rnd()*(10+wOffice)+1)
mySheet.Cells(row,3).Value=rTime
mySheet.Cells(row,4).Value=Fix(Rnd()*999+1000) & "-"
& Fix(Rnd()*999+1000)
Next
mySheet.Columns(1).Autofit
mySheet.Columns(2).Autofit
mySheet.Columns(3).Autofit
mySheet.Columns(4).Autofit
Howthisscriptworks:
Fix(Rnd()*n+1) creates an integer number between 1 and n
inclusive. Rnd()makesa random numberbetween0and1. Well,
actuallyitisnottrulyrandom,itfollowsamathematicalpatternthat
appearstoberandom;thisiscalledpseudorandom.Fix()takesany
decimalandreturnsonlytheintegerpart.Forexample,ifRnd()gave
0.52thenRnd()*10wouldbe5.1andFix(Rnd()*10+1)wouldbe6.
Wecanusethisformulatomakeamixofatwhichofficerepairsare
done, what is wrong and the job number. Also, if one takes two
random numbers and adds them together, just like adding the
numberfromthrowingapairofdice,theresultwillfollowtheclassic
Gaussiancurve.Thatmeansthedistributionofresultsisabellshape
withthebulkofresultsinthemiddle.Ihaveusedthistechniqueto
createarealisticdistributionofrepairtimesfromthescript.
Finally, to give us some variation between offices and between
componentswhichneedrepair,Ihavemixedinthenumberswhich
choose office and device into the calculation of repair time. This
meanswegetthetypeofvariationthatwouldbebeinglookedforin
arealsituation.
DrAlexanderJTurner2007 95
BabySteps
Figure32:TokickofftheprocessofcreatingaPivotTable,we
mustensurethattheSheetwiththedatainwhichweare
interestedisshowing.Then,selectingDatathenPivotTable
andPivotChartReportwillstartthewizardweneedtocreate
outPivotTable.
96 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure33:NextwewillseethePivotTablewizardstartup.The
importantoptionsonthefirstpageofthewizardarewheretoget
thedatafromandifthewizardshouldcreateatableorachart.
ExcelcancreateaPivotTableoraPivotChartfromexternaldata.An
exampleofthiswouldbetocreateitfroman SQLdatabase.Whilst
thisisfabulouslypowerful,itisveryrarelyuseful. Fornowwewill
choosetotakethedatafromaSheet.Wecanalsoignoretheoption
ofusingmultipleconsolidationrangesbecause,tobehonest,itdoes
notworkverywell.
IhighlyrecommendalwayscreatingaPivotTablefirstbecausewe
canalwaysmakeachartfromitlater.Sothechoicesshouldbe:
1) MicrosoftOfficeExcellistordatabase.
2) PivotTable.
DrAlexanderJTurner2007 97
BabySteps
Figure34:Nowthatthewizard'knows'thatwewantaPivot
TablewehavetotellitfromwheretotaketheSheetdata.Thisis
doneusingastandardCellreferenceasshowabove.Excel
usuallymakesthecorrectguessastotheCellstouse.Ifitgetsit
wrong,wecancorrectitbyselectingtheCellswiththemouseor
typingtheCellreferenceintothewizarddirectly.
Figure35:Excelknowsthebasicsofwhatwewantatthisstage.
ItknowswewantaPivotTableandwhatdatawillbeusedto
createit.NextwemusttellExcelwheretoputthenewtable.By
farthetidiestsolutionistoalwaysputanewPivotTableina
newSheetusingtheNewWorksheetoption.
98 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure36:Thisscreenshotshowsthenewlycreatedbutstill
blankPivotTableandthePivotTableFieldList.
Now the fun starts! We can start laying out our Pivot Table. To
facilitatethis,ExcelhasdrawnforuseanemptyPivotTable. The
tablehas4areas. Thisareasare'droptargets';wecandragfield
namesfromthePivotTableFieldListboxintotheseareasofthePivot
Tabletocontrolthewaythetableworks.
Atthetopoftheblanktableisthe Pagearea;wewilllookatthis
later. Ofmoreimmediateinterestisthe Rowarea totheleftofthe
table.ThissaysDropRowFieldsHere.Thisareaisforcontaining
fieldsagainstwhichdatawillbesummarisedinRowsgoingacross
thetable.AboveandtotherightoftheRowareaistheColumnarea
saying Drop Column Fields Here. This area is for fields against
whichdatawillbesummarisedinColumnsgoingdownthepage.In
themiddleisthe Dataarea. Thisiswherethedatawhichistobe
summarisedisplaced.
Inourexamplewehaverepairtimesfordifferentcomponentfailures
atdifferentoffices. Whatwewanttoknowisinformationonthe
repairtimeforaparticularcomponentataparticularoffice.Wealso
wanttobeabletocomparetheoverallperformanceofofficesand
theoveralltimesfordifferentcomponents.
WecandoallthisbymakingthePivotTablesummarisebyofficein
RowsandcomponentsinColumns. Thisway,tofindthedatafor
modemsintheUSoffice,wecansimplylookdowntheRowsuntilwe
find the US Row and then across the Columns until we find the
modem Column. This will find us the Cell which will hold the
number we are interested in. The Pivot Table will also give us a
DrAlexanderJTurner2007 99
BabySteps
summaryforeachRowoverall(foroffices)andColumnoverall(for
components).Thenextfewscreenshotsshowhowwe'tell'thePivot
Tabletodoallthesethings.
Figure37:Alltheinitiallayoutisdonewithdraganddrop.The
availablefieldsareshowninthePivotTableFieldListdialogue
box.TomakeOfficeaRowfieldweclickonisnameinthe
dialogueboxanddragitovertotheRowareawherewedropit
(asshowninthepicture).
Dropping the Office field name onto the Row area immediately
causes Excel to enumerate the unique values of this field as Row
headers.Itisalsoworthnotingthatshouldwechangeourminds,we
candragthegreyOfficebuttonExceladdsatthetopofthe Row
area.Ifwedragitbacktothedialogueboxfromwhichitcame,itis
theOfficefieldisremovedfromthePivotTable.Ifwedragittoa
differentarea(e.g.theColumnarea)Excelplacesitthereinstead.
Just like with the office field we can now draganddrop the
Equipmentfield.Thisfieldrepresentsthecomponentthatisbeing
repaired.WedragittotheColumnareaanddropitthere.
100 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure38:ThisscreenshotshowsthePivotTablesetupto
summarisebyofficeinRowsandequipmentinColumns.The
nextstepwillbetotellExcelwhatdatatoactuallysummarise.
Figure39:DraggingtheRepairTimefieldfromthePivotTable
FieldListdialoguetotheDataareacausesthetableto
automaticallysummarisethesumofrepairtimesforalloffices
andequipment.
DraggingafieldintotheDataareatellsExcelthatitisthefieldwith
thedatatobesummarised. Excelguessesthemethodofsummary.
Inthiscase,Excelguessesthatitshouldsumthevaluesoftherepair
timefield.Forexample,ittakesalltherepairtimesforharddrivesin
Chinaandaddsthemtogether.Inourscreenshotabove(figure39)
thisgives80hours. Thisisnotactuallymuchusetous. Wecan
DrAlexanderJTurner2007 101
BabySteps
changethemethodofsummaryasisshowninthenextscreenshot.
Forthisexample,Ihavechosentosummarisebyshowingtheaverage
(numericmean)oftherepairtime.
Figure40:ByrightclickingoneoftheCellsintheDataareawe
getthecontextmenushowabove.ByclickingtheFieldSettings
optionwegetthePivotTableFielddialogueasshowninthe
nextscreenshot.
Figure41:ThePivotTableFielddialogueletsuschangetheway
thedataissummarised.
102 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure42:Inthisexample,whenIhadchangedthesummary
methodtoaverageIgottheseverylongdecimalnumbers.To
makethislessugly,IusedthenormalrightclicktheFormat
Cellsmethod.
Figure43:Hereitis,ourPivotTableinitsdefaultlayout.Fora
lotofapplications,thismaywellbesufficient.Shoulditbe
necessarytobeautifythingsfurther,thenCellbackgrounds,
numberformatsandalltheseotherthingscanbesetbyhand.
However,doingsocanmakescriptingabittricky;itmightbe
bettertoinitiallyseeifoneofthebuiltinformatsmightdowhat
wewant.
DrAlexanderJTurner2007 103
BabySteps
Figure44:ClickingtheFormatReportbuttononthePivotTable
toolbarrevealstheAutoFormatdialogue.
Figure45:Therearequiteafewbuiltinformatstochoosefrom.
Itisworthbeingabitcarefulhowever,severalrelayoutthePivot
Tablefieldpositions,whichcanbeannoying.AclickoftheOK
buttonappliesaformattotheactualtable.
104 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure46:OneofthethingsIlikeverymuchaboutPivotTables
isthenumberofbuiltinfeatures.InthisscreenshotIhave
clickedtheEquipmentfieldtab.Thisthenhasletmechoose
whichofthevariousvaluesoftheEquipmentfieldIactuallywant
displayedinthetable.Notonlyisthisacoolfeatureforme,itis
alsoavailabletowhomeverIgivemyfinishedtable.
Figure47:AnothermindblowinglyusefulfeatureofaPivotTable
isdrilldown.TogetthenewlycreatedSheetshownabove,I
doubleclickedontheCh/PowerSupplyDataareaCell.This
causedExceltopopulateanewSheetwithjustthatdatawhich
assummarisedtocreatethatCell.
With a Pivot Table we can use the summarised data to find the
informationweareinterestedinanddrilldowntofindtherawdata
DrAlexanderJTurner2007 105
BabySteps
thatwassummarisedtocreateit.Weshouldnotethateventhough
JobNumberisnotdisplayedinthe PivotTable,itisshowninthe
drilldowndata.
If,forexample,IfeltthattheCh/PowerSupplyaveragewastoo
high,Icould:
1) Drilldowntotherawdata.
2) Sortbyrepairtime.
3) MakeanoteofthetoptenJobNumbers.
4) Call the appropriate manager and discuss what might be
donetofixwhatevermadethesejobstakesolong.
Creating Pivot Tables Using Scripts
Looking At The Recorded Macro
The next block of code is the raw Recorded Macro as Excel 2003
created it from same session from which I took the above screen
shots.Atfirstblushitlooksabitscary(oratleastitdoesnotme).
However, taken step by step, the beast can be tamed. So, my
approachherewillbetodojustthat,lookatthescriptinlittlesteps
figuringoutwhatishappeningaswegoalong.
' Raw Recorded Macro
ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase,
SourceData:= _
"Sheet1!R1C1:R301C4").CreatePivotTable
TableDestination:="", TableName:= _
"PivotTable1", DefaultVersion:=xlPivotTableVersion10
ActiveSheet.PivotTableWizard
TableDestination:=ActiveSheet.Cells(3, 1)
ActiveSheet.Cells(3, 1).Select
ActiveWorkbook.ShowPivotTableFieldList = True
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Offi
ce")
.Orientation = xlRowField
.Position = 1
End With
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Equi
pment")
.Orientation = xlColumnField
106 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField
ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Repair Time"), "Sum of
Repair Time", xlSum
Range("B5").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("Su
m of Repair Time"). _
Function = xlAverage
Range("B5:G8").Select
Selection.NumberFormat = "0.00"
ActiveSheet.PivotTables("PivotTable1").PivotSelect "",
xlDataAndLabel, True
ActiveSheet.PivotTables("PivotTable1").Format xlTable2
Whatisthisallabout?HereisastepbystepguidetowhatExcelis
doinghere:
1) TakethePivotCachesCollectionoftheActiveWorkbook(that
whichwearelookingat)andAddanewPivotCache.
2) SetthedatasourcetypeforthisPivotCachetoxlDatabase.
3) Set the Range of Cells for this PivotCache to Sheet1!
R1C1:R301:C4.
DrAlexanderJTurner2007 107
BabySteps
4) NowthatwehavesetupthePivotCache,createaPivotTable
fromit.
5) MakethenewPivotTable'sdestinationbe.Thismakesit
appearinanewSheet.
6) GivethenewPivotTablethenamePivotTable1.
7) Finally, give the new Pivot Table a default layout of
xlPivotTableVersion10.
Soineffect,theselinescreateaPivotCacheObjectwhichworkswith
theRangeofCellswhichcontainstherawdata. Itthencreatesa
PivotTableObjectwhichworkswiththethePivotCachetocreatethe
datasummarywewant.
ActiveSheet.PivotTableWizard
TableDestination:=ActiveSheet.Cells(3, 1)
ActiveSheet.Cells(3, 1).Select
ActiveWorkbook.ShowPivotTableFieldList = True
Thisactuallydoesnothingofuse,itcanbeignored!
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Offi
ce")
.Orientation = xlRowField
.Position = 1
End With
With
Thispieceofcodeisjustthesameasthepreviousone. Theonly
differenceisthatitmaketheEquipmentfieldintoaColumn.
108 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
ActiveSheet.PivotTables("PivotTable1").AddDataField
ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Repair Time"), "Sum of
Repair Time", xlSum
ThispieceofcodeusesthesamemethodagaintofindthePivotTable
Object.Onceithasdoneso,itcallstheAddDataFieldMethodtoadd
theRepairTimefieldasaDatafieldwithatitleofSumofRepair
TimeandasummaryfunctionofxlSum.
Range("B5").Select
Thisdoesnothingimportanthowever,thenextbitdoes:
ActiveSheet.PivotTables("PivotTable1").PivotFields("Su
m of Repair Time"). _
Function = xlAverage
Theabovecodeconvertsthesummarymethodfromsumtoaverage.
Again,mostoftheactualcodeismadeupoffindingthePivotTable
Object.WhenwetranslateovertoaScriptingMacro,wewillgetrid
ofallthismess.
Range("B5:G8").Select
Selection.NumberFormat = "0.00"
Theaboveisthebitthatsetsthenumberstojusthavetwodecimal
places.I'llshowaneasierwayofdoingthislater.Thesnagwiththis
approachisthatourscriptwillhavetoworkoutwhatRangetouse.
Itisbettertouseanapproachwhichavoidsthis.
ActiveSheet.PivotTables("PivotTable1").PivotSelect "",
xlDataAndLabel, True
Thisisnotdoinganythinguseful.
ActiveSheet.PivotTables("PivotTable1").Format xlTable2
ThisfinalpieceofcodesetstheformatofthePivotTabletothebuilt
informatwewanted.
I did mention that there is a better way of setting the Number
Format totwo decimal places. Thenexttwo screenshotsshould
how this is done from the graphic user interface. Whilst I was
creatingthesescreenshots,IhadtheMacroRecorderrunning,sowe
canseethecodethatcameoutaswell.
DrAlexanderJTurner2007 109
BabySteps
Figure48:WehavealreadyseenthatrightclickingintheData
areaandselectingFieldSettingscausesthePivotTableField
dialoguetobeshown.WecanclicktheNumberbuttononthis
dialoguetosetthenumberformatforthewholetable.
Figure49:ThisistheresultofclickingtheNumberbuttonin
thePivotTableFielddialogue.InthisscreenshotIamsetting
thewholePivotTabletouseatwodecimalplaceformat.
UsingthePivotTableFielddialoguetosetthenumberformatofthe
PivotTableresultsinthefollowingcode:
' Fixing the number format without using a Range
With
ActiveSheet.PivotTables("PivotTable1").PivotFields(
_
110 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
HereIhavetranslatedthiscodeintoscripting:
' Fixing number format translated
With myTable.PivotFields("Average of Repair Time")
.NumberFormat = "0.00"
End With
Finished Product
OnceweunderstandwhateachpieceoftherecordedMacroisdoing,
itisstraightforwardtotranslateintoaScriptingMacro.HereIhave
placedallthetranslated Constants atthestartofthescript.Ihave
alsoreplacedallthoseclumsylookupstatementswithVariables. In
otherwords,eachtimeitusedtosaysomethinglike:
ActiveSheet.PivotTables("PivotTable1").
Ihavejustput:
myTable.
Thefinishedproduct:
Option Explicit
Dim myWorkbook, myCache, myTable
Const xlPivotTableVersion10 = 1
Const xlRowField = 1
Const xlColumnField = 2
Const xlAverage = -4106
Const xlTable2 = 11
Const xlDatabase = 1
DrAlexanderJTurner2007 111
BabySteps
"Sheet1!R1C1:R301C4" _
)
' This is the second step which creates the
' PivotTable from the PivotCache
Set myTable= myCache.CreatePivotTable _
( _
"", _
"PivotTable1", _
TRUE, _
xlPivotTableVersion10 _
)
With myTable.PivotFields("Equipment")
.Orientation = xlColumnField
.Position = 1
End With
112 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
IhaveusedaformulaandtheFillDownbecausethisisaveryfast
approach.WecouldmakethescriptinspecteachvalueinColumnC
and put an appropriate value in Column E. The result would be
identical,butitwouldrunhundredsoftimesslower.
NowthatwehaveaColumnindicatingifadatumisovertimeornot,
wecanaddthesenewdataintothe PivotTable. Ihaveaddedthe
OverLimitfieldtotheDataareatwice.ThefirsttimeIhaveadded
it with a summary function of Sum. This results in a number
showing how many repairs were over the limit for a particular
combinationofOfficeandEquipment.ThesecondtimeIhaveadded
itwithasummaryfunctionofCount. Thissimplygivesthetotal
number of repair for a particular combination of Office and
Equipment.
Icallthisapproachbanding.Theideaisthatwetakedatawhichis
continuous(couldbeanythingoutofarangeofvalues)andsortit
intotwoormorebands.Inthisexample,wemaketwobands,over
14hoursandnotover14hours.Anotherexamplemightbepeople's
heights.Withheightswemightmakealessthan1.5meters,1.5to2
metersandgreaterthan2meters.
HereisthecodewhichcreatesthebandingandthePivotTablefor
ourrepairtimeexample:
Option Explicit
' ... Some other code goes here ...
Dim myTable,myCache
Const xlDatabase = 1
DrAlexanderJTurner2007 113
BabySteps
Const xlRowField = 1
Const xlColumnField = 2
Const xlPivotTableVersion10 = 1
Const xlSum = -4157
Const xlCount = -4112
Const xlAverage = -4106
Set myTable=myCache.CreatePivotTable _
( _
"", _
"PivotTable1", _
true, _
xlPivotTableVersion10 _
)
With myTable.PivotFields("Office")
.Orientation = xlRowField
.Position = 1
End With
With myTable.PivotFields("Equipment")
.Orientation = xlColumnField
.Position = 1
End With
myTable.AddDataField _
myTable.PivotFields("Repare Time"), _
"Average of Repare Time",_
xlAverage
myTable.AddDataField _
myTable.PivotFields("Over Limit"), _
"Sum of Over Limit", _
xlSum
myTable.AddDataField _
myTable.PivotFields("Over Limit"), _
"Count Of Jobs", _
xlCount
114 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure50:HerewecanseethePivotTablewithbandeddata.I
haveincludedanenlargedviewoftheCh/HardDrivesummary
data.Wecanseethattherewere6jobsintotalofwhich2were
overthe14hourrepairlimit.However,theaveragerepairtime
is13.33hours,whichmightbeconsideredabitclosetothelimit
forcomfort.Rememberthough,theredataaretotallyinvented!
Cleaning Data
InLesson5wesawthatrealworlddatais'dirty'. PivotTablesare
particularly susceptible to this problem. If we considerour repair
timeexample;whatwouldhappenifinthedatathereisaRowwhich
has'ch'ratherthan'Ch'astheOfficecode?Thiswouldactuallyresult
inawholenewRowinthePivotTable.BoththedatainthenewRow
andintheold'Ch'Rowwouldbeincorrectbecausetheyshouldallbe
summarisedintothesameRow.
Simplyput,cleaninguprealworlddataisthedifferentiatorbetween
awelldonePivotTableMacroScriptandamisleadingmess.
The Page Area
Backwhenwelookedatplacingfieldsintodifferentpartsofablank
PivotTableImentionedthePagearea. Fieldsplacedheremakea
'filter'fortheentiretable.If,forexample,wehaddataondogsand
wewantedtoseeasummaryforjustonebreedatatime,thenwe
wouldputthefieldBreedintothePagearea.
DrAlexanderJTurner2007 115
BabySteps
116 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Anythingat2.5orlatershouldworkfine.
' This is a simple example of managing binary files in
' VBScript using the ADODB object
Dim inStream,outStream
Const adTypeText=2
Const adTypeBinary=1
inStream.Open
inStream.type=adTypeBinary
DrAlexanderJTurner2007 117
BabySteps
dim buff
buff=inStream.Read()
outStream.Close
inStream.Close
IntheaboveexampletheStreamobjectisusedtoloadthecontents
ofthefileintomemoryandstoreitasaBytearray(whichisaspecial
way of storing data in memory which VBScript does not normally
use).Thebytearrayisthenpassedtoanotherstreamwhichiswritten
outtodisk.Notverymemoryefficient,butifwewantreallyefficient
binaryfilehandling,thenyoushouldprobablybeprogramminginC!
thistechniquecomesinhandyasaquickandeasyapproachwhich
doesnotrequireanynewcompiledexecutables.
Another way of achieving the same thing is to use the CopyTo
method.Thisdoesnotallowyouaccesstoanyofthedata,butis
moreefficientifyouarewantingtojustcopyafile.Butthen,ifallwe
wanttodoiscopyafile,whynotusetheScripting.FileSystemObject
CopyFilemethod?
OneproblemyoumightfaceusingthisapproachinVBScriptisthat
wecannotcreateaBytearray.Thefollowingscriptfails:
dim outStream
const adTypeText=2
const adTypeBinary=1
dim data
dim buff()
redim buff(255)
dim i
for i=0 to 255
buff(i)=i
next
118 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
outStream.Write(buff)
outStream.SaveToFile "C:\temp\test.gif
outStream.Close
inStream.Close
ThescriptfailsbecausethearraycreatedisaVariantarray,notaByte
array.Whatdoesthatmean?Wellheregoes.
VBScript triestomakelifefortheprogrammersimple. Onewayit
doesthisistosaythatanyVariablecanholdanytypeofdata.Thisis
actuallyasortoftrickthatworksinthebackground. Variablesin
VBScriptarestoredasathingcalleda'Variant'.AVariantholdsnot
onlyavalue,butinformationontype.SoaVariableholdingaString
inVBScriptnotonlyholdsthedatafortheStringitsself,butanextra
datumwhichineffectsaysThisisaString.
Other pieces of software, ADODB being an example, do not use
Variants. VBScriptcantranslateforthem. SoADODB.Streamwill
passdatainafromVBScriptasanArrayofBytes.VBScriptaddsto
the Variablethe datum sayingThis is an Array ofBytes when it
reads from the ADODB.Stream. When VBScript writes to the
ADODB.Streamitstripsthisextradatumoffagain.
Allthis'magic'worksjustfineuntiltocomestocreatingaVariable
which holds a Array to be written to ADODB.Stream. VBScript
cannot create and Array of Bytes. It can only create an Array of
Variants. The magic does not automatically convert an Array of
VariantstoandArrayofBytes.Toworkaroundthisproblem,wecan
getADODB.StreamtocreateanArrayofBytesforusbywritingouta
textfileoftheappropriatelengthandthenreadingitin.Igavethisa
lotofthoughtanddecidedthatwritingupthismethodwouldbejust
fartoohardcorefor'BabySteps'.However,Iwillbehappytoanswer
anyemailsononthesubjectandmightwriteitupinmyblog.
Reading Data From Binary Files An Example
OK,hereweseethatwecanreadbinaryfilesaslongastheyarenot
toolarge.WecanreadthedatainthembygettingaBytearrayfrom
theLoadFromFilemethodoftheStreamobject,andwecanwriteto
them.Forthelastpieceofthissection,letusdosomething'real'with
thistechnology. Thescriptbelowlooksforallthe'.gif'filesin'My
Pictures'andliststhemalongwiththecontentsoftheGIFversion
label. TheGIFversionlabelisstoredatthestartofthe'gif'binary
files.
Option Explicit
DrAlexanderJTurner2007 119
BabySteps
mySheet.Columns(1).Autofit
mySheet.Columns(2).Autofit
120 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
function GetGifComment(gifFilePath)
dim inStream,buff,commentLen,commentStr,myIndex
dim myByte,myByteValue,myCharacter
set inStream=WScript.CreateObject("ADODB.Stream")
inStream.Open
inStream.type=1
inStream.LoadFromFile gifFilePath
buff=inStream.Read()
inStream.Close
commentStr=""
for myIndex = 1 to 6
' Extract 1 byte from the buffer
myByte = MidB(buff,myIndex,1)
' Gets its numeric value
myByteValue = AscB(myByte)
' Convert that numeric value into a character
myCharacter = Chr(myByteValue)
' Append that character to the string
commentStr = commentStr & myCharacter
next
GetGifComment = commentStr
end function
ADODB.Stream Summary
Properties
Property Description
CharSet Sets or returns a value that
specifies into which character set
the contents are to be translated.
This property is only used with text
Stream objects (type is adTypeText)
EOS Returns whether the current position
is at the end of the stream or not
LineSeparator Sets or returns the line separator
character used in a text Stream
object
Mode Sets or returns the available
permissions for modifying data
Position Sets or returns the current position
DrAlexanderJTurner2007 121
BabySteps
IfthemodeofastreamisadTypeText(2)wewillgetanerrorifyou
trytouseReadorWrite.Equally,ifthetypeisadTypeBinary(1)the
ReadTextandWriteTextwillfail.Notealsothatifthestreamsareset
toTextandCopyToisusedtocopyafile,thefilewillbeconvertedto
122 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
textevenifitdidnotstartoutthisway.Theendresultisnormallya
corruptfile.IwouldstronglysuggestalwaysusingadTypeBinarywith
ADODB and using the FileSystemObject for all text file
manipulations.
Sending Key Strokes To Other Applications Through
SofarwehaveseentheabilityofscriptstoworkwithExcelusing
COM. How about using a script to work with Excel and another
application? Anexampleapplicationmightbe Notepad. However,
thereisnoCOMinterfacetoNotepad,sowearegoingtohavetouse
the WScript.SendKeys method.Sohereisaquickcribonhowthat
works.
Mostkeyscanberepresentedbythecharacterofthekeyitself.e.g,
thekeysequenceFREDcanberepresentedsimplyby"FRED".Hereis
asimplescriptwhichwillopenNotepadandtypeFREDintoit.Todo
that,itcreatesaObjectfromtheWscript.ShellClass.ThisObjecthas
a Method to 'run' an application. This Method is used to run
Notepad.OnceNotepadisupandrunning,thekeysequenceFRED
issenttoit.
Option Explicit
Dim WshShell
Some special keys, such as the control keys, function keys etc are
encodedinastringenclosedby{braces}
Key Code
{ {{}
} {}}
[ {[}
] {]}
~ {~}
+ {+}
^ {^}
% {%}
DrAlexanderJTurner2007 123
BabySteps
Key Code
BACKSPACE {BACKSPACE}, {BS}, or {BKSP}
BREAK {BREAK}
CLEAR {CLEAR}
CAPS LOCK {CAPSLOCK}
DEL or DELETE {DELETE} or {DEL}
DOWN ARROW {DOWN}
END {END}
ENTER {ENTER} or ~
ESC {ESC}
HELP {HELP}
HOME {HOME}
INS or INSERT {INSERT} or {INS}
LEFT ARROW {LEFT}
NUM LOCK {NUMLOCK}
PAGE DOWN {PGDN}
PAGE UP {PGUP}
PRINT SCREEN {PRTSC}
RIGHT ARROW {RIGHT}
SCROLL LOCK {SCROLLLOCK}
TAB {TAB}
UP ARROW {UP}
F1 {F1}
F2 {F2}
F3 {F3}
F4 {F4}
F5 {F5}
F6 {F6}
F7 {F7}
F8 {F8}
F9 {F9}
F10 {F10}
F11 {F11}
F12 {F12}
F13 {F13}
F14 {F14}
F15 {F15}
F16 {F16}
TospecifykeyscombinedwithanycombinationofSHIFT,CTRL,and
ALTkeys,precedethekeycodewithoneormoreofthefollowing:
124 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
HereisafullerexampleinwhichwecreateasmalltableinandExcel
spreadsheet and use copy and paste to place the contents into
Notepad.
Option Explicit
Dim WshShell, myExcel, myWorkbook, mySheet
WScript.Sleep 500
DrAlexanderJTurner2007 125
BabySteps
126 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure51:ThisscreenshotshowstheconceptofTRUE/FALSE
formulaeinExcel.Itthengoesontoillustratehowtoprocessthe
answerstothese'questios'usingAND,ORandNOT.Inthefirst
columnaretheExcelformulae(displayedvia
Tools/Options/Formulas)andinthesecondcolumnarethe
TRUE/FALSEresults.
DrAlexanderJTurner2007 127
BabySteps
Wecantakethesedataandusethemtocreateadecision:
A B C
1 Age Of Car (Years) 3
2 Department Sales
3 Choice =B1>2 =AND(B3,B2=Sales)
IntheabovespreadsheetCellC3willdisplayavalueofTRUE.Ifwe
changeB2tobesomethingotherthan'Sales'orwechangeB1tobe2
orless,thenC3willdisplayavalueofFALSE.Inotherwords,Excel
haschainedtwochoicestogethertomakearule.
The key word AND() in an Excel formula means a special Excel
Function. A comma separated list of arguments goes in the
parenthesis. AND()isTRUEifandonlyifeverysingle argument is
TRUE.
=AND(TRUE,TRUE,FALSE) FALSE
=AND(TRUE,TRUE,TRUE) TRUE
=AND(TRUE,FALSE) FALSE
=AND(FALSE,TRUE) FALSE
=AND(TRUE,TRUE) TRUE
etc...
128 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Sometimesismakesmoresensetoaskwhensomethingisnottrue.
ConsiderthatpeopledonotgetacariftheyliveinHolland(itistoo
flat to bother, one should use a bike). One way to look at this
decisionis:
ApersonmaybeeligibleforacariftheydoNOTlivein
Holland
ExcelhasafunctionNOT()thatdoesthisforus:
=NOT(1>2) TRUE
WecanuseournewtooltoaddthenocarsinHollanddecisionto
ourruleprocessingspreadsheet.
A B C D
1 Age Of Car 3
(Years)
2 Department Sales
3 Country France
4 Choice =B1>2 =AND(B3,B2= =AND(C4,
Sales) NOT(B3=Holland))
Intheexampleabove,BurtwillgetanewcarbecausethevalueofD4
willbeTRUE.IfhemovedtoHollandthenhewouldnotgetthecar.
Excelcanmakethatchoiceforususingthissimplestepbysteprule
system.
Thereareprobablythousandsofwaystoloadthisdecisionsystem
into Excel; using the way I have shown it issimple to create and
simpletomaintainthespreadsheet. Theapproachcanbesummed
uplikethis:
PlacedecisionsinaRow.
MakeonlyoneTRUE/FALSEdecisionsineacheachCellof
thatRow.
ChaintheCellstogethersoeachCell'sdecisionischainedby
ANDtotheresultoftheCelltoitsleft.
DrAlexanderJTurner2007 129
BabySteps
TherightmostCellinaRowgivestheactualoutputchoice
TRUE/FALSEoftherule.
Whatwehavedonesofarisbuildsingledecisionsintorulesusing
chaining. How about if there are more outcomes than just
TRUE/FALSEorGetacar/don'tgetacar? Whataboutmaking
Excelpickwhatsortofcartogive? Thisiswhere blocks and zeds
comein.
Blocks And Zeds
Rules are groups of decisions chained together. We place all the
decisionsforaruleinoneRow. Blocks aregroupsofruleswhich
interactwitheachother.Iftheoutcomeofarule hasnoimpacton
theoutcomeofanotherrulethenthetworulesareindifferentblocks.
Butiftheoutcomeofaruleaffectstheoutcomeofanotherrulethen
thetworulesareinthesameblock.
Considerthenextsetofdecisionswhichgotomakeuptworules.
TheideabeingthatifanemployeeisinSalesbutwillnotbegettinga
newcarthisyear,thentheygeta'bustimetableinstead.
A B C D
1 Age Of Car 3
(Years)
2 Department Sales
3 Country France
4 Get Car ? =B1>2 =AND(B3,B2=Sa =AND(C4,
les) NOT(B3=Hollan
d))
5 Get 'Bus =NOT(D4) =AND(B5,B2=Sa
Time Table? les)
NowExcelcomputestheanswerstotwoquestions:
1. DoesBurtgetanewcar?
2. DoesBurtgeta'bustimetable?
CellC5dependsonB5whichdependsonD4whichdependsonC4
whichdependsonB4.IfweconnectuptheseCellsinthisorderwith
aline(likejointhedots)thenwewilldrawaZshape.Plus,therules
inRows4and5makeupablockbecausetheydependoneachother.
So,theserulesmakeablockandazed.
130 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
ORgivesTRUEifanyofitsargumentsareTRUE.ItsaysIfmyfirst
argument OR my second argument OR my third argument ... are
TRUEthenIamTRUE.
In decision/choice work with Excel, we do not use OR to chain
decisions tomakeaRule. We use OR tocollect togetheranswers
fromRules. Forexample,wemightwanttosaysomethinglikeIf
Rule2OrRule4sayBurtgetsacar,thenhegetsacar.
Hereisthescenarioforournextexample:
ThereisacompanywhichisintendingtoupgradefromMSOffice
2003toMSOffice2007.
However,therearesomecomplexities.Firstoff,noteveryoneistobe
upgraded to 2007; thecompany has a deal by whichsome ofthe
Office2003licensescanberecycledtoallowupgradeofoldOffice
2000licenseforpeoplewhodonotrequirethelatestsoftware.Also,
therearethreetypesofOffice2007licensepackages:
1. Word,Excel,Outlook,PowerPointandAccess
2. Word,Excel,Outlook
3. Word,Excel
Therearethreedepartmentstothiscompany:
1. Admin
2. Sales
3. Supply
Admin require Office 2007 because some of the administration
systemsarebeingupgradedandrequirethethisversionofOfficefor
integration.
DrAlexanderJTurner2007 131
BabySteps
So, here are the rules for choosing what software to install on
people'smachines:
People in Admin who have Access version > 9 get license
package1otherwise,licensepackage2.
PeoplewithPowerPointgetPowerPointagain.
SalesonlyrequireWordandExcelbecausetheytraveland
willuseWebMailforemail.
SupplygetanupgradetoOffice2003(Office11)iftheydo
not already have it. There is only one Office 2003 license
package.
ThisexampleisrunusingthreeSheetsinoneWorkbook.Thefirstis
DataIn.ThisSheetiswheretheinformationabouttheemployeeis
placed. ThenextSheetislogic. Thisiswherealltherulesare
placed.logictakesitsinformationfromDataIn.Finally,thereis
DataOut.ThisSheetisjustapresentationreporttohelpmakethe
resultsunambiguous.
HereisthestructureoftheDataInSheet:
User Information
Title Datum
Name Fred
Department admin
Installed Software
Package Version (0 means Not Installed)
Word 11
Excel 11
Outlook 11
Powerpoint 1
Access 10
HereisthestructureoftheLogicsheet:
Is Admin Has Access > 9 Install L1
=DataIn!.B4="admin" =AND(A2,DataIn!.B12>9) =B2
IsAdmin Has Powerpoint Install L2
132 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
AtthebottomoftheLogicSheet,ORfunctionsareusedtocollect
theoutputoftherules:
Install 2007, L1 =C2
Install 2007, L2 =OR(C4;C8)
Install 2007, L3 =OR(C6;C10)
Install 2003 =OR(C12;C14)
Thenatureoftherulesmeansthataemployeewillgetonlyoneof
thechoices.Inotherwords,onlyoneoftheinstalloptionswillshow
TRUE.
DrAlexanderJTurner2007 133
BabySteps
Figure52:Excelhastheabilitytodrawoutthedependencies
betweenCells.Bydoingthiswecanseethestructureofthe
BlocksandZedsinourWorkbook.Ihaveputdarkborders
aroundeachblocktomakeeasiertoseethestructureoftheLogic
Sheet.
Figure53:WorkingwithZeds!WeloadthechoicesintoExcelby
startingatthetopleftandworkingacrosstotheright.Thenwe
startagainattheleft.Eachlineinagroupislinkedtothe
answerofthelineabovesothatonlyonelineinagroupcanbe
TRUE.Thismeansthedependenciesinbetweenthelinesmakea
Zpattern.
Figure54:Intheabovegroup,therearethreelinesofchoices
yieldingthreepossibleoutcomes.ThebottomlinemakesaZwith
themiddleline.
134 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure55:Herewecanseethegroupwiththreelinesofchoices
again.Thebottomlinecanonlybetrueiftheprevioustwo
choicelinesendupfalse.ThismeansthattherearetwoZeds
whichincludethebottomline.Thereasonthisapproachworksis
thatthetoplineismostselective,thesecondlineisslightlyless
selectiveandthebottomlineistheleastselective.Ifyoucannot
orderthelineslikethis,thechancesarethatyourrulesare
ambiguousandcoulddowithtweakingoralternatively,you
shouldsplitthegroupintotwo.
Figure56:ThenextBlockinourexampleisshownherewithits
ZedsrevealedbyExcel'sCelldependencytracking.
DrAlexanderJTurner2007 135
BabySteps
Figure57:HereisthelastoftheRuleblockswithitsinternal
structuredisplayed.Thedotteddependencylinenearthebottom
showsthewaytheresultoftheblockisreportedforwardontothe
DataOutSheet.
Figure58:InthisexampleIhavemadeaseparateDataOut
Sheetwhichderivesitsdatafromtherulesheetyetpresentsthe
resultsinanunambiguousway.
Moving From One To Many
Sofarinchoice/decisionprocessingwehaveseenanexplanationand
examples of processing for one input data set. In the previous
example that data set represented one person. However, at the
136 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure59:Thisdiagramshowsthewayascriptprocessesdatato
makea'oneatatime'decisionWorkbookturnintoapowerful
decisioncrunchingsystem.
DrAlexanderJTurner2007 137
BabySteps
138 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
.Cells(2,2).Value = startTime
.Cells(2,3).Value = endTime
.Cells(2,4).Formula = "=C2-B2"
.Columns(1).Autofit
.Columns(2).Autofit
.Columns(3).Autofit
.Columns(4).Autofit
End With
DrAlexanderJTurner2007 139
BabySteps
ThekeypartofthescriptistheForloopinthemiddle. Itplacesa
differentStringintoeachoftheCellsinColumn1fromRow2to
10001.TheVBScript'builtin'functionTimer()isusedtorecordthe
numberofsecondssincemidnightbeforeandaftertheloophasrun.
Thedifferenceinthetworesultsisthetimeittookthelooptorun.
Timer()isusuallyaccuratetowithinaroundtwentymilliseconds,soit
makesquiteahandywaytotimetheperformanceofscript.
Figure60:Thisisascreenshotshowingtheresultofrunningthe
CellbyCellloadingscript.Itshowsthatithastaken51.3seconds
toloadaStringinto1000CellswhenthedataisloadedonCells
atatime.
AswecanseefromFigure60,ithastakennearlyaminutetoload
onethousandCells.IfweweretodothisfortenthousandRowsover
tenColumns,thenitwouldtakearoundonehundredminutes.Ifwe
imagine running a script that takes over an hour, then finding
somethinghasgonewrongandhavingtorunitagain,itiseasytosee
whyspeedingthingsupisgood!
Fortunately,thereareseveralwaystospeedupScriptingMacros.A
goodapproachisoftentodevelopthescriptusingasmallsetofdata
andloadingCellsoneatatime.Onceitisworkingcorrectlyitistime
tostartspeedingitupusingthetechniquescoveredhere.
Bulk Data Loading With Arrays
What Is An Array?
AnArrayisaspecialsortofvalueforaVariable. Wehavealready
seenthatVariablescanholdthingslikeString,Object,Dateetc.What
140 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
OrwecouldcreateaVariableusingtheVBScript'dim'specialword:
Dim myString(2)
myString(0) = hello 1
myString(1) = hello 2
myString(2) = hello 2
DrAlexanderJTurner2007 141
BabySteps
Figure61:Thisisascreenshotshowingtheresultofrunningthe
ArraytoCellloadingscript.Itshowsthatithastakenlessthana
fifthofasecondtoloadaStringinto1000Cellswhenthedatais
loadedonintoanArrayandthentheArraybulkloadedintothe
Cells.Thisis250timesfasterthandoingtheloadoneCellata
time.
142 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 143
BabySteps
144 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure62:Tostartrecording,wemustclickthe'Macro'pulldown
underthe'View'ribbon.
Figure63:Clickingthe'Macro'pulldowngivesustwooptions.
TorecordaMacro,wejustclick'RecordMacro'.Selectingthe
Macronameetc.isjustthesameasforpreviousversionsofExcel.
DrAlexanderJTurner2007 145
BabySteps
Figure64:Oncewefinishedperformingtheactionswhichwe
wantrecorded,the'View/Macro'pulldowngivesustheoptionto
'StopRecording'.
Figure65:TheView/Macropulldownletsusviewthecodeof
theMacro.Thewholeofthecodeeditorispettymuchidentical
tothatofpreviousversionsofExcel.
Showing The Developer Tab (Accessing VBA)
It would appear that the default install of Excel 2007 hides the
DeveloperTab. Tobeabletoseeit,andsogaineasyaccesstothe
CodeEditorandObjectBrowser,wecanfollowthesesteps.
146 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure66:SteponeistoclickontheMSOfficesymbolinthetop
lefthandcornerofExcel'swindow.Doingsorevealsthemenu
shownabove.Atthebottomrightisabutton(highlightedinthe
picture)namedExcelOptions.Thismustbeclicked.
Figure67:ClickingtheExcelOptionsbuttonrevealstheExcel
Optionswindow.Onceonehasrecoveredfromtheshock,it
becomesvisiblethatthereisanoptionShowDeveloperTabin
theRibbon.ThetrickistoselectthisandthenclickOK.
DrAlexanderJTurner2007 147
BabySteps
Figure68:HerewecanseeournewDeveloperTab.Highlighted
inthisscreenshotistheVisualBasicbutton.Clickingonthis
openstheCodeEditor.TheCodeEditorandallitsoptions(e.g.
theObjectBrowser)aremoreorlessidenticaltothoseofearlier
versionsofExcel.
148 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure69:KickingoffcreatinganewPivotTablecomesfrom
clickingthePivotTablebuttonontheInsertTaboftheRibbon.
Figure70:ThePivotTablewizardstartswiththepopupshown
above.IhighlyrecommendthatNewWorksheetisselected.
MostofthetimeExcelwillautomaticallyguessthecorrectrange
ofCellsfromwhichtotakethedataforourPivotTable.Ifitdoes
not,wecandirectlytypetherangeintotheTableRangetext
box.AndalternativeistoselectarangeofCellsbydraggingthe
mouseovertheSheet.
DrAlexanderJTurner2007 149
BabySteps
Figure71:OncewehaveclickedOKonthefirstpopup,Excel
insertsablankPivotTableandthePivotTableFieldListboxas
showninthisscreenshot.Thisisreallyverydifferentfromthe
previousversionsofExcel.Wenolongerseeareasintheblank
PivotTablefordraganddrop.Constructingthetableisalldone
viathePivotTableFieldListbox.
Figure72:Tosummariseafieldacrossrows,wedragthefield
namefromthetoppaneofthePivotTableFieldListboxtothe
RowLabelsarea.
150 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure73:TosummariseafielddownColumns,wedraganddrop
thefieldnamefromthetoppanetotheColumnLabelsarea.
Figure74:InthebottomrightofthePivotTableFieldListboxis
wheretheDatafieldnamesaredragged.Thisishighlightedinthe
abovescreenshot.ItstartsoutwiththedefaultSumfunction.To
setupthedatawhichwewantsummarisingwefirstdragthatfield
nametothisarea.JustaswiththepreviousversionofExcel,
changingtosummarymethoditsomethingotherthanSumisa
separatestep(describednext).
DrAlexanderJTurner2007 151
BabySteps
Figure75.RightclickingontheDataareaofthePivotTableField
Listboxbringsupthecontextmenushownabove.Atthebottom
ofthismenuistheValueFieldSettingsoption(highlighted).
Clickingthisrevealstheoptionsnecessarytochangethesummary
method(next).
Figure76:WenowgettheValueFieldSettingsbox.Inthe
screenshotabove,IamchoosingAverageformyDatafields
(whichMicrosoftnowsometimescallValuefields,butrelateto
theDataAreaofpreviousversionsofExcel).
152 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure77:ValueFieldSettingsboxalsohasatabforShow
valuesas.Underthistabwecanfindabutton(highlighted)
whichbringsuptheFormatCellsboxforthePivotTable.This
canbeusedtosetthenumberformat.InthisexampleIhaveset
itto2decimalplaces(next).
Figure78:HerewecanseeournewPivotTableisdefaultlayout
witha2decimalplacenumberformat.
DrAlexanderJTurner2007 153
BabySteps
Figure79:ByusingtheDesigntab(highlighted)wecanpick
oneofthemanybuiltinlayoutsforourtableifthedefaultisnot
quiteasvisuallyappealingaswewant.
Inlesson8welookedatthe'raw'MacroforcreatingaPivotTablejust
asExcelhadrecordedit. Forinterestssake,hereistherawMacro
whichwasrecordedforthecreationthethePivotTableinthescreen
shotshere.Thereisverylittledifference.Asusual,aMacrosetupto
runforanearlierversionofExcelwill(probably)workinExcel2007,
butweshouldnotexpectthereversetobetrue:
' Raw Macro Recording For Creating A Pivot Table In
Excel 2007
Sheets.Add
ActiveWorkbook.Worksheets("Sheet4").PivotTables("Piv
otTable1").PivotCache. _
CreatePivotTable TableDestination:="Sheet5!R3C1",
TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion12
Sheets("Sheet5").Select
Cells(3, 1).Select
ActiveWorkbook.ShowPivotTableFieldList = True
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Offi
ce")
.Orientation = xlRowField
.Position = 1
End With
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Equi
pment")
.Orientation = xlColumnField
.Position = 1
154 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField
ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Repair Time"), "Sum of
Repair Time", xlSum
With
ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum
of Repair Time")
.Caption = "Average of Repair Time"
.Function = xlAverage
End With
With
ActiveSheet.PivotTables("PivotTable1").PivotFields( _
"Average of Repair Time")
.NumberFormat = "0.00"
End With
ActiveSheet.PivotTables("PivotTable1").TableStyle2 =
"PivotStyleLight19"
DrAlexanderJTurner2007 155
BabySteps
156 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 157
BabySteps
goodfeatureofthefontisthatisnarrow,meaningthatBabySteps
doesnothavetokilltoomanytreestobeprinted!
IpersonallyIprefernonseriffontsforheadings,especiallywherethe
body text has serifs. Unfortunately, Bitstream Vera Sans was too
broadforheadingssoIchose Arial (boringbutreliable).AlsoArial
makesaniceheadingfontbecauseitisclearandopensoiseasily
readwithoutdominatingthepage.
Figure80:Hereisme,onmyKubuntulaptop,writingthesection
ofBabyStepsonhowBabyStepswaswritten.
158 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 159
BabySteps
Effectively,bythetimeyouhaveanExcelMacrobasedsolution,itis
morecomplexandunwieldythatthescriptbasedone.
Q:ButtheVBAenvironmentissoniceandeasytouseinExcel,andit
alsohastheMacroRecorder.
A:Yes,theVBAenvironmentiswelldesigned.However,a
professionalgradetexteditorlikethefreenotepad++isalsovery
good.Notepad++hassomedisadvantagesoverVBA'seditor,but
alsosomeadvantageslikeexcellentfindandreplace,tabbedediting
etc.
Theotherbigadvantagewhenitcomestoenvironmentisthatscripts
aretextfilesandtextfilesareeasiertoworkwiththatembedded
Macros.Forexample,youcanusefreetoolslikewinmergetofind
thedifferencesbetweentwocopiesofascript.Itiseasierto'cutand
paste'bitsofcodebetweenscriptsandscriptstakeupmassivelyless
spacethanExcelfiles.
WhenitcomestotheMacroRecorder,thatisaveryroughtool.The
beabletoreleaseaRecordedMacrointothefielditneedalotof
polishing.ThismeansthatoncehaveRecordedyourMacro,youwill
havetodosomeeditingonit.Giventhis,youcanjustaseasilycopy
itoverintonotepad++andeditthereasascript.
Theother'cooltool'intheExcelVBAenvironmentistheObject
Explorer.Thereisnothingtostopyoustillusingitalongwith
anythingelse(helpforexample)thatcomeswithExcel.
Q:Whataboutintellectualpropertyprotection?IcanlockMacros
withapassword.Scriptsarejusttextfiles.
A:MSproduceafreeprogram,thescriptencoder.Theoutputisat
leastassecureaspasswordprotectedExcelMacros.
One Final Thing
WithMSOffice2007,thedefaultfileformatforExcelisxlsx.This
formatdoesnotevensupportembeddedMacros.Thisindicateshow
theworldinmovingawayfromtheideaofembeddingcodeinto
documents.
160 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 161
BabySteps
CCur(almostnever)
GivesanexpressionthathasbeenconvertedtoaVariantofsubtype
Currency.TheuseofthisisbeyondmostthingsonemightdoinExcel
MacroScripting.
CDate(often)
TakeswhateverwepasstoitandtriestoconvertitintoaDate.For
example,CDate(10January2007)willgiveadateofthetenthof
Januarytwothousandandsevenifthecomputerissettoworkin
English.
CDbl(sometimes)
ThisishandyforconvertingStringsintonumberswheretheStrings
arebeingreadfromafileforexample.
Chr(sometimes)
This is the logical opposite of Ansi. It converts a number into a
character using the type of encoding that files use to store text.
Chr(Ansi(A))isA.
CInt(almostnever)
UseCdblorCLnginstead.
CLng(rare)
ThisishandyforconvertingStringsintonumberswheretheStrings
arebeingreadfromafileforexample. However,mostofthetime
CDbl is a better choice unless for some odd reason integer (non
decimal)arithmeticisessential.
Cos(rare)
Givesthecosineofanangle. Thisishandyifyouareworkingin
engineeringetc.
CreateObject(Allthetime).
This is one of the first things we looked at. For example
CreateObject(Excel.Application)
CSng(almostnever)
TheuseofthisisbeyondmostthingsonemightdoinExcelMacro
Scripting.
162 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
CStr(rare)
ThisconvertswhateveryoupasstoitintoaString.Onemightthink
thatwewouldusethisallthetime;howeverthe&operatoriseven
more useful and does much the same thing. For example,
CStr(1.23)isthesameas"" & 1.23.
Date(sometimes)
Givesthecurrentsystemdate.
DateAdd(often)
Usetoaddtime(days,secondsetc.)todates.Seechapter7.Touse
putDateAdd(interval,number,myDate)wheretheintervalisonefrom
thisselection:
SETTING DESCRIPTION
YYYY Year
Q Quarter
M Month
Y Day Of Year
D Day
W WeekDay
WW Week Of Year
H Hour
N Minute
S Second
SotoaddoneweektothefirstofMarchtwothousandandsixwe
couldputDateAdd(D,7,DateSerial(2006,3,1)).
DateDiff(sometimes)
Thisfunctionworksoutthedifferencebetweentwodatesandreturns
theanswerasanumberofintervals. Thoseintervalsarethesame
intervalsasareusedinDateAdd.Togetthenumberofdaysbetween
the first of March nineteen ninety seven and thecurrent date, we
couldputDateDiff(D,DateSerial(1997,3,1),Date())
DatePart(rare)
Gives the specified part of a given date. It is called like this
DatePart(interval,date).
DrAlexanderJTurner2007 163
BabySteps
DateSerial(often)
CreatesaDateforaspecifiedyear,month,andday. Seechapter7.
TocreateaDaterepresentingthefirstofMarchnineteenninetyseven
wewouldputDateSerial(1997,3,1).
DateValue(never)
UseCDateorDateSerialinstead.
Day(rare)
Givesawholenumberbetween1and31,inclusive,representingthe
currentdayofthemonth.
Exp(rare)
Givese(thebaseofnaturallogarithms)raisedtoapower.
Filter(rare)
Givesazerobasedarraycontainingsubsetofastringarraybasedon
aspecifiedfiltercriteria. Theuseofthisisbeyondtheexamplesin
thisbook.
Fix(rare)
Gives the integer portion of a number. If we put Wscript.Echo
fix(1.5)wewillgetapopupboxsaying1.
FormatCurrency(almostnever)
Givesanexpressionformattedasacurrencyvalueusingthecurrency
symboldefinedinthesystemcontrolpanel. Formattinglikethisis
betterdoneinExcelitsselfinExcelMacroScripting.
FormatDateTime(almostnever)
Givesanexpressionformattedasadateortime.Formattinglikethis
isbetterdoneinExcelitsselfinExcelMacroScripting.
FormatNumber(almostnever)
Givesanexpressionformattedasanumber. Formattinglikethisis
betterdoneinExcelitsselfinExcelMacroScripting.
FormatPercent(almostnever)
Givesanexpressionformattedasapercentage(multipliedby100)
with a trailing %character. Formattinglike this is better done in
ExcelitsselfinExcelMacroScripting.
164 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
GetObject(rare)
GivesareferencetoaCOMobjectfromafile.Thismeansthatifthe
file has an 'binding' to a COM object (like .xls files are bound to
Excel)thenwecanuseGetObjecttoloadtheCOMobjectandgetthe
COMobjecttoloadthefile.Frankly,thisisamess;pleasedonotuse
it.
Hex(rare)
Gives a String representing the hexadecimal value of a number.
Hex(32)gives20andHex(255)givesFFetc.
Hour(rare)
Givesawholenumberbetween0and23,inclusive,representingthe
currenthouroftheday.
InStr(sometimes)
Givesthepositionofthefirstoccurrenceofonestringwithinanother.
It also allows us to say where to start searching. So, Instr(,
AlexanderJulianTurner)willgive10andInstr(11,,Alexander
JulianTurner)willgive17.
InStrRev(rare)
Givesthepositionofanoccurrenceofonestringwithinanother,from
theendofstring.ItisjustlikeInStrbutitworksinreverse.
Int(almostnever)
Givestheintegerportionofanumber.UseClnginstead.
IsArray(almostnever)
GivesaBoolean(TRUE/FALSE)valuespecifyingwhetheraVariableis
anarray.
IsDate(rare)
Gives a Boolean (TRUE/FALSE) value specifying whether an
expressioncanbeconvertedtoadate.Sometimeswecangetavalue
fromaSheet'sCellanditishandytofindoutifExcelconsideredthis
valuetobeaDate.Thisbuiltinfunctionwilltellus.
IsEmpty(constant)
IfaCellorVariablehasnoteverhadanythinginit,thenthiswill
return TRUE otherwise it returns FALSE. Examples are
IsEmpty(mySheet.Cell(row,1)) or IsEmpty(myVariable). We use
IsEmptytofindemptyrowsinSheets.
DrAlexanderJTurner2007 165
BabySteps
IsNull(sometimes)
Gives a Boolean (TRUE/FALSE) value that indicates whether an
expression contains no valid data. If we work with data from
databasesthenwewillfindtheseusefulsometimes.Itisprobablya
bitbeyondthescopeofBabySteps.
IsNumeric(sometimes)
Gives a Boolean (TRUE/FALSE) value specifying whether an
expressioncanbeevaluatedasanumber.
IsObject(rare)
GivesaBooleanvaluespecifyingwhetheranexpressionreferencesa
validAutomationobject.TheonlytimeIseethisbeingusedifExcel
ScriptingMacrosisifsomethinglikeaWordDocumentisembedded
inaSheet.ThentheValueofaCellwouldactuallybeanObjectso
IsObject(myCell.Value)mightbeusedtodetectthis.
Join(sometimes)
Givesastringcreatedbyjoininganumberofsubstringscontainedin
anarray.Seechapter11.
LBound(rare)
Givesthesmallestavailablesubscriptforthespecifieddimensionof
anarray.
LCase(often)
Givesastringthathasbeenconvertedtolowercase
Left(sometimes)
Givesaspecifiednumberofcharactersfromtheleftsideofastring.
Left(DogWaffle,3)willgiveDog.
Len(sometimes)
Givesthenumberofcharactersinastringorthenumberofbytes
requiredtostoreaVariable.ThisisbyfarthemostusefulforStrings.
Forexample Len(DogWaffle) will give 10, i.e. thelength of the
String.
LoadPicture(almostnever)
Givesapictureobject.
Log(rare)
Givesthenaturallogarithmofanumber.
166 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
LTrim(rare)
Givesacopyofastringwithoutleadingspaces.Normallywejustuse
Trim().
Mid(often)
ReadchunksoutofStrings.Mid(helloworld,6)givesworldand
Mid(helloworld,6,2)giveswo.
Minute(rare)
Givesawholenumberbetween0and59,inclusive,representingthe
currentminuteofthehour.
Month(rare)
Givesawholenumberbetween1and12,inclusive,representingthe
currentmonthoftheyear.
MonthName(rare)
Givesastringspecifyingthespecifiedmonth. MonthName(1)will
giveJanuaryifthecomputerissettouseEnglish.MonthName(1)
willgiveJanvierifthecomputerissettouseFrench.
Now(often)
Gives the current date and time according to the setting of your
computer'ssystemdateandtime.
Oct(almostnever)
Givesastringrepresentingtheoctalvalueofanumber.
Replace(often)
Givesastringinwhichaspecifiedsubstringhasbeenreplacedwith
another substring a specified number of times. For example
Replace(10102007, , /) will give 10/10/2007.
Replace(10102007, , /,1,1) will give 10/102007 and
Replace(10102007,,/,4,1)willgive1010/2007.
Right(sometimes)
GivesaspecifiednumberofcharactersfromtherightsideofaString.
Rnd(sometimes)
Givesarandomnumberbetween0and1.
DrAlexanderJTurner2007 167
BabySteps
Round(sometimes)
Givesanumberroundedtoaspecifiednumberofdecimalplaces.For
exampleRound(Rnd(),2)givesatwodecimalplacerandomnumber
between0and1(e.g.0.24).
RTrim(rare)
Gives a copy of a string without trailing spaces. We tend to use
Trim()instead.
ScriptEngine(almostnever)
Returnsastringrepresentingthescriptinglanguageinuse.
ScriptEngineBuildVersion(almostnever)
Returnsthebuildversionnumberofthescriptengineinuse.
ScriptEngineMajorVersion(almostnever)
Returnsthemajorversionnumberofthescriptengineinuse.
Second(rare)
Givesawholenumberbetween0and59,inclusive,representing
thecurrentsecondoftheminute
Sgn(rare)
Givesanintegerspecifyingthesignofanumber. Ifthenumberis
negative, then this always give 1 otherwise it will give 1.
Sgn(0.0000123) gives 1 whilst Sgn(0) gives 1 and Sgn(131234)
gives1.
Sin(rare)
Givesthesineofanangle.
Space(sometimes)
Givesastringconsistingofthespecifiednumberofspaces.Space(4)
gives"".
Split(often)
Gives a zerobased, onedimensional array containing a specified
number of substrings. It is used Split(StringToSplit,String
Delimiter,MaxNumberOfPieces).myArray=Split(MyDogIsCute,
,3)willgivea3elementarraystartingwithelement0.Sofrom
thearraymyArray(0)willhavethevalueMy,myArray(1)willbe
168 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DogandmyArray(2)willbeIsCute. IfwemissouttheMax
NumberOfPieces,itreturnsasmanypiecesaspossible.
Sqr(rare)
Givesthesquarerootofanumber.
StrComp(rare)
GivesavaluespecifyingtheresultofaStringcomparison.
String(sometimes)
Gives a repeating character string of the length specified.
String(5,.)willgive......
StrReverse(almostnever)
Gives a string in which thecharacterorderofaspecifiedstringis
reversed.StrReverse(Dog)givesgoD.
Tan(rare)
Givesthetangentofanangle.Thisisnotableonlyinthatitisused
moreoftenthanAtn!
Time(sometimes)
GivesaDatespecifyingthecurrentsystemtime.
TimeSerial(rare).
Gives a Date containing the time for a specific hour, minute, and
second.
TimeValue(rare)
GivesaDatecontainingatimeasworkedoutfromaStringetc.For
exampleTimeValue(12:00:00A.M.)orTimeValue(18:30:00).
Trim(constant)
Givesacopyofastringwithoutleadingandtrailingspaces.
TypeName(rare)
Gives a string that provides type information about a Variable or
Value.ItcanbeusefulforfindingoutwhattypeaCellValueis.
UBound(almostnever)
Givesthelargestavailablesubscriptforthespecifieddimensionofan
array.
DrAlexanderJTurner2007 169
BabySteps
UCase(sometimes)
Givesastringthathasbeenconvertedtouppercase.SeeLCase.
VarType(almostnever)
GivesavaluespecifyingthesubtypeofaVariable.
Weekday(rare)
Givesawholenumberrepresentingthecurrentdayoftheweek.
WeekdayName(rare)
Givesastringspecifyingthespecifiedcurrentdayoftheweek.
Year(rare)
Givesawholenumberrepresentingcurrenttheyear.
Built In Constants
VBScriptbuiltinconstantscanbeuseinplaceofVariablesexceptyou
canonlyreadfromthemyoucannotassigntothem.Forexamplethe
followingisOK:
dim myString
myString=vbcrlf
Butthisisnot:
dim myString
myString = "abc"
vbcrlf="abc"
TherearequiteafewVBScriptbuiltinconstants. Tobecompletely
honest,mostarenotreallymuchuseinExcelMacroScripting;they
are designed for other things using VBScript (like making web
pages). However, the String constants are quite useful so I have
describedthemhere.
Built In String Constants
Constant Value Description
vbCr Chr(13) Carriage return.
Chr(13) & Carriage returnlinefeed
VbCrLf
Chr(10) combination.
Form feed, this is never really
vbFormFeed Chr(12) used nowadays (it relates to old
style printers).
vbLf Chr(10) Line feed.
vbNewLine Chr(13) & Same as VbCrLf.
170 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 171
BabySteps
172 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Inmysillyexampletheargumentsaretheeggtobeboiled,howhard
theeggshouldbeandiftheeggshouldbecooleddownafterwards.
Ofthese,theeggargumentmustalwaysbepassedtoBoiler.BoilEgg;
however,thehardnessandcoolAfterargumentscouldhavedefault
values.Inotherwords,ifwedonotspecifythem,theBoilerjustdoes
thedefault.Forexample:
Boiler.BoilEgg(myEgg)
Thismightactuallymean,boilmyEgg,softandcoolafterwards.We
only need to specify the other arguments if we do not want the
default.So,tohardboilandcoolafterwardswecouldput:
Boiler.BoilEgg(myEgg,xlHard)
TohardboilmyEggandnotleaveittocoolwecouldput:
Boiler.BoilEgg(myEgg,xlHard,FALSE)
Theinterestingbitcomesifwewanttosoftboiltheeggbutnotnot
coolitafterwards. InExcelScriptingMacroswewouldhavetoput
somethinglikethis:
Boiler.BoilEgg(myEgg,xlSoft,FALSE)
EventhoughxlSoftisthedefault,westillhavetospecifyit. Thisis
becauseweneedtospecifythethirdargument(coolAfter)andthe
DrAlexanderJTurner2007 173
BabySteps
onlywayofdoingsoistospecifyallthreearguments.Ifmighttryto
put:
Boiler.BoilEgg(myEgg,FALSE)
Butthiswillcauseanerror.VBScriptwillnotbeabletotellthatwe
meantFALSEforcoolAfter;itwilltryandmakethehardnessFALSE
whichmakesnosenseatall.
MostofthetimeVBScript(whichisusedforScriptingMacros)and
VBA(whichisusedbytheMacroRecorder)asprettymuchidentical.
However,thereisafeatureinVBAwhichcouldhelpwiththeegg
boilingsituation. VBAsupportsnamedarguments. So,inVBAone
couldactuallyput:
Boiler.BoilEgg(egg := myEgg, coolAfter := FALSE)
Why specifies only two of the three arguments but by using the
argumentnamesstillworksjustfine.However,itisfarfromfinefor
usbecausewewanttotranslateitintoVBScript.Thisisarealworld
problem because the Macro Recorder sometimes uses named
arguments which we have to translate into the simpler argument
systemofVBScript.
How To Translate From Named Arguments
BackinLesson8welookedatcreatingPivotTableswithascript.The
rawrecordedMacrolookedsomethinglikethis:
CreatePivotTable _
( _
TableDestination:="", _
TableName:= "PivotTable1", _
DefaultVersion:=xlPivotTableVersion10 _
)
IntheabovecodewecanthattheMacroRecorderasusednamed
arguments for the CreatePivotTable Method. In general we can
assumethatithascreatedthisinthecorrectorderforusingasnon
namedargument. However,wecannotassumethatithasspecified
allthearguments.Inthiscase,simplyremovingthenameswillnot
work:
' This will fail!
CreatePivotTable _
( _
"", _
"PivotTable1", _
xlPivotTableVersion10 _
174 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Figure81:HereIhavesearchedforthedefinitionofthe
CreatePivotTableMethod.Ihavehighlightedthedefinitioninthe
picture.Wecanseethatittakes4argumentsratherthanthe3
thattheMacroRecordersupplied.
DrAlexanderJTurner2007 175
BabySteps
Errata
ThecodewhichgeneratedtheexampleforPivotTables(Lesson8and
AppendixA)incorrectlyusedthewordsreparetimewhichshould
have been repair time. Whilst the text of the book has been
corrected,someofthescreenshotsshowtheincorrectspelling.
176 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Index
256.................................................72 CDate............................................78
65536.............................................72 Cell.................................................36
ActiveWindow.Zoom......................76 Cell reference................................98
ActiveWorkbook..........................107 Cell.Formula..................................76
Add.................................12p., 16, 50 Cell.Interior...................................37
AddDataField...............................109 Cells...............................................15
ADODB........................117, 119, 123 CELLSPACING..............................90
ADODB.Connection.....................117 Chains............................................48
AdTypeBinary......................117, 123 Characters.................59p.,60, 69, 80
AdTypeText..........................117, 122 Choice.........................................126
Alert boxes.....................................41 Class..................................11, 13, 16
AllUsersDesktop............................45 CLEAR.........................................124
AllUsersPrograms.........................45 Close........................................62, 64
AllUsersStartMenu........................45 Collections...............................16, 21
AllUsersStartup.............................45 ColorIndex.....................................39
ALT...........................................124p. Colour............................................37
AND.................................127p., 129 Column area................................100
Append....................................62, 69 COM.............................................123
Arabic numeral..............................74 Comma Separated Values.............80
Argument.....................................128 Comments...............................12, 19
Arguments...................................128 CompareMode...............................49
Array............................................140 Conditional....................................67
AtEndOfStream.............................64 Const.......................................63, 82
Audit..............................................61 Constants...................37, 40,68, 111
Auto Format.................................104 Copy....................................125, 143
Autofit................................47, 64, 76 CopyFile......................................118
Automate.......................................10 Count...............................16, 50, 113
Average.....................................102p. CreateObject...........................12, 17
Background...................................71 CreatePivotTable.................107, 112
Background colour........................36 CreateShortcut..............................46
Backgrounds................................103 CRM..............................................81
BACKSPACE................................124 CSV....................................81, 82pp.
Banding.......................................113 CSV Files.......................................80
Bands...........................................113 CTRL.........................................124p.
Binary..........................................119 Customer Relationship
Binary files..................................117 Management..................................81
Binoculars......................................40 D..............................................77, 79
Black..............................................90 Data area...........99, 101p., 105, 110
Blocks.................................130, 134 Data field............................109, 112
Blog........................................9, 119 Database....................................7, 10
Booleans........................................19 Date...............................................47
Border.........................37, 87p., 90p. Date standards..............................92
Border-bottom...............................90 DateAdd.............................77, 78pp.
Border-left.....................................90 Dates.......................................74, 84
Border-right...................................90 DateSerial......................77, 79p., 84
Border-top.....................................90 Day...........................................77, 79
BREAK.........................................124 Day Of Week..................................93
Browse...........................................41 Day Of Year....................................77
Bugs...............................................41 Days...............................................80
Capitals..........................................56 Death.............................................74
CAPSLOCK..................................124 Decision......................................126
Carriage-return..............64, 65p., 68 Definition.......................................38
Case sensitive................................40 DELETE.......................................124
DrAlexanderJTurner2007 177
BabySteps
178 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
Keys.........................................45, 50 Ol...................................................88
Language.......................................75 Open......................................16, 117
Layout..................................100, 103 Open Source..................................31
Layout character...........................60 Opening.........................................47
LCase....................................53, 67p. OpenTextFile............62p., 82p., 85p.
LEFT............................................124 Option Explicit.....................42, 43p.
Li.............................................88, 89 OR.......................................127, 131
Line Feed.......................................64 Ordered list...................................88
Line-feed..................................65, 68 Orientation..........................108, 112
Listing............................................66 Overview........................................94
LoadFromFile..............................117 Overwrite.......................................69
Logic....................................127, 134 Overwriting...................................66
Logical programming.........126, 127 P....................................................88
Loop...............................................23 Page...............................................89
Loop tape.......................................23 Page area..............................99, 115
Loops.............................................23 Paragraph......................................88
M.............................................77, 79 Parenthesis....................................16
Macro Recorder......32p., 37, 39, 96 Paste...................................125, 143
Management Information.............93 Pattern...........................................39
Merge............................................50 PatternColorIndex.........................39
Merging.............................48, 57, 68 Performance................................140
Method....................................12, 16 PGDN...........................................124
Microsoft.........................12, 47, 117 PGUP...........................................124
Microsoft Office.............................97 Pivot Cache.................................107
Milliseconds................................140 Pivot Chart.................................96p.
Minute...........................................77 Pivot Table. 93p., 96p., 100p., 103p.,
Misinterpreting.............................92 106, 108, 113
Module...........................................35 Pivot Table ....................................98
Month......................................77, 79 Pivot Table Field..........................102
Month Of Year...............................93 Pivot Table Field List................100p.
Mouse......................................24, 36 Pivot Table Field List box.............99
Mp3.............................................117 Pivot Table tool bar.....................104
MS Word......................31, 87, 89, 90 Pivot Tables..............................105p.
MS Word 2003...............................91 PivotCache.......................107p., 111
MS Word 2007 ..............................90 PivotCache Object.......................108
My Computer.................................45 PivotCaches.........................107, 111
My Documents...............................45 PivotField....................................108
MyDocuments..........................45pp. PivotField Object........................108
N....................................................77 PivotFields........................109p., 112
Named Arguments......................173 PivotFields Collection.................108
NetHood........................................45 PivotTable Field...........................110
Network Neighborhood................45 PivotTable Object.....................108p.
New Worksheet.............................98 Podcast............................................9
New-line..................................60, 66 Position................................108, 112
New-lines.......................................31 PrintHood......................................45
Nodepad++...................................36 Programmatic interface................40
NOT..................26, 82, 85, 127, 129 Programmer..................................10
Notepad............14, 31, 60, 123, 125 Programming language.................18
Notepad++.................31, 32, 44, 60 Properties......................................21
Now...............................................47 Property...................................13, 16
NumberFormat................47, 79, 111 PRTSC..........................................124
Numeric mean.............................102 Pseudo scripts...............................11
NUMLOCK..................................124 Pseudo-random.............................95
Object......................................11, 13 Pumpkin........................................93
Object Browser......37, 38, 39pp., 44 Punctuation...................................56
Objects...........................................16 Q....................................................77
DrAlexanderJTurner2007 179
BabySteps
Quarter..........................................77 Space.............................................60
Quit................................................47 Spaces...........................................56
Quotation marks............................81 SpeciaFolders.Item.......................46
Random.........................................95 Special Folder................................46
Range............................................36 Special Folders...........45, 47, 51, 67
Raw................................................75 SpecialFolders......45, 57, 67, 83, 85
Read..............................65, 118, 122 Split...............................................84
ReadAll.................................65p., 83 SQL Database................................97
Reading...................................59, 62 Standard Directories.....................45
Readline......................................64p. Start Menu.................................45p.
ReadText......................................122 StartMenu.....................................46
Real world.....................................53 Startup...........................................46
Recent............................................45 Stream.........................................118
Recorded.....................................106 Strings...........................................18
Recorder........................................36 Strip Spaces..................................64
Recording Macros.........................32 Style....52, 55, 89p., 120, 155, 170p.
Regional configuration..................75 Sub................................................71
Remove..........................................50 Subroutines.............................71, 92
RemoveAll......................................50 Sum...........................................112p.
Replace...........................83p., 86, 92 Summarises...................................93
Report.........................................89p. Summary.......................................93
Reports..........................................87 System.FileSystemObject.............60
Researching.....................................8 TAB..............................................124
Restrictions...................................10 TABLE...............................87, 88, 90
Returns..........................................73 Tables.............................................59
Ribbon................................147, 149 Tags...............................................89
RIGHT.................................67p., 124 TBODY...........................................90
Rnd................................................95 Td..................................................87
Row area...............................99, 100 Template Files...............................46
Rule.........................................8, 130 Templates......................................46
Rules...............................8, 128, 130 Text..........................................14, 90
S....................................................77 Text Editor.....................................31
SaveToFile...................................118 Text File.......................60, 62, 69, 80
Saving............................................47 TextStream...............60, 65p., 69, 82
Scientific notation.........................85 TextStream Object.....60, 62, 65, 69,
Script translation..........................44 82
Scripting Macros...........................44 Then........................................68, 84
Scripting.FileSystemObject. .86, 118 Time...............................................47
SCROLLLOCK.............................124 Timer...........................................140
Search........................................40p. Translate........................................96
Search engine................................39 Translated.....................................36
Second...........................................77 Translating....................................37
Security.........................................10 Translation....................................36
Select.............................................36 Trim...............................................64
Selection........................................36 Typos.............................................71
Send-to..........................................46 UCase............................................73
SendKeys.............................123, 125 Ul...................................................88
SendTo...........................................46 Unordered list...............................88
Sheet..............................................15 UP................................................124
Sheet.Select................................143 Upload...........................................59
SHIFT.......................................124p. Upper case....................................72
Shortcut.........................................46 Upper-case.................................73p.
ShowPivotTableFieldList.............112 Value..............................................50
Sleep............................................123 Variable...................................13, 43
Small business.................................8 Variables.................................17, 18
Solid...............................................90 Variant.........................................119
180 DrAlexanderJTurner2007
HowToBecomeAnExcelGod(withoutreallytrying)
DrAlexanderJTurner2007 181