You are on page 1of 153

2/24/2015

programming_microsoft_word__01_introductionDevtome

ProgrammingMicrosoftWord01
Introduction
Introduction
IhavebeenplanningforseveralyearstoautomatesomeoftherepetitiveWordtasksIencounterona
dailybasis.Forcompanies,softwaredevelopmentisnotsomethingpurchasedlikeaboxofprinterink
andpencils.Itinvolvesalotofplanning,testing,interviewsandmoney.Thereseemstobenochance
ingettingyourownrepetitivetasksautomatedveryquickly.Well,that'swereopportunityisarising.
Writingsoftwarebecomeseasierandeasier.Opensourcetoolsbutalsotoolsmadeavailableby
companieslikeMicrosoftincreaseourabilitytobeourowndeveloperandsolvingourownchallengesat
homeandatwork.
ThiscontributiontoDevtomeisintendedtobethefirstofmany,describingthestepstodevelopa
softwareapplicationwithfreetools(assumingyouhaveMSWordavailable).Asoftwareapplication
thatyoucanfitandmoldtoyourexactrequirements,savingyoualotoftimeandtroubleinyourfuture
ambitionsandwork.Iamnotandwillneverbeaprofessionalcoder.It'sallaboutreading,tryingoutand
educationoneselfinthelongrun,andmakingsoftwarethatworks(whetherwefullyunderstanditor
not).SinceIhavenotencounteredasinglesourceofinformationexplainingallbasicaspectsofbuilding
yourWordautomationproject,Ihavemadeitmyaimtodoexactlythat.Aguideforenthusiastswilling
toputintheefforttolearnautomatingtheirdocuments.
Thisfirstcontributionkicksoffwithasmallintroduction,followedbysettingupthenecessary(free)
software,andfinallybuildingandrunningasimpleprogramthatautomatesWord.Thislittleprogram
willnotbetheendtherearealotofissueswithitthatneedtobesolvedsomethingwewilltacklein
futurecontributionsbutwetakeitstepbystep.Youwilldosomecodingofyourself.Thatmeansyou
willactuallybewritingaprogramandexecutingit.Don'tworry,thecodewillbeprovidedtoyousoit
can'tgowrong.Iwillusethefollowingboxtodescribecode.
[[codegoesinhere]]

Mostofthecodingwillbedonebytheprogrammingsoftware.Yourtaskmainlyconsistofbuildingthe
userinterfacewithdraganddropandinsertingsomeminimalcodeattherightspottomakeitwork.You
willlearnquicklyhowitworksandbecomefamiliarwithit.

AutomatingMicrosoftWord
EverybodyknowsMicrosoftWord.Thisprogramisstillnumber1softwareusedinmostbusinessesand
widelyknowntopeopleallovertheworld.Theamountofhoursspentbehindakeyboard,typingin
lettersthatformwords,thatformsentences,thatformetc,isendless.WhatislessknownisWord's
http://www.devtome.com/doku.php?id=programming_microsoft_word__01_introduction

1/3

2/24/2015

programming_microsoft_word__01_introductionDevtome

design.Asfromthestart,MicrosoftmadeWordverymuchprogrammable.Inlaymen'sterms:the
abilitytoletWorddothingsautomaticallybymeansofaprogram.Someoftheseautomationtasksare
alreadybakedinWorditself.AnexampleistheTableofContents,thatcanbeaddedtoadocumentwith
inbuildfunctionality.Arudimentaryformofautomationthatyoucanbuildyourselfisthemacro.
Macro'scanbecreatedbytheWorduserbyrecordingatask,whichcanberepeatedbymeansofthis
macroendlesslybymeansofashortcutorabuttonassignedtothismacro,thussavingtheusertimeand
effort.Infact,IthinkmostpeoplealreadyusetheseautomationoptionsofWord,whetherbyowndesign
orbydesignoftheiremployer.
However,Wordcanbeautomatedalotfurther.
AssumingthatyouoryouremployeralreadyhasboughtMicrosoftWord,youalreadyhaveavery
powerfultoolathandtobringyouthosedocuments,lettersandreports.Wordcandoalotmorethanjust
takingkeyboardstrokesonebyone.Itisdesignedtobeprogrammedandsteeredbyexternalprograms
inalmosteveryconceivableway.Generally,usersdonotuseeven10%ofitscapabilities.Inconclusion,
thecompleteengineforourautomationisalreadythere,boughtandpaidfor.

Requiredtools
Asstatedabove,IassumeyoualreadyhaveMicrosoftWordavailable.Itdoesnotmatterwhichversion
youuse.Withsomesmalladjustments,theapproachtoWordautomationusedinthiscontribution
shouldworkforeachrecentversionofWord.Therestofthesoftwareneededisbasicallyoneadditional
programonly:MicrosoftVisualStudioExpress(forDesktop).SinceMicrosoftcameoutwith.NET,it
hasalsobeenreleasingnewerversionsofitsrelatedprogrammingsoftware:VisualStudio(VS).
WhereasthefullversionsofVScomeataprice,MicrosoftalsomakeslimitedversionsofVSfreely
available:the'Express'version.Withhardwaremovingfromdesktoptotheweband,nowadays,mobile,
thereareseveraldifferenttypesofVisualStudioExpress2013tochoosefrom.Forthiscontribution,we
willuseVisualStudioExpressforDesktop2013.

http://www.devtome.com/doku.php?id=programming_microsoft_word__01_introduction

2/3

2/24/2015

programming_microsoft_word__01_introductionDevtome

