VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ84²¿·Ö
°´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ£¬°´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ£¬°´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿£¡
¡ª¡ª¡ª¡ªÎ´ÔĶÁÍꣿ¼ÓÈëÊéÇ©ÒѱãÏ´μÌÐøÔĶÁ£¡
¡¡¡¡¡¡¡¡¡¡The¡¡IDebug¡¡interface¡¡has¡¡a¡¡single¡¡Boolean¡¡property¡¡called¡¡Debug£»¡¡which¡¡can¡¡be¡¡assigned¡¡and¡¡¡¡
retrieved¡£¡¡The¡¡idea¡¡behind¡¡the¡¡IDebug¡¡interface¡¡is¡¡to¡¡enable¡¡a¡¡ponent¡¡to¡¡generate¡¡debug¡¡¡¡
output¡£¡¡One¡¡of¡¡the¡¡major¡¡headaches¡¡with¡¡debugging¡¡applications¡¡that¡¡process¡¡large¡¡amounts¡¡¡¡
of¡¡data¡¡is¡¡finding¡¡where¡¡the¡¡problem¡¡is¡£¡¡Imagine¡¡processing¡¡several¡¡million¡¡records£»¡¡and¡¡the¡¡¡¡
bug¡¡happens¡¡in¡¡record¡¡900£»001¡£¡¡You¡¡don¡¯t¡¡want¡¡to¡¡debug¡¡900£»000¡¡records¡¡before¡¡hitting¡¡the¡¡bug¡£¡¡¡¡
Thus£»¡¡the¡¡challenge¡¡is¡¡figuring¡¡out¡¡what¡¡went¡¡wrong¡¡without¡¡using¡¡the¡¡debugger¡£¡¡This¡¡is¡¡where¡¡¡¡
IDebug¡¡es¡¡into¡¡play¡£¡¡It¡¡provides¡¡a¡¡mechanism¡¡to¡¡let¡¡the¡¡implementation¡¡say¡¡what¡¡is¡¡going¡¡¡¡
on£»¡¡so¡¡if¡¡a¡¡bug¡¡needs¡¡to¡¡be¡¡deciphered£»¡¡you¡¡do¡¡so¡¡by¡¡looking¡¡at¡¡the¡¡output¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡following¡¡example¡¡demonstrates¡¡how¡¡to¡¡use¡¡the¡¡Debug¡¡flag¡£¡¡The¡¡class¡¡that¡¡contains¡¡this¡¡¡¡
code¡¡implements¡¡the¡¡IDebug¡¡interface¡¡and¡¡sets¡¡the¡¡Debug¡¡flag¡¡at¡¡the¡¡beginning¡¡of¡¡its¡¡execution¡£¡¡
Dim¡¡baseType¡¡As¡¡String£¨£©¡¡=¡¡_¡¡
¡¡¡¡typeToInstantiate¡£Split£¨New¡¡String£¨£©¡¡£û¡¡¡¨£§£§¡¨£»¡¡¡¨£§£§¡¨¡¡£ý£»¡¡StringSplitOptions¡£None£©¡¡
If¡¡baseType¡£Length¡¡=¡¡0¡¡Then¡¡
¡¡¡¡¡¡¡¡Throw¡¡New¡¡Exception£¨¡¨There¡¡is¡¡no¡¡base¡¡type£»¡¡which¡¡is¡¡an¡¡error¡¨£©¡¡
End¡¡If¡¡
If¡¡Debug¡¡Then¡¡
¡¡¡¡¡¡¡¡For¡¡Each¡¡str¡¡As¡¡String¡¡In¡¡baseType¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡GenerateOutput¡£Write£¨¡¨Workbook¡£Load¡¨£»¡¡¡¨baseType£¨¡¨¡¡&¡¡str¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡Next¡¡
End¡¡If¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡first¡¡line¡¡of¡¡code¡¡is¡¡used¡¡to¡¡split¡¡up¡¡a¡¡buffer¡¡into¡¡individual¡¡pieces£»¡¡where¡¡double¡¡square¡¡¡¡
brackets¡¡delimit¡¡the¡¡buffers¡£¡¡The¡¡Debug¡¡property¡¡is¡¡used¡¡to¡¡output¡¡the¡¡split¡up¡¡buffer¡¡using¡¡the¡¡¡¡
mand¡¡GenerateOutput¡£Write£¨£©¡£¡¡¡¡
¡öTip¡¡¡¡Although¡¡I¡¡have¡¡defined¡¡my¡¡own¡¡debugging¡¡infrastructure£»¡¡there¡¡is¡¡another¡¡infrastructure¡¡that¡¡you¡¡can¡¡¡¡
use£»¡¡called¡¡log4net¡¡£¨http£º//logging¡£apache¡£org/log4net/£©¡£¡¡This¡¡is¡¡a¡¡prehensive¡¡infrastructure¡¡¡¡
that¡¡you¡¡may¡¡want¡¡to¡¡investigate¡£¡¡
¡¡¡¡¡¡¡¡¡¡A¡¡Debug¡¡flag¡¡was¡¡used¡¡to¡¡output¡¡some¡¡text£»¡¡otherwise£»¡¡that¡¡information¡¡is¡¡not¡¡usually¡¡visible¡£¡¡¡¡
Without¡¡a¡¡Debug¡¡flag£»¡¡the¡¡only¡¡way¡¡to¡¡get¡¡that¡¡information¡¡is¡¡by¡¡setting¡¡a¡¡breakpoint¡¡after¡¡the¡¡¡¡
Split£¨£©¡¡statement£»¡¡and¡¡then¡¡individually¡¡investigating¡¡the¡¡resulting¡¡buffers¡£¡¡If¡¡you¡¡had¡¡to¡¡do¡¡¡¡
that¡¡for¡¡900£»000¡¡records£»¡¡you¡¡would¡¡bee¡¡bored¡¡very¡¡quickly£»¡¡and¡¡let¡¯s¡¡not¡¡even¡¡talk¡¡about¡¡¡¡
how¡¡much¡¡time¡¡you¡¡would¡¡waste¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡Debug¡¡flag¡¡serves¡¡two¡¡purposes¡£¡¡The¡¡first¡¡is¡¡to¡¡generate¡¡output¡¡to¡¡allow¡¡you¡¡to¡¡do¡¡a¡¡post
mortem¡¡analysis¡¡when¡¡trying¡¡to¡¡figure¡¡out¡¡a¡¡bug¡£¡¡The¡¡second¡¡is¡¡to¡¡generate¡¡output¡¡when¡¡a¡¡bug¡¡¡¡
occurs¡¡in¡¡a¡¡production¡¡context¡£¡¡By¡¡giving¡¡the¡¡user¡¡the¡¡ability¡¡to¡¡define¡¡a¡¡Debug¡¡flag£»¡¡you¡¡are¡¡no¡¡¡¡
longer¡¡reliant¡¡on¡¡having¡¡the¡¡user¡¡explain¡¡to¡¡you¡¡step¡¡by¡¡step¡¡how¡¡to¡¡reproduce¡¡the¡¡bug¡£¡¡All¡¡you¡¡¡¡
need¡¡to¡¡do¡¡is¡¡tell¡¡the¡¡user¡¡to¡¡activate¡¡the¡¡Debug¡¡flag¡¡£¨your¡¡program¡¡would¡¡probably¡¡have¡¡a¡¡menu¡¡¡¡
item¡¡for¡¡this£©£»¡¡run¡¡the¡¡program¡¡until¡¡the¡¡bug¡¡occurs£»¡¡and¡¡then¡¡send¡¡you¡¡the¡¡debug¡¡log¡¡file¡¡output¡¡¡¡
for¡¡analysis¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡316¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
294¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡1¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡¡£¡¡N¡¡E¡¡T¡¡¡¡G¡¡E¡¡N¡¡E¡¡R¡¡I¡¡CS¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Defining¡¡the¡¡IWorksheetBase¡¡and¡¡IWorksheet¡¡Interfaces¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡worksheet¡¡is¡¡implemented¡¡using¡¡worksheet¡¡and¡¡workbook¡¡interfaces¡£¡¡Remember¡¡that¡¡one¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡of¡¡the¡¡requirements¡¡is¡¡to¡¡have¡¡a¡¡spreadsheet¡¡implementation¡¡that¡¡is¡¡very¡¡fast¡£¡¡This¡¡would¡¡mean¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡if¡¡a¡¡spreadsheet¡¡contained¡¡numbers£»¡¡the¡¡best¡¡implementation¡¡would¡¡be¡¡a¡¡spreadsheet¡¡of¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Double¡¡types¡£¡¡However£»¡¡if¡¡the¡¡spreadsheet¡¡contained¡¡string¡¡buffers£»¡¡the¡¡best¡¡implementation¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡would¡¡be¡¡a¡¡spreadsheet¡¡of¡¡¡¡String¡¡types¡£¡¡Figure¡¡11¡2¡¡shows¡¡a¡¡spreadsheet¡¡of¡¡Double¡¡and¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡String¡¡types¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Figure¡¡11¡2¡£¡¡Spreadsheet¡¡of¡¡strings¡¡and¡¡doubles¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡Figure¡¡11¡2£»¡¡the¡¡workbook¡¡references¡¡a¡¡worksheet¡¡of¡¡type¡¡Worksheet£¨Of¡¡Double£©¡¡and¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Worksheet£¨Of¡¡String£©£»¡¡and¡¡in¡¡the¡¡general¡¡case£»¡¡Worksheet£¨Of¡¡BaseType£©¡£¡¡You¡¡can¡¡see¡¡how¡¡an¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡interface¡¡using¡¡¡¡generics¡¡for¡¡a¡¡worksheet¡¡could¡¡be¡¡potentially¡¡defined£º¡¡define¡¡a¡¡general¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡worksheet¡¡and¡¡define¡¡the¡¡actual¡¡type¡¡using¡¡¡¡generics¡£¡¡The¡¡problem¡¡with¡¡this¡¡solution¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡that¡¡a¡¡workbook¡¡would¡¡define¡¡a¡¡collection¡¡of¡¡mixed¡¡types¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡You¡¡might¡¡be¡¡tempted¡¡to¡¡believe¡¡that¡¡Worksheet£¨Of¡¡Double£©¡¡and¡¡Worksheet£¨Of¡¡String£©¡¡are¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡of¡¡the¡¡type¡¡Worksheet£¨Of¡¡BaseType£©£»¡¡and¡¡thus¡¡are¡¡all¡¡a¡¡single¡¡type¡£¡¡This¡¡is¡¡not¡¡the¡¡case£»¡¡because¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡with¡¡¡¡generics£»¡¡a¡¡type¡¡that¡¡hasn¡¯t¡¡been¡¡concretized¡¡is¡¡not¡¡a¡¡type¡¡at¡¡all¡£¡¡Think¡¡of¡¡it¡¡as¡¡being¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡an¡¡almost¡¡type£»¡¡and¡¡to¡¡make¡¡the¡¡program¡¡work£»¡¡you¡¡need¡¡to¡¡concretize¡¡everything¡£¡¡Figure¡¡11¡2¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡shows¡¡two¡¡concrete¡¡types£º¡¡Worksheet£¨Of¡¡Double£©¡¡and¡¡Worksheet£¨Of¡¡String£©¡£¡¡These¡¡are¡¡two¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡different¡¡types¡£¡¡The¡¡two¡¡different¡¡types¡¡make¡¡it¡¡plicated¡¡for¡¡the¡¡workbook£»¡¡because¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡workbook¡¡wants¡¡to¡¡maintain¡¡a¡¡single¡¡collection¡¡of¡¡worksheets¡£¡¡If¡¡we¡¡assume¡¡for¡¡the¡¡moment¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡that¡¡the¡¡worksheet¡¡interface¡¡is¡¡defined¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Interface¡¡IWorksheet£¨Of¡¡BaseType£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Interface¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡the¡¡workbook¡¡could¡¡reference¡¡the¡¡worksheet¡¡as¡¡this¡¡collection£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡_worksheets¡¡As¡¡List£¨Of¡¡IWorksheet£¨Of¡¡BaseType£©£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡However£»¡¡that¡¡reference¡¡is¡¡inplete£»¡¡and¡¡the¡¡piler¡¡would¡¡want¡¡to¡¡know¡¡what¡¡BaseType¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡references¡£¡¡To¡¡keep¡¡your¡¡options¡¡open£»¡¡one¡¡solution¡¡is¡¡to¡¡not¡¡plete¡¡the¡¡BaseType£»¡¡but¡¡let¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡user¡¡of¡¡workbook¡¡figure¡¡things¡¡out£»¡¡thus¡¡defining¡¡workbook¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Class¡¡Workbook£¨Of¡¡BaseType£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡_worksheets¡¡As¡¡List£¨Of¡¡IWorksheet£¨Of¡¡BaseType£©£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Class¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡317¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡1¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡¡£¡¡N¡¡E¡¡T¡¡¡¡G¡¡E¡¡N¡¡E¡¡R¡¡I¡¡CS¡¡295¡¡
¡¡¡¡¡¡¡¡¡¡This¡¡solution¡¡seems¡¡to¡¡be¡¡a¡¡good¡¡one£»¡¡but£»¡¡in¡¡fact£»¡¡it¡¯s¡¡passing¡¡the¡¡buck¡£¡¡The¡¡solution¡¡does¡¡¡¡
not¡¡address¡¡the¡¡problem¡¡of¡¡Figure¡¡11¡2¡¡and¡¡forces¡¡the¡¡end¡¡user¡¡to¡¡solve¡¡it¡£¡¡The¡¡core¡¡problem¡¡is¡¡¡¡
that¡¡Figure¡¡11¡2¡¡uses¡¡¡¡generics¡¡to¡¡define¡¡worksheets¡¡of¡¡specific¡¡types£»¡¡which¡¡means¡¡mixed¡¡¡¡
types¡¡that¡¡need¡¡to¡¡be¡¡addressed¡¡by¡¡the¡¡workbook¡£¡¡In¡¡other¡¡words£»¡¡a¡¡workbook¡¡can¡¡contain¡¡only¡¡¡¡
spreadsheets¡¡of¡¡a¡¡certain¡¡type£»¡¡as¡¡in¡¡this¡¡example£º¡¡
Workbook£¨Of¡¡String£©¡¡workbook1¡¡
Workbook£¨Of¡¡Double£©¡¡workbook2¡¡
¡¡¡¡¡¡¡¡¡¡It¡¡would¡¡seem¡¡that¡¡¡¡generics¡¡make¡¡everything¡¡more¡¡plicated¡£¡¡However£»¡¡there¡¯s¡¡¡¡
more¡¡to¡¡this¡¡than¡¡first¡¡appears¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡generics¡¡have¡¡not¡¡made¡¡things¡¡more¡¡plicated£»¡¡but¡¡rather¡¡have¡¡required¡¡us¡¡to¡¡be¡¡¡¡
more¡¡explicit¡¡about¡¡what¡¡we¡¡actually¡¡want¡¡to¡¡do¡£¡¡We¡¡want¡¡to¡¡be¡¡able¡¡to¡¡define¡¡specific¡¡work
sheet¡¡types£»¡¡which¡¡means¡¡we¡¡have¡¡a¡¡mixed¡¡list¡¡of¡¡types¡¡that¡¡the¡¡workbook¡¡must¡¡manage¡£¡¡As¡¡¡¡
explained¡¡in¡¡Chapter¡¡9£»¡¡non¡¡¡generics¡¡list¡¡types¡¡cannot¡¡control¡¡whether¡¡or¡¡not¡¡a¡¡list¡¡contains¡¡¡¡
mixed¡¡types¡£¡¡
¡¡¡¡¡¡¡¡¡¡To¡¡solve¡¡the¡¡worksheet¡¡problem£»¡¡we¡¡need¡¡to¡¡put¡¡on¡¡our¡¡object¡oriented¡¡thinking¡¡caps¡£¡¡¡¡
First£»¡¡what¡¡is¡¡a¡¡worksheet£¿¡¡It¡¯s¡¡a¡¡spreadsheet¡¡that¡¡fulfills¡¡the¡¡role¡¡of¡¡a¡¡two¡dimensional¡¡thing£»¡¡¡¡
and¡¡it¡¡applies¡¡to¡¡all¡¡worksheets¡¡regardless¡¡of¡¡types¡£¡¡Therefore£»¡¡the¡¡first¡¡interface¡¡to¡¡define¡¡is¡¡a¡¡¡¡
base¡¡worksheet£»¡¡as¡¡follows¡¡£¨do¡¡this¡¡in¡¡the¡¡ServerSideSpreadsheet¡¡project£»¡¡as¡¡well¡¡as¡¡adding¡¡a¡¡¡¡
reference¡¡to¡¡the¡¡Devspace¡£Trader¡£mon¡¡project£©£º¡¡
Imports¡¡Devspace¡£Trader¡£mon¡¡
Public¡¡Interface¡¡IWorksheetBase¡¡
¡¡¡¡¡¡¡¡Inherits¡¡IDebug¡¡
¡¡¡¡¡¡¡¡Sub¡¡Dimension£¨ByVal¡¡rows¡¡As¡¡Integer£»¡¡ByVal¡¡cols¡¡As¡¡Integer£©¡¡
¡¡¡¡¡¡¡¡ReadOnly¡¡Property¡¡MaxCols£¨£©¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡ReadOnly¡¡Property¡¡MaxRows£¨£©¡¡As¡¡Integer¡¡
End¡¡Interface¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡interface¡¡definition¡¡of¡¡IWorksheetBase¡¡has¡¡one¡¡method¡¡and¡¡two¡¡properties¡£¡¡The¡¡method¡¡¡¡
Dimension£¨£©¡¡is¡¡used¡¡to¡¡assign¡¡the¡¡maximum¡¡rows¡¡and¡¡columns¡¡of¡¡the¡¡individual¡¡spreadsheet¡£¡¡¡¡
The¡¡properties¡¡MaxRows¡¡and¡¡MaxCols¡¡return¡¡the¡¡maximum¡¡rows¡¡and¡¡columns¡£¡¡The¡¡properties¡¡¡¡
and¡¡method¡¡have¡¡nothing¡¡to¡¡do¡¡with¡¡the¡¡specific¡¡type¡¡managed¡¡by¡¡the¡¡worksheet£»¡¡but¡¡the¡¡inter
face¡¡manages¡¡to¡¡uniquely¡¡identify¡¡the¡¡instance¡¡as¡¡being¡¡a¡¡type¡¡of¡¡spreadsheet¡£¡¡
¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡workbook¡¡code£»¡¡the¡¡list¡¡of¡¡worksheets¡¡would¡¡be¡¡defined¡¡as¡¡follows£º¡¡
Private¡¡_worksheets¡¡As¡¡IDictionary£¨Of¡¡String£»¡¡IWorksheetBase£©¡¡=¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡New¡¡Dictionary£¨Of¡¡String£»¡¡IWorksheetBase£©¡¡
¡¡¡¡¡¡¡¡¡¡Now¡¡the¡¡workbook¡¡knows¡¡it¡¡has¡¡a¡¡series¡¡of¡¡worksheets£»¡¡but¡¡the¡¡workbook¡¡does¡¡not¡¡know¡¡¡¡
or¡¡care¡¡about¡¡the¡¡types¡¡of¡¡the¡¡worksheets¡£¡¡When¡¡users¡¡of¡¡the¡¡workbook¡¡want¡¡to¡¡manipulate¡¡an¡¡¡¡
individual¡¡worksheet£»¡¡they¡¡can¡¡retrieve¡¡the¡¡worksheet¡¡from¡¡the¡¡workbook£»¡¡but¡¡the¡¡users¡¡need¡¡¡¡
to¡¡know¡¡the¡¡worksheet¡¯s¡¡type¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡spreadsheet¡¡is¡¡typically¡¡addressed¡¡using¡¡rows¡¡and¡¡columns£»¡¡but¡¡to¡¡simplify¡¡declara
tions£»¡¡there¡¡is¡¡also¡¡the¡¡ability¡¡to¡¡define¡¡something¡¡called¡¡the¡¡SheetCoordinate£»¡¡which¡¡is¡¡a¡¡type¡¡¡¡
that¡¡has¡¡a¡¡row¡¡and¡¡column¡£¡¡The¡¡SheetCoordinate¡¡is¡¡defined¡¡in¡¡ServerSideSpreadsheet¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡318¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
296¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡1¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡¡£¡¡N¡¡E¡¡T¡¡¡¡G¡¡E¡¡N¡¡E¡¡R¡¡I¡¡CS¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Structure¡¡SheetCoordinate¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Row¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Column¡¡As¡¡Integer¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Sub¡¡New£¨ByVal¡¡row¡¡As¡¡Integer£»¡¡ByVal¡¡column¡¡As¡¡Integer£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡If¡¡£¨row¡¡¡¶¡¡0£©¡¡Then¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Throw¡¡New¡¡ArgumentOutOfRangeException£¨¡¨Row¡¡is¡¡below¡¡zero¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡If¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡If¡¡£¨column¡¡¡¶¡¡0£©¡¡Then¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Throw¡¡New¡¡ArgumentOutOfRangeException£¨¡¨Column¡¡is¡¡below¡¡zero¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡If¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Me¡£Row¡¡=¡¡row¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Me¡£Column¡¡=¡¡column¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡ReadOnly¡¡Property¡¡OneUp£¨£©¡¡As¡¡SheetCoordinate¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Get¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Return¡¡New¡¡SheetCoordinate£¨£¨Me¡£Row¡¡1£©£»¡¡Me¡£Column£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Get¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Property¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡ReadOnly¡¡Property¡¡OneDown£¨£©¡¡As¡¡SheetCoordinate¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Get¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Return¡¡New¡¡SheetCoordinate£¨£¨Me¡£Row¡¡£«¡¡1£©£»¡¡Me¡£Column£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Get¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Property¡¡
¡¡