baby steps

181
How To Become An Excel God (without really trying)  © Dr Alexander J Turner – 2007 1

Upload: aissaoui25

Post on 18-Dec-2015

7 views

Category:

Documents


1 download

DESCRIPTION

vb programming

TRANSCRIPT

  • HowToBecomeAnExcelGod(withoutreallytrying)

    DrAlexanderJTurner2007 1

  • BabySteps

    Dedicatedto:ProfessorI.H.Williams.

    Forhistirelesssupportandguidanceofmyselfandmanyothersinoursearchforagreaterunderstandingof

    nature'screation.

    2 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Table o f C o nt ent s

    Forward:RunTheWorldFromExcel!........................................7A Dream No Reality......................................................................7Who can benefit from Excel Scripting Macros?..............................8Where Does This Idea Come From?................................................8Why 'Baby Steps'.............................................................................9

    Introduction:Whatisthisallaboutthen?...............................10Do I Need To Be A Programmer?...................................................10Using This Book............................................................................10

    Lesson1:BasicConcepts.........................................................11'Take Home' Ideas from Lesson 1..................................................14

    Lesson2:BuildingBlockConcepts..........................................15Collections:....................................................................................15Variables:.......................................................................................17More On Variables.........................................................................18With Statements............................................................................20'Take Home' Ideas from Lesson 2..................................................21

    Lesson3:Loops.......................................................................23Finally we start to make things easier:.........................................23Drag And Drop Scripting, An Introduction....................................24For Loops.......................................................................................27For Each Loops..............................................................................28'Take Home' Ideas from Lesson 3..................................................29

    Lesson4:GettingTooledUp....................................................31A Quick Note.................................................................................31Get A Good Text Editor..................................................................31Recording Macros.........................................................................32Translating Recorded Macros.......................................................36

    Keyboard and Mouse to Script Translation..........................................................36Translating Excel Constants.................................................................................37

    Using The Object Browser.............................................................39Finding And Removing Bugs.........................................................41'Take Home' Ideas from Lesson 4..................................................44

    Lesson5:StartingToWorkWithData.....................................45Special Folders..............................................................................45

    Using 'SendTo' As A Really Easy Way To Run Scripts..........................................46Saving And Opening From Special Folders..........................................................47

    Merging Between Workbooks........................................................48Merging Data By Example....................................................................................48Dictionary Objects.................................................................................................49Simple Merge Script.............................................................................................51Working Merge Script...........................................................................................53Merging Multiple Columns...................................................................................56

    'Take Home' Ideas from Lesson 5..................................................57Lesson6:Reading&WritingFiles...........................................59

    What Is A File?..............................................................................59Writing To A Text File....................................................................60

    DrAlexanderJTurner2007 3

  • BabySteps

    Reading From A Text File..............................................................62Reading And Writing In Chunks....................................................64Listing Files...................................................................................66'Take Home' Ideas from Lesson 6..................................................69

    Lesson7:EnhancedDataProcessing......................................71Subroutines And Functions...........................................................71Death By Dates..............................................................................74

    DateAdd And DateSerial Fixing The Problem....................................................77Importing Data From CSV Files....................................................80Creating Reports...........................................................................87'Take Home' Ideas from Lesson 7..................................................92

    Lesson8:WorkingWithPivotTables.......................................93Why Pivot Tables Are So Very Important.......................................93Understanding Pivot Tables...........................................................93

    Creating An Example Pivot Table.........................................................................94Creating A Pivot Table And Scripting Macro.................................96Creating Pivot Tables Using Scripts............................................106

    Looking At The Recorded Macro........................................................................106Finished Product.................................................................................................111

    Tricks To Improve Data To Help Pivoting....................................113Banding Data.......................................................................................................113Cleaning Data......................................................................................................115The Page Area.....................................................................................................115

    Lesson9:Working'OutsideTheBox'.....................................117Accessing Binary Files.................................................................117

    Reading Data From Binary Files An Example..................................................119ADODB.Stream Summary...................................................................................121Properties............................................................................................................121Methods...............................................................................................................122

    Sending Key Strokes To Other Applications Through .................123Stopping Excel From Complaining.....................................................................125

    Choice And Decision Processing................................................126Yes Excel Really Is This Powerful!....................................................................126What Is Choice/Decision Processing?.................................................................126First Off Just The Very Minimum Of Logic.......................................................127TRUE & FALSE....................................................................................................127Chaining Decisions To Make Rules.....................................................................128Blocks And Zeds..................................................................................................130Putting It All Together.........................................................................................131Moving From One To Many.................................................................................136

    Lesson10:SpeedingScriptsUp............................................139Cell By Cell Access Is Slow..........................................................139Bulk Data Loading With Arrays...................................................140

    What Is An Array?...............................................................................................140Using Arrays Like Spread Sheets.......................................................................141

    Bulk Data Transfer With Copy/Paste...........................................143Don't Forget Formulae And Fills.................................................143

    AppendixA:DifferencesWithExcel2007.............................145Recording Macros:......................................................................145Showing The Developer Tab (Accessing VBA).............................146Creating A Pivot Table.................................................................149

    4 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    AppendixB:HowThisBookWasWritten..............................157AppendixC:WhyScriptWhenExcelHasMacros?................159

    One Final Thing...................................................................................................160

    AppendixD:VBScriptBuiltInFunctions&Constants...........161Built In Functions........................................................................161

    The Functions Enumerated And Explained........................................................161Built In Constants................................................................................................170Built In String Constants.....................................................................................170

    AppendixE:NamedArgumentsAndThe:=Symbol.............173Why This Is Here.........................................................................173The Where, Why And When Of :=...............................................173How To Translate From Named Arguments................................174

    Errata....................................................................................176Index.....................................................................................177

    DrAlexanderJTurner2007 5

  • BabySteps

    6 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Forward: Run The World From Excel!MostcalculationsandnearlyallbusinessprocessesstartoutlifeinExcel. They grown in complexity and slowly require multiplespreadsheetstofunction. Humanerrorleaksintothemixandthewholehouseofcardscomescrashingdown.

    Thestandardsolutiontothischallengeistocommissionsomehugesoftwaresystemtosolveallourproblemsinonehit. Thissupersystemwillbedeliveredlateandwillbeoverbudget.Whatisworse,therequirementswillhavemovedonsincethesystemwasdesigned.Thewonderful(wonderfullyexpensive)systemwillsolveyesterday'sproblemsandnotaddresstoday's.

    ThefinalactinourITtragedyiswheretheinadequaciesofthesupersystemareovercomebypreandpostprocessingall thedatawithExcel!

    Alltheabovepaincansoeasilybeavoided.ItiscausedbyExcelonlygoingsofar. Excelwillprocessdata,butnotautomaticallychainprocessingstepstogether. Thislackofchainingmeansthathumansendupintheprocesses.Evenhighlytrainedhumansmakemistakesat the rate of 1 in 200 to 300 hundred repeated actions. Dataprocessingwhichinvolvesignificanthumaninteractionwillbecomeunstuckirrespectiveofhowhardthepeopletry.

    A Dream No RealityHowaboutaworld where data processing andbusiness decisionstakeplace inExcelwithouthumanerror? All repetitive tasksareautomatedandefficient.Inthisworld,wewouldhavetheflexibilityand responsiveness of Excel but the reliability and speed of adedicatedsystem.

    Howaboutaddingtothiswishlist?Itwouldalsobegreatifeventhemostcomplexprocesseswererenderedsosimpletosetupthatnonprogrammerscoulddoit!

    This is not a fantasy world, it exists. The techniques of ExcelScriptingMacrosdoexactlywhatisrequired.Ibelievethatanentirebusiness, of thousands of people, could be run with just ExcelScriptingMacros, Excelandafree database. 90%ofallbusinessprocessescanbeperformedevenwithoutthedatabase,allweneedisExcelandScriptingMacros.

    DrAlexanderJTurner2007 7

  • BabySteps

    Who can benefit from Excel Scripting Macros? Ifyouareina smallbusinessandwanttoautomated work

    flowthisisforyou.

    If you are in a huge business and want to processperformancefiguresthisisforyou.

    Ifyouareresearchinganimalbehaviourandneedtoanalyseresultsthisisforyou.

    Ifyouwanttoapplyarulesettochoosewho,outof10000employees,getsaChristmasbonusthisisforyou.

    Ifyouwanttodojustaboutanythingthatinvolvednumbers,dataorrulesthisisforyou!

    Where Does This Idea Come From?Theschoolofhardkicks, thatthis where iscomesfrom. Back in20012002 I began to realise two things. Firstly, the huge andcomplex Java based systems on which I was working just neverprovidedwhatrealpeoplewanted.Secondly,nearlyallbusinesswasalreadybeingperformedinExcel.

    ItwasatthistimethatIsetupacompany'JDIT'totakeadvantageoftheserealisations. WetookExceland,usingExcelmacros,pushedwaybeyondwhatmostpeoplehaddreamtof.However,despitethesuccess of the concept, it was not fully what was needed. ThesystemsJDITproducedweretoolargeandtwocomplex. Insomeways,theyturnedExcel intothehugeandcomplexsystemsIwastryingtogetawayfrom.

    The key breakthrough came when considering how to directlyinterconnectExcelwithalargewebbasedsystemforwhichIwasarchitect. IrealisedthatasimplescriptcouldrunExcelandplacedataintoit.ThetechnologyIhadusedinJDITinsideExcelcouldbeputoutsideExcel inascript. However, theresult wasmuchmorepowerfulthanIhadexpectedbecauseitallowedcomplexthingstobedoneinsimpleways.Contrastthis,ifyouwould,withnormalITwheresimplethingsaredoneinextremelycomplexways!

    Excel ScriptingMacros evolveda fair way fromthis initial wowmoment. The next challenge was to beat every last ounce ofcomplexityoutoftheapproach.Thatwasnotasstraightforwardasone might imagine. But, each time I found an approach whichreducedcomplexity, theprojectonwhich I wasworkingbenefitedenormously.Inshort,IknewIwasontherighttrack.

    8 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Why 'Baby Steps'UptothispointIhadthoughtofExcelScriptingMacrosasagoodwaytosolveproblemsontheprojectswithwhichIwasinvolved.Astime went on, feedback from my coworkers and my blog(www.nerdscentral.com) started to indicate they had crossed awatershed. Nolongerwasthisseenasaprogrammerconceptbutmore as a business tool. The opportunity to devolve data anddecisionprocessingfromprogrammerstothepeoplewhoneededitwastantalisingtosaytheleast.

    I knew that to achieve this breakthrough democratisation oftechnology,thelearningcurvewouldhavetobeveryshallow.Hence,Icameupwiththenotionof'BabySteps';AseriesoftinystepswhichtakeapersonfrombeingfamiliarwithExcelthroughtobeingabletoperformseeminglysuperhumanfeatswithit.

    Havingconsideredmanyformatsfrom blog to podcast, Ifiguredafriendlybookformatwasideal.Abookthatisnotfullofpaddingtogetthepagecountup.Abookthatissmallenoughtofitinalaptopcaseandreadonthetrain.Inshort,abookwhich,likeitscontents,demandsonlytheminimumofeffortinvestedforthemaximumofbenefitgiven.

    DrAlexanderJTurner2007 9

  • BabySteps

    Introduction: What is this all about then?'Babysteps'isallaboutlearninghowtowrite'ScriptingMacros'forExcel.IamsurethatyouhaveheardofExcelMacros.ThesearelittleprogramsembeddedintoanExcelWorkbookwhich automate tasks.Scriptingmacrosareverysimilar.Thebiggestdifferenceisthattheydonot'live'insideaWorkbook.TheyaresmallfilesthatexistoutsideWorkbooksbutcanactupononeormoreWorkbooksatonce.

    Because Scripting Macros are outside of the Workbooksonwhichtheyact,theyareverymuchmoreflexiblethantraditionalMacros.They also get around many of the nasty security problems andconsequentrestrictionsthatarepartandparcelofExcelMacrosthesedays.

    Theconceptbehind'BabySteps'isthat,whilstyoucanbesomethingmassivelycomplexwithScriptingMacros, it is alsopossible to doamazingstuffwithmassivelysimpleScriptingMacros.Experienceinthefieldhasshownthattheapproachhashugebenefitstobusinessprocesses which are dependant on people sending data to oneanother via Excel spreadsheets. Automation via Scripting Macrosremoves'typo'mistakeswhichpeopletendtomakewhenfacedwithrepetitivetasks.Additionally,oneortwosimpleScriptingMacroscanprocessdatathatwouldtraditionallybeloadedintoa databaseandfromwhichprogrammerswouldwritereports.

    Do I Need To Be A Programmer?100%no.Theideabehind'Babysteps'isthatalittleknowledgewilltakeyouaverylongway.Eachconceptistiedbackto 'realworld'examplesandeveryeffortpossiblehasbeentakentoremovejargon!

    IfyoucanuseExcel,youcanunderstand'BabySteps'.

    Youdonotneedtobeaprogrammer.

    Thisbookwillnottrytoteachyoutobeaprogrammer.

    Using This BookIfyouhaveneverdoneanycomputerscriptingatall,donotworry.Everythingyouneedtoknowiscontainedinlessons1,2and3. Ifyouareslightlyfamiliarwiththeconceptsofscripts,loopsVariablesandallthatstuff,thendiveinatlesson4.

    Evenifyouareanexpertprogrammer,youmaygainalotfromthelaterchapters.Iwouldrecommendalittlespeedreadingatlesson4topickupafewtipsandthendiveinmoreatlesson5.

    10 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 1: Basic ConceptsLetusstartoffconsideringdrinkingaglassofwine...

    Toinstructacomputerthatapersonshoulddrinkaglassofwine,itseemslogicaltotellthecomputerthatthereisa'thing'calledpersonanda'thing'called glass-of-wine.Oncewehaveestablishedthissetup,wecansaysomethinglike:

    persondrinkglassofwine

    (Thehyphensareincludedjustforclarity,togroupwordstogether)

    NowwehavestartedwritingaScriptingMacro. Tomakethisabitmorerealisticweneedtosplitouttheconceptof'aglassofwine'from'myglassofwine'. Afterall,youwanttoknowwhichglassyouraredrinking(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)

    YoucanprobablytellthatIamgoingsomewherewiththelayoutofthese'pseudoscripts';Iamtransformingeverydayspeakintothewaywetellthecomputertodostuff.Alotofthetime,itisfairlystraightforwardtodoso.Sometimes,however,historyandconventiongetintheway.But,fornow,letuscontinuealongthispath.

    Key Concept:Incomputerspeak,wecall'myglassofwine'anObjectandwecall'aglassofwine'aclassofobjects,orsimplyaClass.

    Onereallynicethingaboutcomputingisthatmakingglassesofwineisverysimpleandjustaboutfree.Ifwewantanewglassofwine,wejust saysomething like 'Createmyglassofwinewhich is fromtheClassof'aglassofwine'.

    Makingglassesofwineinascriptmightlooksomethinglikethis:

    set my-glass-of-wine = CreateObject(a-glass-of-wine)

    Butactually,hyphensbetweenwordsarenotallowedsoweput:

    set myGlassOfWinne = CreateObject(aGassOfWine)

    DrAlexanderJTurner2007 11

  • BabySteps

    Thatdoesnotlookverymuchlikeeverydayspeakanylonger,butthereisaclearlineagetobeseen! Onequestionthatcomesupiswhatdoesthe'='signmean?Therearetwothings'='canmeaninScriptingMacros:

    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 = yor: set myExcel=CreateObject(Excel.Application)

    Nowwecanputallthistogethertomakeanearlycompleteprogram:

    ' Create the Objects which we require set myself = CreateObject(People.Person) set myGlass = CreateObject(Wine.Glass)

    ' Do stuff with the Objects, in this case ' Object myself, drink the Object myGlass: ' drink is a pre-defined Method which any ' Object from the Class People.Person can do.

    mySelf.drink(myGlass)

    To explain what is described in the comments to the codeabove:.drinkiswhatwecallaMethod.ItisamethodoftheObjectmySelf.Wedonothavetodefinewhat.drinkisbecauseitsdefinitioncomes alongwithClass People.Person. Because mySelf is a Objectfrom People.Person (it is a personObject) it will have theMethoddrink.

    Methods(doingthings)canhaveparenthesisafterthem. Insidetheparenthesistherecanbealistofthingsthemethodistoworkwith.In the above example, the list has one element myGlass. Somemethods,likethe.AddmethodofExcel's Workbookscollection,havenoelementsinthelistandsoarefollowedbyemptyparenthesisasin.Workbooks.Add().

    IhavecalledtheClassesPeople.PersonandWine.Glass,withthesedoublenames,becausethatisthe Microsoft convention. AnExcelapplication is called Excel.Application. To create one you putCreateObject(Excel.Application).

    Nowwehavefiguredouthowtoget'CyberSloshed',letusseeiswecanapplythesamethingtoExcel!

    set myExcel = CreateObject(Excel.Application)

    12 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    This simple piece of code actually causes Windows to create acompletelynewExcelapplication.The'Variable'myExcel'refers'toit.So,laterintheprogram,whenwewanttodosomethingwithExcel,wecanuse theVariable 'myExcel' topass instructions to ournewExcelapplication.

    Forourveryfirst'babystep'towardsbeinganExcelgod,wearegoingtodojustthat.WearegoingtocreateaninstanceofExcelanddosomethingwithit.Thatsomethingwillbesimplytomakeitvisible(theyarecreatedhidden)andthencreateanew,emptyWorkbookinsideit.

    PleasefollowtheseinstructionstothelettertocreateyourveryfirstExcelMacroScript:

    1) Open Notepad2) Type in:

    set myExcel = CreateObject(Excel.Application) myExcel.visible = TRUE myExcel.Workbooks.Add()

    3) Save your magical words as step1.vbs on your desktop.4) Double click on the Icon that has appeared on your desktop to represent you new file.5) Stand back in amazement!Thispieceofcodecanbedescribedinwordslikethis:

    SettheVariable myExcel tobeannewlycreated Objectwhich is fromthe Class Excel.Application. Make thevisible Property of that Object be true. Get theWorkbooks Property ofthatObjectandrunitsMethodAdd,whichwillcauseanewWorkbooktobecreated.

    DrAlexanderJTurner2007 13

  • BabySteps

    'Take Home' Ideas from Lesson 1WehaveseenthatMacroScriptscancontrolExcelandthattheyhaveadirectlineagefromnormalEnglish.

    Whenwritingscripts,werepresentreal,tangiblethings(like glassesofwineorworkbooks)asObjects.Theobject 'myGlassOfWine'comesfromtheClassofObjects'aGlassOfWine'.

    MacroScriptsaresimpletextfiles.Theyareeditedusingatexteditor(likenotepad)andsavedwiththe'.vbs'fileextension.

    WhenwritingaScriptingMacro,beforewedoanythingwithExcel,weneedtocreateanExcel.ApplicationObject.

    14 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 2: Building Block ConceptsCollections:

    Fig1:AdigramshowinghowinExcelObjectsoftenhaveCollectionsofObjectsinsidethem.ACollectionholdsalistof zeroormoreObjectsinsideitandallowsyoutofindthose Objectsbyindex(e.g.0,1,2etc.,orsometimes:1,2,3etc.)or

    name(e.g.sheet1,sheet2etc.).ThisdiagramshowsyouhowtostartoffwithExcel.Applicationand'drill'allthewaydownto

    individualCellsinaSheet.

    DrAlexanderJTurner2007 15

  • BabySteps

    Inlessononewelookedathowthings,likeglassesofwineandExcelApplications,arecalledObjects.'myGlassOfWine'isanObjectwhilst'aGlassOfWine'definesaClassofObjectsandsowecallitaClass.

    WhenworkingwithExcel,weuseObjectsalot;also,wetendtousealotofthesameClassofObjectatonce.WhenyoucreateaWorkbookObject(likewedidwithwithoursimplescript)youseethreeSheets,notone.Indeed,anExcel.ApplicationcanhavemanyWorkbooksandeachWorkbookcanhavemanySheetsandeachSheetwillhavemanyCells.

    Tohandle all these groups of Objects, Microsoft usewhat it calls'Collections'. Thesearenumbered, andsometimesnamed, lists ofObjects. A Collection is also an Object its self. For example, aCollectionofWorkbooksisanObjectfromtheClassofCollections.

    All Collections have the Property .count (note, because it is aProperty,notaMethod,thereisnoparenthesis).ThistellsyouhowmanythingsareinsidetheCollection.SomespecialCollectionshaveother properties and/orMethods. For example, Excel's WorkbooksCollection has .Add() to create a new Workbook and .Open(filename)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()

    ' Find the first Workbook in the Collection ' of Workbooks. i.e. this says: set the ' word 'myWorkbook' to refer to the Workbook ' Object at position 1 in the Collection. Set myWorkbook = myExcel.Workbooks(1)

    ' Do the same this time but to get a Sheet Set mySheet = myWorkbook.Sheets(1)

    ' Finally, find one particular Cell Set myCell = mySheet.Cells(1,1)

    ' Now we have the top left Cell of ' the first Sheet. i.e. the Object which represents

    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:

    CollectionsareawayofstoringzeroormoreObjectssothattheycanbeeasilyfoundandused.

    Variables:Whenweput:

    Set myExcel= CreateObject(Excel.Application)

    Wearesaying:

    SetaVariablecalledmyExceltorefertoanewlycreatedExcel.ApplicationObject.

    WhenworkingwithObjectsinExcel,weoftensetVariablestorefertoObjectstomakeiteasytousetheseObjects.Hereisanexampleastowhy:

    ' 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,istosetaVariabletorefertotheExcel.ApplicationObject. Thisapproachhasother benefits aswell.Oncewegetthehangofitwecan:

    1. Saveourselvesalotoftyping.

    2. Savethecomputeralotof'thinking'.

    3. Make developing (adding to, editing, improving) scriptsmucheasier.

    Theseadvantagescomefromtheabilitytostore'working'informationinVariablesjustlikewemightstorenotesonpostits. Ifyouhadtowork out what the square root of 23456was each morning, youmightwellwritedowntheanswertosavetheeffort! Variablesareusedforthispurposeinscripting.

    DrAlexanderJTurner2007 17

  • BabySteps

    KeyConcept:Variablesarelike'postitnotes'forscripts;theyallowustostorethingssowedonothavetokeeprecreatingthem.

    Letusseethis'postitnote'conceptinusebyaddingtoourpreviousscript:

    ' 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 Collection of Workbooks myExcel.Workbooks.Add()

    ' Find the first Workbook in the ' Collection of Workbooks set myWorkbook = myExcel.Workbooks(1)

    ' Do the same but this time to get a Sheet set mySheet = myWorkbook.Sheets(1)

    ' Finally, find one particular Cell set myCell = mySheet.ells(1,1)

    ' Now we have an Object for the top left Cell of ' the first Sheet. We can use this Object to ' set the value of the contents of the Cell. myCell.value = Hello World

    ' Now we can re-use the mySheet Variable to get ' the Object for the next Cell in the Column set myCell = mySheet.Cells(2,1) myCell.value = Hello Again

    HerewehavereusedthevalueofmySheetratherthanhavingtorefindtheSheetObject. ThisuseofaVariablehassavedusrewringandrerunningallthecodewhichfindstheSheet.

    More On VariablesVariablesdonotonlyrefertoObjects;theycanholdotherstufflikeNumbers,DatesandStrings(piecesoftextarecalled'Strings'asin'astringofcharacters').

    When working with Excel Scripting Macros we are using aprogramming language called VBScript. VBScript, just like anyprogramminglanguagethathasbeenaroundforawhile,hashistory;ithasaccumulatedafewoddities.Whilstthesecanbeexplained,itis

    18 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    oftenbettertojustacceptthem. OneoftheseisthewayweworkwithVariablesandthingswhicharenotObjects.

    Strings,Numbers,DatesandBooleans(logicalvalues,true/false)arenotObjectsin VBScript. Thisisnotforanyparticularreasonotherthanhistory. VariablesarealmostexactlythesamewhenworkingwithObjectsandnonObjects,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

    One way of thinking about this is to say that Numbers, Strings,BooleansandDatesaretoosimpletobethoughtofasObjectsandsoaretreateddifferently.Alsonotethatifnumberisinquotesitisusedastext.1.0isnotanumber,itisaString.

    Youmighthavealsorealisedbynowthatanytextafter'onalineisconsidered to be a comment. Comments are not read by thecomputer andhavenoeffect onthescript, theyaretheretohelppeoplereadingthescripttoknowwhatisgoingon.Thecommentgoesfromthefirst'totheendoftheline.

    NowwehaveareallypowerfultoolbecausewecanletaVariablereadthevaluefromaCellandwecanwriteaVariable'svalueintoaCell.ThisisthebasisofmostExcelMacroScriptingdataprocessing.

    ' Script to show how values can be read and ' written in and out of Cells and Variables ' ========================================= Set myExcel = CreateObject(Excel.Application) myExcel.Workbooks.Add() Set myWorkbook = myExcel.Workbooks(1) Set mySheet = myWorkbook.Sheets(1) ' Start the process by writing a value into ' the top left Cell Set myCell = mySheet.Cells(1,1) myCell.value = 1

    ' We can then take that value and work with it myValue = myCell.value ' (explain how this is done) myValue = myValue + 1 ' Get the next Cell along (B1) Set myCell = mySheet.Cells(1,2)

    DrAlexanderJTurner2007 19

  • BabySteps

    ' This will make the value of B1 be 2 myCell.Value = myValue

    With StatementsWithstatementsareanotherwayofworkingwithObjectwhichcanbehandyasanadditiontousingVariables.ThisisespeciallysoifwewanttodoseveralthingswiththesameObjectintightsequence.Itiseasiesttoshowthisbyanexample;herewewillsetthevaluesofseveralCellsinsequence.

    Set myExcel = CreateObject(Excel.Application) myExcel.Workbooks.Add() Set myWorkbook = myExcel.Workbooks(1)

    ' Here is the with, note the extra indentation ' which is here to make the code easier for ' humans to read: With myWorkbook.Sheets(1) .Cells(1,1).value="Row=1,Col=1" .Cells(2,1).value="Row=2,Col=1" .Cells(1,2).value="Row=1,Col=2" End With

    KeyConcept:NotehowanythinginsidetheWith(betweentheWithandEndWith)whichbegins.istreatedasaMethodorpropertyoftheObjecttowhich theWithstatementrefers.

    20 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    'Take Home' Ideas from Lesson 2ObjectsarestoredinCollectionstomakethemeasiertofind.

    InExcel,manyObjectshaveaCollectionofObjectsasoneoftheir Properties.Thisallowsusto'drilldown'fromatoplevelObject likeExcel.ApplicationallthewaydowntoCells.

    VariablesarenamedcontainersforObjectsornonObjectdatalikeStrings,Booleans,DatesandNumbers.

    VariablesareahandywayofbeingabletofindanObjectoncebutuseitseveraltimes.

    AnotherhandywayofusingthesameObjectseveraltimesistouseaWithstatement.

    DrAlexanderJTurner2007 21

  • BabySteps

    22 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 3: LoopsFinally we start to make things easier:Iamnotyou,butifItrytoimaginebeingyou,rightnowIwouldbethinking:

    Thisisallverywell,butIhavejusttakenanagetodosomethingIcouldhavedoin30secondswithExcelusingjustformulaeorfills.

    Thatsentimentisperfectlycorrect!So,itistimetostartdoingsomestuffwhichiseasierandfastertodowithscriptsthanitisbyhand,andthatusuallyinvolvesloops.

    Fig2:Thelooptapemodelofcomputerloops.Herewearemakingaloopwhichsays'Add2And2'overandoveragain,for

    ever!

    People do not normally like doing the same thing over and overagain;computersloveit. Loopsareawayoftellingacomputerto'loopover'thesamesetofactionsrepeatedly.Youcanthinkofloops

    DrAlexanderJTurner2007 23

  • BabySteps

    as 'looptapes'. Figure2showsgraphically howthismentalmodelworks.

    Theobviousflawinthisapproachisthattheloopwillrunforever.Thisiscalledan'InfiniteLoop'. Sometimesinprogrammingthisisexactlywhatyouwant.Mostofthetime,however,wewanttolooponlyuntilsomecriterionhasbeenmet.

    ForExample:

    1. WorkdownColumnAoneCellatatime.

    2. AddthecontentsoftheCellyouareontotoitsrownumber.

    3. PuttheresultintothesamerowinColumnB.

    4. StopwhenyougettoanemptyCellinColumnA.

    ThatexampleisexactlythesortofthingonedoesallthetimewhenScripting Macros. The way that it automatically stops when aconditionismet(whenanemptyCellisreached)hintsatthepowerofthistechniquewhencomparedtojustusingformulaeinExcel.

    Drag And Drop Scripting, An IntroductionTomakemeaningfullexamplesofhowloopscanautomaterepetitivetasks, we need to be able to load preexisting Excel Workbooks.Again,fromexperienceinthefield,thebestwaytoachievethisisvia'draganddropscripting'.

    ThisapproachworksbyclickingonaWorkbookfileanddragging itover the icon for our script. Whenwe 'drop' (release the mousebutton)WindowsrunsthescriptandtellsthescriptthefilenameoftheWorkbookyoudroppedonit. Windows'tells'youthefilenamebyaspecialCollectionthatyoucanalwaysusefrominsidethescript.This is the WScript.Arguments Collection. All scripts of type'.vbs' (VBScript) have a special Object precreated that is calledWScript. YoucandolotsofhandythingswithWScript;readingthenamesoffileswhichhavebeendroppedontoascriptisjustoneofthem.

    24 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Figure4:HereistheWorkbookfileBabyStepsExamples.xlsbeing'draganddropped'ontoaMacroScriptfile.Whenthescriptruns,

    thefilenameoftheWorkbookwillbebeplacedintheWScript.ArgumentsCollectionofthescriptatindex0.

    Now that we have figured out how to tell a script which ExcelWorkbooktoopen,weneedtoactuallyopenit.ThispieceofcodewillopenanExcelWorkbookwhichisdroppedontoit:

    ' Create an Excel application Object and make it ' become visible Set myExcel = CreateObject("Excel.Application") myExcel.visible=true

    ' WScript.Arguments is a special Collection into ' which Windows places a list of the file names of any ' files that were dropped on to the script. ' It is a bit unusual because it starts from index 0, ' rather index 1 like most Collections do. ' You just have to remember it as a special case! myFileName = Wscript.Arguments(0)

    ' The Workbooks Collection has a special method ' which loads and Workbook file into a new Workbook. Set myWorkbook=myExcel.Workbooks.Open(myFileName)

    Nowthat wehaveautomated the loadingof a Workbookwecanautomateitsprocessingusingascript. Aswehaveseen,eachCellObjecthasaProperty Value. There is aspecial Methodbuilt intoVBScriptwhichcantellifavalueisempty. ThisMethodiscalled

    DrAlexanderJTurner2007 25

  • BabySteps

    IsEmpty(). It producesaBooleanvalueof true or false. It isthishandymethodthatweusedtocontrolwhenourloopwillexit.Hereisanexamplescript,whichIwilldiscussinmoredetailafterwards:

    Set myExcel = CreateObject("Excel.Application") myFileName = WScript.Arguments(0) Set myWorkbook=myExcel.Workbooks.Open(myFileName)

    ' Note that the Sheets Collection starts at ' the more normal index of 1. Set mySheet=myWorkbook.Sheets(1)

    ' row is a Variable in which we store the number ' of the current row that the loop is working on. ' We are going to start with row = 2 because ' Row 1 holds the headers. Please also note ' I have called this Variable row just to make ' the script easy to read for humans. It could ' be called anything. For example, I could have ' called the Variable bob as in: bob = 2 row = 2

    ' This loop will carry on until the current ' Row has an empty Cell in Column 1. ' For a full descripting of this ' loop, see the main text of "Baby Steps" While Not IsEmpty(mySheet.Cells(row,1).Value) mySheet.Cells(row,2).value = _ mySheet.Cells(row,1).value * 2.0 row = row + 1 Wend

    Note:ifyouendaline_itmeansthatthelineiscontinuedonthenextline.i.e.: a = _ bIsthesameas: a = b

    TotestthisscriptweshouldcreateanExcelWorkbookinwhichthefirstSheethasvaluessomethinglikethis:

    Price Price $1.52.30.5

    26 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    OncethescripthasrunthefirstSheetwilllooklikethis:

    Price Price $1.5 3.02.3 4.60.5 1.0

    To achieve this the script has performed the following steps(rememberthatCellsarereferencedy,xi.e.row,column):

    1. StartedwiththeVariablerowwithvalue2.

    2. CheckedthatValueofCell(2,1)andfoundittobenotempty.

    3. TakentheValueofCell(2,1)andmultiplieditby2.

    4. PlacedtheresultofthecalculationinCell(2,2).

    5. Added1tothevalueofrowandputtheresultbackintorow.

    6. CheckedthatValueofCell(3,1)andfoundittobenotempty.

    7. TakentheValueofCell(3,1)andmultiplieditby2.

    8. PlacedtheresultofthecalculationinCell(3,2).

    9. CheckedthatValueofCell(4,1)andfoundittobeempty.

    10. Notprocessedtheloopanyfurther(sometimescalled'exitingtheloop').

    For LoopsSofarwehavelookedat While loops. Thesearethemostobviousformof loop; they say keepdoing somethingwhile something istrue.Theyarenottheonlyformofloop.AnothersortthatisquiteusefulistheForloop.Theysaydosomethingforacertaincount.

    Thefollowingtwoloopsarecompletelyidentical.

    ' While loop: bob = 2 While bob < 10 mySheet.Cells(bob,1)= Row number = & bob bob = bob + 1 Wend

    ' For loop: For bob = 2 To 9 mySheet.Cells(bob,1)= Row number = & bob Next

    DrAlexanderJTurner2007 27

  • BabySteps

    Note:ifbob = 3thenRow number = & bobproduces Row number = 3i.e.thesymbol&joinsaStringtoaString,Number,BooleanorDate.

    Because,inExcelscripting,wearemoreoftenthannotloopingoverdata until some data related condition is met, For loops are lesscommonthanWhileloops.However,asyoucanseefromtheaboveexample,whenyoucanusethemtheytakeuplessspaceanditismoreobviouswhatishappening.

    For Each LoopsWehavejustseenhowForloopsareaneasywayofperformingasetofactionsforasetnumberofrepetitions.HowaboutifwewanttoperformanactiononeachofthecontentsofaCollection?InotherwordsForEachelementintheCollection.Happily,VBScriptprovidesuswithareallysimplewayofdoingthis.

    WecouldmakethishappenusingaForloop:

    For index = 1 To myWorkbook.Sheets.Count mySheet = myWorkbook.Sheets(index) mySheet.Cells(1,1).Value = Hello World Next

    However,usinga ForEach ismuchsimpler(andactuallyfasterforthecomputertorun)!

    For Each mySheet In myWorkbook.Sheets mySheet.Cells(1,1).vValue = Hello World Next

    28 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    'Take Home' Ideas from Lesson 3Therearethreetypesofloopswhicharereallyhandy:While,ForandForEach.

    TheeasiestwayofsettingupaScriptingMacrotoopenpreexistingWorkbooksistouseDragAndDropScripting.

    WScriptisapreexistingObjectwhichisavailablefromall scripts.Italowsus,amongstmanyotherthings,togetthefile nameofaWorkbookwhichhasbeen'dropped'ontoourscript.

    AlotofthetimewewillwanttoprocessCellsuntilwefindonormoreemptyones.ThiscanbeachievedusingthehandyIsEmpty()methodinconjunctionwithaWhileloop.

    DrAlexanderJTurner2007 29

  • BabySteps

    30 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 4: Getting Tooled Up.A Quick NoteFromhere onward in Baby Steps, there will be times when it isimpossibletofitawholelineofscriptingcodeintoalineonthepage.Tohelppreventthis beingconfusing, emptyspaceat thestartofscriptlineswillbefilledwiththisspecialcharacter. Ifyoudonoseeanyofthisgreystuffatthestartofaline,thenthelineisacontinuationfromthelineabove.

    Get A Good Text EditorAswehaveseensofar,MacroScriptsarejusttextfiles.TextfilesareunlikedocumentsfromthingslikeMSWordbecausetheycontainjustcharacters;even newlines arestoredjustacharacters.WecanedittextfileswithNotepad(likewehavetillnow)butitisnotaverynicetoolfordoingthis.Beforeourscriptsgetmuchmorecomplex,itwillbemucheasierforustouseamorepowerfultool.Fortunately,therearemanyfreetexteditorsinexistence.Theyaresoimportanttotheactofprogramming,thatmanypeoplehavecreatedthem.

    MyfavouritetexteditorforWindowsisNotepad++.Itsnamegivesthe game away. It is a lot like Notepad but with loads of extrafeatures like line numbering, text colouring and excellentfind/replacetools.

    Notepad++is'OpenSource'andfreeofcharge.Thismeansthatyoudonothavetopayforitatallandyoucanuseitinanywayyouwantotherthanresellit.

    DrAlexanderJTurner2007 31

  • BabySteps

    Figure4:ThisisascreenshotofNotepad++beingusedtoeditoneoftheexamplefilesfromBabySteps.

    Todownloadacopy,pleasegotothisURL:

    http://www.sourceforge.net/project/showfiles.php?group_id=95717&package_id=102072. Alternativelyyoucandotothepackagehomepageandfollowthelinkstodownloadthebinaryexecutablefiles:

    http://notepad-plus.sourceforge.net/uk/download.php

    Recording MacrosItwouldbeahugetasktolearnandrememberhowtogetExceltodoeverythingviaScriptsthatwecangetittodoviatheuserinterface.Wow, that is scary. Fortunately, we do not have to learn andrememberallthat!Excelhas(asyoumaywellalreadyknow)areallyhandyfeaturecalledthe'MacroRecorder'.

    The Macro Recorder records 'Internal' Macros; those being oneswhichareembedded intoaWorkbook. However, Internal MacrosandScriptingMacrosasverysimilar.WecanrecordInternalMacrosandtheneasilytranslatethemintoScriptingMacrosorintopieceswhichcanbeaddedintoScriptingMacros.

    First,IwillbrieflydescriberecordingMacrosforthispurpose.Then,inthenextsection,IwillexplainhowtotranslatetheInternalMacrosintopiecesofScriptingMacro.

    32 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Figure5:HowtostartrecordingaMacro.

    Theusualuseofthe MacroRecorder istocreateanInternalMacrowhichwillautomateatask.Usingitrequiresthreesimplesteps:

    1. Startrecording.2. Performthetask.3. Stoprecording.

    Startingtherecording,inmostversionsofExcel,isdoneviatheToolsmenuoption. Figure5showsthisbeingdoneandAppendixAhasdetailsofhowtodoitinExcel2007.

    Figure6:WhenchoosingaMacroname,youmayaswellusetheoneExcelsuggestsbecauseyouarenotgoingtokeeptheMacro,

    itisgoingtobetranslatedintoyourScript.

    DrAlexanderJTurner2007 33

  • BabySteps

    Oncewehave requested to start theMacroRecorder, weneedtonametheMacro.BecausewearenotgoingtokeepthisMacro(justtranslateitintoaScriptingMacro)itisnotveryimportantwhatwecall it; inmostcases,thenameExcelcreatesautomaticallyisjustfine.

    Oncewehavechosenanameandclicked'OK'(seefigure6)Excelstartsrecording.Eachactionwhichistaken(e.g.eachmouseclickorbutton press) will be recorded as Visual Basic code which willperformthe sameaction. For example, selecting the top RowofColumnsAtoIwillcausetheMacroRecordertorecord:

    Range(A1:I1).Select

    Unfortunately, we cannot actually see the recording happen as itrecords. However,itisimportanttothinkverycarefullyasweareperformingthetaskswhichwewantrecorded;everyactionwillberecorded,includingmistakes,'undos'andaccidentalCellselections!

    Figure7:ThisscreenshotshowsasetofCellsbeingcolouredwhilsttheMacroRecorderisrunning.

    RememberthatwearenotwantingtokeeptheMacro.WearegoingtotranslateitintopartofaMacroScript.Becauseofthis,itismucheasiertorecordaseparateshortMacroforeachstepofaprocessthantorecordahugeMacroofanentire,complexprocess.Infigure7wecanseeaMacrobeingrecorded.ThisoneconsistsofselectingsomeCellsandthencolouringthem.Thisisaboutthelevelofcomplexitywe should be aiming for in any one recording. There are some

    34 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    exceptionswhereitisnotpossibletomakereallyshortrecordings.Forexample,whenwecreatePivotTablesinlesson8.

    Figure8:Thisscreenshotshowshow,oncetheactionswewantrecordinghavebeencompletedandtheMacroRecorderstopped, wecanopentheVisualBasicEditorandviewtheMacrocode.

    Figure9:HerewecanseehowthecodefortheMacrohasbeenwrittenintoaModuleofname'Module1'.Byexpandingthe

    Modulesnodeinthelefthandtreeviewandthendoubleclickingon'Module1'wecanseetherecordedcode.

    DrAlexanderJTurner2007 35

  • BabySteps

    Translating Recorded MacrosOncewehaverecordedaMacro,wecanusecopyandpastetoputtheMacrocodeintoNodepad++(orwhatevereditorweareusing).WeareonlyinterestedinthecodebetweenthelinestartingSubandthelineEndSub. Everythingelse,includingthesetwolines,canbethrownaway.

    The'raw'InternalMacrocodehastobetranslatedbeforeitwillworkasaScriptingMacro.Translatingmacrosrequiresthreefundamentalsteps:

    1. The keyboard and mouse based approach of the Macroshouldbeconvertedtoasimplerformforscripting.

    2. Excelconstantsneedtobetranslatedintonumbers.

    3. Theresultsof1and2needtobeintegratedintothescriptsothatitoperatesonthecorrectObjects.

    Keyboard and Mouse to Script TranslationInourexampleweliterallyselectedsomeCellsandthenchangedthebackgroundcolour oftheselection.ThisisexactlywhattheMacroRecorderhasrecorded.A RangeObjectisidenticaltoa CellObject(whichwehaveusedbefore)exceptitreferstooneormoreCellsatonce.

    mySheet.Cells(1,1).Value = Hello World

    Is100%thesameas:

    mySheet.Range(A1:A1).Value = Hello World

    RangeandCellObjectshaveaMethodSelect()whichsimplyselectsthemjustasthoughyouhadselectedthemonaWorksheetusingthemouse.SotheMacroRecorderhasrecordedtheCellsbeingselectedand converted this action into the code which calls the Select()MethodonaRange.

    mySheet.Range(A1:I1).Select

    OncetheCellshavebeenselected,theRecorderrecordsthechangestothatselection.WeshouldremovethisuseofaselectionandworkwiththeCellsdirectly:

    Range(A1:I1).SelectWith Selection.Interior

    Becomes:

    36 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    With mySheet.Range(A1:I1).Interior

    The Interior PropertyofaCellorRangeObjectisaspecial ObjectwhichExcelusesforcontrollingthe colour, borderandothervisualCellfeatures.

    Translating Excel ConstantsExcel constants arenumberswhichhavespecialmeaningstoExcel.Forexamplethenumber1tellsthe Cell.Interior ObjectthataCellborder shouldbesolid.The MacroRecorder hasspecial namesfortheseconstants. Forexampleinsteadofusing1tosignifyasolidborder,itwillusexlSolid;Excel'knows'thatxlSolidactuallymeans1.Unfortunately,aScriptingMacrodoesnot'know'whatxlSolidmeanssowetotellit.

    BeforewecanwritethecodeintoaScriptingMacrotodefinexlSolid,oranyExcelconstant,weneedtofindoutwhatitsvalueis.Whilstwemightbeabletorememberthevalueofoneortwoconstants,Excelhashundredsofthem. Fortunatelyforus,Excelalsohasaneasytousetoolforfindingouttheirvalues.

    Figure10:TostarttheprocessoffindingthevalueofanExcel constantrightclickontheconstantintheVisualBasicviewofthe

    Macro.

    ExcelhasatoolcalledtheObjectBrowser.Wearegoingtolookintousingthisinmoredetailinthenextsection.UsingitforfindingthevalueofExcelconstantsisverysimpleindeed.Thatisexactlywhatwewilldonow.

    DrAlexanderJTurner2007 37

  • BabySteps

    Figure11:ThesecondsteptofindingoutthevalueofanExcel constantistoclickon'Definition'whencontextmenucomesup.

    AllthatisrequiredistoviewthecodeofourrecordedMacro.Fromthisview,wecanrightclickonthetextoftheconstantitsself.Inourexample,if werightclickonthetext 'xlAutomatic' acontextmenuappears.Allweneedtodoisclickon'Definition'.

    Figure12:Oncewehavechosen'Definition'fromthecontextmenuoveranExcelconstant,theObjectBrowserwillopen.InthebottompaneoftheObjectBrowser,wecanseethedefinitionoftheExcel

    Constant.Inthiscase,xlAutomaticisdefinedas4105.

    38 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Oncewehaveclickedon'Definition'Excelwillautomaticallystartupthe Object Browser showing details of the constant on which weclicked. Constantsareshownasthenumberinournormaldecimalnumbersystemandtheninbracketsusingthemorecomputercentrichexadecimalsystem.Weonlyneedtoconsiderthedecimalversion.

    ForourScriptingMacrotousetheconstantswehavetodefinethemintheScriptingMacro. Hereisanexampleof thefinishedScriptsegment(thisisnotafullscript):

    xlAutomatic = -4105xlSolid = 1With mySheet.Range(A1:I1).Interior.ColorIndex = 36.Pattern = xlSolid.PatternColorIndex = xlAutomatic End With

    Using The Object BrowserIntheprevioussectionwesawhowExcelwillautomaticallylaunchtheObjectBrowserifweaskitforthedefinitionofanExcelconstant.WecanalsomanuallyopentheusetheObjectBrowser.ThiscanbeveryhandytohelpworkouthowtodosomethingwithExcel.

    The Macro Recorder can be very helpful, however sometimes wewanttoworkouthowtodosomethingwhichishardorfiddlytodowiththeMacroRecorder.ThisiswheretheObjectBrowsercomesinextremelyuseful.

    JustabouteverythingExcelcandofromthegraphicalinterfaceitcanalsodofromtheprogramminginterface.ThismeansthatourMacroScriptscandojustaboutanythingwewant.ToallowExceltohavesuchexcellent programmatic control, there are a huge number ofObjectsandConstantsinExcel. TheseareallknownaboutbytheObjectBrowser.TheObjectBrowsertakesitsinternaldescriptionofalltheseObjectsandConstantsanddisplaystheminahumanusableform.Itisnotonlyabrowser,butalsoasearchengine.YoucanuseittosearchforObjectsorConstantsbyname.

    TogettheObjectBrowserstarted,wefirstneedtobeinVisualBasicForApplications view(seefigure13). Fromthere,wecandirectlyopentheBrowserfromthe'View'menu.

    DrAlexanderJTurner2007 39

  • BabySteps

    Figure13:WecanstarttheObjectBrowsermanuallyfromtheViewmenu.

    OncewehavestartedtheBrowserwecanstartlookingaroundinsidetheprogrammaticinterfacetoExcelandsolearnalittlemoreaboutjustwhatwecandowithScriptingMacros.

    Figure14:ThisscreenshotshowswhattheObjectBrowserlooks likewhenithasbeenopened.AlsohereIhavetyped

    'xlsolid'(notethatthesearchisnotcasesensitive)intothesearchboxandclickedthesearchbutton(ithasbinocularsonit).InthepaneatthebottomoftheBowserwecanseetheresultofmysearch.InthemiddlepaneswecanseethatxlSolidisamember

    ofConstants.

    40 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Figure15:NotonlycanwesearchusingtheObjectBrowserwecanbrowsewithit.ThebottomtwopanesallowustomovearoundtheClassesandCollectionsofExcelandseewhatis

    available.

    Finding And Removing BugsBugsareafactoflifeinanythingcomputerbased.Basically,abugiswhenourscriptdoesnotdowhatwewantorexpect. Thereisnosimplecureorremedyforbugs.Whenweseetheeffectofabuginthewayascriptisrunningwemust'findthebug'. Thisisjustlikefixinganymachine;thefirststepistofindoutwhyitisnotworkingproperly.Fixingtheproblemalwayscomessecond.

    Thebestadviceforfindinganythingistodevelopthebestpossiblewayoflookingforit.Ifwearelookingforaneedleonacarpet,wemightuseamagnet. Ifwearelookingforastar,wemightuseatelescope.So,weneedtoolstohelpusfindbugsinScriptingMacros.Fortunatelyforustherearethree:

    1) Ourbrains!Wemustnotmakeanyassumptions.Thehumanbrainisamazingpowerfulattheartoffiguringoutwhatisgoingon,aslongaswedonotassumewealreadyknowwhatisgoingon.Findingbugsrequiresanopenmindandlotsofconcentration.

    2) Wscript.Echo:ThisMethodpopsupalertboxesthatletusseetheinnerworkingsofascript.OnewayoflookingforabugistoimagineallthevaluesofVariablesasthescriptruns.Analternativeistoimaginewhichpiecesofcodewillberunningatwhichpointintime. Placing Wscript.Echo statementsin

    DrAlexanderJTurner2007 41

  • BabySteps

    thescriptsallowsusto'see'ifourimaginingsarecorrect.Iftheyarenot,maybethatpoints tothebug. Forexample,whatvalueswillmyNumbertakeon?

    For row = 1 To 10myNumber = (row * row) / (row * 0.25)Next

    Tofindout,simplyjustgetthescripttotellus:

    For row = 1 To 10myNumber = (row * row) / (row * 0.25)Wscript.Echo myNumberNext

    Ifhavingtenpopupboxesisjusttooannoyingthenthisisanalternative:

    myList = for row = 1 to 10myNumber = (row * row) / (row * 0.25)myList = myList & myNumber & ,nextWscript.Echo myList

    3) OptionExplicit:Thissasimpledirectivethatwecanputatthe top of scripts. It forces the VBScript interpretor (thethingthatactuallyrunsourScriptingMacro)tocheckthatyouhaveexplicitlyuseDimtocreateallVariablesbeforeyouusethem.

    Here is anexampleof theuseof OptionExplicit tohelpdebugascript:

    Inthisexample,thescriptwillproducemeaninglessresults:

    ' Create Excel Etc...' Populate a Spreadsheetfor row=1 to 100value=row * 10mySheet.Cells(row,1).Value=valeunext i

    Amistakelikethisisalargescriptcantakeaverylongtimetospotusingjustthehumaneye.Thesolutionistodothis:

    Option ExplicitDim mySheet,row,value' Create Excel Etc

    42 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    ...' Populate a Spreadsheetfor row=1 to 100value=row * 10mySheet.Cells(row,1).Value=valeunext i

    The'OptionExplicit'atthetopofthescripttellsVBScriptnottouseaVariable unlessit hasbeencreatedwithaDimstatement. Inthiscase,wehavenotcreatedaVariablevaleusothescriptwillnotrun;insteaditwillgiveusawarningtellingusthattheVariableisnotdefinedandthelineonwhichthebugis.

    DrAlexanderJTurner2007 43

  • BabySteps

    'Take Home' Ideas from Lesson 4Fromnowonscriptswillhaveinsteadofspacesatthestartofnewlines.

    Scriptsaretextandsoarebesteditedwithatexteditorlike notepad++.

    Excel'sInternalMacrosandScriptingMacrosareverysimilar.Agoodapproachtofiguringouthowtodosomethingwithascript istorecordanExcelInternalMacroandthentranslateitintoaScriptingMacro.

    Scripttranslationrequires3steps:

    1) Covertfromthekeyboardandmousebasedapproachto asimplerdirectmethodology.

    2) Translateconstants.3) Integrate.

    Totranslateconstants,wecanrightclickontheminExcel'scodeviewandgotoDefinition.

    FindingdefinitionsusestheObjectBrowser.TheObjectBrowserisveryusefulforlookingatotherpartsofExcel'sprogrammatic interface.

    Gettingridofbugstakes3techniques:Keepingandopenmind, usingWscript.Echoto'see'whatisreallyhappeningandalwaysusingOptionExplicit.

    44 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 5: Starting To Work With DataSpecial FoldersInthislessonwearegoingtodosomerealdataprocessing. TodothisweneedtofindWorkbookstoopenandfindgoodlocationstosavenewWorkbooks. Todothiswecanuse SpecialFolders. So,pleasebepatient;thissectionwillonlybebrief,thenwecanstartwithsomerealwork!

    Special Folders are folders that are or at least potentially can bepresentonallWindowscomputers;theseincludetheMyDocuments,FontsandStartMenufolders.TherearetwotypesofSpecialFolders:Thosethatmapto standarddirectories andthosethatdonot.TheFavourites folder,forexample,mapstoastandarddirectory;theMyComputer folderdoesnot. WeareonlyinterestedinSpecialFolderswhichmapto(represent)realfolders.

    The WScript.ShellSpecialFolders collectioncontainsthefullpathtoeachofthespecialfoldersthatwecanaccessusingScriptingMacros.Thetablebelowliststhe Keys totheCollectionandthecontentsofeachofthespecialfoldersintheSpecialFolderscollection.

    Identifier Folder ContentsAllUsersDesktop Shortcuts that appear on the

    desktop for all usersAllUsersStartMenu Shortcuts that appear on the Start

    menu for all usersAllUsersPrograms Shortcuts that appear on the

    Programs menu for all usersAllUsersStartup Shortcuts to programs that are run

    on startup for all usersDesktop Shortcuts that appear on the

    desktop for the current userFavorites Shortcuts saved as favorites by the

    current userFonts Fonts installed on the systemMyDocuments Current users documentsNetHood Objects that appear in Network

    NeighborhoodPrintHood Printer linksRecent Shortcuts to current users recently

    opened documents

    DrAlexanderJTurner2007 45

  • BabySteps

    Identifier Folder ContentsSendTo Shortcuts to applications that show

    up as possible send-to targets when a user right-clicks on a file in Windows Explorer

    StartMenu Shortcuts that appear in the current users start menu

    Startup Shortcuts to applications that run automatically when the current user logs on to the system

    Templates Application template files specific to the current user

    ThewaytousetheSpecialFolderfeatureofaWScript.Shellobjectisvia the .SpeciaFolders.Item() Method. The script below finds thelocationoftheMyDocumentsspecialfolderanddisplaysittous.

    Option ExplicitDim myShell, myPathSet myShell = WScript.CreateObject("WScript.Shell")myPath = myShell.SpecialFolders.Item("MyDocuments")WScript.Echo "MyDocuments='" & myPath & "'"

    Using 'SendTo' As A Really Easy Way To Run ScriptsThe script below creates a shortcut to a Scripting Macro'myMacro.vbs'intheSendTospecialfolderwhichmeanswecanthenrightclickonanyWorkbookfileandsendittothatScriptingMacro.The script assumes that our Scripting Macro is inMyDocuments\ScriptingMacros.

    Option ExplicitDim myShell, sendToFolder, myScriptPath, myShortcut

    Set myShell = WScript.CreateObject("WScript.Shell")sendToFolder = myShell.SpecialFolders("SendTo")myScriptPath = myShell.SpecialFolders("MyDocuments") & "\myMacro.lnk" Set myShortcut = myShell.CreateShortcut(sendToFolder & "myMacro.lnk")myShortcut.TargetPath = myScriptPathmyShortcut.Save

    46 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Saving And Opening From Special FoldersWhenweuseScriptingMacrostoautomateataskwewanttheinputandoutputfilestobeplacedineasytofindplaces. Microsoft hascarefully moved us into thinking in terms of MyDocuments andDesktopetc.;thismakesspecialfolders likethisidealforautomatedscriptingtasks.

    Belowaretwoexamples.ThefirstscriptcreatesanewWorkbook.ItthenplacesthecurrenttimeanddateintooneoftheSheets.Onceithas done this it saves the Workbook onto the Desktop. ItautomaticallyoverwritesanyexistingWorkbookofthesamename.Youcantellthatithasdonethisbecauseeachtimethescriptrunsthedateand/ortimewillbeupdated.

    Thesecondscriptisevensimpler;itjustopenstheWorkbookthefirstscriptcreated.ThescriptrequiresnouserinterventionbecauseitcanfindtheWorkbookusingthespecialfolder'Desktop'.

    ' This script saves a Workbook to the DesktopOption ExplicitDim myShell, myExcel, myWorkbook, mySheet, myShell, xlNormal

    ' Open ExcelSet myExcel = CreateObject("Excel.Application")' Create a Workbook and set myWorkbook to refer to it' all in one goSet myWorkbook = myExcel.Workbooks.AddSet mySheet = myWorkbook.Sheets(1)mySheet.Cells(1,1).Value="Date"mySheet.Cells(2,1).Value=Date()mySheet.Cells(1,2).Value="Time"With mySheet.Cells(2,2).Value=Now().NumberFormat = "[$-409]h:mm:ss AM/PM;@"End WithmySheet.Columns(1).AutoFit

    ' Tell Excel not to complain about overwrite files and ' other things like thatmyExcel.DisplayAlerts = FALSE

    ' Save Excel Workbook to DesktopxlNormal = -4143Set myShell=CreateObject("WScript.Shell")myWorkbook.SaveAs myShell.SpecialFolders("Desktop") & "\AutoSaved.xls",xlNormalmyExcel.Quit

    DrAlexanderJTurner2007 47

  • BabySteps

    Figure16:ThisscreenshotisresultofthefirstofthetwoDesktopscripts.ThisistheExcelWorkbookthatIopenedfromdouble

    clickingonAutoSaved.xlsonthedesktop.

    ' This script opens the Workbook saved by the' previous oneDim myShell, myExcel,myShellSet myExcel = CreateObject("Excel.Application")Set myShell=CreateObject("WScript.Shell")myExcel.Open myShell.SpecialFolders("Desktop") & "\AutoSaved.xls"

    Merging Between WorkbooksInmyforwardItalkedaboutchainsofExcelspreadsheets.Thesearecausedwheredatapassesthroughmanystepsand/ormanyhands.Onekeyactioninsuchchainsisdatamerging. Oftenwemusttaketwoorthreedatasetsandmergethemtogether.

    MovingColumnsofdataaroundbyhandcanbetedious.Searchingthrough rows of data to find matches can be soul destroying.ScriptingMacroscancometotherescue.

    Merging Data By ExampleTosetthesceneofdatamerging,agoodexamplewilldonicely.Bylooking at a plausible business scenario wecan truly imagine thestepsinvolvedinmerging.

    Afairlycommoncausefortheneedtomergeis 'incompletedata'.Considerthatweareinasalesdepartment.Salespeopleareouton

    48 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    the road collecting orders. They report the orders back to headofficeonspreadsheetslikethis:

    Customer Name Part Number Quantity Date

    ABC Engineering 12345 1 11/11/2007

    XYZ Fabrication 7234 4 6/11/2007

    Our job is to record there orders and get them dispatched tofulfilmentfromwherethepartswillbesenttothecustomers.

    Butnotice, theorder records fromthesales peopledonot tell usenough for fulfilment to dotheir job. All wehave is acustomername. Toovercomethis wehaveanother master customer list.This is the critical core Workbook from which all customerinformation is run. In this Workbook is a Sheet with customercontactdetailslikethis:

    Name Id Address Tel Fax Main Contact

    ABC Engineering

    5 45 False Road

    012345678

    012345679

    John

    XYZ Fabrication

    8 23 Nowhere Avenue

    087564321

    012345672

    Jane

    OurfirstchallengeistowriteaScriptingMacrowhichwilloutputaSheettosendtofulfilment.ThisscriptwilltakeeachorderRowfroma sales person and match the customer name against the Namecolumninthe CustomerContact Details Sheet. Theoutputof thisprocess should have the customer name, address, part number,quantityandorderdate.

    Dictionary ObjectsDictionaryObjects areveryuseful things indeed. They letus justlookupvaluesratherthanhavingtogoandsearchforthem.Inthecaseofourexample, wecanstoreall thecustomeraddressesand'lookthemup'bycustomername.Thethingwearelookingupisavalueandwelookitupbyakey.HereisadescriptionofallthePropertiesandMethodsofaDictionaryObject.

    DictionaryObjectProperties:

    CompareMode This sets the compare mode for using different character sets. We can normally

    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:

    Add key,value Places a new key/value pair into the Dictionary.

    Exists(key) Returns TRUE is key is in the Dictionary and FALSE otherwise.

    Remove(key) Removes a key/value pair from the Dictionary.

    Items() Returns an array of all the values in the Dictionary.

    Keys() Returns an array of all the keys in the in the Dictionary.

    RemoveAll() Totally empties the Dictionary so it has no key/value pairs at all.

    So,to merge orderswith addresseswecanstore allthecustomernamesaskeys.Foreachcustomernamekeywestoretheaddressasthevalue.

    Letususeacustomercalledhackandslashwithanaddress123FakeStreet.wecanthenstoretheaddresswiththenamesasakeylikethis:

    Dim myDictionarySet myDictionary=CreateObject(Scripting.Dictionary)myDictionary.Add hack and slash, 123 Fake Street

    Thereverseofthisistolookupthevalueassociatedwithanalreadystored key. We can demonstrate this with a continuation of thepreviousscript.

    50 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Dim addressaddress = myDictionary.Item(hack and slash)Wscript.Echo address

    Theabovescriptwillecho123FakeStreet

    Simple Merge ScriptTomakeamergescriptworkitwillhaveto:

    1) Loadtheordersheet.

    2) Loadthecustomerinformationsheet.

    3) Createanewsheet.

    4) Populatethenewsheetwithamergeddataset.

    5) Savethenewsheet.

    TomakethisniceandsimpleIwillsaythatthecustomerinformationWorkbookisalreadyonmyDesktop.Thismeansthatwecanusethe'specialfolders'wehavealreadylookedattolocatetheWorkbook.Tocontinuewiththeeasyconcept,IwillputtheoutputWorkbookontheDesktopaswell. Finally,using'draganddrop'seemsasensiblechoiceforloadingthesalesWorkbookintomyScriptingMacro.

    Todothedatamergethescriptwillhavetolookupaddressesbycustomer name. So it will load a Dictionary; the keys will becustomernamesandthevalueswillbecustomeraddresses.NextthescriptwillworkitswaydownthesalesSpreadsheet(fromthesalesWorkbookthat wasdroppedonto it). ForeachRowonthesalesSpreadsheetthescriptwillreadinthecustomersnameandlookuptheaddress.

    Onceithasfoundtheaddressitwillwritethename,address,orderquantityanddateintotheordersSheetintheoutputWorkbook.Thefollowingscriptperformsthissimplemerge:

    Option Explicit Dim myShell,myExcel,ordersWBDim 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 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)

    ' This loads the dictionary with the ' addresses keyed by name row=2 While(NOT IsEmpty(customersSh.Cells(row,1))) myDict.Add customersSh.Cells(row,1).Value,customersSh.Cells(row,3).Value row=row+1 Wend

    ' Lay out the output sheet outputSh.Cells(1,1).Value="Customer Name" outputSh.Cells(1,2).Value="Part Number" outputSh.Cells(1,3).Value="Quantity" outputSh.Cells(1,4).Value="Date" outputSh.Cells(1,5).Value="Address"

    ' This scans the orders and creates the output row=2 While(NOT IsEmpty(ordersSh.Cells(row,1))) outputSh.Cells(row,1).Value=ordersSh.Cells(row,1) outputSh.Cells(row,2).Value=ordersSh.Cells(row,2) outputSh.Cells(row,3).Value=ordersSh.Cells(row,3) outputSh.Cells(row,4).Value=ordersSh.Cells(row,4) ' This is the merge, looking up the address from' the DictionaryoutputSh.Cells(row,5).Value= _myDict.Item(ordersSh.Cells(row,1).Value) 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"

    Thisscriptproducesthisoutputwhenoneoftheordersisforabcengineering:

    52 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Customer Name

    Part Number

    Quantity Date Address

    ABC Engineering 12345 1

    11-Nov-2007 45 False Road

    XYZ Fabrication 7234 4

    6-Nov-2007

    23 Nowhere Avenue

    abc engineering 12348 12

    15-Nov-2007

    Thisscriptisallwellandgoodbutitwillbenouseintherealworld.Forexample,thecustomerinformationWorkbookmaywellhaveacustomer names as ABC Engineering; however, a sales person(maybeinarush)mightputabcengineering(seetheabovetable).Thesalespersonmightevenputabcengineering.Howcanwedealwiththesesituations?

    Thesolutionis tothis real world situationis abit ofpragmatism.Step one is to remove all unnecessary information. ABCEngineeringandabcengineeringareclearlythesamecompany.Wecanchangethescripttoignorethecaseofnamestoreflectthisreality. Thiscanbedonebymakingallthekeysinthe DictionarylowercaseviatheLCase()functionwhichisbuiltintoVBScript.Theother built in Function to use here is Trim() which removed anyunwantedspacesfromthestartorendofaString.

    Dim MyStringmyString = "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 "'"

    Our second issue is where ABC Engineering is writtenabcengineeringorevenbcaengineering. Theseareexamplesofgenuinemistakesmadebythesalesperson. Ifwetrytoengineersomehypercomplexscripttoworkouttheanswerdespiteincorrectinputs,wewillendupwastingalotoftime.

    The only thing really qualified to sort out a real human error isanotherhuman.SowewillcreateanextraSheetoferrorswecangothroughandfixbyhand.

    Working Merge ScriptOption Explicit

    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)

    ' This loads the dictionary with the ' addresses keyed by name row=2 While(NOT IsEmpty(customersSh.Cells(row,1))) myDict.Add LCase(Trim(customersSh.Cells(row,1).Value)),customersSh.Cells(row,3).Value row=row+1 Wend

    ' Lay out the output sheet outputSh.Cells(1,1).Value="Customer Name" outputSh.Cells(1,2).Value="Part Number" outputSh.Cells(1,3).Value="Quantity" outputSh.Cells(1,4).Value="Date" outputSh.Cells(1,5).Value="Address"

    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"

    ' This scans the orders and creates the output ' We need three different Row Variables because the ' Row we write to is not the same as the number' as the one we read from any more row=2 errorRow=2

    54 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    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:

    1) FindaColumnwhichisinbothSheets

    DrAlexanderJTurner2007 55

  • BabySteps

    2) WorkoutwhichSheethasthemasterrecordsandwhichtheslave.InourexamplethecustomerinformationSheetwasthemaster. Donotworryifitisnotobviouswhichiswhich;youcanalwaystryitbothwaysandseewhichworksbetter.

    3) FindtheColumninthemasterwhichissharedwiththeslave(e.g.customername).

    4) Figureoutallthevariabilitywhichcanberemovedfromtheshared column data. Examples are capitals, spaces,punctuation.

    5) Loadthedatayouwantfromthemasterintoa DictionaryObject.KeytheDictionarybythesharecolumn.

    6) Foreachrowintheslave,lookupthedataintheDictionary.

    7) Ifamatchingentryinthe Dictionary isfound,putthedatafromtheslaveandtheDictionaryintotheoutputSheet.

    8) Ifnomatchisfound,putthedatafromtheslaveintothe'errors'Sheet.

    Merging Multiple ColumnsSofarwehavelookedatmergingmultiplecolumnsfromtheslaveSheet with a single column(e.g. address) from the master. HowcouldwemergemultiplecolumnsfrombothSheets? Itwouldbequite hard to load more than one Column into the Value of akey/valuepairintheDictionaryObjectsothatisprobablynotthesolution.

    Asitturnsout,thesolutionisverysimple. DoeverythingthesamewayasforthesinglemasterColumnmerge,butthistimestoretheRownumberinthemasternottheColumndata.EachtimeamatchisfoundintheDictionary,theRownumbercanbeusedtoextractthedatafortheoutputdirectlyfromthemasterSheet.

    56 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    'Take Home' Ideas from Lesson 5Wscript.ShellhasaCollectioncalledSpecialFolders.

    TheSpecialFolderCollectionisveryusefulindeedforfindingeasytouseplacesonthecomputer'sharddriveliketheDesktop.

    DictionaryObjectsletusstorevaluesandthenlookthesevalues bykeys.

    MergingdatafrommultiplespreadsheetsisaverycommonandimportantScriptingMacrotask.

    Mergingcanbedonequickandeasilywiththehelpof Dictionaries.

    DrAlexanderJTurner2007 57

  • BabySteps

    58 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Lesson 6: Reading & Writing FilesWhat Is A File?Thismightseemanoddquestion. Weallusecomputerfilesallthetime.Weopenthem,savetothem,uploadthemanddownloadthem.However,dowereallyknowwhattheyare? Likemanyeverydayitems,weoftenlearntousethemwithouttrulyknowingthem.

    Thankfullyfilesaresimple.Theyaresimplerthanmostpeoplewouldimagine.Afileisjustalonglistofnumbers.Eachnumbercantakeavaluebetween0and255.Thatisit!

    Wemayhaveextrastuff associatedwiththefile; forexample, wemightgiveitaname.Butthenameisnotpartofthefile;thefileisjust a list of numbers. Wemight make a place where people orprogramscan find our file. Weoften call these places folders ordirectories.However,afolderisnotthefile.Neitheristhenameweusetohelplocatethefileinsidethedirectory;thatnameispartofthedirectorynotpartofthefile.Afileisjustalistofnumbers.

    AllthisbegsaquestionIffilesaresoverysimple,howcomewecandosomanyamazingthingswiththem?

    Theanswertothisliesinasimplechild'sgame.Oftenchildrenseektomakeaeasytousecypherbyreplacingletterswithnumbers:

    a=1,b=2,c=3,d=4etc.

    Towritedownabcwecouldput123.Nowthenumbershavetakenonameaning. Theyarestilljust numbers,butwehaveputspecialmeaningsontothem.Usingasimpleschemejustlikethiswecanstorewhatwethinkofastextasalistofnumbers. Yes,thatmeanswecanstoretextinacomputerfile!Thefiledoesnot'know'thatitcontainstext;itisjustalistofnumbers. However,wecaninterpretthosenumbersasrepresentingcharactersandso,tous,thefilecontainstext.

    WecouldconsiderthefilewhichcontainsthedigitalversionofBabySteps. This has to hold muchmore than just text; it as images,tables and complex structure information. How, how can suchcomplexitybestoredinasimplelistofnumbersbetween0and256?This is where format comes intoplay. Format takessequencesofnumbersandgivethemmeaning.ThisisjustlikeinEnglishwritingwritinghasmoremeaningthanthesumofitindividualletters.

    DrAlexanderJTurner2007 59

  • BabySteps

    Fileformatscanbecomeverycomplexindeed. InBabyStepswearenotinterestedincomplexsowewillkeepthingssimple. It isamazingwhatcanbedonesimplywithfilesandExcel.

    Formostoftherestifthisbookwewillonlydealwithwhatarecalledtextfiles.Thesehavedirecttranslationsofthenumbersinthefileto characters,punctuationandafewlayoutrules. Textfilesaresosimplethattheycanbereadandconvertedtohumanreadablefromusing Notepad. Notepad (or Notepad++) reads in each numberfromthetextfileandconvertsitintoahumanreadablecharacteretc.

    Whenwewrite text in Notepad, every so oftenwewill press the'enterkey'todroptothenextline.Yearsagosomecomputerscalledthe enter key 'newline'. This is because in text file editors likeNotepad,pressingitproducesaspeciallayoutcharacterwhichmeansstartanewline. This isanexampleofoneof thehandfull ofspeciallayoutcharactersintextfiles.

    Newline characters are stored in the text file as the number 13.Spaceisanotherexamplewithitsnumberbeing32.Thenumeral1isrepresentedbythenumber48andtheletterAby64.So123Ais4849503264.

    Whenweworkwithtextfileswetendtoletthecomputerprogramsweworkwithdoallthetranslationbetweenthefiles'numbersandthetextweareworkingwith.Inotherwords,wereadtextfilesintoStringsandwewriteStringstotextfiles. Towardstheendofthebook I discuss what are called binary files. These are where theactualnumbersarereadandwrittendirectly.WealmostneverneedtodirectlyhandlebinaryfilesinExcelMacroScripting.

    Writing To A Text FileMacroScriptingusesaspecialObjecttoaccessfilesdirectly.Towritetoafilewecreatea System.FileSystemObject. WegivethisObjectinformationonwheretoputthefilethatwewillbewriting,itsnameandifitshouldreplaceanypreexistingfilewiththesamenameinthesamefolder.FromthisinformationtheFileSystemObjectcreatesaTextStreamObject.ItisthisTextStreamObjectwhichactuallydoesthewriting.

    TheexamplebelowwillcreateatextfileontheDesktopadinsidethatfileitwillplacetwolinesoftext.

    Option ExplicitDim myFSO, myTSO,myShell,myName,forWritingforWriting=2

    60 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    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 NamemyName=myShell.SpecialFolders("Desktop") & \example.txt' 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 existSet myTSO = myFSO.OpenTextFile(myName,forWriting,true)myTSO.WriteLine("Hello this is a text file")myTSO.WriteLine("It was created by a script")' It is good practice to always close a TextStreammyTSO.Close

    Figure17:ThisiswhatNotepadshowsifweuseittoopenthefile example.txtcreatedbyourfilefilewritingscript.

    Thepreviousscriptwillalwaysreplaceanexistingfilewithanewone.Thismeansthatit'secretly'performsthefollowingsteps:

    1) CheckifafileofthatFolder\Nameexists.

    2) Ifitdoes,deleteitpermanently.

    3) CreateanewfilewiththesameFolder\Name.

    4) Writetothenewfile.

    Whathappensifwejustwanttoaddtothefileratherthanreplaceit?Thisisnotsoodd;wemightwanttowritealineatheendofasfileeverytimeascriptisruntoactasanaudittrailforexample.Todo

    DrAlexanderJTurner2007 61

  • BabySteps

    thiswetelltheFileSystemObjectto'Append'ratherthan'Write'whenweopenthefileandcreatetheTextStreamObject.

    Thisscriptaddsanewlinegivingthedateandtimethescriptwasruntoafilescript.log.ThefilewillbecreatedontheDesktopthefirst time the script runs. After that, a line will beadded to theexistingfileeachtimeitisrunagain.

    Option ExplicitDim myFSO, myTSO, myShell, myName, forWriting, forAppendingforWriting = 2forAppending = 8Set 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 NamemyName=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 existSet myTSO = myFSO.OpenTextFile(myName,forAppending,true)myTSO.WriteLine("Script Run: " & now)myTSO.Close

    Iranthisscriptafewtimeandhereisthecontentsoftheresultingfile:

    Script Run: 18/10/2007 13:03:31Script Run: 18/10/2007 13:04:30Script Run: 18/10/2007 13:04:31Script Run: 18/10/2007 13:04:42Script Run: 18/10/2007 13:04:44Script Run: 18/10/2007 13:04:45Script Run: 18/10/2007 13:04:46

    Reading From A Text FileNowthatwecanwritefiles,howabout reading them? Firstofall,whywouldwewanttoreadone?ExcelcanreadExcelfilessowhydoweneedadifferentwayofreadingfiles?

    Sometimesweneedtouseascripttoreadafile,workwithwhatithasreadandthenputtheresultinExcel. Forexample,wemighthaveafilethathasaformatelikethis:

    BeginUser = AJT

    62 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    Date = 01/07/2007Action = logonEndBeginUser = FFDate = 01/08/2007Action = logoffEnd

    InthisfileweknowthatalinewhichsaysBeginstartsablockoflines and a line which says End ends that block. This extrainformationaboutthemeaningofthecontentsofthefileiswhatwecallformat.ThisformatisnotonethatExcelunderstandssowehavetoloadthedataintoaspreadsheetusingascript:

    Option Explicit Dim myFSO,myExcel,myWorkbook,mySheet,myTS,row,line,keyWord,datum

    ' Another way of defining Variables which we will not' change is to use the Const keywordConst forReading = 1

    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

    ' Set row to the first Row we ' want to write to in Excel row=2

    ' Open our file in a TextStream Object Set myFSO=CreateObject("Scripting.FileSystemObject")

    ' This is how we open a file reading using the ' FileSystemObjectSet myTS=myFSO.OpenTextFile _( _"myFile.txt", _forReading, _FALSE _)

    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

    Reading And Writing In ChunksMostofthetimereadingandwritinglinesisjustfine.WhenweputmyTextStream.Writeline(Fred) the actual file gets two extranumberswrittentoitinadditiontothoserepresentingFred.ThesearecalledCarriageReturnandLineFeed. Theygettheirnamesfromtypewriters.Theyrepresenttheactionofreturningthecarriage(holdingthepaper)totheleftandfeedingthroughthepaperbyonelineheight.Nowadaysthesenumbersjustrepresenttheendofalineandthebeginningofthenext.

    64 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    WhenweusemyTextStream.ReadLine()wegetbackthenextlineoftext froma file. Just like a human reading a page of text, theTextStreamObjectremembersits'place'inthetextandsocangiveusthenextlinefromthat.

    Thereareafewotherthingswhichwemightwanttodowithatextfile.Thesearenotusefulquiteasoftenasworkingwithonelineatatime,buttheycomeinhandyeverysooften:

    1) ReadanentirefileatoncetoaString.

    2) WriteanentirefileatoncefromString.

    3) Readanexactnumberofcharactersfromafile.

    4) WriteaStringtoafilewithoutaddingonthecarriagereturnlinefeed.

    Whilstthesearefourdifferentthingsweneedonlylearntwonewtechniquestobeabletodothem! WhenweopenaTextStreamforreadingwecancallcallmyTextStream.Read(count)wherecount isanumber. This is just like Readline in that the TextStreamObjectremembers its 'place' in the file and reads on from that place.However, rather then readinga whole line, it readsexactly countcharactersandreturnstheseasaString.Anotherslightdifferenceisthatwhenitencounters carriagereturn or linefeed,itwillactuallyput these characters in the returned String. Also note that if itreachestheendofthefilebeforeithasreadcountcharactersitjustgivesusthecharactersithasreadsofar.

    InExcelMacroScriptingIhaveyettocomeacrossaneedtoreadcount characters from a file except in one common special case.SometimewewanttoreadanentirefileintoaStringallinonego.Again,tomakethissupereasy,wecanjustmissoutcountaltogether.InthebelowscriptweopenaTextStreamreadingfromafileandcallReadAll()whichislikeusingRead(count)wherecountisthenumberof characters left whichcanberead. This slurps the entire file'scontentsintoaStringforus(thisisnotanentirescript,justapieceofone):

    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.ByusingtheMethodWrite(myString)onaTextStreamObject(whichwasopenedtowriteorappend)wesimplywriteoutthenumbersforthecharactersintheStringtothefile. Write(myString)doesnotadd carriagereturn ornewline.Ifwecallitmanytimeswecanaddtothefilesonechunkatatime.IfweopenaTextStreamforoverwriting(notappending)and we call Write(myString) just the once before closing theTextStream,wehavewrittentheentirecontentsofthefilefromourString.

    Hereisascriptwhichreadsanentiretextfileinonego. It thenreplaceseveryinstanceof/with//. Finally,itwritesanewfilewiththeupdatedcontents.Wewillseeinlesson7(thenext)whywemightwanttodothis(again,thisisjustasubsectionofascript):

    Set myFSO=CreateObject("Scripting.FileSystemObject") Set myTS=myFSO.OpenTextFile _( _"myFile.txt", _forReading, _FALSE _) ' Read the entire contents at oncefileContents=myTS.ReadAll()myTS.Close

    ' Do the replace of / with //fileContents=Replace(fileContents,"/","//")

    ' Now write out our new file contentsSet myTS=myFSO.OpenTextFile _( _"myFile.txt", _forWriting, _TRUE _) ' Write the entire contents at oncemyTS.Write(fileContents)myTS.Close

    Listing FilesI was considering not including this section. Then I suddenlyrememberedaveryimportantsortofapplicationforlistingfiles.Letus imaginethatwehavewrittenascriptwhichtakesa 'dragand

    66 DrAlexanderJTurner2007

  • HowToBecomeAnExcelGod(withoutreallytrying)

    drop'WorkbookandmergesthedatawithasecondWorkbook.ThisscriptthencreatesanoutputWorkbookcontainingthemergeddata(see lesson5). Whilst this is fineforone, twooreventen inputWorkbooks, how about if there were 100 or even 1000. ThealternativetospendingthebalanceofournaturallifedragginganddroppingistogetourscripttofindtheinputWorkbookfilesitsself.

    Thenextscriptdoesexactlythat.Itisabit'dense'inthatitdoesalotwithonlyafewlinesofcode.Ratherthanstuffitfullofcomments,Ihavediscussedhowitworksafterthescript.

    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

    ThefirstthingthattheabovescriptdoesistouseSpecialFolderstofindthepathtotheDesktop.NextitcallstheGetFolder(path)methodofaFileSystemObjectObject.ThismethodreturnsaFolderObject.BecausethepathwepasstotheGetFoldermethodisthepathtotheGetFoldermethod,wegetaFolderObejctrepresentingtheDesktop.

    FolderObjectsareusedtoallowustodothingswithFolders.Inthiscase,wewanttofindallthefilesintheFolder.TheFolderObjecthasaCollectioninitcalled'Files'whichcontainsaFileObjectrepresentingeachoftheFilesintheFolder.ThisbeingaColl