DownloadandinstallVisualStudioExpressforDesktop[http://www.visualstudio.com/enus/downloads/].
Installingtakessometime.Iftheprogramasksyouwhatprogramminglanguageyouwillprimarilybe
using,chooseVisualBasic.Onceinstalled,youarereadytostartwiththefirstprogram.
Next:ProgrammingMicrosoftWord02Ourfirstprogram[http://www.devtome.com/doku.php?
id=programming_microsoft_word__02__our_first_program]

Computing|Programming|Software

programming_microsoft_word__01_introduction.txtLastmodified:2014/08/2017:05by
wekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CC
AttributionShareAlike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://www.devtome.com/doku.php?id=programming_microsoft_word__01_introduction

3/3

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

ProgrammingMicrosoftWord02Ourfirstprogram
Let'sgetstartedandwritethefirstprogram
AftertheIntroduction[http://www.devtome.com/doku.php?id=programming_microsoft_word__01_introduction],it'stimeforustowriteourfirstprogramautomatingWord.
WewillbuildasimpleWindowsformthatwilltaketextinputandwriteitinanewWorddocumentattheplaceofthecursor.
TheWordversionusedis2007butitshouldworkwithotherWordversionsaswell(olderandnewer).

Ifnotalreadydoneso,DownloadandinstallVisualStudioExpressforDesktop[http://www.visualstudio.com/enus/downloads/].

WorkingwithVisualStudioExpress
StartVisualStudio.Iftheprogramasksyouwhichlanguageyouwillprimarilybeworkingwith,chose'VisualBasic.Soon,youwillbelookingattheIDEofthis
program.Thismayseemabitoverwhelmingthefirsttime,butyouwillknowyourwayaroundfairlyquickly.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

1/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

YouwillbeworkingwiththisIDEalot,sohereisabasicintroduction.YouarelookingatthedefaultlookofVisualStudio(VS)rightafterthestart.Ontop,youfind
thefamiliarmenu'sforopeningandclosingfiles,edit,viewetc.Therestofthescreenisusedforwindowboxesthatwillhelpyouwriteyourfirstprogram.
Ontheleft,there'sthe'toolbox'.Thetoolboxwillshowallkindsoftoolslikebuttons,textboxesandotherstuffthatyouwillneedforyourprogram.Itworkswithdrag
anddrop,placingitemsontheWindowsformofyourprogram.Inthemiddlewindow,youfindthetabsontoptoswitchbetweenfiles.Mostofthecodingwillbedone
inthiswindow,sosomescreenestatewillcomeinhandytofitthisbetweenthetoolboxontheleftandthesolutionexplorerontheright.
Themiddlewindowonthebottomwillbydefaultbeanerrorlist,showingpossibleerrorsinyourcodesoyoucanhaveanimmediatelookatitwhilecoding.
Finally,ontherightsidethereisthe'solutionexplorer'thatwillshowprojectfileslikesomesortoffilebrowser.Wewillnotbeusingthisinthiscontribution.Onthe
lowerrightside,whenworkingonaprojectyouwillseealistofpropertiesofaparticularselectedobject.Thiswindowallowsyoutolookupandchangepropertiesof
objects(likethenameofabutton).
Ifyoufeeluncomfortableaboutis,Irecommendthatyoufollowhttp://www.youtube.com/watch?v=pp5UuZxayCktogetafirstfeelingofworkingwiththeIDE.

Startanewproject
Step1
First,youneedtoopenanewproject.SelectFileNewProjectandchooseaVisualBasicWindowsandchoose'WindowsFormApplication'fromtheoptions.
Giveyourprojectaname(likeMyFirstMSWordProgram)andclick'OK'.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

2/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Step2
Oncetheprojectisloaded,weneedtomakeareferencetotheOfficelibrary.Thislibrarybasicallyenablesyouto'talk'toWordprogrammaticallyandmakeitdo
things.Thisiscalled'Interop',atermyouwillusewhenwritingthecode.TheprogramelementstosteerWord,mustbelinkedtoourprojectandwewilldothiswith
VisualStudiobymakingareferencetothesocalledOfficeObjectLibrary.ForWord2007itisversion12(2003is11,2010is13etc).
Thereferenceismadeasfollows:(topmenu)ProjectAddReference

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

3/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Step3
Intheresultingwindow,chooseunderthe'COM'elementMicrosoftOffice12.0[oryourversionofWord]ObjectLibrary.Thesearchfieldasshownbelowcan
helpyoulocatethisreferenceeasier.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

4/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

ClickOKandyouareallset.

Workingwithsomecode
Ok,westillneedtodoonethingbeforewecanprogramWord.IntheIDE'smiddlewindow,youfindtheemptyWindowsform(agreyrectangle).Bydefault,VScalls
thisrectangle'Form1'.DoubleclicktheForm1.TheIDEwillgotothecodebehindtheForm.
Inyourform,addareferencetotheInteroplanguagebymeansofthefollowingcode(placeitabovethetextwheretheformstartswithPublicClassForm1,see
samplebelow).
ImportsMicrosoft.Office.Interop.Word

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

5/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Itispossiblethatthislineofcodegivesyouerrors.TheautomatichelpforinsertingtextwillnotletyouchooseInteropand/ortheerrorlistinthemiddlewindow
belowwillstarttocomplainabouterrors.Inthatcase,makesurethatyouhaveinstalledthesocalledPrimaryInteropAssemblies(PIA)forWordforyourWord
version.Inmyexample,thePIAforWord2007versioncanbefoundhere[http://www.microsoft.com/enus/download/confirmation.aspx?id=18346].

DesigningtheGUIofourprogram
OurprogramwillbesteeredfromtheGraphicalUserInterface(GUI).ThisisafamiliarWindowsformonwhichwewillplaceatextboxandabutton.Thetextboxand
buttoncanbedraggedwiththemousefromthetoolboxontheleftontoForm1(seepicturebelow).Dragthemaroundandresizethemasfit.Wewillnotchangetheir
namesinthisround.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

6/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Intheend,yourForm1willlooksimilartothis.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

7/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Codingtime
Nowforsomeaction.DoubleclickthebuttonyoujustdraggedontoForm1.TheIDEwillshowyouthecodebehindthatbuttonandplacesthecursorreadytoinsert
somecode.Alternatively,youcanswitchtothecodebehindForm1byrightclicking'Form1'intheSolutionExplorer(seepicture),butthenyouwillhavetogotothe
blockthatholdsthecodeforthebuttonyourself.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

8/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Youwillbeinsertingthefollowingcodeonthatexactspot:
DimwdAppAsNewWord.Application
DimwdDocAsWord.Document
Try
wdDoc=wdApp.Documents.Add()
wdApp.Visible=True
CatchexAsException
MsgBox("ErrorcreatingWorddocument.")
EndTry
wdApp.ActiveWindow.Selection.TypeText(TextBox1.Text)
wdApp=Nothing

Whendone,itwilllooklikethis:

Wewillgothroughthiscodestepbystepexplainingwhatitdoes,butfirstlet'sruntheprogram!

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

9/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Runningtheprogram

Thebutton'Start'willbuildourprogramandsubsequentlyrunitasaregularWindowsprogram.VSwillnotletyouruntheprogramiftherearestillerrorsinthecode.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

10/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Theprogramisrunningsuccessfully.Intheexampleabove,Iinsertedsometextinthetextbox.Writesometextinthetextboxyourselfandpressthebutton.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

11/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Voila,theendresult.TheprogramhasopenedanewWorddocumentandinsertedthetextfromthetextboxintheWorddocumentattheplaceofthecursor(=startof
Worddocument).YourfirstmanipulationofWordbymeansofasoftwareprogram

Howdoesthiscodework?
Below,wewillgothroughthecodeinmoredetailbutfirstthewarningthathiscodeisnotsuitableyetforourpurposes.YouwillnoticethatifyouhadWordalready
runningasecondversionofWordwasstartedthatwillconflictwiththeearlierrunningversion.Ifyouclosethenewlycreateddocumentandclosethe2ndversionof
Wordrunning,itwillcomplainaboutanotherversionofWordrunning.CloseWordbutdonotoverwritethenormal.dotfile.Wewillfixthisbehaviourinfuture
contributions.
Nowthecode.
1.Withthe'Dim'command,wemakesurethattheprogramknowsthattherewillbeaWordobject(Word.ApplicationtheWordsoftware)andaWorddocument
object(Word.DocumentaWorddocument).
2.Thecode'try,catchandEndtry'isinsertedtoperformsomebasicerrorhandling.Ifanerrorwouldoccurwhenexecutingthecodeandnoerrorhandlingisprovided,
ourprogramwouldcrash.Now,anerrorwouldtriggeramessageboxindicatingsomethingwentwrong.Propererrorhandlingisveryimportantwhenwriting
software.
3.thecommand'wdDoc=wdApp.Documents.Add()'basicallystartsWord(whetheralreadyrunningornot)andopensthedefaultblankdocument.With
'wdApp.Visible=True',wemakesurethatWordwillbevisibleonscreen.
4.ThecommandtotypetextintoaWorddocumentattheplaceofthecursoris'wdApp.ActiveWindow.Selection.TypeText(TextBox1.Text)'.BehindTypeTextwe
couldhaveaddedtextbetweenourselves,butinstead,wepointtheprogramtothecontents'.Text'ofourtextbox(whichbydefaultisnamed'TextBox1').
5.theobjectwdAppismade'nothing'againascleanupafterwards.

Nextcontribution:stepbystep
ThenextcontributiondealswiththeGUI.WewillcreatealittleprogramthathidesintheWindowstrayandwillshowamenuwhenrightclickedwiththemouse.This
menuwillholdallourfutureWordactions,sothatwewillhaveWordautomationreadyatourfingertipswhenneeded.

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

12/13

2/24/2015

programming_microsoft_word__02__our_first_programDevtome

Nextcontribution(part3)[http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray]
Computing|Programming|Software

programming_microsoft_word__02__our_first_program.txtLastmodified:2014/08/2017:04bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0Unported
[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program

13/13

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

ProgrammingMicrosoftWord03Runningtheprogramfromthetray
Givingourprogramaplacetostart
Inthepreviouspost[http://www.devtome.com/doku.php?id=programming_microsoft_word__02__our_first_program],wemadeawindowsprogramthatusesaWindows
form.Theformcontainsourcontrolsincludingbuttonswithwhichtheusercanworkwiththeprogram.Wecouldalsousethisformtolink(withabutton)toother
forms,providingforastartingpointtoaccessseveralpartsofourprogram.Wecouldtothesamebyinsertingtabsorusingatopsidemenu.
Inthis3rdpost,wewillapproachthisalittledifferent.
OurprogramwhichwillgainmorefunctionsinthefuturewillbeusedinatypicalsettingwherebytheuserworkswithWord,typingindocuments.Partofour
programwillbefullyautomateddocumentgeneration,butanotherpartwillbeallaboutinsertingoftextblocks(fixedorcompletedwithuserinput).Wewanttoavoid
thattheuserhastoopenourprogramandkeepitopenasawindow,buttuckingitawayonlytoreviveitonceinawhile,whenhewantstogenerateandinserttext
blocksinhisactivedocument.
Soundsconfusing?Don'tworry.Itwillbecleartoyousoon.

Whatarewegoingtobuild?
WearegoingtobuildaregularWindowsapplicationusingastandardwindowsform.Onthisform,wewillplaceandbuildacontextmenu(amenuthatcanhave
multiplelayers).Now,insteadofrunningthisformuponstartupintheregularmanner,wewilltellWindowstostartitminimizedandtoonlyshowaniconinthe
Windowstray.Ouraimistolettheuseropenourcontextmenubyrightclickingtheiconinthetray.Exactlythebehaviorwearelookingforinordertoletouruser
haveeasyaccesstoalloursoontobuildWordautomationpower.

Thestepstomakeithappen
Step1

First,westartVisualStudioandstartanewproject(youcandownloadVisualStudioExpressforDesktopforfreehere[http://www.visualstudio.com/enus/downloads/]
requiresaWindowslive/hotmailaccount).Itallstartsbygoingtothetopleftscreenandaccessingthe'File'tab.

Step2

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

1/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

GofromFileNewProject.

Step3

Inthewindowthatpopsup,selectVisualBasicWindowsontheleftsideandchoose'WindowsFormsApplication.Youcanusethenamesuggestedinthe
illustrationorchooseyourownname.Click'OK'.

Step4

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

2/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Justasastandardoperation,werenametheform'svisiblenamefromForm1tosomethingmoreapplicable.Makesureyouselecttheformwithamouseclicksoyou
canlookupthe'Text'propertyinthe'Properties'window.

Step5

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

3/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Next,fromthe'Toolbox'ontheleft,selectanddragtheNotifyIcontotheform.

Step6

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

4/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Ifdoneright,theNotifyIconwillshowupas'NotifyIcon1'inthelowerpartoftheform'sdesignwindow.Thiswillhappenifyoudropacontrolontotheformthatdoes
notshowontheform(e.g.,adatabasecontrolorthisnotifyiconcontrol).

Step7

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

5/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Now,wewillinsertsomecodetotelltheprogramtominimizetheformfromstart.Doubleclicktheforminthedesignview(pleaseignorethe'ContextMenuStrip1in
thepicture,wewillgettothatinamoment).

Step8

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

6/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Doubleclickingtheformwillbringthecodebehindtheform.Pleasenotethelineontopattheend.the'Load'elementinMybase.Loadtellstheprogramtodo
somethingwhentheformisloaded.Sincewewanttheformtominimizeonstart,thatisexactlywherewewanttoaddcode.Takeoverthecodeshowninthe
illustrationandmakesurethatitisplacedbetweenthePrivateSubForm1andEndSub.
Incode:
Me.WindowState=FormWindowState.Minimized
Me.ShowInTaskbar=False
WithnotifyIcon1
.Icon=Me.Icon
.Visible=True
.Text="TaskTray"
EndWith

Thisisthecodethatmakestheprogrambehavelikewewant.Startminimizedandshowaniconinthetasktray.Theonlythinglefttodoisbuildingamenuand
enablingaccessthroughtheiconinthetasktray.

Step9

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

7/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Selectanddragthecontrol'ContextMenuStrip'fromtheToolboxonthelefttotheform.IfyoucannotfindtheContextMenuStrip,pleasemakesurethatyouexpand
'AllWindowsForms'intheToolbox.

Step10

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

8/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Ifdoneright,a'ContextMenuStrip1'willappearnexttotheNotifyIcon1intheform'sdesignview.Intheformitself,aContextMenuStripisaddedinwhichyoucanfill
inmenustrips,bothinthemainstripasinsubstrips.Pleasefinalisethestripasyoudeemfit.

Step11

Thisismyexampleoffillingoutthemenustrip.Thisisthemenuyouruserwillseeandworkwith.Therefore,makesurethatthemenuitemsaredescriptiveand
logical.

Step12

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

9/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Hangon,wearealmostthere.Youhavebuildthemenu,butthemenuneedstobeaccessiblefromthetaskbar.Wewilldothisbymanipulatingapropertyofthe
notifyicon.Selectthe'NotifyIcon1'andlookfortheproperty'ContextMenuStrip'inthePropertieswindow.Youcanselectthedownarrowandchoosethe
ContextMenuStrip1wejustdraggedontoourform.
Now,thismenuisaccessiblewitharightclickofthemouseonthetasktrayicon.

Step13

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

10/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Finally,wewanttoattachactionstothevariousmenuitems.Wewillnotdothisinthispostthisisreservedforthenextpostwherewewillstarttoworkonthefirst
elementsofourWordautomationcode.Justtofinalizethispost,wewilladdcodesotheusercanexittheprogramviathemenu.
Forthispurpose,weaddan'exit'elementtothemenu'smainpart.

Step14

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

11/12

2/24/2015

programming_microsoft_word__03__run_program_from_the_trayDevtome

Doubleclickthe'Exit'menuitem,soVisualBasicbringsyoutothecodesection.Pleasenotetheendofthetopline.The'Click'itemofthe
ExitToolstripMenuItem.Clickphrasetellsusthatthecodewewillinsert,willbeexecutedupona'click'ontheExitpartofourmenu.Exactlywhatwewant.
Thecodeitselfissimple.Justadd'End'tellingtheprogramtostopexecutionandterminate.

Step15

Theendresult:aniconinthetasktray,completewithseverallayersofmenu.VeryeasyforausertoaccesswhenworkingonaWorddocumentforaquickdoseof
WordAutomation.
WearenowinanexcellentpositiontostartwritingthefirstpartoftheactualWordautomationelements.Inthenextpost,wewillbuildasimpleformtoinsertthe
detailsofapartytoaWorddocument.
ComputingAZ|Programming|Software

programming_microsoft_word__03__run_program_from_the_tray.txtLastmodified:2014/08/2017:06bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0Unported
[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://www.devtome.com/doku.php?id=programming_microsoft_word__03__run_program_from_the_tray

12/12

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

ShapeShiftLensPlugin
SendaltcoinstoanyBitcoinaddressonlineShapeShift.io
AdsbyCoinURL

ProgrammingMicrosoftWord04FromFormtoWordDocument
Whatarewegoingtodointhislesson?
ThepurposeofthislessonistocreateawindowsformthatwilltakeuserinputandinsertitinaWorddocument.Oneofthebestaspectsofsoftwareisitsreusability.
Softwarecodeisjustelectronictextthatcanbereusedoverandoveragain.Todemonstratethisfeature,wewillbuiltontopoftheapplicationmadeintheprevious.
First,wearegoingtosaveourpreviousprogramasatemplate.Ifyouhavenotbuilttheprogramfromthepreviouslesson[http://www.devtome.com/doku.php?
id=programming_microsoft_word__03__run_program_from_the_tray],dosonowbeforeproceeding.
Inthefirststeps,wearegoingtoreopenourtrayapplicationandsaveitasatemplate.Fromthenon,thistemplatewillbeavailableforreuseinfuturelessons.

Step1
FireupVisualStudioandopenyourtrayapplicationfromthepreviouslesson[http://www.devtome.com/doku.php?id=programming_microsoft_word__03_
_run_program_from_the_tray].Dosobyopeningviathemenu:FileOpenProject.

Now,selectyourtrayapplicationbuiltinthepreviouslessonandopentheproject.

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

1/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Onceyouhaveopenedthetrayapplication,youexportthisprojectasatemplate(Iassumeyouhavebuild/runthetrayapplicationatleastoncealready).Exportitasa
templatethrough:FileExportTemplate.

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

2/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Awindowpopsupwiththequestiontochooseatemplatetype.Isuggestyouchoose'Projecttemplate'fornowandclick'Next'.Leaveeverythingasitisinthe
followingwindow(notshownbelow)otherthanchoosingarelevantTemplatenameandaproperTemplatedescriptionifyouwant.Thenclick'Finnish'

Okay,youdidit.Yourtemplateisreadyforthenextpartofthistutorial.

Step2
Inthefollowingstep,youaregoingtouseyourfreshlycreatedtemplatetomakeanapplicationbasedonthattemplate.Thatwillsaveyoufrombuildingthetray
applicationfromscratchsowecangetrighttotheWordautomationpart.Great,isn'tit?
Goto:FileNewProjectandsearchforyournewtemplate(exampleshownbelow).

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

3/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Selectthetemplateandcreateyournewproject.Asyoucansee,thetrayapplicationisalreadypresentinyournewproject.Thatsavesalotoftimecodingthetray
applicationfromscratch!

Step3
Dependingonwhereyoufinishedwiththeoriginaltrayapplicationbeforeyoumadethetemplate,thereisanextrastepinvolved.Wewanttobesurethatthetray
applicationhasanactualmenu.Ifyourapplicationalreadyhasamenu,gotostep4below.Otherwise,proceedasfollows.Makesurethattheformisvisiblebydouble
clickingonForm.vb(orwhateverthenameofyourformis)intheSolutionExplorer.NowclickontheContextMenuStrip1item(seepicturebelow).

Thecontextmenuappearsinthedesignviewoftheform.Makesuretocreateatleastonemenuitem.MakingmenuitemsisfairlyintuitiveinVisualStudiosoIwill
letyouworkthisoutyourselves.Whendone,testthemenubyrunningtheapplication.Ifyoudidthingsright,aniconwillappearinthetraythatwillshowyourmenu
structurewhenrightclicked.Ifso,youarereadyforthenextstep.

Step4
ThenextfewstepswillbeaboutshowinganewformwhentheuserclicksanitemofthetraymenusystemandbuildingsomeroutineinthatnewformtoshowWord
automationinaction.First,wewillcreatethenewform.
http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

4/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Rightclickontheapplication'snameinthesolutionexplorer.Throughthemenuthatappears,goto:AddWindowsForm.

Chooseanameforthenewform.Isimplychoseform2.vb(thedefaultnamepresented)andclick'Add'.Anewformisaddedtoyourprojectandaform2.vbisshown
indesignview.Now,switchbacktoform1.vbandclicktheContextMenuStrip1again.Thecontextmenustripappearsontheformagain.

Inmyexample,Igotooneofthesubmenu'screatedandIdoubleclickononeoftheitems(seepicture).Youcandothesamewithoneofyourownmenuitemsyou
createdearlier.

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

5/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Doubleclickingthemenuitemofthecontextmenustripbringsyoutothecodeeditor.Don'tworry,thenextstepisveryeasy.

Step5
Whentheuserclicksthatmenuitem,wewanttoshowthenewform(form2)wejustcreated.That'seasy.Justinsertthefollowingcode:
Form2.Show()

That'sit!Runtheapplicationandtestitbyclickingtherelevantmenuitemfromthetrayapplication.YournewForm2willbeshown.

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

6/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

Step6
BeforewemovetotheWordautomationpart,wearegoingtosetuptheform(form2).Theuserwillprovideinputbymeansoftextboxesontheformthatwillcapture
thatinput.GototheformagaininVisualStudio.
MakesurethatthetoolboxisshownontheleftsideoftheVisualStudioprogram.Withthelittlepingontopofthetoolboxwindow,youcanpinthetoolboxsothatit
remainsopenontheleftside(theleftsideisthedefaultviewofthetoolboxinVisualStudio).Now,placeonebuttononthelowerrightsideoftheformandadd4
textboxes,arrangedinrows.Dosobyeitherdraggingtheseelementsfromthetoolboxontotheform,ordoubleclickeachiteminthetoolboxsotheyappearonthe
form.Rearrangeasshowninthepicturebelow.Asmarttipistocreateonetextboxontheform,selectitanddraggingitwhileholdingCtrl.VisualStudiowillthen
makeacopyofthetextbox,makingiteasytocreatealotoftextboxesquickly.

Step7
ThefinalstepbeforeworkingonWordautomationisaquickroutineshowinghowthetextboxescanhelpyoucaptureinputfromtheuser.Thetextboxesonourform
arenamedbydefault'TextBox1','TextBox2','TextBox3'and'TextBox4'.Youaregoingtowritecodetocaptureanytextinputfromthosetextboxesandshowthis
inputthroughastandardpopupmessagewindow.
First,clickthebuttonandyouaretakentothecodebehindthebutton.Insertthefollowingcodebetweenthe'PrivateSub'and'EndSub':PrivateSub
Button1_Click(senderAsObject,eAsEventArgs)HandlesButton1.Click
MsgBox("ThisisthecontentsofTextbox1:"&TextBox1.Text&vbCrLf_
&"ThisisthecontentsofTextbox2:"&TextBox2.Text&vbCrLf_
&"ThisisthecontentsofTextbox3:"&TextBox3.Text&vbCrLf_
&"ThisisthecontentsofTextbox4:"&TextBox4.Text)
EndSub

Now,runtheprogram,bringupform2,typesometextthefourtextboxesandhitthebutton.Themessageboxshowsthecontentsofthetextboxes.
http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

7/8

2/24/2015

programming_microsoft_word__04__from_form_to_word_documentDevtome

WewillusethismethodinasimilarmannerinourfirstWordautomationprogram.Thatwillbecoveredinthenexttutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__05__from_form_to_word_document_ii].
ComputingAZ|Programming|Software

programming_microsoft_word__04__from_form_to_word_document.txtLastmodified:2014/08/2017:02bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0Unported
[http://creativecommons.org/licenses/bysa/3.0/]

Every15minutes3000satoshi
ClaiminXAPOWallet
motherfaucet.com

AdvertisewithAnonymousAds

http://www.devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document

8/8

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

VirWoX
DieTauschbrsefrvirtuelleWhrungen.www.virwox.com
AdsbyCoinURL

ProgrammingMicrosoftWord05FromFormtoWordDocument(II)
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__04__from_form_to_word_document],wemanagedtotakethetray
applicationfromtutorial3,expandonitbybuildingasecondwindowsformandusetextboxesonthatnewformtocaptureinputfromauser.Thepurpose
ofthistutorialistodirectthisinputtoaWorddocumentinsteadofthemessageboxoftheprevioustutorial.
BecausetheinteractionbetweenyourprogramandWindowsWordrequiressomebackgroundinformation,Idecidedtodedicateaseparatetutorialtothe
magicbehindallthis.Onceyougetthisupandrunning,it'seasy,butforfutureeaseofuseisvitaltounderstandthebasicsbehindit.Iassumeyouhavea
copyofOffice(2003orupwards)installedonyourPC.

Step1
Beforewegoonwiththeprogramfromtheprevioustutorial,youarefirstgoingtocreateanewprojectcalled'MyFirstWordApp'.Todoso,startVisual
Studioandgoto:FileNewProjectandchooseWindowsFormsApplication.Setthenameoftheprojectto'MyFirstWordApp'.Movingforwardquickly,
placeatextboxontheformandabutton.Yourscreenwilllooklikethis:

Step2
Beforeweaddcode,weneedtomakeourprogramawareoftheprogramminglanguagenecessarytomanipulateWorddocuments.Wewilldosonow.
InthetopmenuofVisualStudio,goto:ProjectAddReference

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

1/6

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

Inthe'ReferenceManager'windowthatpopsup,wearelookingfortheCOMlist.ClicktheCOMelementontheleftandalargelistofreferencesappears.
Wearelookingforthe'MicrosoftOffice12.0ObjectLibrary'.Theversionnumber12.0indicatesthatIamusingOffice2007.OtherversionsofOfficewill
renderotherversionnumbersfortherelevantlibrary(Forinstance,Office2003is11.0).Justchoosetheversionthatisofferedinyourcase.
Findingthislibraryiseasierbylookingitupthroughthesearchwindowatthetopright(seepicturebelow).Clickandselect'MicrosoftOffice12.0Object
Library'(oryourversionofthisObjectlibrary.

Wewanttoaddreferencetoanotherlibrary:the'MicrosoftWord12.0ObjectLibrary'.Again,theversionshowninyourwindowmaybedifferent,
dependingonyourOfficeversion.Selectthe'MicrosoftWord12.0ObjectLibrary'andclickOK.

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

2/6

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

Addingreferenceisnotvisibleinyourcode.However,itisavitalsteptoensurethatyourprogramcan'talk'toWord.Wearegoingtoinsertanother
reference,butnowinourcode.Inthetopoftheform'scode(sonotthedesignviewbutthecodebehindtheform),abovetheline'PublicClassForm1',
insertthefollowingcode:

ImportsWord=Microsoft.Office.Interop.Word

YouwillfindoutlateronthatthisenablesareferencetotheWordobjectmodelthroughthestatement'Word'inyourcode.

Step3
Nowitistimetostartwithsomerealcoding.Inthedesignview,doubleclickonthebuttonVisualStudiowillbringyourcursorbetweenthelines'Private
SubButton1_Click'and'EndSub'.

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

3/6

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

Enterthefollowingcode:

DimwdAppAsNewWord.Application
DimwdDocAsWord.Document
'ThiscodewillstartWordandopenanewdocument
'fromthestandardtemplate.Ifanerroroccurs,theprogram
'throwsamessage
Try
wdDoc=wdApp.Documents.Add()
wdApp.Visible=True
CatchexAsException
MsgBox("ErrorcreatingWorddocument.")
EndTry
'Withthislineofcode,thetextinthetextboxwillbeinserted
'attheplaceofthecursorinword
wdApp.ActiveWindow.Selection.TypeText(TextBox1.Text)
'cleaningup
wdApp=Nothing

Thiscodestartswithdeclaringtwovariablesthatwilldealwithtwoobjects:theMicrosoftWordprogramitselfandaMicrosoftWorddocument(thelines
startingwith'Dim').Bydoingso,yourprogramhasanobjecttoworkwith(eitheraWorddocumentorWorditself).
Second,thecodedeclaresaWordDocument(wdDoc)andaskto'Add'adocument(wdApp.Documents.Add()).TomakesurethattheWordapplicationis
visibletotheuser,thewdApp.Visibleissettotrue.ThisblockofcodeisplacedbetweenaTryCatchexEndTryconstruction.Thisisdonetoavoid
theprogramcrashingiftheuserhasnoMicrosoftWordinstalled.The'Exception'willthenleadtoamessageboxappearingwithanerrornotice.
ThentheactualcodetowritetextinaWorddocument.TheprogramhasalreadyopenedMicrosoftWordandopenedablankdocument.Theline
'wdApp.ActiveWindow.Selection.TypeText'tellstheprogramacoupleofthings.ActiveWindowisthewindowactivewhenthecoderuns.Selectionis
basicallytheplacewerethecursorisinourcasethestartofablankWorddocument.Thenthecommandthatactually'types'text.Hence'TypeText'.The
texttobetypedistakenfromtheTextbox1(Textbox1.Textinthecode).
Thefinallineofcodeisaboutcleaningup.TheobjectwdAppissettonothing.
Now,runtheprogram,typesometextinthetextboxandhitthatbutton.Voila,yourtextappearsinablankWorddocument

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

4/6

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

Aproblemappears
Keeptheprogramrunningandtryanotherline.Andtheninsertathirdlineoftextandhitthatbuttonagain.YouwillhavethreeWorddocumentsopen,
showingthelinesyoujustinsertedinyourprogramonebyone.
However,thereisaproblemhiddeninthedark.Eachtimeyourprogram'adds'aWorddocument,itopensanewinstanceofWord.Consequently,younow
have3instancesofMicrosoftWordrunning.StartthetaskmanagerviaCtrlAltDelandlookattheprogramsrunning.YouwillfindthreeWordprograms
(Winword.exe)runninginsteadofone(seepicture).

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

5/6

2/24/2015

programming_microsoft_word__05__from_form_to_word_document_iiDevtome

YouruserwillfindoutthatthereisaproblemwhenheclosesaWordinstance.BecausetherearemorethanoneWordinstancesrunning,theseinstances
willinterferewitheachotherandrenderakwarderrornotices.

WordiscapableofopeningmultipledocumentswithinoneinstanceoftheWordprogramrunning.Wehavetofixourcodetocheckwhetheraninstanceof
Wordisalreadyrunningbeforeopeninganewinstance.Wearegoingtotothisinthenexttutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__06__creating_word_docs_the_right_way].
ComputingAZ|Programming|Software

programming_microsoft_word__05__from_form_to_word_document_ii.txtLastmodified:2014/08/2816:38bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0Unported
[http://creativecommons.org/licenses/bysa/3.0/]

WithdrawBitcoinandLitecointoDebitCards!
247Exchange.comRegulatedBitcoinExchange
www.247exchange.com

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii

6/6

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

ProgrammingMicrosoftWord06CreatingWord
DocumentstheRightWay
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__05__from_form_to_word_document_ii],
wemanagedtoplacetextfromatextboxinourprograminaWorddocument.However,weencounteredaproblem:our
programdoesnottakeintoaccountthatoneWordinstance(theprogramMicrosoftWord)canhandlemultipledocumentsat
once.OurcodedoesnotknowthatandfaithfullyopensanewinstanceofWordeachtimetheprogramrunsthecode.These
Wordinstances(visibleas'Winword.exe'inthetaskmanager)interferewitheachotherandconfuseyouruser.Timetoget
ridofthatproblem!
Basically,wearegoingtoteachourprogramtolookforainstanceofWordalreadyrunning.Ifso,theprogramwill'catch'
thatrunninginstanceandstartworkingwithit.IfnoinstanceofWordisrunningyet,ourprogramwillstartanewinstance.
Let'sdelveintothecode.

Step1
Youwillcontinuewiththe'MyFirstWordApp'programfromtheprevioustutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__05__from_form_to_word_document_ii].Youaregoingtochangethecodethat'sbehind
Button1.TheprocedureforcheckingwhetherWordisrunningiscourtesyofCindyMeister.Please
ChangethecodebetweenPrivateSubButton1_Click(senderAsObject,eAsEventArgs)HandlesButton1.ClickandEnd
Subasfollows:

DimwdAppAsNewWord.Application
DimappNameAsString="Word.Application"
'thiscodewascreatedbyCindyMeisterofMicrosoft
DimwdProcesses()AsSystem.Diagnostics.Process=_
System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
IfwdProcesses.Length>0Then
wdApp=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
Else
wdApp=NewWord.Application
EndIf
'endofcodefromCindyMeister
'createtheOject'Worddocument'
DimwdDocAsWord.Document

'ThiscodewillstartWordandopenanewdocument

'fromthestandardtemplate.Ifanerroroccurs,theprogram

'throwsamessage
Try

wdDoc=wdApp.Documents.Add()

wdApp.Visible=True

CatchexAsException

MsgBox("ErrorcreatingWorddocument.")

End

EndTry

http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

1/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

'Withthislineofcode,thetextinthetextboxwillbeinserted
'attheplaceofthecursorinword
wdApp.ActiveWindow.Selection.TypeText(TextBox1.Text)

'cleaningup
wdApp=Nothing

Let'srunthroughthemechanicsofthefirstpartofthenewcode.AnobjectofaWordappiscreatedandtheprogramistold
toholdastringcalled'Word.Application'inmemory.Thereasontokeepthislineinmemoryistocheckwhetheraninstance
ofWordisalreadyrunning.

Thenextfewlinesofcodecreatetheobjects'wdProcesses'and'wdprocess'.Theprogramcheckswhetherwinwordis
running.

Ifso,theprogramisnotaskedtostartanewinstanceofWord.Instead,ourWordprogramobject(wdApp)isattachedtothe
runninginstanceofWordbythe'GetActiveObject'command.

IfWinwordisnotrunning(thenumberofprocessescalled'winword'iszero),yourprogramwillstartanewinstanceof
Word.

Therestoftheprogramisbasicallythesameasintheprevioustutorial.

Step2
Nowthatthistechnicalissuehasbeensolved,let'staketheprogramonestepfurther.AWordautomationprogrammayhave
tointeractwithWordseveraltimesatdifferentplacesinthecode.Youdonotwanttocopy/pastetheprocedureeachtime
theprogramhastointeractwithWord.Instead,thiscodewillbewrittenonceandcalleduponeachtimeyouneedit.
Let'sgettowork.
First,deleteallcodebetweenPrivateSubButton1_Click(senderAsObject,eAsEventArgs)HandlesButton1.Clickand
EndSub.Youcanswitchtothiscodeeasilyifyouclickonthebuttoninform1intheDesignview.

http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

2/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

Step3
Now,addanewclasstoyoursolution.RightclickthesolutionintheSolutionExplorerandchooseAddClass.

http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

3/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

Inthenextwindow,choose'Class'andnametheclass'WordActions'andclick'Add'.

http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

4/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

Step4
PlacethefollowingcodeinthenewWordActionsclass(anddon'tforgettoinsertthelineImportsWord=
Microsoft.Office.Interop.Wordatthetopoftheclass).Placeitbetweentheblocks'PublicClassWordActions'and'End
Class'.
PublicSharedFunctionNewWordDoc()
'ProcedureNewWordDoc()
'
'1.checkwhetherWordisrunning
'2.ifso,openanewdocument
'3.ifnot,startwordandopennewdocument
'
'CodetocheckwhetherWordisrunning
'courtesyofCindyMeister,VSTO/WordMVP
DimoWordAsWord.Application
DimoDocAsWord.Document
DimappNameAsString="Word.Application"
DimwdProcesses()AsSystem.Diagnostics.Process=_
System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
'IfWordisrunning,attachoWordtothatinstanceofWord
IfwdProcesses.Length>0Then
oWord=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
'ifWordisnotrunning,startnewinstanceofWord
Else
oWord=NewWord.Application
EndIf
http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

5/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

IfNotoWordIsNothingThen
oWord.Visible=True
oWord.Activate()
EndIf
oWord.Visible=True
'opennewWorddocumentbasedonthebasictemplate
oDoc=oWord.Documents.Add
'Don'tknowwhatitdoesbutbydoingso,I
'avoidawarninginVisualStudioaboutpossibly
'noreturningavalueonallcodepaths
ReturnoWord
oDoc=Nothing
oWord=Nothing
EndFunction

ThiscodecontainstheroutinethatcheckswhetheraninstanceofWordisalreadyrunning.Ifso,itjustcreatesanew
documentandifnot,anewinstanceofWordisstartedandcreatesanewdocument.Thecodeisreadyforuseinourform.

Step5
SwitchbacktothecodeforForm1.Doubleclickthebuttononthisformtogotothecodebehindthebutton.Insertthe
followingline.

ThiscodereferstotheWordActionsclassandtheprocedure(Function)inthatclasscalledNewWordDoc.VisualStudio
insertsthe()automatically.
Now,runtheprogram.Whenclickingthebuttonontheform,anewWorddocumentiscreated.Clickthebuttonagain,and
againanewbuttoniscreated.Withthesimplecommand'NewWordDoc',yourprogramcreatesanewdocumentwhilethe
codetodosoiscentrallyavailableintheWordActionsclass.Powerfulstuff.
Wearegoingtoexpandonthisinthenexttutorial[http://devtome.com/doku.php?id=programming_microsoft_word__07_
_reusing_your_code]byaddingextracodetoinserttextinaWorddocument,allthiswhilekeepingcodecentrallylocatedin
theWordActionsclass.
ComputingAZ|Programming|Software

programming_microsoft_word__06__creating_word_docs_the_right_way.txtLastmodified:2014/08/2016:59by
wekkel
http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

6/7

2/24/2015

programming_microsoft_word__06__creating_word_docs_the_right_wayDevtome

Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShare
Alike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way

7/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

ProgrammingMicrosoftWord07ReusingYourCode
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way],
wetookawaytheproblemofmorethanoneinstanceofWordrunningwhilerunningyourcodeoverandoveragain.The
routinetoavoidthisfromhappeningisfairlycomplexandlong.Inthisnewtutorialwearegoingtobreakupthecodesome
more,sotheblockofcodetoopenanewWorddocumentcanbereusedmultipletimes.
Wearegoingtobuildontopofthe'MyFirstWordApp'fromtutorial5[http://devtome.com/doku.php?
id=programming_microsoft_word__05__from_form_to_word_document_ii]thatwasenhancedintutorial
[http://devtome.com/doku.php?id=programming_microsoft_word__06__creating_word_docs_the_right_way].Ifyoudonothavethis

projectavailable,pleasegothroughtheprevioustwotutorialstocreatethatprogram.

Step1
Openthe'MyFirstWordApp'programasyouleftitintheprevioustutorial:FileOpenProject[chooserelevant.sln
file]

Step2
ThedesignofForm1willremainthesame.

However,wearegoingtochangethecodebehind'Button1'.First,wearegoingtoaddanewclasstoourproject.Inthe
SolutionExplorer,rightclicktheprojectandmovethroughthemenuthatappears:AddClass

http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

1/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

Namethenewclass'Wordactions.vb'.

http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

2/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

Step3
Ifyournewclassisnotshownyetinthecodeeditor,doubleclickthenewWordActionsclassintheSolutionExplorer.First,
insertareferencetoWordInterop.

Second,createaFunctioncalled'NewWordDoc'byinsertingthefollowingcodebetween'PublicClassWordActions'and
'EndClass'.
PublicSharedFunctionNewWordDoc(oWordAsWord.Application)AsWord.Application
'ProcedureNewWordDoc()
'
'1.checkwhetherWordisrunning
'2.ifso,openanewdocument
'3.ifnot,startwordandopennewdocument
'
'CodetocheckwhetherWordisrunning
'courtesyofCindyMeister,VSTO/WordMVP
DimoDocAsWord.Document
DimappNameAsString="Word.Application"
DimwdProcesses()AsSystem.Diagnostics.Process=_
http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

3/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
'IfWordisrunning,attachoWordtothatinstanceofWord
IfwdProcesses.Length>0Then
oWord=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
'ifWordisnotrunning,startnewinstanceofWord
Else
oWord=NewWord.Application
EndIf
IfNotoWordIsNothingThen
oWord.Visible=True
oWord.Activate()
EndIf
oWord.Visible=True
'opennewWorddocumentbasedonthebasictemplate
oDoc=oWord.Documents.Add
'Don'tknowwhatitdoesbutbydoingso,I
'avoidawarninginVisualStudioaboutpossibly
'noreturningavalueonallcodepaths
ReturnoWord
oDoc=Nothing
oWord=Nothing
EndFunction

Thereareacoupleofthingsdifferentinthiscodethaninthecodefromtutorial6.Wewillrunthroughthislaterinthis
tutorialtoshowthedifferences.
Third,insertanotherblockofcodebetween'PublicClassWordActions'and'EndClass'(Isuggestplacingitbelowthe
NewWordDocfunctionjustcreated).

ThisWordActionsclasscontainscodethatwecanreuseoverandoveragaininourproject.Thissavestimeandavoids
unnecessarybugs.Furthermore,updatingcodebecomeseasier.Now,wewilllookatthecodebehind'Button1'.

Step4
DoubleclickontheButton1inForm1inthedesignview.
Now,pleaseupdatethecodebetween'PrivateSubButton1_Click'and'EndSub'toreadlikethis:

http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

4/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

Now,testyourapplicationbyrunningit,placingtextinthetextboxandhittingButton1.

Anditisworkingfine:
Intheparagraphsbelow,wewillrunthroughthisnewcodetogetabetterideahowthecodeworks.

http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

5/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

Reviewingthecodecloser
Let'stakeacloserlookatwhathappenswhentheuserclicksthebutton.Myexplanationisnotverytechnical.Ijusttryto
makesomesenseinwhat'shappeningsoyougetabasicunderstandingofwhatthecodedoes.ItallstartsinForm1.
First,therearetoobjectsdeclared:oWordasWordapplicationandSelasWordselection.Thisisdonebecauseweneed
thosetwoobjectslateroninthecode.
Second,thetextinthetextbox1onourformisplacedinthevariable'iNsert'.Afterthesevariableshavebeendeclared,the
commandNewWordDociscalled.Thereareafewthingshappeninghere.
1.theoWordvariableisredefinedasthe'outcome'or'result'oftheFunction'NewWordDoc'.Becausethisfunctionis
locatedintheclass'Wordactions',itistypedas'WordActions.NewWordDoc'.
2.Theadditionof(oWord)attheendfeedstheoWordobjectcreatedinForm1totheNewWordDocfunctionintheclass
WordActions.
Whenlookingatthecodeforthefunction'NewWordDoc'intheclass'WordActions',youwillnoticethatthefirstline
containsafewparticularelements.
PublicSharedFunctionNewWordDoc(oWordAsWord.Application)AsWord.Application

'Public'and'Shared'meanthatthiscodeisaccessibleandcanbeusedinacertainwayinyourprogram,notonlywithinthe
WordActionsclassitself.TheFunctiondescriptioncontainssomeadditionalinputbetweenthebrackets.Whatwearetelling
thecomputeristhatitshouldexpectaWordApplicationobjecttobefeededintothefunction.Inourcasewefeeditwith
'oWord'createdintheForm1code.
Thecodeafterthebrackets'AsWord.Application'isusedtohavethisfunctionreturnaWordapplicationobject.Wepass
thisbacktotheForm1codewiththe'returnoWord'commandlaterinthe'NewWordDoc'code.Wedothisbecauseweneed
thatoWordobjectinthenextstepsinForm1.TheWorddocumentcreatedwascreatedintheNewWordDocfunction.To
makethisWordobjectinthecontextoftheNewWordDoccodeattachedtotheactualWordapplicationrunningalso
http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

6/7

2/24/2015

programming_microsoft_word__07__reusing_your_codeDevtome

accessibletothecodeinForm1,thefuncitonreturnsthisWordobject(oWord)tothecodeinForm1.Thismaylook
confusing(andthecomputerbeingdumb),butthisisaveryessentialelementtomakethiscodework.Pleaselookatthis
conceptcloselyandtrytounderstandwhatishappening.
AftertheNewWordDocfunctionhascreatedanewWorddocument,thenextlineintheForm1codegivesthecomputerthe
assignmenttoplacethetext,heldinthevariable'iNsert'(astring)intotheWorddocumentjustopened.Letstakeacloser
lookatthiscodeinForm1.
Sel=oWord.Selection

Remember,wedeclaredanobjectbeingaWord.Selection.Now,theselction(Sel)issetequaltotheselectionintheoWord
objectwhichcameoutoftheNewWordDocfunction.Basically,thisisthestartofthenewlycreatedWorddocument.This
enablesthecodetoinserttextatthecursorintheWorddocument.Welookatthisincloserdetailinourreviewofthenext
lineofcode.
WordActions.TypeText(iNsert,Sel)

Again,intheForm1codereferenceismadetoacommandintheWordActionsclass.Thistimethe'TypeText'commandis
called.TheTypeTextcommandiscompletedwithtwoelementsbetweenbrackets.WefeedthiscommandwithiNsert(a
string)andtheselectionintheWorddocument(basicallytheplaceofthecursor).
PublicSharedSubTypeText(ByValtextAsString,ByRefSelAsWord.Selection)
Sel.Text=text
Sel.Start=Sel.End

Again,weseethe'Public'and'Shared'attributestoacommand.Becausethiscommand(alsocalledaprocedure)doesnot
returnanything,itiscalleda'Sub'insteadofa'Function'.TheSub'TypeText'hastwoparametersbetweenthebrackets:1.
'text'asastring(thelineoftextthatwewanttypedinourdocument)and2.'Sel'asawordselection(theplaceofthecursor
intheWorddocument).Subsequently,thecommand'Sel.Text=text'istheactualcommandplacingthetextintheWord
document.Thenextline'Sel.Start=Sel.End'isusedtomakesurethatthecursorintheactualWorddocumentissetjust
afterthelastcharacterourprogramplacedintheworddocument.Thisishandyifwehaveadditionallinesofcodeinserting
additionallinesoftextintheWorddocument.
ThereisaneasierwayoftypingtextintheWorddocumentcreated.InsteadoftherouteviaourWordActions.TypeText
routine.youcouldalsousethefollowingcodetoinserttext.PlacethiscodeintheSub'TypeText'intheWordActionsclass
andseewhetheritworks.
Sel.TypeText(text)

WecouldalsoinsertthiscodeintheForm1codedirectly(change'text'to'iNsert'then),butthatwoulddefeatthepurposeof
showingreusingcodeinthistutorial:)
Thisconcludesthistutorialonreusingcode.Inthenexttutorial,wewillexpandonreusingcodealittlebit.
ComputingAZ|Programming|Software

programming_microsoft_word__07__reusing_your_code.txtLastmodified:2014/08/2016:58bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShare
Alike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

Every15minutes3000satoshi
ClaiminXAPOWallet
motherfaucet.com

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code

7/7

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

ProgrammingMicrosoftWord08PopulatingaWordDocument
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code],youtackledthetopicofreusingcode.Thistopicisnot
overbyalongshot,butyoucoveredsomeground,enoughtothinkaboutstructuringyourcodetobenefitfromreusingcode.Inthistutorial,wemovetotheWord
documentitself.Afterall,thewholeideaofthiscourseistoautomatethecreationofWorddocuments.
ThistutorialcoverstwomethodstoinsertinputprogrammaticallyintoaWorddocumentbyusingbookmarksandbyusingthe'findandreplace'functionofMicrosoft
Word.Youneedtodotwothingsforeachmethod:prepareasuitableWorddocumentandusespecificcodetofillinthatWorddocument.
BecausetwomethodswillbeshownincludingpreparationoftherelatedWorddocuments,thistutorialwillbequitelargecomparedtotheothertutorials.Although
overlappingprevioustutorialsabit,wearegoingtostartfromscratch.

Step1
First,wearegoingtoprepare2Worddocuments.TheWorddocumentswillbepreparedas.dotxdocuments,meaningasa'template'.Wecanbuildthetwotemplates
fromonWorddocument.
StartWordandopenanewWorddocument.TypethefollowingtextintheWorddocument.

Now,replacethetextwith'**'(2instancesinthetext)with'[name]'withoutthequotes.The[name]tagisplaintextandthiscanbehelpfulasIwillshowlateron.
Timetosavethisdocumentasourfirsttemplate(Inamedthedocument'FandR.Template.dotx(FindandReplace)).Savingthedocumentastemplateisshowninthe
picturebelow.
OfficebuttonSaveasSaveastemplate

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

1/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Youcanbuildthe2ndtemplatefromthesamedocument.Wearegoingtoinsertbookmarksatthespotswherethe'[name]'tagsareshown.Selectthetextofthefirst
[name]tagwiththecursorsothatitishighlightedinblue.UndertheWordRibbonunderInsert,thereisabutton'bookmarks'underthe'links'section(seepicture
below).

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

2/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Whenclickingthe'bookmark'button,thebookmarkswindowsthatpopsupshowsablanklistofbookmarks.Justtypethenameofyourfirstbookmark(Isuggest
'Name1')andpressthe'Add'button.Closethebookmarkswindowandselectthe2ndinstanceof'[name]'inyourWorddocument.Again,pressthebookmarkbutton,
typethenameofthe2ndbookmarkandpress'Add'(Isuggest'Name2').Youcouldactuallynamethe2ndinstanceof'[name]'Name1aswell,butthenthe1st
bookmarkyoucreatedwillbedeleted.Thisisparticularbehaviourofbookmarksandyoudonotgetawarning.

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

3/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Nowthatyouhaveinserted2bookmarksintheWorddocument,savethedocumentagainasatemplate,butgiveitthename'Bkm.Template.dotx'.YoucancloseWord
now.

Step2
TimetofireupVisualStudio.IassumeyoualreadyknowyourwayaroundtheVisualStudioInterfacesowecanquicklygothroughthefirststeps.Startanewproject:
FilenewprojectchooseWindowsFormsApplicationgiveitthename'InteropInsertTextinWordDoc'.

Step3
YouhavetoinsertreferencestotheWordobjectmodel(likeyoudidinprevioustutorials).Goto:ProjectAddReferenceclickthe'COM'tabtype'Word'in
thesearchfield.Inmyoccassion,thesearchresultsin,interalia,areferencetotheMicrosoftWord12.0ObjectLibrary.DependingontheOffice/Wordversion
installedonyourPC,theversionnumbermayvary.Selectthislibraryandaddareferencetoitbyclicking'OK'.
Onemorethingtodobeforewestartwithsomerealprogramming.Ontopoftheform1inserttheline'ImportsMicrosoft.Office.Interop'asshowninthepicturebelow.
Youcangettothecodeoftheformbydoubleclickingthegraphicpresentationofform1intheVisualStudioIDE.

Step4
http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

4/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Addthe2Wordtemplatesyoujustcreatedtoyourproject.Todoso,rightclicktheprojectnameandgothroughthemenuthatappears:AddExistingItem.

IntheresultingDialogbox,makesuretoselect'AllFiles(*.*)'inthefilenamefilterdialogbox.Otherwise,yourWordtemplatedocumentswon'tshowasselectable
files.

Goandfindthelocationofthe2Wordtemplatesyoucreatedinstep1.Addthose2filestoyourproject.Youcanseethatthetwofileshavebeenaddedtoyourproject.
Ifyousaveyourproject,youcanactuallyfindthe2filesintheproject'sfilefolder.Theywerecopiedintoyourproject.
Justtoavoidanyproblems,makesuretosetthepropertiesforeachfileto'Copyalways'(seepicture):

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

5/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Step5
BuildForm1soitlooksasshownbelow(1textboxand2buttons).

Ididnotchangethedefaultnamesforthelabels,textboxesandbuttonswhencreatingthesecontrolsontheform.

Step6
Nowforthecoding,thiswillgetalittleintense.Youwillcodetwoproceduresoneforeachbutton.ThefirstprocedurewillinserttextatbookmarksinaWord
documentandthesecondprocedurewillinserttextatnametagsinaWordDocument.
EachprocedurewilluseaseparateproceduretoopenaWordtemplatedocument.Youwillcreatethisprocedureinaseparateclass.TheproceduretoopenthisWord
template(orbettersaid:createanewWorddocumentonthebasisofaWordtemplate)cansubsequentlybeusedbybothmainprocedures.Thestrengthofusinga
Wordtemplateisthatthetemplateitselfisnotopened,butinstead,anewWorddocumentwillbeopened(thattheusercansave,basedonthechosentemplate).
Youwillhavetousethecodefromtheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code],butthenslightly
changed.Youwillhavetocodeoneblockofcodethatopensatemplate.Youcanusethatblockofcodeforbothmainprocedures.
RightclickonyourprojectintheSolutionExplorerandgothroughthemenu:AddClass

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

6/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Nameyourclass'WordActions.vb'andpress'OK'.IntheSolutionExplorer,youwillseeyourWordActionsclassaddedtoyourproject.
DoubleclicktheWordActionsclassintheSolutionexplorertogettothecode.
Ontopofthisclass(abovethestartline'PublicClassWordActions'),addareference:'ImportsMicrosoft.Office.Interop'(seepicturebelow).

Createanewprocedureinthisclassnamed'OpenWordTemplate'(seepicturebelow).

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

7/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Specificallynotethatyouaregoingtofeedthisprocedurewitha'doc'variable,explainingtothiscodewhichWordtemplatetoopen.ThefunctionwillreturnaWord
objectaswell(the'Word.Document')',soyoucancontinuetoworkwiththeWorddocumentjustopenedoncethecodeexecutionreturnstoyourForm1.Thisis
expressedbythefinaladditionattheendoftheFunction'sfirstline:'PublicSharedFunctionAsWord.Document').Wearegoingtolookintothisabitfurther
below.
Enterthefollowingcodebetweenthetwolines'PublicSharedFunctionOpenWordTemplate('and'EndFunction'
'ProcedureOpenWordTemplate()
'
'1.checkwhetherWordisrunning
'2.ifso,createanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'3.ifnot,startwordandthencreateanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'
'======================================
'CodetocheckwhetherWordisrunning
'courtesyofCindyMeister,VSTO/WordMVP
DimoWordAsWord.Application
DimoDocAsWord.Document
DimappNameAsString="Word.Application"
DimwdProcesses()AsSystem.Diagnostics.Process=_
System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
'IfWordisrunning,attachoWordtothatinstanceofWord
IfwdProcesses.Length>0Then
oWord=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
'ifWordisnotrunning,startnewinstanceofWord
Else
oWord=NewWord.Application
EndIf
IfNotoWordIsNothingThen
oWord.Visible=True
oWord.Activate()
EndIf
oWord.Visible=True
'======================================
'opennewWorddocumentbasedonthebasictemplate
oDoc=oWord.Documents.Add(doc)
ReturnoDoc
oDoc=Nothing
oWord=Nothing

Thefirstpartofthiscode(betweenthe'===='characters)dealswithcheckingwhetheraninstanceofMicrosoftWordisalreadyrunning.Wecoveredthiscodeinthe
previoustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__07__reusing_your_code].Thenextpartofthecodesimplytakesthevalueofthe'doc'
variablespecified(thelocationofyourWordtemplatefile)andopensthistemplateasanewWorddocument(thecommand'oDoc=oWord.Documents.Add(doc)').
Notethatthecommand'Add'isusedandnotthecommand'Open'.Thecommand'Open'wouldopentheWordtemplatefileitself,whichisnotthebehaviourweare
lookingfor.
Theline'ReturnoDoc'ispartofthecrypticexplanation.Asstatedabove,thisFunctionisspecifiedto'return'aWord.Document.Whatthismeansisthatthecodein
thisfunctionintheWordActionsclasscreatesanewinstanceofaWorddocument(aWordobject).ThatWordobject(whichincludesthejustopenedWorddocument,
the'Word.Document'object)isreturnedtotheForm1codeduringexecution.

Step7
Nowthatyougottheinternalssetup,itistimetocheckwhetherthoseinternalswork.SwitchbacktothecodeofForm1andinsertthefollowingcode(seepicture
below).
PlacethefollowingcodeinthesubroutineforButton1(doubleclickButton1togettothecodesection):
DimoDocAsWord.Document
'openWordtemplatebasedontheBookmarkTemplate
oDoc=WordActions.OpenWordTemplate("Bkm.Template.dotx")
'codetoinserttextatabookmarkintheopenedWordtemplate
oDoc.Bookmarks("Name1").Range.Text=TextBox1.Text
oDoc.Bookmarks("Name2").Range.Text=TextBox1.Text

Button1isassociatedwithinsertingtextintobookmarks.First,youdefinethevariable'oDoc'asplaceholderfortheWorddocumenttobecreated.Thecommandto
createanewWorddocumentonthebasisoftheBkm.Template.dotxtemplate(thefunctioncalled'OpenWordTemplate')isthefunctionwecreatedintheWordActions
class.Toaccessthisfunction,werefertotheWordActionsclassbeforespecifyingthisfunction.Thenameofourtemplate'Bkm.Template.dotx'isfedintothisfunction
asparameter.
ThecodetoinserttextatthebookmarksintheWordtemplateissimple.Thecommand'oDoc.Bookmarks([name_of_bookmark).Range.Text'takesthetextspecified
(thetextelementofourtextbox1)andplacesitastextintheWorddocumentatthespecifiedbookmark.
ThismakesclearwhyitisimportantthatthefunctiontoopentheWorddocument(onthebasisofthetemplatereturnsthatWorddocumenttoform1.Otherwise,the
codeinform1doesnotnowwhichoDocvariableisspecifiedwhenissuingthecommandtoinserttextinabookmark.
Runthecodeandpressthefirstbutton(inmyexamplenamed'Insert@Bookmark').YourWordtemplateisopenedasanewWorddocument.Youcanopenmore
Worddocumentsbasedonthesametemplatebypressingthebuttonagain.ThetemplateremainsuntouchedinsteadanewWorddocumentisopenedthatausercan
editandsave.
http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

8/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

Asafinalconclusionofthisstep,insertthefollowingcodeforButton2(doubleclickButton2togettothecodesection):
DimoWordAsWord.Application=Nothing
'openWordtemplatebasedontheBookmarkTemplate
oWord=WordActions.OpenWordTemplate2("FandR.Template.dotx",oWord)
'codetoinserttextatabookmarkintheopenedWordtemplate
'Findandreplacetag[name]withinputfromtextbox1
DimFindObjectAsWord.Find=oWord.Application.Selection.Find
WithFindObject
.ClearFormatting()
.Text="[name]"
.Replacement.ClearFormatting()
.Replacement.Text=TextBox1.Text
.Execute(Replace:=Word.WdReplace.wdReplaceAll)
EndWith

Youwillnoticethatnow,oWordisspecifiedasWordApplication.ThisdiffersfromtheprocedureofButton1.ThereasonisthatweneedaWord.Applicationobject
inthisprocedureonForm1forthe'FindandReplace'actions,andnotnecessarilyaWord.Documentobject.Therefore,youneedtocodeanotherfunctioninthe
WordActionsclass.Inthecodeabove,Inamedthisfunction'OpenWordTemplate2'andspecifiedboththenameoftheWordtemplate(FandR.Template.dotx)aswell
astheoWordApplication.
Tomakethisworkproperty,insertanewFunctionintheWordActionsclass:
PublicSharedFunctionOpenWordTemplate2(docAsString,oWordAsWord.Application)AsWord.Application
'ProcedureOpenWordTemplate()
'
'1.checkwhetherWordisrunning
'2.ifso,createanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'3.ifnot,startwordandthencreateanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'
'======================================
'CodetocheckwhetherWordisrunning
'courtesyofCindyMeister,VSTO/WordMVP
DimoDocAsWord.Document
DimappNameAsString="Word.Application"
DimwdProcesses()AsSystem.Diagnostics.Process=_
System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
'IfWordisrunning,attachoWordtothatinstanceofWord
IfwdProcesses.Length>0Then
oWord=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
'ifWordisnotrunning,startnewinstanceofWord
Else
oWord=NewWord.Application
EndIf
IfNotoWordIsNothingThen
oWord.Visible=True
oWord.Activate()
EndIf
oWord.Visible=True
'======================================
'opennewWorddocumentbasedonthebasictemplate
DimpathAsString=Application.StartupPath&"\"
doc=path&doc
oDoc=oWord.Documents.Add(doc)
ReturnoWord
oDoc=Nothing
oWord=Nothing
EndFunction

Thecodeaboveforthenewfunction'OpenWordTemlate2'isalmostsimilartotheoriginalfunction'OpenWordTemplate'.However,thechangesaretheadditionofa
WordApplicationobjectasparametertothefunction('oWordAsWord.Application')andthespecificationthatthefunctionreturnsaWord.Applicationobjectinstead
ofaWord.Documentobject.ThefactthataWord.Documentisreturnedisreflectedbythechangesinthe'return'partofthecode('ReturnoWord').
Thesechangestotheoriginalfunctionareneeded,becauseotherwisetheFindandReplacecodeonForm1(attheButton2code)won'trunproperly.Iamsurethat
cloningthisfunctionisnotbestcodingpractice,butitwilldoforthemoment.
GobacktothecodeattheForm1code(forButton2)andlookatthecodetofindandreplacetext.Thispartofthecodeisshownbelowagain:
'codetoinserttextatabookmarkintheopenedWordtemplate
'Findandreplacetag[name]withinputfromtextbox1
DimFindObjectAsWord.Find=oWord.Application.Selection.Find
WithFindObject
.ClearFormatting()
.Text="[name]"
.Replacement.ClearFormatting()
.Replacement.Text=TextBox1.Text
.Execute(Replace:=Word.WdReplace.wdReplaceAll)
EndWith

http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

9/10

2/24/2015

programming_microsoft_word__08__populating_a_word_documentDevtome

TheFindandReplacecoderequiresanoWordobject.Ournewfunction'OpenWordTemplate2'returnsjustthat:).
Basically,thispartofthecodelooksforthetext[name]andreplacesitwiththetextintextbox1.Nowtryyourprogramandnoticehowclickingbothbuttonsendup
withthesameresult,althoughusingdifferentmethods.Thebookmarksmethodisslightlymorecomplicated,becausetofillouttwospotsintheWorddocumentwith
thesametextstring,you'llneed2separatebookmarks.Thefindandreplacemethodonlyrequiresonetermbetweenbracketstofillout2spots(oralotmoreif
necessary).

Conclusion
Theroadwascomplicatedwithalargetutorial,butyouhavesuccessfullycodedWordtoinserttextinadocumentataspotyoucandesignate.Let'sincreasethispower
inthenexttutorial[http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database]bylinkingyourformtoasimpledatabase.
ComputingAZ|Programming|Software

programming_microsoft_word__08__populating_a_word_document.txtLastmodified:2014/08/2016:56bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0Unported
[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds
http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document

10/10

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

ProgrammingMicrosoftWord09WorkingWithA
Database
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__08__populating_a_word_document],we
coveredthetopicofinsertingtextinaWorddocument.Thetexttobeinsertedwasderivedfromuserinput.
Agreatwaytoleverageyourprogramisaddingadatabase.Theusercanusethedatabasetostoreinformationwhichis
subsequentlyavailableintheprogramforreuse.Thereisthatword'reuse'again.
Addingadatabasesoundscomplicatedbutissurprisinglysimple.Perhapsthemoststrenuouspartofthistutorialiscreating
thedatabaseitself.Inthistutorial,youwilluseaMicrosoftAccessdatabase.ThatmeansyouneedacopyofMicrosoft
Accessinstalledonyourmachine.IfyouhaveneverworkedwithAccess,thiswillbethehardestpart.Don'tworryyouwill
beguidedthroughthesteps.

Step1
Asstatedabove,buildingtheAccessdatabaseisthefirststep.Basically,youwillcreateadatabaseinAccessandsaveitas
anAccessfile.ThisfilecanbeusedasdatabaseintheVB.NETprogramyouwillwrite.Let'sstartmoving.
StartMicrosoftAccesssoyouseethefollowingstartscreen.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

1/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Clickonthebutton'BlankDatabase'andfilloutthenameofthedatabaseontheright.Givethedatabasethename
'DbParties'.Isuggestthatyouplacethedatabasefileonyourdesktopsoyoucanfinditeasilywhenaddingittoyour
program.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

2/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Whendone,clickonthebutton'Create'.

Step2
Nowitstimetofilloutatable.AssumethatyourprogramisgoingtobeusedtoinsertpartydescriptionsinWorddocuments
(likeinagreements).Tokeepitsimple,yourprogramwillusethefollowingdetailsforanindividual:name,placeofbirth,
address,cityandcountry.TimetoinserttheserowsintheAccessdatabasefile.
Accesshasalreadyopened'Table1'withthecursorinanorangefieldnamed'AddNewField'.Youwillhavetoaddnames
toeachcolumnequalthenamesmentionedabove(name,placeofbirth,etc).YoucanignoretheIDcolum,whichAccess
madeautomatically.TheIDcolumnisvitalbecauseitwillgiveeachrowofdataauniquenumberandcountsupward
automatically.
TheeasiestwaytoinsertnewFieldsisbyswitchingtotheDesignview.Rightclickthe'Table1:Table'textattheleftofthe
screenandchoose'DesignView'.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

3/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Inthepopupwindowthatappears,giveTable1thename:'TbIndividuals'

Onthepagethatappears,proceedadding'fields'untilyouhavethefollowingorderofthings:

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

4/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Alsofillinsomesampledatasoyoucanplaywithitdirectlywhenrunningtheprogramlateron.Dothisbyswitchingback
totheearlierview.Thisisonebydoubleclickingthename'TbIndividuals:Table'ontheleftsideofthescreen:

Upontheprompt,clicktheYesbuttontosaveyourtableandproceed.Filloutsomesampledata(seesamplebelow).

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

5/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Step3
Asthenextstep,createanotherTable.Thisisdonebygoingtothe'Create'tabinAccess'ribbonandclickingthe'Table'
button.

Again,switchtothe'DesignView'andnamethenewTable'TbCompanies'.Again,leavetheIDfieldaloneandaddthe
'fields'asshowninthepicturebelow:

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

6/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Switchbacktothepreviousviewbyclickingthetablenameattheleftofyourscreen,click'Yes'tosaveitandfilloutsome
sampledata:

Youcannowsaveyourfile(withthesavebuttonlefttopoftheAccesswindowandcloseAccess.TimetostartupVisual
Basic

Step4
Openanewprojectthrough:FileNewProject.ChooseaWindowsFormApplicationandnameit
'MyFirstFormWithDatabase'.ClickOK.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

7/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

YourForm1isshown.IncreasethesizeoftheformabitandrenametheFormto'DataForm'inthepropertieswindow.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

8/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Beforewemovetothenextstep,weneedavisualtooltodifferentiatebetweenthedetailsIndividualstobeinsertedinour
WorddocumentsandthedetailsofCompanies.Anappropriatetoolisthe'TabControl'.FromtheToolbox,draga
'TabControl'ontotheFormandresizeitasshown.RenametheTabControlto'TcParties'(under'(Name)'intheProperties
window).ThenamesoftheTabPagescanbechangesbyclickingthe''partof'(Collection)'andfillingoutthe'(Name)'
and'Text'propertiesinthewindowthatpopsup.ForTabPage1,choose'TpNP'asNameand'Individuals'asText.Usersof
theformwillseetheText,nottteName.DothesameforTabPage2withthenames'TpRP'and'Companies'andclickOK.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

9/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Runyourprogramandnoticethatyourformcontainsasocalled'container'thatcanholdobjectssuchasbuttonsand
textboxesontheseparatetabpages.Timetopopulatethesetabpageswithobjects,butfirstedittheTabControlbychanging
someofitsparameters.SelecttheTabControlobjectasawhole(notjustthetabpages)andgotothepropertieswindows.
Changethefollowingproperties:1.Anchor:Top,Left,Right2.Dock:Top
Furthermore,selectthetabpage'Individualsandselecttheboxbeneaththistab(sodonotselecttheentiretabcontrol,but
http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

10/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

justtheboxbeneaththetabs.Inthepropertieswindow,changethepropertyBackColorfrom'Transparent'to'ButtonFace'.
Thiscolorcanbeselectedinthe'System'tabwhenchangingtheBackColor.Dothesamewiththetappage'Companies'.
Finally,addtwobuttonstoyourformandplacethemontotheFormbelowyourTabControl.Namethebuttons'btnOK'and
'btnCancel'andgivethemthetext'OK'and'Cancel',respectively.Yourformnowlookslikethis:

Step5
Thenextstepisaddingaconnectiontothedatabase.Addingtextboxestotheformisnotnecessaryatthisstage.Youwill
findoutwhy.
Addanewdatasource(database)toyourproject:ProjectAddnewdatasource.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

11/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Inthenextwindow,choose'Database'andclicknext.

Inthenextwindow,choose'Dataset'andclicknext.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

12/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Inthenextwindow,choosethebutton'NewConnection':afilebrowerwindowpopsup.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

13/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Iassumethe'Data

source:'isalreadysetto'MicrosoftAccessDatabaseFile(OLEDB)'.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

14/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Click'Browse'nexttothebox'Databasefilename:SearchforyourDbPartiesaccessfileonyourdesktop,selectitandclick
'Open'.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

15/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Backtothe'AddConnection'window,youcantesttheconnectiontothedatabasejustaddedbyclickingthe'Test
Connection'button.Ifeverythingisright,apopupwindowtellsyouthatthetestconnectionsucceeded.Click'OK'andinthe
nextwindow'Next'.Awindowpopsup:VisualStudioisaskinguswhethertocopytheaccessfile(thedatabase)intoour
project.Choose'Yes'.Inthenextwindow,choose'Next'.

Inthefinalwindow,choosethedatatouseinyourprogram.Selectthetwotables(seepicture)andclick'Finnish':

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

16/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

OnelastthingtodoafterVScopiedthedatabasefiletoourprogram'sfolder,istosettheproperty'CopytoOutput
Directory'ofthatfile'DbParties.accdb'to'Copyifnewer'.Thisensuresthatthedatabasewhichtheprogramcanchange
whenitruns,isnotdestroyedbythedefaultdatabaseyoucreatedeachtimeyouruntheprogram.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

17/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Step6
Nowthattheconnectiontothedatabaseisready,itistimetopopulateeachtabpageofourform.
Makesurethatthetabpage'Individuals'isselectedintheform.
First,let'splacesometextboxesandlabelsontheTabpage'Individuals'.Youshouldmatchtheresultshowninthepicture
(namethetextboxestxtNPName,txtNPPlaceOfBirth,txtNPAddress,txtNPCity,txtNPCountry).

DothesamefortheTabpage'Companies'(namethetextboxestxtRPName,txtRPSeat,txtRPAddress,txtRPCity,
txtNRCountry).

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

18/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Toconcludethispartofthetutorial,let'swriteaSubthatputsoutthecontentsofthetextboxesinaMessageBox.Putting
thiscontentinaWorddocumenthasbeendealtwithintheprevioustutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__08__populating_a_word_document],whichisnotthescopeofthistutorial.
Clickonthe'OK'buttononyourformandwritethefollowingcode.
SelectCaseTcParties.SelectedTab.Name
CaseTbNP.Name
MsgBox("Name:"&txtNPName.Text&vbCrLf&"PlaceofBirth:"&txtNPPlaceOfBirth.Text&vbCrLf&_
"Address:"&txtNPAddress.Text&vbCrLf&"City:"&txtNPCity.Text&vbCrLf&_
"Country:"&txtNPCountry.Text&vbCrLf,,"ShowData")
CaseTbRP.Name
MsgBox("Name:"&txtRPName.Text&vbCrLf&"Seat:"&txtRPSeat.Text&vbCrLf&_
"Address:"&txtRPAddress.Text&vbCrLf&"City:"&txtRPCity.Text&vbCrLf&_
"Country:"&txtRPCountry.Text&vbCrLf,,"ShowData")
EndSelect

Thecodeshownisverystraightforward.Withthe'SelectCase..EndSelect'code,thecomputerlooksattheTabControl,
checkswhichTabisselectedandsubsequentlyexecutesthecodewrittenforthat'Case'.Thisismoreefficientthanan'If
EndIf'code.AveryelegantcodetomakethedistinctionbetweenthecontentsinbothTabpages.
ThecodeforbothTabPagesisasimplemessageboxcodethatlistsalldatafromtherelevanttextboxesfortherelevantTab
page.Noticethesmalldifferenceinbothcommands,whichreflectsthedifferencebetweenthedatausedforIndividualsand
http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

19/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

thedatausedforCorporations.Furthermore,totopitalloff,thetitleoftheMessageBoxisspecifiedas'ShowData'.Alot
betterthanthestandardtitle(noticethedoublecommainthecodetomakethiswork).
Nowruntheprogram,filloutsometextandhittheOKbutton.AMessageBoxappearsshowingthedata.Dothesamefor
thetabCompaniesandnoticehowwellthecodebehaves.

Atthisstage,thereisonethinglefttodoforthisForm.Increasethesizeoftheformalittlebit,soyoucanaddabuttonat
therightsideoftheform.Addabuttonforeachtabpageontheform.FortheIndividualstab,namethebutton
btnNPLookupwithtext=andfortheCompaniestab,namethebuttonbtnRPLookup,alsowithtext=Theendresultis
shownbelow.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

20/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Thisisourbasissetup.Timetomakesomerealuseofthatdatabaseinsertedearlier.

Step7
YouaregoingtoperformanicetrickinVB.NETcalled'inheritance'.Itavoidsyouhavingtowritecodetwice.Intheend,
thiskeepsyourcodeneatandtidyandeasiertomaintain.Mightaswellstartdoingthisrightfromthestart,alsoinsmaller
codingprojects.Twooftheseformswillbeusedtopassdatatoandretrievedatafromthedatabase.
CreatethreenewWindowsForms(ofequalsize)byrightclickingontheprojectintheSolutionExplorerandchoosing:
AddWindowsForm

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

21/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

First,wewillworkontheBasefmLookup.Placetwobuttonsonthisformwiththenames'btnOK'(text=OK)and
'btnCancel(text=Cancel).DoubleclickontheOKbuttonandinsertthefollowingcode.
Doubleclickonthisformandinsertthefollowingcode.
Me.DialogResult=Windows.Forms.DialogResult.Cancel

DothesamefortheCancelbuttonandinsertthefollowingcode.
Me.DialogResult=DialogResult.OK

Iamgoingtoexplainthiscodelateron.Itisenoughfornowtoknowthatiscodeispartofthesolutiontotransferdataina
Lookupformtothemainform(theformwiththetabscreatedearlier).YourBaseformwilllookasshowinthepicture
below.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

22/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

DoubleclickonthefrmNPLookupintheSolutionExplorer.VisualStudioautomaticallyaddscodeforaform_loadevent
('PrivateSubfrmNPLookup_Load.EndSub').Youcansafelydeletethatcodeagain.Between'PublicClass
frmNPLookup..EndClass',insertthefollowingline.
InheritsBasefmLookup

TheErrorListwillshowanerror.Youcancorrectthisbymovingthemousecursorovertheunderlined'BasefmLookup',
selectingthedropdownmenuandchoosingthefirstsolutionshown(changingtheclasstoinheritfrom
MyFirstFormWithDatabase.BasefmLookp,seepicture).ThisshowsthepowerofIntellisensethatfollowswhatyouare
writinginthecode.Togiveyousomebackground:VisualStudiocannotacceptthesameparametersforourfrmNPLookup
twice(liketheformscolouranditssize).Byinsertingthecode'InheritsBasefmLookup',thisisexactlywhathappenedina
partofthecodehiddenfromourview.VisualStudio'sIntellisensecancorrectthisforuswithoutseeingwhatcodewas
actuallychanged.Don'tworry,ourerrormessageisgone.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

23/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

InsertthesameInheritancestatementinthecodeofthefrmRPLookupform.
YoucanseethevisualinheritanceatworkalreadybylookingatthefrmNPLookuporfrmRPLookupbylookingatthisform
inVisualStudiointheDesignview(doubleclickoneoftheseformsintheSolutionExplorer).YoucanseetheOKand
Cancelbuttonontheform,whichbuttonsare'inherited'fromthebaseform.Resizeyourformifthebuttonsarenotvisible.
Actually,thiscanbefixedbyanchoringthebuttonsonthebaseformtothebottomrightofthebaseform,sothattheynever
popoutofsightoninheritedforms.Let'sfixthatrightawaybyselectingeachbuttononthebaseformandsettingthe
anchoringpropertyto'bottom,right'.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

24/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Runyourprogramtoupdatethecodeofthebaseformandimmediatelyclosetheprogramagain.Whenlookingatthe
lookupformsagainintheDesignview,youwillnownoticethattheOKandcancelbuttonfollowthebottomoftheform
whenresizingit.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

25/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

ThisisthepowerofInheritanceinVB.NET.Createitonce,useitendlessly.Tofinalisethispart,changesthe'text'property
ofbothlookupwindows(notthebaseform,butthetwootherformsthatinheritfromthebaseform)andinsertsensibletitles
fortheforms(Ichose'LookupIndividual'and'LookupCompanies').Thatenhancestheuserexperiencewhenusingthe
program.

Tofinalisethestepsinthispart,gototheForm1anddoubleclickthebtnNPLookup(thebuttonjustcreatedwiththe''
text).

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

26/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Insertthefollowingcodeforthisbutton.
frmNPLookup.ShowDialog()

DothesameforthebuttonbtnRPLookupwiththecode'frmRPLookup.ShowDIalog()'.
The'ShowDialog'partisessential.ItbasicallytellsthecomputerthatForm1willopenanewformbutthatthe'result'ofthat
form(theDialog)mustbereturnedtoForm1.Withoutexplainingittotechnically(Ican't),inessencethedataavailableon
thefrmNPLookupform(orfrmRPLookupform)willremainavailabletoForm1untilthefrmNPLookupisactivelydisposed
ofagainintheForm1code.Thisisaveryeasymannerofpassingcodefromoneformtotheother.Forthepurposeofour
sampleprogramitissufficient.Theexactcodeforthissolutiontopassdatabetweenformswillfollowlater.First,runthe
programandnoticethatalookupformpopsupifyouclickthelookupbutton.Thislookupformisderivedfromthebase
class:Inheritanceatwork!
Inthenextstep,youwillpopulatethelookupformsandconnecttheformwiththedatabase(finally).Toconcludethis
tutorial,youwillfinishthecodetopassdatafromthelookupformstothemainform(form1).

Step8
Bringupthe'DataSources'window.Makethiswindowvisibleby:ViewOtherWindowsDataSources.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

27/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

IntheDataSourceswindow,ourdatasourceisshown.Itisnotactuallyouraccessdatabase,butacopyofthatdatawhichis
broughtintoourprogram:aDataSet.VisualStudiosetsupthecodetoretrieveinfofromandtothatDataSetandthe
exchangeofinfofromandtotheunderlyingAccessfile.Thegoodpartisthatwedonothavetobotherwiththatcode.
VisualStudiowilldoallthework.
ClicktheTbIndividualslineandthedropdownmenu.Wearegoingtochoose'Details'.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

28/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Now,dragtheitem'TbIndividuals'toyourformintothetabpage.Dragithighontheformbecauseafteryouletgoofthe
mousebutton,you'llseethatVisualStudiohasaddedanicesetoflabelsandtextboxesonyourform.Eachitemfromthe
Individualstableinyouraccessfileisshownontheform.Thebestpart:eachofthesetextboxesisconnectedtothe
database.VisualStudioevenaddedamenustriptonavigaterecords(rows)inthedatabase.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

29/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

YoucanremovetheIDlableandcorrespondingtextbox.Wedonotneeditforourprogramandthesoftwarefillsinthis
dataitself(rememberthatinMicrosoftAccess,thisfieldofthedatabasewassettoautonumberingthecomputersortsthis
outitself).
RepeatthisprocessforthefrmRPLookupandruntheprogram.IfoundoutthatIhadtoresizebothlookupformsabitto
showallbuttonsinthedatabasenavigationmenustripinbothforms.
Beforewemovetothefinalpieceofbode(passingdatabetweenforms),weneedtodosomethingimportant.Whentheuser
fillsoutdatafornewIndividuals(usingthemenustripinthelookupformtoaddnewrecordsofIndividuals,insertingdata
inthetextboxes),theuserwillexpectthisdatatobesavedifheclosesthelookupformbyclickingthewellknown'x'
button.Therefore,ontheLookupformforIndividuals,clickthe'save'buttoninthemenustrip.

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

30/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Thecodeshownforthatbuttoniscodeweneedtoapplyalsoiftheuserclosesthelookupformbyclickingthe'x'button.
Cutthiscodeandcreatethefollowsubatthebottomofwiththiscode.
PrivateSubSaveDatabase()
Me.Validate()
Me.TbCompaniesBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.DbPartiesDataSet)
EndSub

Updatethecodeforthesavebuttonwiththefollowingcode

PrivateSubTbCompaniesBindingNavigatorSaveItem_Click(senderAsObject,eAsEventArgs)HandlesTbCompaniesBindingNavi
SaveDatabase()
EndSub

Now,forthelookupformweneedtocallthisSaveDatabasesubagainiftheuserclosestheform.Youcancreateasubfor
thiseventbyusingthedropdownmenu'sonthetopoftheform'scodeinthecodeeditorwindow(seepicturebelow).

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

31/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Updatethecodefortheevent'Deactivate'offrmLookupNPwiththefollowingcode
SaveDatabase()

Now,tothesameforthefrmRPLookupform.
Runyourprogram,clickthebuttontobringupaLookupformandtrytoinsertanewrecordbypressingtheyellow+inthe
menustripandfillingoutthetextboxesforthisnewparty.Closethelookupformbypressingthe'x'andimmediatelyopen
thelookupformagain.Ifeverythingworksalright,therecordyoujustaddedisstillthere(cyclethroughtherecordstofind
yournewlyaddedrecord).Thepartofthedatabaseisdone.

Step9(final)
Asindicatedabove,thefinalstepisfinalisingthecodetopassdatabetweenforms.Theupsideofthe'ShowDialog'element
ofFormsisthattheLookupform,openedbycodeonthemainform(form1),willdisappearfortheuserwhenheclicksOK,
butthatthedataonthatform(e.g.,initstextboxes),isstillavailabletoForm1forprocessing.AftertheForm1codehas
usedthisdatafromtheLookupform,itdisposestheLookupform.Fortheuser,itlookslikeaflawlesspassingofdatafrom
http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

32/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

theLookupformtothemainform.Worksgreat.
Tofinalisethiscode,gotothecodeforForm1.InthecodeforthebuttontoopentheLookupformforIndividuals
(btnNPLookup)andupdatethecodeasfollows.
frmNPLookup.ShowDialog()
IffrmNPLookup.DialogResult=System.Windows.Forms.DialogResult.OKThen
txtNPName.Text=frmNPLookup.NPNameTextBox.Text
txtNPPlaceOfBirth.Text=frmNPLookup.NPPlaceOfBirthTextBox.Text
txtNPAddress.Text=frmNPLookup.NPAddressTextBox.Text
txtNPCity.Text=frmNPLookup.NPCityTextBox.Text
txtNPCountry.Text=frmNPLookup.NPCountryTextBox.Text
'thefollowinglineisexecutediftheDialogresultis'Cancel'j.Basicallythe
'programistoldtodonothing
ElseIffrmNPLookup.DialogResult=System.Windows.Forms.DialogResult.CancelThen
'Donothing
EndIf
'wenolongerneedthedataofthedatabaseformsowedisposethedataofthedatabaseform
frmNPLookup.Dispose()

DothesameforthebuttonbtnRPLookuponForm1,butwiththefollowingcode.
frmRPLookup.ShowDialog()
IffrmRPLookup.DialogResult=System.Windows.Forms.DialogResult.OKThen
txtRPName.Text=frmRPLookup.RPNameTextBox.Text
txtRPSeat.Text=frmRPLookup.RPSeatTextBox.Text
txtRPAddress.Text=frmRPLookup.RPAddressTextBox.Text
txtRPCity.Text=frmRPLookup.RPCityTextBox.Text
txtRPCountry.Text=frmRPLookup.RPCountryTextBox.Text
'thefollowinglineisexecutediftheDialogresultis'Cancel'j.Basicallythe
'programistoldtodonothing
ElseIffrmRPLookup.DialogResult=System.Windows.Forms.DialogResult.CancelThen
'Donothing
EndIf
'wenolongerneedthedataofthedatabaseformsowedisposethedataofthedatabaseform
frmRPLookup.Dispose()

Again,inessenceForm1opensaLookupformandwaitsuntiltheLookupformreturnswiththeresultofthe'ShowDialog'
element.Theresultiseither'Cancel'or'OK'.Subsequently,thecodeinForm1doessomethingwiththatresult.Uponthe
result'Cancel',Form1doesnothing.Upontheresult'OK',thecodeonForm1reachesouttotheLookupformandmore
preciselythecontentsofthetextboxesontheLookupform.Afterthecontentsofthesetextboxesiscopiedintothetextboxes
ofForm1,theLookupformisnolongerrequiredanddisposedof.
Runyourprogramandtestitthoroughly.AddnewanddeleterecordstothedatabaseforIndividualsandCompanies,bring
databackfromtheLookupformtotheMainformandshowthedatainthemainforminaMessagebox.

Conclusion
Youhavenowmasteredacoupleofthings:
connectingadatabasetoyourprogramandmanipulatingthecontentsthereof
workingwithtabs
passingdatabetweenforms
usinginheritancetowritesleekcode
That'sagreatresult.
http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

33/34

2/24/2015

programming_microsoft_word__09__working_with_a_databaseDevtome

Wewillexpandonthisprograminthenexttutorial[http://devtome.com/doku.php?id=programming_microsoft_word__10_
_working_with_a_collection_part_1]byenhancingourForm1.Form1willinserttheinputtextinaWorddocumentandyou
willaddaclasstocollectmultiple'parties'inalist,whichlistcanbeusedtooutputthedetailsofmultiplepartiestothe
Worddocument.Again,powerfulstuff.
ComputingAZ|Programming|Software

programming_microsoft_word__09__working_with_a_database.txtLastmodified:2014/08/2016:54bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShare
Alike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database

34/34

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

ProgrammingMicrosoftWord10WorkingWithA
Collection(Part1)
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__09__working_with_a_database],we
coveredthetopicofincludeadatabaseinyourproject.Agreatwaytoleveragework.Theuser(ofyourprogram)
Onedrawbackofthatprogramistheinabilitytoprocessmultiplesetsofdata.Onceonesetofinformation(thedetailsofan
individualorcompany)hasbeenloaded,theprogramcanonlyputoutthissetofinformation.Abitofahassleifyouruser
wantstoprocessmorepartiestoinsertinaWorddocument.
Inthistutorial,wearegoingtoexpandontheprogrammadeintheprevioustutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__09__working_with_a_database].Becauseofthelength,thetutorialisdividedovertwoparts.
Thisfirstpartconsistsofbuildingtheinfrastructureintheprogramtohandlethedetailsofmultiple'parties'.
Inthesecondpart,theprogramwillbetestedwithshowingdatatobeprocessedthroughmessageboxes.Oncethisworks,
theuseofmessageboxesischangedtoinsertingthedataintoaWorddocument.Thegoalistoaddversatilitytothe
program,soitcanaddthedetailsofonepartytoaWorddocument(e.g.,acontract)butalsomultipleparties.Thisisgoing
tobealongtutorial,sopleasemakesomecoffeeandstretchyourfingers

Step1
Beforedivinginthecode,Iwillgiveadescriptionofthegeneralconcepthere.Thefirstpartofthecodingisprettycryptic
andcanbethoughtounderstand.Itishelpfultounderstandwhatwearetryingtodoheresoyoudonotlosesightofthebig
picture.Youmayrememberthattheprogrambuildsofartakesdatafromthemainform(Form1)fromtheuserorfroma
databaseinyourproject.Thisdatacomprisesofthedetailsofoneparty(anindividualoracompany)andiscontainedin
textboxesonthemainform.Theoutputisgeneratedbytakingthecontentsofthesetextboxesandshowingthemina
messagebox.Youaregoingtochangethis.
Dataofeachpartywillnotbestoredintextboxesonthemainformanymore,butinaseparatecontainer(a'Class').The
detailsofeachpartythatneedstobepartoftheprogram'soutput(inthefirstpartofthistutorial:showinginfoonthescreen
throughamessagebox),willbestoredasaClass(a'party'class).Subsequently,eachclass(holdingtheinformationofone
partyeitheranindividualoracompany)willbestoredinonesinglecollection,holdingtheinformationofeachpartythat
theuserwantstooutput.Thiscollectionwillserveasoneblockofinformationthatwillbetheoutputoftheprogram.
Takingthisstepinthecodewillgreatlyadvanceyouroptionstoaddadditionalfeaturesfortheuser,suchassortingor
deletingdatainthecollectionbeforegoingtotheoutputstage.Classesareincrediblypowerfulin.NET.Let'sgetstarted
withthispart.
StartVisualBasicandopentheprojectmadeintheprevioustutorial(inmycasenamed'MyFirstFormWithDatabase'):File
OpenProject.Alternatively,ifyouwanttosavetheoriginalprogrammadeintheprevioustutorial,youcanworkina
newcopyoftheprogram.InWindowsExplorerfindthefolderMyFirstFormWithDatabaseintheVisualStudioProjects
folder.Thisfoldershouldbelocatedin(Win8)C:\Users\[yourusername]\Documents\VisualStudio2013\Projects\.Copy
thefolderwiththeprogram,pastethefolderatthesamelocationandrenamethenewfolder
MyFirstFormWithDatabase02.NowopentheprojectinthenewfolderinVisualStudio.
Addaclassnamed'Party'byrightclickingtheprojectnameintheSolutionExplorer:AddClass

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

1/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

2/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

Betweenthelines'PublicClassPartyEndClass',enterthefollowingcode:
PublicClassPartyCompany
PublicPropertyNameAsString
PublicPropertySeatAsString
PublicPropertyAddressAsString
PublicPropertyCityAsString
PublicPropertyCountryAsString
EndClass
PublicClassPartyIndividual
PublicPropertyNameAsString
PublicPropertyPlaceOfBirthAsString
PublicPropertyAddressAsString
PublicPropertyCityAsString
PublicPropertyCountryAsString
EndClass

That'sit:youcreatedaclass'Party'thatholdstwo(sub)classes.Looksverysimple,isn'tit?Lateron,wearegoingtoexpand
thisclassbutfornowtheclassissufficienttoholdalldataweneed.Pleasenotethetwoseparate(sub)classesonefor
IndividualsandoneforCompanies.

Step2
Nextstepisaddingthecollectionclass.Thecollectionclasswillbeusedtostoreeachinstanceofaparty.Innormalwords
thecollectionwillholdoneormulitpleboxes,eachcalleda'party',andeachboxcalled'party'willholdthedetailsofthat
party.Allofthisisarrangedneatlyinyourcode,usingthepartyclasswrittenaboveandthecollectionclassyouaregoingto
coderightnow.
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

3/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

Addaclassnamed'PartiesCollection'byrightclickingtheprojectnameintheSolutionExplorer:AddClass

Between'PublicClassPartijCollection..EndClass',insertthecodeshownbelow.Ihavecutthiscodeinpiecestogivea
littlebackground.Thecodereflectsisacustomcollectionclass.TheprogramwouldalsofunctionusingastandardVisual
BasicCollectionclass,butcustomizingthatcodelateronwouldbedifficult.Isuggesttouseacustomcollectionrightfrom
thestart.
PrivatecolAsCollection=NewCollection

WhenthecodecallsthePartyCollectionClass,thisclasswillcallanewCollectionclass.Thenextlinesmakethiscollection
('col')performthebasicstuff.
PublicSubRemove(ByValindexAsInteger)
col.Remove(index)
EndSub

Afewlinesofcodetoremoveanitemfromthecollection('col').Pleasenotethatthiscodetakesinthe'index'asinput.The
'index'willbeanumber.InVisualBasic,acollectionisnumberedasof1upwards.
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

4/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

PublicFunctionContains(ByValitemAsString)AsBoolean
Returncol.Contains(item)
EndFunction

CodetolookwhethertheCollectioncontainsanitem.Thiscodeisnotusedinourprogram,butaddedasastandard
regardlessbecauseitbelongstothebasicsofacollection.Pleasenotethattheinputisnotanumberoftheindex,butastring
(apieceoftext).
PublicFunctionCount()AsInteger
Returncol.Count
EndFunction

CodetocountthenumberofitemsintheCollection.Mandatorytobuildcodetocyclethroughacollectionasyouwillsee
lateron.
PublicFunctionItem(ByValindexAsInteger)
Returncol.Item(index)
EndFunction

Codetoreturnanitemfromthecollection(inthiscasea'party')byprovidinganindexnumberofthecollection.

PublicSubAdd(ByValpartyAsObject,OptionalByValbeforeAsInteger=1,OptionalByValafterAsInteger=1)
Ifbefore=1Andafter=1Then
col.Add(party)
ElseIfbefore=1Then
col.Add(party,,after)
ElseIfafter=1Then
col.Add(party,before)
EndIf
EndSub

Thiscodecouldhavebeenverysimple.Theminimumrequiredwouldbeaddinganobject'party'(aninstanceofour'party'
class)withthecommand'col.Add(partij)'.Thiscodeismoreelaborate.Normally,thecommand'Add()'insertstheobjectto
beinsertedasnewitemattheveryendofthecollection.Remember,VisualBasiccountsallelementsofacollectionfrom1
upwards.Inordertoprovidesortingoptionsorinthistutorialoptionstorearrangethelistofitemsheldinthecollections,
additionalcodeisneeded.Thecollectiondoesnotknowacommandtomoveanelementinthecollection:doingthis
requiresamixofdeletingandreinsertingitemsagain.Insteadofbuildingthislogicinthemainform,webuilditinthe
PartiesCollectionclass.Don'tworryaboutthisnow,justinsertthecode.
PublicFunctionGetData(ByValindexAsInteger)AsObject
DimpartyAsObject=Item(index)
Returnparty
EndFunction

Finally,apieceofcodetogetanitemfromthecollection(inthiscasea'party')byprovidinganindexnumberofthe
collection.Notethatthisfunctionisquitesimilartothefunction'Item()'mentionedabove.Thedifferenceisthatthefunction
GetData()returnstheitem'party'asanObject.
ThisisthecodeforthePartiesCollectionClassfornow.Timetoputbothclassescreated(PartyandPartiesCollection)to
work.

Step3
Themainformneedssomework.Addalistbox(named'lstParties')totheFormfromtheToolbox.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

5/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

Furthermore,addtwosmallbuttons(named'btnAdd'withtext'Add'andnamed'btnRemove'withtext'Remove')(see
picturebelow).ResizeForm1andmovebuttonsifnecessary.Theendresultshouldlooklikethis.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

6/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

Step4
Gotothemainform'scode(Form1)(ifnecessary,doubleclickoneofthebuttonsinForm1inthedesignviewtogettothe
codeview).Justunder'PublicClassForm1',insertthefollowinglineofcode:
PublicMyPartiesCollectionAsNewPartiesCollection

Thisisanimportantpieceofcode.TheprogramtakesthePartiesCollectionclassandcreatesanewinstanceofitinthe
Form1'scode.RememberthatthePartiesCollectionclasscreatesanew'collection'(named'col'inthatclass)?Thecodein
Form1cannowworkwithdatainthisnewlycreatedcollection.Itcandoallthatwithouthavingtowriteextensivecodethe
basicsareallintheclassesyouwrotealready
TheMyPartiesCollection(again,aninstanceofthePartiesCollectionclass)willdrivethedatainourForm1.Thiscollection
isinvisibletotheuser.Itispossibletoaddandremoveitemstothiscollectionwhiletheuserhasnoideawhatisgoingon
andwhatiscollectedinthatcollection.Toavoidthis,thedatainthiscollectionwillbeshowntotheuserinthelistbox.
Let'saddcodefortheAddandRemovebutton.First,theAddbutton.
SelectCaseTcParties.SelectedTab.Name
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

7/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

CaseTbNP.Name
'object"partijvullenmetdata
DimpartyAsNewParty.PartyIndividual
party.Name=txtNPName.Text
party.PlaceOfBirth=txtNPPlaceOfBirth.Text
party.Address=txtNPAddress.Text
party.City=txtNPCity.Text
party.Country=txtNPCountry.Text
Ifparty.NameIsNot""Then
'VisualBasicGenericCollectionvullen
MyPartiesCollection.Add(party)
'textboxenclearenzodatuserbegrijptdathetisingevoerd
txtNPName.Text=Nothing
txtNPPlaceOfBirth.Text=Nothing
txtNPAddress.Text=Nothing
txtNPCity.Text=Nothing
txtNPCountry.Text=Nothing
'listboxupdatenmetallepartijnamen
AddPartiesToListBox(MyPartiesCollection)
Else
MsgBox("Pleasefilloutanameofthispartybefore"&_
"addingittothelist")
party=Nothing
EndIf
CaseTbRP.Name
'object"partijvullenmetdata
DimpartyAsNewParty.PartyCompany
party.Name=txtRPName.Text
party.Seat=txtRPSeat.Text
party.Address=txtRPAddress.Text
party.City=txtRPCity.Text
party.Country=txtRPCountry.Text
Ifparty.NameIsNot""Then
'VisualBasicGenericCollectionvullen
MyPartiesCollection.Add(party)
'textboxenclearenzodatuserbegrijptdathetisingevoerd
txtRPName.Text=Nothing
txtRPSeat.Text=Nothing
txtRPAddress.Text=Nothing
txtRPCity.Text=Nothing
txtRPCountry.Text=Nothing
'listboxupdatenmetallepartijnamen
AddPartiesToListBox(MyPartiesCollection)
Else
MsgBox("Pleasefilloutanameofthispartybefore"&_
"addingittothelist")
party=Nothing
EndIf
EndSelect

Youwillnoticethatthewholecodeblockisenclosedbythe'SelectEndSelect'routine.Thisroutineisusedtoruna
specificblockofcodedependingonwhichtabisselectedintheform(IndividualsorCompanies).Let'sruntosucha
specificblockofcodetoseewhat'shappening.
IncasethetabforIndividualsischosen,first'party'isdeclaredasaPartyclassofthesubtype'PartyIndividual'.Thisobject
'party'iscreatedinordertoputitawayinthecollection(theMyPartiesCollectionwhichwasdeclaredatthetopofthemain
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

8/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

form).Butfirst,the'party'object(let'scallitthepartyclass)mustbefilledwithdata.Thisdataistakenfromthetextboxes
onthemainform.BecauseweknowtheIndividualstabisselectedonthemainform,thedatafromthetextboxesonthat
tabpageareinsertedintherelevantelementsofthepartyclass(name,address,etc).
Afterthepartyclasshasbeenloadedupwiththedatafromthetextboxes,thecodeperformsanadditionalcheck.Wewant
thepartytohaveaname.Ifthepartyclasselement'Name'isempty(IsNot),thecodewillnotaddthepartyclasstothe
collectionbutshowamessageboxwithawarning.Iftheparty.nameelementdoeshavecontents,thecodecallsthe'Add'
procedurethatispartoftheMyPartiesCollectionclassandaddsthepartyclasstothecollection.Next,thecodeclearsthe
textboxessotheusergetsavisualconfirmationthattheinformationinthetextboxeswasprocessed.
Finally,thecodecallstheprocedure'AddPartiesToLIstBox'withtheMyPartiesCollectionasinput.Ignoretheerrormessage
fornow:thisprocedureindeeddoesnotexistyet.Youwillinsertthisprocedureinthecodeofthemainform.Addthe
followingproceduretothemainform(between'PublicClassForm1.EndClass').
PrivateSubAddPartiesToListBox(ByRefpartiescollectionAsPartiesCollection)
DimiAsInteger=1
DimpartynameAsString
DimpartyAsObject
lstParties.Items.Clear()
Fori=iTopartiescollection.Count
party=partiescollection.Item(i)
partyname=party.Name
lstParties.Items.Add(partyname)

Nexti
EndSub

Let'sanalysethiscode.
TheMyPartiesCollectionisfedintotheprocedure.'i'isdefinedasanintegertobeusedtoiteratethroughallelementsofthis
collection.The'partyname'variableisusedtoholdapartynameandpartywillholdinstancesofourpartyclass.Nowthe
executionpart.First,thelistboxontheformisfullycleared.Next,thecodecyclestothefirstrecordinthecollection(with
index1)totheendoftherecords(thefinalnumberisprovidedbythe'Count'procedure,partoftheMyPartiesCollection
class).Foreachrecord,theprogramtakesthepartyclassfromthecollectionassociatedwiththatindexnumberandlooksup
the'Name'elementforthatpartyclass.Subsequently,thatnameisaddedtothelistbox.
Asanalternative,wecouldalsocodeaFunctionintheoriginalPartiesCollectionclassfiletoretrievethe'Name'elementof
apartybygivingtheindexnumberofthecollection.Thebenefitwouldbemoreelegantcode.Nowthatwespeakofthis
let'senhanceourcodeinthismanner.
FirstamendthesubprocedureAddPartiesToListBoxasfollows.
PrivateSubAddPartiesToListBox(ByRefpartiescollectionAsPartiesCollection)
DimiAsInteger=1
DimpartynameAsString
lstParties.Items.Clear()
Fori=iTopartiescollection.Count
partyname=partiescollection.ReturnPartyName(i)
lstParties.Items.Add(partyname)

Nexti
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

9/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

EndSub

Ignoretheerrormessagefor'ReturnPartyName(i)'fornow.Noticehowthecodebecomesleaner.Wedonotneedthe'party'
variableanymore,andthecodedoassignapartyclasstothisvariable.Instead,thepartynamevariableisfilledbyaFunction
thatwillbeaddedtothePartiesColllectionclass.
InthePartiesCollectionclass,addthefollowingFunction:
PublicFunctionReturnPartyName(ByValindexAsInteger)AsString
DimpartyAsObject=Item(index)
DimpartynameAsString
partyname=party.Name
Returnpartyname
EndFunction

Thisfunctiontakesanintegerasinput,beingtheindexnumberofthecollection.Withthecommand'Item',thecode
retrievesthepartyclassthatisheldinthecollectionthatisstoredwiththatindexnumber.Subsequently,thevariable
partynameisfilledwithdatafromtheelement'Name'inthepartyclassretrieved,andreturnedastheoutputofthefunction.
Rememberthatthisworksbecausebothtypesof'party'classeshaveanelementcalled'Name'.Thiscodedoesnotcheck
whichtypeofpartyclassiscalledsopleasebeawarethatthismaybeapotentialplaceforbugs.IfthePartyclassischanged
sothatoneormoreofthesubpartyclasses(PartyIndividualorPartyCompany)nolongerasa'Name'element,thecodewill
startthrowingerrors.Butfornow,thisworks.
Runthecodeandnoticethatitfuntionsasintended.
FinallyinthisstepaddcodefortheRemovebuttoninthemainform(Form1).Doubleclickontheremovebuttoninthe
mainformtogettothecodeandinsertthefollowingcode.
DimiAsInteger
Try
i=lstParties.SelectedIndex+1
MyPartiesCollection.Remove(i)
AddPartiesToListBox(MyPartiesCollection)
CatchexAsException
MsgBox("Pleaseselectanameinthelistboxtoremove")
EndTry

Thecodetoremoveanentryfromthelistboxcontainsa'TryEndTry'block.Thisisdonetoensurethatthecodeonly
callsthe'Remove'functinfromtheMyPartiesCollectionclassifitdoesnotreturnanerror.Anerrorcouldeasilyoccurifthe
userhasnotselectedaniteminthelistboxforremovalbeforepressingtheremovebutton.Ifnothingisselectedwhenthe
userclickstheremovebutton,amessageboxshowswithawarning.Ifsomethingisselected,thecoderetrievestheinteger
'i'touseasindexnumberforthe'Remove'functionoftheMyPartiesCollection.ItemsinalistboxinVisualBasicstartsat
number0whereasacollectioninVisualBasicstartswithnumber1.Therefore,theindexnumber'i'isincreasedwith1.
Subsequently,the'remove'functionoftheMyPartiesCollectionclassiscalledandfinallythelistboxisupdatedwiththe
AddPartiesToListBoxcommand.
Now,runthecode.Addafewpartiestothecollection.Makeuseofthedatainthedatabasetodothis.Thisdatacanbe
accessedbybringingupthelookupforms(button'').Thepartiesaddedwillshowupbytheirnamesinthelistbox.Now,
selectoneofthenamesinthelistbox:thenamewillberemovedfromthelistbox.Moreimportant,thepartyasawholeis
alsoremovedfromthecollection.Itisnolongerthere.Ifnonameisselectedwhenclickingtheremovebutton,theprogram
warnswithamessageboxthatnopartywasselected.
Timetowrapthispartofthecodeupwithbuttonstoshiftapartyupordowninthelistbox(andthecollectionthatishidden
fromview).
Addabutton'Up'(btnUp)and'Down'(btnDown)tothemainform(Form1).Rearrangethe'Add'and'Remove'buttonif
necessary.ThefourbuttonscanbealignedbytheinbuiltaligntoolsofVisualStudio.Toensurethattheverticaldistance
betweenthefourbuttonsisequal,selectallfourbuttonsanduse:FormatVerticalSpacingMakeEqual.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

10/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

Clickthenewlycreated'Up'buttonandinsertthefollowingcode.
DimiAsInteger
DimobjAsObject
i=lstParties.SelectedIndex+1
Ifi=1Then
MsgBox("Itemisalreadyontop!")
ElseIfi>1Then
obj=MyPartiesCollection.Item(i)
MyPartiesCollection.Remove(i)
MyPartiesCollection.Add(obj,,(i1))
AddPartiesToListBox(MyPartiesCollection)
EndIf

Let'sanalysewhatthiscodedoes.
ThecodeneedsavariableiasIntegertoworkwiththecollection(bymeansoftheindexnumberoftherowsinthe
collection).The'obj'Objectisusedtoworkwitha'party'fromofthecollection.'i'issetastheindexnumberofthelistbox
(withthecommand'SelectedIndex').Thisnumberisincreasedwith1becauseaVisualBasiclistboxcountsfrom0upwards
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

11/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

whereasaVisualBasiccollectioncountsfrom1upwards.
Theprogramdetermineswhichiteminthelistboxisselected(byindexnumber).Thisnumberisincreasedwith1tomatch
theindexofthecollection.Let'staketheexamplethattheseconditemwasselectedinthelistbox(thus1inthelistboxindex
and2inthecollectionindex).Thecodetestswhetheri=1.Ifso,theitemselected(indexinthecollectionwouldbe1)is
alreadyontopandawarningshows.Else,ifiislargerthan1,thepartyassociatedwiththeindexnumberofthecollectionis
retrievedandassignedto'obj'.Intheexample,2islargerthan1soindeedthepartylocatedatindexno2inthecollectionis
assignedto'obj'.Next,thisitemisremovedfromthecollection.Asaconsequence,thecollection'sindexnumberingisreset
from1upwards.Thethirditeminthecollection(withindex3inthecollection)isrenumberedto2andifthereismore
behindindex3inthecollection,allthosenumbersshift1down.Asfinalstepforthecollection,thesameitemisadded
again(the'obj'whichisessentiallyacopyoftheitemwithindex2thatwasremovedfromthecollection),butthisitemis
nowinsertedattheindexnumberonestepabovetheoriginalindexnumber.Therefore,theitemisinsertedagaininthe
collectionatindexno1insteadof2.Thereasonforthismethodeofmovinganiteminacollectionisthatthecollection
classdoesnothaveanativecommandtomoveitems.Thecodeshownisthewaytodothis.Abitclumsy,butitworks.At
theveryend,thelistboxisupdatedagaintoshowthenewlineupofitemsinthecollection(throughtheelement'Name'of
eachpartyclassinthecollection).
Nowthatyouunderstandwhatishappening,addthefollowingcodefortheDownbutton.
DimiAsInteger
DimobjAsObject
DimcountAsInteger=MyPartiesCollection.Count
i=lstParties.SelectedIndex+1
Ifi=countThen
MsgBox("Itemisalreadyatthebottom!")
ElseIfi<countAndi>0Then
obj=MyPartiesCollection.Item(i)
MyPartiesCollection.Add(obj,,(i+2))
MyPartiesCollection.Remove(i)
AddPartiesToListBox(MyPartiesCollection)
EndIf

ThiscodeisquitesimilartothecodefortheUpbutton,butwithsomedifferences.Thecodefirstcheckswhethertheindex
selected(again,theindexnumber'i'isincreasedwith1toaccountforthedifferentmannerofnumberingofaVBcollection)
isthelastindexnumberinthecollection.Itdoessobycomparingtheindexnumberwiththetotalcountofthecollection
(countingallitemsinthecollection).Iftheindexnumberisindeedequaltothecount,amessageboxshowswithawarning
thattheitemisalreadyatthebottom.Iftheindexnumberisnotthelastnumber,theprogramcopiesthe'party'classinthe
collectionlocatedatthatindexnumber,insertsthesameparty('obj')intheindexbuttwoplacesfurtherthantheoriginal
indexnumberandthenremovesthatpartyfromthecollectionattheindexnumberchosen.Thiscanbeclarifiedwithan
example.
Let'staketheexamplethatthereare3itemsinthelistboxandthatindexnumber2ofthecollectionwasselectedbytheuser.
Thepartylocatedatindexno2inthecollectioniscopiedandthenreinsertedintheexistingcollectionatindexno4.The
nextstepistoremovethe(same)partyfromthecollectionatindexno2.VisualBasicautomaticallyrefreshesthenumberof
thecollectionandrecountstheindexfrom1to3.Voila,thepartyatindexno3isnowatindexno2andthenewlyinserted
(same)partyatindex4isnowatindexno3.Finally,thelistboxisupdatedagaintoshowthenewlineupofitemsinthe
collection(throughtheelement'Name'ofeachpartyclassinthecollection).Fortheuser,itlooksliketheitematno2
shiftedto3andtheitematindexno3shiftedtoindexno2.Infact,thathappenedbutwithaparticularmethod.
ThisishowVBcollectionsworkwhenmovingitemsupanddown.
Whenrunningthecode,youwillnoticethatwhenanitemismovedupordowntheselectionofthatiteminthelistboxis
lost.Thisisbehaviourthatannoysyouruser.ItLet'scorrectthisbyaddingcodetotheproceduresforupanddownsothat
thecodeendswithselectingthemovediteminthelistbox.FortheUpbutton,insertthefollowingcoderightabovethe'End
If'statement.
lstParties.SelectedIndex=i2

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

12/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_1Devtome

andfortheDownbutton,insertthefollowingcoderightabovethe'EndIf'statement
lstParties.SelectedIndex=i

Byinsertingthiscode,theuserdoesnotlosetheselectionchoseninthelistboxwhenmovinganitem.Theitemcannotbe
unselected,butthatisnotaproblemwiththisprogram.

Conclusion
Youhavebuilteverythingtoworkwithmultipleparties.Inthenexttutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__10__working_with_a_collection_part_2],youwillwritethecodetoinsertallthatdataina
Worddocument.
ComputingAZ|Programming|Software

programming_microsoft_word__10__working_with_a_collection_part_1.txtLastmodified:2014/09/0516:54by
wekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShare
Alike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1

13/13

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

ProgrammingMicrosoftWord10WorkingWithA
Collection(Part2)
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_1],
youfinishedaprogramthatcouldtakeindata(ofanIndividualorCompany,savethatdatain(ortakedatafrom)a
MicrosoftAccessdatabaseandcollectthedetailsofvariouspartiesinacollection.Doingso,yourprogramusedclasses,
includingacustomVisualBasiccollectionclass.
Inthispart2ofthetutorial,itstimeformthefinalstep:gettingthatdatawrittenoutinaMicrosoftWorddocument.Inorder
todothat,youwillusecodefromthisearliertutorial[http://devtome.com/doku.php?id=programming_microsoft_word__08_
_populating_a_word_document].Foryourconvenience,thestepsareshownagainbelow.Thiscodeneedsinputtowriteinthe
WordDocument.Thatinputresidesinthecollectionclassasyoumayrememberfromtheprevioustutorial.Wearegoingto
showyouhowtogetallthatdatafromthecollectionandinsertitinaWorddocument.
Let'sgetstarted.

Step1
First,webuildasimpleWordtemplateandaddcodetoopenthattemplateandinserttext.StartMicrosoftWord(this
tutorialusesWord2007).

Openanewdocument:OfficebuttonNew(nextwindow)Create

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

1/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

2/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Typethefollowingtext.Youcancreateyourowntextbutmakesurethatyouinsertthemarkedtextwithbrackets[]in
thetextasshown.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

3/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

SavethedocumentasaWordTemplate:OfficebuttonSaveAsWordTemplatenamethefile
'Devcoin.Contract.dotx'andSaveonthedesktop(easiertofindinthenextsteps)

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

4/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

ClosetheWordtemplate.

Step2
StartVisualBasicandopentheprogramfromtheprevioustutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__10__working_with_a_collection_part_1](MyFirstFormWithDatabase).Youaregoingto
expandonthisprogram.
First,addtheWordtemplatejustcreatedtotheproject.IntheSolutionExplorer,rightclicktheprogram'snameandselect
inthemenu:

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

5/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Inthefilemenu,makesurethatyousetthefilefilterto'Allfiles'.Gotoyourdesktopandselectthefile
Devcoin.Contract.dotx'.Click'Add'andthefileisaddedtotheproject.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

6/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

IntheSolutionExplorer,selectthefileandgotothePropertieswindow.Makesurethattheproperty'CopytoOutput
Directory'issetto'Copyifnewer'or'Copyalways'.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

7/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Thetemplateisreadyforuse.Let'saddthebasiccodeforopeningWordandinsertingtext.

Step3
AddanewclasstotheprojectbyrightclickingtheSolutionExplorerandusingthemenu:AddClass.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

8/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Namethenewclass'WordActions'andclick'Add'

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

9/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

TheWordActionsclassopensincodeview.Addalineontopoftheclass:
ImportsMicrosoft.Office.Interop

AlsoaddareferencetotheWordobjectmodel.Inthetopmenu:ProjectAddReference

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

10/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Inthenextwindow,searchfor'word'asindicated,selecttheWordlibraryandclickOK(youmusthaveWordorOffice
installedforthistowork).

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

11/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

ThiswillsetupyourprogramtointeractwithWord.

Step4
NextstepswillbetocreatecodethatwillopenaWorddocument.Inanearliertutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__06__creating_word_docs_the_right_way],codewassuggestedtoproperlyopenaWord
document.Thiscodecausedsomeissuesinasubsequenttutorial[http://devtome.com/doku.php?
id=programming_microsoft_word__08__populating_a_word_document],inwhichaquickanddirtysolutionwasused(basically,
usingcodetwicewithsmallvariations).Let'sdothisbetterinthistutorial.
Foragoodunderstanding,recallthattheprogrammostlyinteractswithMicrosoftWordthroughelementsofthe
Word.ApplicationobjectandtheWord.Documentobject.Ideally,wewanttohavebothobjectsavailable(andattachedtoa
runninginstanceofWord)sothecodecaneitheraddresstheWord.DocumentobjectortheWord.Applicationobject
whateverisneededforthespecificcodethere.
Asabasicprinciple,codeshouldbewritteninsuchmannerthateachblockofcodeperformsataskfullywithoutrequiring
othercodetocontainbitsandpiecesofthattasktomakeitwork.Otherwise,codewillbedifficulttoreuseandunderstand.
ThepreviouslyroutineusedtoopenaWorddocumentcausesanissue.Thecodecontainsafunction(called
'OpenWordTemplate'inthosetutorials)thatonlyreturnsoneobject.Inthetutorialsusedthishadtobeeitherthe
Word.DocumentobjectortheWord.Applicationobject.ThecodetoinserttextinaWordbookmarkrequireda
Word.Documentobjecttoworkwith,andthecodetoreplacetext(FindandReplace)inadocumentneededa
Word.Applicationobject.Intheearliertutorial,thiswassolvedbyusingtwoversionsoftheOpenWordTemplatefunction
(onereturningaWord.DocumentobjectandtheotherreturningaWord.Application).Thisisbadpractice,becauseheapsof
codearewrittentwice.
Let'savoidthisproblembyenhancingthecodetoopentheWorddocument.Youwillbuildafunctionthatdoeswhatit
needstodo:openaWorddocumentonthebasisoftheWordtemplateinourproject.Butatthesametime,thefunctionwill
return2objects:aWord.DocumentobjectandaWord.Application.Thisenablesyoutobringthoseobjectsintothemain
codeblockthatcontainsorcallstheentiresetofinstructionstoopenaWorddocumentandpopulateit.Itwillbecomeclear
whenwritingthecode.
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

12/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

First,youneedtocreateasocalled'Structure'.Astructureisaneasymethodtobuildanobjectthatcanholdvarioustypes
ofdataorobjects.IntheWordActionsclass,insertthefollowingcode(placeitjustbelowthe'PublicClassWordActions'
line):
PublicStructurewrdObjects
DimwordDocAsWord.Document
DimwordAppAsWord.Application
EndStructure

Lookingatthecode,thecollectionofobjectswillbenamed'wrdObjects'anditselementsare'wordDoc'and'wordApp'as
Word.DocumentandWord.Applicationobjects,respectively.
TheFunctiontoopenaWorddocumentwillusethisstructuretostoreboththeWord.Applicationobjectand
Word.Documentobjectusedinthatfunction.Let'sbuildthefunctionandanalyzeit.Insertthefollowingcodebelowthe
codefortheStructureyoujustinsertedintheWordActionsclass.
PublicSharedFunctionOpenWordTemplate(docAsString)AswrdObjects
DimmyWordObjectsAsNewwrdObjects
'ProcedureOpenWordTemplate()
'
'1.checkwhetherWordisrunning
'2.ifso,createanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'3.ifnot,startwordandthencreateanewdocumentbasedonthesupplieddocvariable(aWordtemplate)
'
'======================================
'CodetocheckwhetherWordisrunning
'courtesyofCindyMeister,VSTO/WordMVP
DimoWordAsWord.Application
DimoDocAsWord.Document
DimappNameAsString="Word.Application"
DimwdProcesses()AsSystem.Diagnostics.Process=_
System.Diagnostics.Process.GetProcessesByName("winword")
DimwdprocessAsSystem.Diagnostics.Process
ForEachwdprocessInwdProcesses
System.Diagnostics.Debug.Print(wdprocess.MainWindowTitle)
System.Diagnostics.Debug.Print(wdprocess.StartInfo.Arguments.Length.ToString())
Next
'IfWordisrunning,attachoWordtothatinstanceofWord
IfwdProcesses.Length>0Then
oWord=System.Runtime.InteropServices.Marshal.GetActiveObject(appName)
'ifWordisnotrunning,startnewinstanceofWord
Else
oWord=NewWord.Application
EndIf
IfNotoWordIsNothingThen
oWord.Visible=True
oWord.Activate()
EndIf
oWord.Visible=True
'======================================
'opennewWorddocumentbasedonthebasictemplate
DimpathAsString=Application.StartupPath&"\"
doc=path&doc
oDoc=oWord.Documents.Add(doc)
myWordObjects.wordApp=oWord
myWordObjects.wordDoc=oDoc
ReturnmyWordObjects
oDoc=Nothing
oWord=Nothing
EndFunction
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

13/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Below,weanalyzepartsofthiscode.
Lookingatthecode,thefirstlineisalreadyinterestingtonote.Lookatthefollowingcode:
PublicSharedFunctionOpenWordTemplate(docAsString)AswrdObjects

ThistellsusthattheFunction'OpenWordTemplate'willtakea'doc'asstring.The'doc'isthenameofthetemplatetobe
openedasanewWorddocument.Second,theFunctionalsostatesthatitwillreturn'wrdObjects'.Thisisthestructurejust
created.ThismeansthattheFunctionwillreturntheobject'Structure'whichwillholdourwordDocandwordAppobjects.
Let'slookatthenextinterestingblockofcode:
DimmyWordObjectsAsNewwrdObjects

myWordObjectsisdeclaredasanewinstanceofthewrdObjectsstructurejustcreated.Thismakesthestructureavailablefor
useinthisfunction.
'opennewWorddocumentbasedonthebasictemplate
DimpathAsString=Application.StartupPath&"\"
doc=path&doc
oDoc=oWord.Documents.Add(doc)
</pre>

Toensurethattheprogramknowswheretofindthetemplatetobeopened,codeisaddedtoretrievethelocationofth
Nowtothecorechangestothisfunction:
<pre>
myWordObjects.wordApp=oWord
myWordObjects.wordDoc=oDoc
ReturnmyWordObjects

Asstatedabove,themyWordObjectsobjectisaninstanceofthestructurewrdObjects.First,thestructureisloadedwiththe
objectsoWordandoDoc.Next,thestructureis'returned',meaningthatthestructure'myWordObjects'(includingits
elementsjustloaded)ispassedbythefunctiontothecodethatcallsthefunction.Nextstepiscallingthisfunctionfromthe
mainform.
DoubleclickontheForm1.vbfileintheSolutionExplorer.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

14/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Thedesignviewofthisformisshown.
Doubleclickonthe'OK'button:youarebroughttothecodeofthisbutton.Deletethecodebetween'PrivateSub
btnOK_Click(sender..EndSub'.
Insertthefollowingblockofcode:
DimmyWordObjectsAsWordActions.wrdObjects
myWordObjects=WordActions.OpenWordTemplate("Devcoin.Contract.dotx")
DimoWordAsWord.Application=myWordObjects.wordApp
DimoDocAsWord.Document=myWordObjects.wordDoc

Nowtesttheprogrambyrunningitandpressingthe'OK'button.WordopensadocumentonthebasisoftheDevcoin
contracttemplate.NotethatthecodefirstcreatesaninstanceofthewrdObjectsstructure,thenproceedstocallthe
OpenWordTemplatefunctionandsubsequentlydeclaresobjectsoWordandoDocandloadsthemwiththeobjectswordApp
andwordDocthatthefunctionOpenWordTemplatereturned.TheoWordandoDocobjectsarenowreadyforuseintherest
ofthecodeforthisbutton.
Beforefinalisingthiscode,theprogramneedssomeadditionalfunctionality.Let'scodethatinthenextstep.

Step5
YourprogramwillinserttextintheWorddocumentopenedwhenclickingthe'OK'button(theDevtomecontract).Thiscan
bedonebytakingthedataintheMyPartiesCollectionclass(residingintheForm1code)andcyclingthroughthiswitha
loop.However,theprogramneedstowriteoutthepartydetailsfortheDevtomecontract(theWorddocument).Essentially,
theprogrammusttakethedatafromeachpartyclass,storedintheMyPartiesCollectionclass,andbuildapropersentence
first.Subsequently,thissentencecanbewrittenintheDevtomecontract.OpenthecodeofthePartyClassbydouble
clickingon'Party.vb'intheSolutionExplorer.

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

15/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Insertthefollowingcodebelowthe'PublicClassPartyIndividualEndClass'
SharedFunctionReturnPartyline(ByRefpartyAsObject)AsString
DimpartystringAsString=Nothing
DimpartycompAsPartyCompany
DimpartyindAsPartyIndividual
SelectCaseTypeName(party)

Case"PartyCompany"
partycomp=party
partystring=partycomp.Name&",acompanywithcorporateseatin"&partycomp.Seat&",havingits
partycomp.Address&","&partycomp.City&","&partycomp.Country
Case"PartyIndividual"
partyind=party
partystring=partyind.Name&",bornin"&partyind.PlaceOfBirth&",havingitsplaceofbusinessa
partyind.Address&","&partyind.City&","&partyind.Country
EndSelect
Returnpartystring
EndFunction

Thisfunctiontakesa'party'asinput(holdingallrelevantdataofaparty)andreturnsasentenceasastring.Itismerely
writingoutasentence,fillingblankswithinformationcontainedintheelementsofthe'party'object.Thisroutineusesa
'SelectCase'statementtomakeadistinctionbetweena'party'holdingdataofaCompanyanda'party'holdingdataofan
Individual.An'If..EndIf'statementwouldworkaswell,butislessefficient(theSelectCasestatementgoesdirectlytothe
appropriatecaseinsteadoftestingthemall).
NextinlineiscodingafunctionthatinsertsthesentenceintheWorddocument.Aproperplaceforthisfunctionisthe
WordActionsclass.DoubleclicktheWordActions.vbfileintheSolutionExplorerandinsertthefollowingcodeasnew
function.
PublicSharedSubInsertParties(ByValcollectionAsPartiesCollection,ByRefowordAsWord.Application)
DimpartylineAsString=Nothing
DimiAsInteger
DimobjAsObject
DimcountAsInteger=collection.Count
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

16/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

DimSelAsWord.Selection=oword.Selection
Fori=1Tocount
obj=collection.Item(i)
partyline=Party.ReturnPartyline(obj)
Ifi=1Then

DimFindObjectAsWord.Find=oword.Application.Selection.Find
WithFindObject
.ClearFormatting()
.Text="[parties]"
.Replacement.ClearFormatting()
.Replacement.Text=partyline
.Execute(Replace:=Word.WdReplace.wdReplaceAll)
EndWith
DimrngAsWord.Range=oword.ActiveDocument.Range
rng.Find.ClearFormatting()
Ifrng.Find.Execute(partyline)Then
DimdirectionAsObject=Word.WdCollapseDirection.wdCollapseEnd
rng.Select()
rng.Collapse(direction)
rng.Select()
Ifcount=1Then
TypeText(".",Sel)
ElseIfcount>1Then
TypeText(";"&vbCrLf,Sel)
EndIf
Else
'donothing
EndIf
ElseIfi>1Andi<countThen
TypeText(partyline&";"&vbCrLf,Sel)
ElseIfi=countThen
TypeText(partyline&".",Sel)
EndIf
Nexti
EndSub

Below,alsoinsertthefollowingcodeasanewSub:
PublicSharedSubTypeText(ByValtextAsString,ByRefSelAsWord.Selection)
Sel.Text=text
'thenextlineplacesthecursorattheendoftheinsertedtext
Sel.Start=Sel.End
EndSub

Youhaveprobablynoticethattherearenowthreeseparateblocksofcode(2functionsand1sub)toinsertdatafromthe
'party'objectintotheWorddocument.Inthelongerrun,thismakesyourcodereusableandbettertomanage.Let'sanalyze
theselatesttwoblocksofcodesomefurther,startingwiththeInsertPartiesfunction.
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

17/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

PublicSharedSubInsertParties(ByValcollectionAsPartiesCollection,ByRefowordAsWord.Application)

Thefunction'sheadlineindicatesthatthefunctionstakesinacollectionfromthePartiesCollection.Remember,this
collectionholdsall'parties'thatwereaddedtothiscollection(bothCompaniesasIndividualsdependingonwhattheuser
chose).Furthermore,anexistingWord.Applicationisfedintothefunction'byreference'.Thisenablesthefunctiontowork
withtheWordinstancethatwascreatedwhenopeningtheWorddocument.Youhavenotseencodeyetthatactuallyopens
theappropriateWorddocument.Don'tworry,thatwillfollow.
DimpartylineAsString=Nothing
DimiAsInteger
DimobjAsObject
DimcountAsInteger=collection.Count
DimSelAsWord.Selection=oword.Selection

Nextareacoupleofvariables.Noticethe'count'andthe'Sel'variable.Essentially,thecodeneedstotakethe'collection'
objectfedintothefunction,cyclethrougheachelementofthatcollection(eacha'party'object),returnasentencebasedon
eachparty'sdetailsandplacethatsentenceintheWorddocument.
Thecyclepartofthecodeisshownbelowinpieces.
Fori=1Tocount
obj=collection.Item(i)
partyline=Party.ReturnPartyline(obj)

Thecycleisstartedwiththefamiliar'for..to'routine.Youdonothavetoadjustthe'count'here,becauseacollectionin
VisualBasicstartsat1.Next,the'party'objectthatbelongstothecountnumberisretrievedfromthecollectionwith
'collection.Item(i)'.Thisisafunctionthatispartofthecollectionclass.Second,thefunction'ReturnPartyLine'isinvoked,
feedingitwiththeobjectjustretrieved(aparty).Thesentencetobeinsertedisthusassignedto'partyline'asastring.
Allverycompactcodebecausethecodeiselsewhere.
Movingonwithanalyzingthecode.
Ifi=1Then

DimFindObjectAsWord.Find=oword.Application.Selection.Find
WithFindObject
.ClearFormatting()
.Text="[parties]"
.Replacement.ClearFormatting()
.Replacement.Text=partyline
.Execute(Replace:=Word.WdReplace.wdReplaceAll)
EndWith

Thefirstpartyisinsertedinthedocumentatthetag[parties](intheprocessreplacingthistaginthedocument).Thisisdone
bythefind..replaceroutine.Noticethatthecodemustfirstmeetthetestthatcount=1sothatindeeditconcernsthefirst
partytobeinserted.Note:thefind..replaceroutinerequiresaWord.Applicationobject.That'swhythe'oword'As
Word.Applicationisfedintothefunction.
Movingon.ThecodehasnowinsertedthedetailsofthefirstpartyintheWorddocument.Thecodemustnowinvestigate
whethertherewillbeasecondpartyinsertedintheWorddocument(remember,thecodecyclesthroughall'parties'
containedinthecollection.Thefollowingcodedoesexactlyso.
DimrngAsWord.Range=oword.ActiveDocument.Range
rng.Find.ClearFormatting()
Ifrng.Find.Execute(partyline)Then
DimdirectionAsObject=Word.WdCollapseDirection.wdCollapseEnd
http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

18/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

rng.Select()
rng.Collapse(direction)
rng.Select()
Ifcount=1Then
TypeText(".",Sel)
ElseIfcount>1Then
TypeText(";"&vbCrLf,Sel)
EndIf
Else
'donothing
EndIf

ThecodefirstsetsthecursorintheWorddocumentattheveryendofthefirstpartydetailsjustwritteninthedocument.
Thisisnecessarybecausethefind..replaceroutinedoesnotleavethecursorattheendofthetextjustinserted(thecursor
willremainatthedefaultpositionwhenopeningtheWordDocument,beingtheverybeginningoftheWorddocument).
Forthis,arangeobjectisneededandsomecodetomakeitwork.Essentially,thecodelooksforthepartydetailsjust
inserted,selectsit,collapsestheselectiontotheveryend(afterthelastwordofthepartydetailsjustinserted)andplacesthe
cursorthere.
Subsequently,thecodetestswhethertherewillbeonlyonepartyinserted(countis1then)ormore.Incaseofoneparty,the
codeinsertsadotafterthepartydetailsjustinserted.Incaseofmoreparties,thecodeinsertsasemicolumnandgivean
enter,readytoinsertthenextpartydetails.
Therestofthecodedealswithinsertingthesecondandpossiblylaterparties.
ElseIfi>1Andi<countThen
TypeText(partyline&";"&vbCrLf,Sel)
ElseIfi=countThen
TypeText(partyline&".",Sel)
EndIf
Nexti

Thereare2tests:whether'i'intheloopismorethanonebutnotthelastnumberorwhether'i'isthelastitem.Incaseofthe
former,thepartydetailsareinsertedwithasemicolumn,followedbyaenter.Incaseofthelatter,thepartydetailsare
insertedfollowedbyadot.
Thecodetoinserttextonthesetwooccasionsistheregular'typetext'command,availableaspartoftheWordobjectmodel.
Thiscommandrequiresa'selection',alsoaregularelementoftheWordobjectmodel.The'TypeText'subbelowdealswith
this.
PublicSharedSubTypeText(ByValtextAsString,ByRefSelAsWord.Selection)
Sel.Text=text
'thenextlineplacesthecursorattheendoftheinsertedtext
Sel.Start=Sel.End
EndSub

Thesubtakesinatextasstringandaselection(intheWorddocument).ThesubplacesthetextstringintheWord
documentattheplaceoftheselection.
Thisconcludestheanalysisofthecode.Onefinalstep:actuallyissuingthepropercommandinthemainformtosetthis
wholebarrageofcodeintomotion!

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

19/20

2/24/2015

programming_microsoft_word__10__working_with_a_collection_part_2Devtome

Step6
Doubleclickon'Form1.vb'intheSolutionExplorer.InthedesignviewofForm1,doubleclickthe'OK'button.Thecode
forthe'OK'buttononForm1willbeshown.
Insertthefollowingcodebetween'PrivateSubbtnOK_Click.EndSub':
DimmyWordObjectsAsWordActions.wrdObjects
myWordObjects=WordActions.OpenWordTemplate("Devcoin.Contract.dotx")
DimoWordAsWord.Application=myWordObjects.wordApp
DimoDocAsWord.Document=myWordObjects.wordDoc
'codetoinserttextatabookmarkintheopenedWordtemplate
'Findandreplacetag[name]withinputfromtextbox1
WordActions.InsertParties(MyPartiesCollection,oWord)

First,anewWorddocumentisopenedonthebasisofourWordtemplate.Aspartofthatprocess,theobjects
Word.ApplicationandWord.DocumentarebroughtintothecodeonForm1(containedinastructurecalled
'myWordObjects').Next,theseobjectsareattachedtovariables'oWord'and'oDoc'.Thismakesthecodereadytoworkwith
aWorddocument.
Thefinalstepissettingtherestofallcodeinmotion.Onesinglelineissufficienttostartandfinisheverything.That's
propercoding.Thecommand'InsertParties'doesjustwhatthenamesays:insertingallrelevantdataintheWord
document.

Conclusion
Inthistutorial,youhavebuildcodetoinsertpartiesinaWorddocument.Thecodeisflexibleitcanhandleinsertingone
partyoracountlessnumberofparties.Thecodeisspreadlogicallyovertheprojectsoitiseasilymaintainableandreusable.
Greatwork!
Inthenexttutorial,youaregoingtoenhancetheoperationofthedatabasesomefurtherandassisttheuserwithselectingthe
rightdatatobeinsertedintheWorddocument.
ComputingAZ|Programming|Software

programming_microsoft_word__10__working_with_a_collection_part_2.txtLastmodified:2014/09/0516:52by
wekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShare
Alike3.0Unported[http://creativecommons.org/licenses/bysa/3.0/]

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2

20/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

#1BITCOINCASINO.
Premiumslots,roulettesandcardgames.Playnow!btccasino.io
AdsbyCoinURL

ProgrammingMicrosoftWord11EnhancingtheUser
Experience(autocomplete)
Whatarewegoingtodointhistutorial?
Intheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__10__working_with_a_collection_part_2],you
enhancedaprogramtowriteoutinputfromtheprogram(detailsofpartiestoacontract)inaMicrosoftWorddocument.Nowthat
theprogramcanworkwithdataincludingoutputthereof,it'stimetoenhancetheuserexperience.
Therearetwoitemsthatcanuseanupgrade.Firstitemisthelookupformforaccessingthedatabase(intheprogram,therearetwo
lookupformsoneforIndividualsandoneforCompanies).Scanningthroughthedatarecordsonebyoneisnotveryhandy.The
usercoulduseadatagridviewinthisforminwhichdatacanbesortedandsearched.Mucheasieriftherearehundredsofrecords
available.
Seconditemisthemainform.Wouldn'titbeeasyfortheusertoinsertanautosearchfunction?Whentheusertypesanameofan
IndividualorCompanyinthenamebox,theprogramcouldautosearchthedatabasealreadyandpresentoptionsinadropdown
list.Userswouldloveit.
Let'sgettoworkwiththefirstitemonthewishlist.

Step1
Opentheprojectyouworkedonintheprevioustutorial[http://devtome.com/doku.php?id=programming_microsoft_word__10_
_working_with_a_collection_part_2]anddoubleclickthe'frmNPLookup.vb'fileintheSolutionExplorer.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

1/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Resizetheformto812,700(seepicturebelow)andmakethetextboxesabitlarger(thepictureshows700,600changethisto
812,700):

Dothesamewiththe'BasefmLookup'form(resizeitto812,700).DoingsowillensurethatthebuttonsonthefrmNPLookup
formthatarederivedfromthisbaseformwillbevisibleafterresizingthefrmNPLookupform.
SwitchbacktothedesignviewoftheNPLookupform.Now,makesurethattheToolboxisvisibleattheleftsideoftheVisual
StudioIDE.Lookforthe'DataGridView',clickandholditanddragitontothelookupformjustbelowthetextboxes.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

2/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

ApopupmenuappearswithsomesettingsfortheDataGridView.

Deselectallboxesshown(unlessyouhavewishthattheusercanusethestatedfunctionality).Nextstepistochoosethedata
sourcebymeansofthismenu.Pulldownthedropdownmenuandselect'TbIndividualsBindingSource'.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

3/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Next,editthecolumnsbyclickingtherelevantlinkinthesamepopupwindow.

YoucandeletetheIDcolumnbecausethisdataisnotinterestingforouruser.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

4/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Inrespectoftheothercolumns,youwanttoshowyourusersanormalnameforeachcolumnwithoutthe'NP'prefix.Changethe
nameofeachcolumnbyselectingeachColumninthismenuandchangingthenameproperty.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

5/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Finally,selecttheDataGridViewboxonthelookupformandchangeitsnamefrom'DataGridView1'to'DataGridViewNP'inthe
Propertieswindow.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

6/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

RuntheprogramandlookupthedetailsofanIndividual.Thelookupformpopsupwiththenewlook,includingaDataGridView
window.Playaroundwithitandaddanotherpartybytypingnewdatainthetextboxes,addingittothedatabasewiththe'+'button
above.Noticethatyoucansortthedatagridviewalphabeticallybyclickingaheaderandthatyoucanselectdatainthedatagrid
view.Anyselectionchosenisautomaticallyalsoshowninthetextboxes.
Onemorethingtoaddhere.

Step2
Uponloadingthelookupform,theuserispresentedwiththedatagridviewasanunsortedlistofdata.Let'saidtheuserandhave
thedatainthefirstcolumn(Name)automaticallysortedwhentheuserloadsthelookupform.
Yourprogramisgoingtodothisbyinsertingcodethatisexecutedwhenthelookupformisloaded.Clickthelookupforminthe
designview(butnotabutton,textboxorotheritemontheform.Ifdonecorrect,VisualStudiobringsyoutothecodeforthe
form'sLoadevent.Thereisalreadyalineofcodethere,basicallyloadingthedatafromthedatabaseintotheprogram.
Addanewlineofcodebelowtheexistingcode(butbeforethe'EndSub'):
DataGridViewNP.Sort(DataGridViewNP.Columns(0),ListSortDirection.Ascending)

Thisleadstoanerrormessage.Theerrormessagecanberemovedbyinsertingattheverytopofthecode(before'PublicClass
frmNPLookup'):
ImportsSystem.ComponentModel

That'sit.RuntheprogramandnoticethatwhenbringingupthelookupformforIndividuals,thedataintheNamecolumnofthe
datagridviewisneatlyalphabeticallysorted.
RepeatallstepsforthelookupformforCompaniesbutchosethedatasourceforCompanies,notIndividuals,andnamethe
DataGridView'DataGridViewRP'

Step3
YouhaveupgradedtheLookupformconsiderably.Theusercanlookupspecificdatafromthedatagridview,whichis
automaticallysortedalphabeticallybyname.Butanevenbetterenhancementispossible.
Theprogramhasalldatafromthedatabaseavailable.Theuserwouldbeverythrilledifyourprogramactuallyunderstandsthatthe
userisinsertingdetailsofapartythatitalreadycontainedinthedatabase.WhatIambasicallysuggestingisanautosuggestmode
forthe'name'textboxonthemainform(form1).Iftheusertypesaname,theprogramcouldlookintotheavailabledataandcheck
whetherthatnameexistsinthedatabase.Ifso,theprogramcouldsuggesttheparty'snametotheuserand,upontheuserselecting
thissuggestedname,retrieveallofthatparty'sdetailsanddirectlyfillouttheremainingtextboxesonform1.Thissavesyouruser
thestepsofopeningthelookupformandfindingtherelevantparty.
Youaregoingtoprogramthisfunctionalityonform1.Inessence,yourcodewillenablethefollowinglogic.Thecodeonform1
willhaveaccesstotheinformationfromthedatabase,whichdatabaseisalreadylinkedtotheprogram.Fromthisinformation,
onlythe'Names'areretrievedandputintoalist.ThislistisusedtopopulateanAutocompletefeatureoftextboxes.Onceanitem
fromtheautocompletelistisselected,theprogramwilllookuptheotherelementsbelongingtothatname(likeaddress,city,etc)
andpopulatestheothertextboxes.
Let'sgetstarted.
DoubleclickontheForm1.vbfileintheSolutionExplorer.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

7/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Inthetabpage'Individuals',selectthetextbox(txtNPName).ScrolldowninthePropertieswindowandsetAutoCompleteModeto
'Suggest'andAutoCompleteSourceto'CustomSource'.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

8/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Thedatatofillthesourcefor'AutoCompleteSource'willbetakenfromthedatabasealreadylinkedtotheprogram.IntheToolbox,
scrollupwardsandfindthedatacomponent'TbIndividualsTableAdapter'.ThiselementisintheToolboxbecausetheprogramuses
thisfortheIndividualslookupform.Clickanddragthiselementontotheform.Theelementwillappearatthebottomoftheform
(witha'1'addedtoitsname).

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

9/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Fromthisdatasource,theprogramwillbuildalistofnames.Thecodeisasfollows:
PrivateSubForm1_Load(senderAsObject,eAsEventArgs)HandlesMe.Load
UpdateDataTable()
EndSub

UponloadingtheForm1,thecodecallstheprocedure'UpdateDataTable()'.Thismakesthedataavailableforuseforthe
AutoCompletefeature.
Insertcodefortheprocedure'UpdateDataTable()'asfollows:
PrivateSubUpdateDataTable()
DimdtAsDataTable=TbIndividualsTableAdapter1.GetData
ForEachdrAsDataRowIndt.Rows
txtNPName.AutoCompleteCustomSource.Add(dr("NPName").ToString())
Next
EndSub

Analysisofthecode:thecodedefinesadatatablethatisimmediatelyfilledwithalldataviatheTbIndividualsTableAdapter1.This
adapterhasanextension'GetData'thatreturnsalldata.Ifyouwanttoseewherethisextensioncomesfrom,doubleclickon
'DbPartiesDataSet'intheSolutionExplorer.IntheTbIndividualsblockthatappears,youcanseethe'GetData'element(as
http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

10/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

'Fill,GetData()).Basically,thisisacommandtolookintotheattacheddatabaseandreturncertainelementsofthedatabase.Note
thatyoudeliberatelyasktoreturnalldataofthedatabase(names,addressesetc)andnotjustthenames.Itwillbecomeclearlater
onwhy.

Backtotheanalysis.Nowthatthereisdatatable'dt'filledwithdata,thesubsequent'ForNext'looptakeseachrowinthe
datatableandsearchesforthecolumn'NPName'inthatrow.TheresultofthatsearchisaddedtotheAutoCompletesource.Inthe
end,theAutoCompletesourcehasalistofallnamescontainedinthedatatable.Ifyouruntheprogram,theautocompletefunction
shouldalreadybeworking.

Step4
Ok,yougotAutocompleteworking.Butasindicatedabove,thisfeaturewillonlybeverypowerfulifuponselectingoneofthe
suggestednamestheprogramautomaticallyfillsouttheremainingtextboxesonform1withtheappropriatedata.Beforedelving
intothecode,youneedtobuildacustommessagebox.Itispossiblethattherearemultiplepartiesinthedatawiththesamename.
Whentheuserselectsanamethatcouldbelongtomultipleparties,wewanttheprogramtopopupamessagebox,showingall
relevantpartieswithalldetails(address,cityetc).Thisenablestheusertoselectthecorrectpartyandgetonwiththeprogram.
Becauseyouneedthemessageboxtwice(alsofortheCompaniespartoftheprogram),itmakessensetostartwitha'baseform'.
ThebaseformcanservetobuildboththemessageboxforIndividualsandthemessageboxforCompanies.
Addaformtotheprojectwiththename'BaseMessageBox'.Addtwobuttonstotheform('btnCancel'and'btnOK')(seepicture).

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

11/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

SelecttheOKbutton.InthePropertieswindow,setthe'DialogResult'propertyto'OK'(fortheCancelbutton,thispropertywillbe
'Cancel').Alternatively,youcansetthebuttons'behaviourwhenusingthisformasaDialog(moreonthislater)programmatically.
Inthatcase,leavethebuttons'propertiesaloneandinsertthefollowingcodeforbothbuttons:
PrivateSubbtnCancel_Click(senderAsObject,eAsEventArgs)HandlesbtnCancel.Click
Me.DialogResult=DialogResult.Cancel
EndSub
PrivateSubbtnOK_Click(senderAsObject,eAsEventArgs)HandlesbntOK.Click
Me.DialogResult=DialogResult.OK
EndSub

Dialogresultisafunctionthatcanbeusedtoretrievetheresultthattheuserchoosewhenclickingabuttononaform.This
functioncomesintoplaywhenaformisnotshownwiththe'Show'command,butwith'ShowDialog'.Basically,thecodesees
whichbuttontheuserchoseontheformthatwasshowninthe'ShowDialog'commandandreturnsthisforuseinthemaincode
fromwhichtheshowdialogformwasused.Thedataonthisshowdialogformremainsavailableforthemainformuntilthe
showdialogformisdisposedof.Theuserdoesnotnoticeanythingfromthis.Afterclickingabuttonontheshowdialogform,this
formdissappearsandhegoesbacktothemainform.Theoperationofashowdialogformiscalledamodalformnootherform
canbeaccesseduntilthemodalformisclosed.Itisaneasymethodofgettinguserinputandpassingthistoanotherform.Let's
proceed.
Selectbothbuttonsontheformandmakesurethatthe'Anchor'inthePropertieswindowissetto'Bottom,Right'.
Thebasemessageboxformneedssomethingelse.Insertthefollowingcodejustbelow'PublicClassBaseMessageBox'
ProtectedfndrowsAsObject
ProtectedcntAsInteger

ThiscodeiswritteninthebasemessageboxbecauseboththemessageboxforIndividualsandthemessageboxforCompanieswill
usethesevariables.Goodcodingpracticerequirescodetobewrittenonlyonceifpossible,soadheretothisprincipleasmuchas
possible.
Let'smoveontobuildingthemessageboxforIndividuals.Addanewformtotheprojectwiththename
'MsgBoxAutocompleteNP'.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

12/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Makesurethatthe'Size'inthePropertieswindowisequaltothebasemessageboxform.Thatavoidsawkwardpositionsofthe
buttonsplacedonthebasemessageboxform.

Doubleclickthisformsoyougettothecode.Ignorethe'Load'procedurethathasbeencreated.Youwillfilloutcodelateronin
thisprocedure,butfornow,insertthefollowingcodejustbelowtheline'PublicClassMsgBoxAutocompleteNP':
http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

13/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

InheritsBaseMessageBox

Thissimplelineensuresthattheelementsandcodeofthebasemessageboxjustcreated,willbepartofthe
MsgBoxAutocompleteNPform.VisualStudioremindsyouthatyouhavetobuildtheprojectfirstbeforetheeffectsareshown.
Buildtheproject,closetheprogramandgototheDesignviewoftheMsgBoxAutocompleteNPform(doubleclickthisforminthe
SolutionExplorer).Now,thebuttons'OK'and'Cancel'fromthebasemessageboxareshown.Youarereusingforms(andcode)!
Themessageboxneedsafewextraitems.IntheDesignview,addalistviewitem(name:'lvParties')andtwolabels(alabel1anda
labelwithsometextshown)(seepicture).

Inthepictureabove,thelistviewelementshowscolumns.Addthosecolumnsbyselectingthelistviewelementonthe
MsgBoxAutocompeteNPformandclickingthesmallarrowontheright.

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

14/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Thatarrowgivesaccesstoamenu.Fillinthelistviewitemwiththecolumnsasshownandgivethemappropriatenames(aname
forVisualStudioandanamethattheusersees(inthelistviewitem)).

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

15/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Withthelistviewitemselected,gotothePropertieswindowandmakesurethatthe'FullRowSelect'propertyissetto'True'and
thatthe'MultiSelect'propertyissetto'False'.
Nowforthecodingpart.First,addapublicpropertytothemessageboxform(gotothecodeeditorforthe
MsgBoxAutocompleteNPform):
PublicReadOnlyPropertyselecteditemAsInteger
Get
ReturnlvParties.SelectedIndices(0)
EndGet
EndProperty

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

16/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

Thispropertyisusedtoreturnthenumberoftheselectedindexinthelistview.Thepropertyissettoreadonlybecausewedonot
havetosetavalue,onlyretrieveavalue.Lateron,youwillwritecodetousethisnumberinthemainform'scodetolookupthe
relevantpartydetailsinthe'parties'collectioninthemainform,sothatalltextboxesonthemainformcanbecompleted.Perhaps
thissoundsabitcryptic.Don'tworry,youwillseewherethisisheadingto.
Next,insertthefollowingcode:

PublicSubNew(ByValfoundrowsAsObject,ByValcountAsInteger)
InitializeComponent()
fndrows=foundrows
cnt=count
EndSub

Thisisasocalled'constructor'.Whenthisformiscreated('initialised',likewiththeShoworShowdialogcommand)the
constructormakessurethatcertainelementsoftheformareset.Inthiscase,theconstructorrequiresyouascodertofeedthe
commandcreatingthisformwithtwovariables:foundrowsandcount.Asyoumayremember,thevariablesfndrowsandcntwere
introducedinthebasemessageboxform,sothesetwovariablesarealreadypresentintheMsgBoxAutocompleteNPformthat
inheritsfromthisbaseform.Thetwovariablessuppliedintheconstructorareusedtosetthevariablesfndrowsandcntinthe
form.Inthemainform,youwillinsertthesevariablesinthecommandtoshowthemessageboxform.The'foundrows'inputwill
consistofthedetailsofallpartiesthatsharethesamename.Moreonthatlater.
Next,insertthefollowingcodethatwillrunwhentheformisloaded.
PrivateSubMsgBoxAutocomplete_Load(senderAsObject,eAsEventArgs)HandlesMyBase.Load
lvParties.Items.Clear()
Label1.Text="Multipleinstancesof"&fndrows(0)("NPName").ToString&"found!"
DimiAsInteger
DimlviAsListViewItem
Fori=0Tocnt
lvi=NewListViewItem(fndrows(i)("NPName").ToString)
lvi.SubItems.Add(fndrows(i)("NPPlaceOfBirth").ToString)
lvi.SubItems.Add(fndrows(i)("NPAddress").ToString)
lvi.SubItems.Add(fndrows(i)("NPCity").ToString)
lvi.SubItems.Add(fndrows(i)("NPCountry").ToString)
lvParties.Items.Add(lvi)
Nexti
EndSub

Analysisofthecode:thelistviewitemontheformiscleared.Thislineisinsertedtoavoidcertainbehaviour(we'llgetbacktothis
shortly).Thelabelontopoftheformissettodisplayatext,indicatingthatacertainnamewasfoundmultipletimesinthedata.
Theparticularnameisretrievebyselectingthedatathatiscontainedinthefirstrow(0)ofthefndrowsobject(adatatable)
(retrievedby:'fndrows(0)(NPName).ToString').
Thenextblockofcodeisa'Fori=0to..Nexti'loop.Thisloopfillsthelistviewwiththedetailsofallpartiesfoundthathave
thesamename.Thisenablesyourusertopicktherightpartybylookingatotherpropertiesofthepartiesinsteadofthenamealone
(whichnameisequalforallpartiesshown).
Thisconcludesthecodeonourform.Let'sputthatcodeinactionbycodingthemainform.

Step5
Theonlythingtomaketheautocompletefunctionworkasintendedistoaddappropriatecodeforthemainform(form1).Addthe
followingcodetotheform1:
PrivateSubtxtNPName_KeyDown(senderAsObject,eAsKeyEventArgs)HandlestxtNPName.KeyDown
Ife.KeyCode=13Then
DimdtAsDataTable=TbIndividualsTableAdapter1.GetData
DimstrValueAsString
DimfoundRow()AsDataRow
http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

17/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

strValue="NPName='"&txtNPName.Text&"'"
foundRow=dt.Select(strValue)
IffoundRow.Length>0Then
IffoundRow.Length=1Then
txtNPPlaceOfBirth.Text=foundRow(0)("NPPlaceOfBirth").ToString
txtNPAddress.Text=foundRow(0)("NPAddress").ToString
txtNPCity.Text=foundRow(0)("NPCity").ToString
txtNPCountry.Text=foundRow(0)("NPCountry").ToString
ElseIffoundRow.Length>1Then
DimcountAsInteger=foundRow.Length1
DimfrmMsgBoxAsNewMsgBoxAutocompleteNP(foundRow,count)
Line1:
DimresAsDialogResult=frmMsgBox.ShowDialog()
Ifres=Windows.Forms.DialogResult.OKThen
Try
DimiAsObject=frmMsgBox.selecteditem

txtNPName.Text=foundRow(i)("NPName").ToString
txtNPPlaceOfBirth.Text=foundRow(i)("NPPlaceOfBirth").ToString
txtNPAddress.Text=foundRow(i)("NPAddress").ToString
txtNPCity.Text=foundRow(i)("NPCity").ToString
txtNPCountry.Text=foundRow(i)("NPCountry").ToString
frmMsgBox.Dispose()
CatchexAsException
MsgBox("Nothingselected!")
GoToLine1
EndTry
ExitSub
ElseIfres=Windows.Forms.DialogResult.CancelThen
frmMsgBox.Dispose()
ExitSub

EndIf

EndIf
EndIf
EndIf
EndSub

Analysisofthecode:
1.thecoderunsupona'keydown'event.Thatbasicallymeansthatthecodeisrunwhentheuserselectsanitemfromthe
dropdownlistsuppliedbytheautocompletefunction.Itisimportanttoaddthecode'Ife.KeyCode=13Then'becausethattiesthe
coderunningtothisspecificeventonly.
2.Whenthecoderuns,the'dt'variableisloadedwithalldatafromthedatabase(forIndividuals).Noticethe'GetData'command
ofthetableadapterthatretrievesallthisdata.
3.Thenextfewlinesservetolookupallrowsinthedatatable'dt'thathaveanameinitthatmatchesthenametheuserclicked
fromthelistshownbyautocomplete(basically,thenamethatisnowintheappropriatetextboxontheform).Thecodechecks
http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

18/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

whethertheresultisnot0(otherwise,thiscouldleadtoaprogramerror).Second,thecodecheckswhethertheresultismorethan
1,becausethemessageboxroutineyoubuiltonlymakessenseifthereismorethanonepartywiththesamename.Theprogram
basicallydecideswhethertheresultofthequeryis1(ifso,itproceedswiththenormalcode)ormorethan1(ifso,itwillgo
throughthemessageboxroutine).
3.Iftheresultofthequeryreturnsonlyonerow,thedetailsofthatparty(thedataintherowfoundinthedatatable'dt')are
insertedintheappropriatetextboxes.
4.Iftheresultofthequeryreturnsmultiplerows(meaning,morepartiesthathavethesamename),codeissetuptoshowthe
messageboxcreated,taketheuser'sinputandusethatinputtogetthedetailsofthechosenpartiesintothetextboxesonthemain
form.
5.Thecodeneedsa'count'variableforusewiththeindexoftherowsfound(the'foundRow'variablecontainstherowsthatwere
returnedbytheearlierquery).Thecountissettothenumberofrowsfoundbutminus1becausetheindexstartsat0insteadof1.
6.PleasenotethattheMsgBoxAutocompleteNPisfirstinitiated('DimfrmMsgBoxAsNew.'),takingintwovariables(the
foundRowvariableandthecountvariable).Onlythen,themessageboxisshowthroughtheShowDialogcommand.Thecommand
toshow(dialog)themessageboxisconstruedtoreturnaresult'res'.Thisresult(thatinthemessageboxformcanbe'OK'or
'Cancel')isusedagaininthemainformtorunparticularcode.
7.Iftheresultfromthemessageboxis'OK',thecodeonthemainformwill'Try'togetthenumberoftheselecteditemonthe
messagebox'slistview(lvParties).Ifthatdoesnotreturnanerror,thecodesimplyusesthatnumbertoretrievefromthe
'foundRow'variablethedetailsofthatparticularpartyanduseittopopulatetheappropriatetextboxesonthemainform.When
that'sdone,themessageboxformisdisposedof.
8.Ifthecodereturnsanerror,theuserhasprobablynotselectedapartyinthemessagebox.Thecodesolvesthisbyshowinga
(separate)messageboxtotheuserthathehasn'tselectedanythingandsubsequentlyjumpingbacktothecodethatshow(dialog)s
themessagebox.This'GoTo'methodisnotthepreferredmethodofcoding,butinthiscaseitisasuitablesolution.
9.Lastly,iftheresultfromthemessageboxis'Cancel',themessageboxformisdisposedof.
Thiscomplexcodescatteredovermultipleformscreatesthelogicthatmakestheautocompletefunctionwork.Alotofworkbut
verysatisfactoryforyouruser.Hecaninsertloadsofdatathroughthelookupformcreatedinanearliertutorialandsubsequently
retrievethatinfoinajiffyusingtheautocompletefeature.
CreatethesamecodeandformsfortheCompaniestabpageonthemainform(theautocompletefeatureofthetxtRPNametextbox
includingamessageboxthatinheritsthebasemessagebox).RememberthatyouwillneedtoaddtheTbCompaniesTableAdapterto
themainformjustliketheTbIndividualsTableAdapterandthatthecolumnsinthedatabaseforCompaniesareRPName,RPSeat,
RPAddress,RPCityandRPCountry.AdjustthecodeaccordinglyandcreatetwovariantsoftheUpdateDataTable()function(one
forIndividualsandoneforCompanies).RememberthattheoriginalUpdateDataTablefunction(toberenamedto
UpdateDataTableNP)isusedinseverallocationssoupdateaccordinglyandinsertthenewUpdateDataTableRPsubatthe
appropriatespots(similartothisfunctionforIndividuals).Anexcellentopportunitytorevisittheabovementionedpartsofthis
tutorial.

Conclusion
Youenhancedtheexistingcodeconsiderablywithadatagridviewonthelookupforms,orderedalphabeticallybyname,andan
autocompletefeatureinthemainform.YounowhaveeverythingyouneedtobuildafeaturerichapplicationtoautomateWord
documents.
ThenexttutorialswillfocusmoreongettingdetailsofworkingwithWorddocumentsright,likeswitchingfromsingulartoplural
inaWorddocumentbycode.ThosetutorialswillhavetheformofseparateVisualStudioprojectsinsteadofonelargeprojectthat
getsbuiltfurtherwitheachtutorial.
ComputingAZ|Programming|Software

programming_microsoft_word__11__enhancing_the_user_experience_autocomplete.txtLastmodified:2014/09/20
11:25bywekkel
Exceptwhereotherwisenoted,contentonthiswikiislicensedunderthefollowinglicense:CCAttributionShareAlike3.0
Unported[http://creativecommons.org/licenses/bysa/3.0/]

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

19/20

2/24/2015

programming_microsoft_word__11__enhancing_the_user_experience_autocompleteDevtome

AdvertisewithAnonymousAds

http://devtome.com/doku.php?id=programming_microsoft_word__11__enhancing_the_user_experience_autocomplete

20/20

You might also like