版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章如果你不能创建循环代码结构,往往不得不编写成百上千行代码。所有类型的循环的基本作用是相同的,那就是减少重复执行一项任务时需要的代码语句的数目。循环结构有着许多不同的类型,应该根据不同的情况使用相应的循环类型。有些循环能够执行规定的次数,而另一些循环则执行到出现某种条件时为止。将正确的循环用于某项作业,意味着它是个更加健壮、有效和易读的代码。注 使用For...Next循环的最基本类型是oret循环,它能够循环运行规定的次数。当到达最大的迭代次数时,便继续执行et语句后面的语句。创建一个o...et循环时,要规定用于计数的起始数字和最终数字。也可以使用teFor...Next循环结构的句法Forcounter=startToend[Stepstep][statements][Exit[statementsNext[counterFor...Next循环结构具有下counter(计数器)一个必须有的数字变量,用作循环计数器。该变量不能是布尔变量或start(起始值)计数器必须有的初始值。end(结束值)计器必须有的最终值。当计数器到达最终数字时,循环中的语句最后执行一次,然后从NextendNextStep(递增量)一个可有可无的数字,用于规定计数器每次运行循环时递增的数量。如果For...Next循环中的大部分编程工作是在启动循环的For语句中进行的。For...Next循环的大部分代码是相当简单的,循环计数器按照递增量1从一个数字跳到另一个数字。将递增量设置DimintCounterAsIntegerForintCounter=1To10Next若要使计数器按1以外的递增量进行递增,就必须在r语句中设置ep参数。例如,若要按递增量21到10orDimintCounterAsForintCounter=1To10StepDebug.PrintNext若要创建按你的要求来运行的循环,必须全面理解Step参数的作用。如果按递增量2计数启动一个带有For语句的循环时,计数器变量将被初始化为它的起始值。在上面的例子中,起始值是1Step的值来递增(如果递增量为负值,则递减9并且11。由于11超过了结束值1,因此该循环就不再重复运行。有些编程人员不理解这个运行特性。例如,当下面的代码运行时,调试窗口中输出DimintCounterAs‘*Loop10ForintCounter=1ToNextDebug.Print如果你的是它输出10,那么你就错了,不过你并不是唯一这样想的人。当运行到NextintCounter是9,那么intCounter10,同时该循环再次运行。当intCounter的值是10时遇到NextintCounter的值递增为11,代码的运行再次返回到For语句。当For语句计算intCounter的值并且发现它的值超过结束值时,代码的执行转到紧靠Next语句后面的这个语句,并输出intCounter的值。输出的intCounter值是1。 实际应用举例1说明了当你用常量取代For除了幻数和常量外,还可以将变量或控制值用作起始值和结束值等参数。例如,下面的代码将变量值用作上限:DimintCounter DimintupperLimitAs‘*Initializeupperlimit.Thisvaluecancomefromanywhere,‘*upperLimit=100ForintCounter=1ToNextDimintCounter DimintupperLimitAs‘*Initializeupperlimit.Thisvaluecancomefromanywhere,‘*UpperLimit=-5ForintCounter=1ToNext这个循环根本就不能执行。初次遇到For语句时,intCounter被初始化为1,并且与每个For语句必须有一个对应的NextNext语句,不过你应该将它纳入该语句。省略计数器变量对只有一个循环的简单过程来说,不是个大问题。但是,随着过程的规模变得越来越大和越来越复杂,或者随着嵌套式循环的创建,使用DimintCounter DimintSecondCounterAs‘*CreatetheouterForintCounter=1To‘*CreateanestedloopalongwithanewForintSecondCounter=1To‘*PrintthevalueofthesecondDebug.Print这个代码例子中,一个循环之中套了一个循环。由于Next语句没有计数器变量,因此究竟是哪个Next语句关闭哪个循环,这个问题显得不太清楚。如果在For语句与Next语句之间存在对For语句与Next语句之间的所有语句,你至少应该将它们缩进一个制表位,使代码结构(第章详细介绍了语句缩进的规则,不过这里也应该说明它的重要性开始语句与结束语句在代码的层次结构中位于相同层次上,而代码主体语句则处于从属层次。For语句后面的第一个语句必须缩进一个制表位。主体语句的其余部分的缩进要取决于它们与第一个语句的关系。虽然大多数oro...xtoTo所示。退出oretExto语句:DimintCounterAs‘*LoopthroughthepossibledaysoftheForintCounter=1To‘*Ifthecounterisequaltothecurrentdayofthe‘*exittheIfintCounter=Format(Date,“d”)ThenExitForDebug.PrintintCounterNext上面这个代码并没有特别的作用,不过它说明了一个问题。如果你必须提早退出该循环,请使用ExtFor语句。PrivateFunctionRawNumber(strNumberAsString)As‘*Purpose:Stripsanalphanumericstringdownto itsnumericcomponenttobeusedfor‘*Accepts:strNumber-astringcontainingaphone e.g.,(402)555-‘*Returns:ThestringwithallnonnumericelementsOnErrorGoToDimstrRaw AsStringDimintLocation intLocation=‘*LoopthroughallthecharactersintheDoWhileintLocation<=‘*DeterminewhetherthecurrentcharacterisIfIsNumeric(Mid$(strNumber,intLocation,1))strRaw=strRaw&Mid$(strNumber,intLocation,EndintLocation=intLocation+RawNumber=strRawExitCallShowError(Me.Name,“RawNumber",Err.Number,GoToEndPrivateFunctionRawNumber(strNumberAsString)As‘*Purpose:Stripsanalphanumericstringdownto itsnumericcomponenttobeusedfor‘*Accepts:strNumber-astringcontainingaphone e.g.,(402)555-‘*Returns:ThestringwithallnonnumericelementsOnErrorGoToDimstrRaw AsStringDim As‘*LoopthroughallthecharactersintheForintLocation=1To‘*DeterminewhetherthecurrentcharacterisIfIsNumeric(Mid$(strNumber,intLocation,1))strRaw=strRaw&Mid$(strNumber,intLocation,EndNextintLocationRawNumber=strRawExitCallShowError(Me.Name,“RawNumber",Err.Number,GoToEnd'*Drawverticalgridlinesonthecanvas.ForintCount=0To(intEditWidth+1)Step4‘*usetheAPItomovethedrawingpen.lngResult=MoveToEx(lngScratchPadDC,intCount,0,ByVal‘*DrawastraightlngResult=LineTo(lngScratchPadDC,intCount,NextConstc_Magnification=‘*DrawverticalgridlinesontheForintCount=0To(intEditWidth+1)Step‘*UsetheAPItomovethedrawinglngResult=MoveToEx(lngScratchPadDC,intCount,0,ByVal‘*DrawastraightlngResult=LineTo(lngScratchPadDC,intCount,Next循环结束后不要计数器变量。当For...Next循环结束时,计数器变量的最后值不等于endStep的值。如果你希望一个循环按照规定的循环次数运行到结束,请在循环结束之后不要使用计数器变量。运行时,在试图将输出放入调试窗口的语句上会生成一个错误。这个错误是Error9,即Subscriptoutrange(使用超出范围),它的发生是因为循环终止运行时intCounter的值实际上是11(数组中的最后元素的下标是10。PrivateSub‘*Purpose:Fillanarraywithvalues,andprint valueinthelastOnErrorGoToDimintCounter DimaintArray(1To10)As‘*Initializetherandomnumber‘*PopulatethearrayelementswithrandomForintCounter=1To10aintArray(intCounter)=(10*Rnd)+1Next‘*PrintthevalueofthelastDebug.PrintExitCallShowError(Me.Name,“FillArray",Err.Number,GoToEndPrivateSub‘*Purpose:Fillanarraywithvaluesandprint valueinthelastOnErrorGoToDim AsConstc_ArrayMax=Constc_ArrayMin=DimaintArray(c_ArrayMinToc_ArrayMax)As‘*Initializetherandomnumber‘*PopulatethearrayelementswithrandomForintCounter=c_ArrayMinToc_ArrayMaxaintArray(intCounter)=(c_ArrayMax*Rnd)+1Next‘*PrintthevalueofthelastDebug.PrintExitCallShowError(Me.Name,“FillArray",Err.Number,GoToEndConstc_MinPort=Constc_MaxPort=‘*SettheCommportbasedontheselectedoptionForintCounter=c_MinPortTo‘*IfaCommportoptionbuttonisselected,usethatComm‘*andexitthe mPort(intCounter).value=TruemPort=EndIfConstc_MinPort=Constc_MaxPort=‘*SettheCommportbasedontheselectedoptionForintCounter=c_MinPortTo‘*IfaCommportoptionbuttonisselected,usethatComm‘*andexitthe mPort(intCounter).value=TruemPort=EndIfNext为了清楚起见,应该对For...Next循环中的代码主体语句进行缩进。每当你的代码结构'*Fillthedateselectioncombobox.ForintYear=1969To2020cboYear.AddItemStr(intYear)Next‘*FillthedateselectioncomboForintYear=1969To2020Next如果你必须提早退出For...Next循环,请使用ExitFor语句。不要使用GoTo和一个标注'*Selectthe"unassigned"categorynodeintheTreeviewForlngIndex=1To‘*Checktoseewhetherthisisthe“unassigned”IftreCategory.Nodes(lngIndex).Text=c_strUnassignedtreCategory.Nodes(lngIndex).Selected=‘*Noneedtokeeplooking;getoutoftheGoToEndIf‘*Selectthe“unassigned”categorynodeintheTreeviewForlngIndex=1To‘*Checktoseewhetherthisisthe“unassigned”IftreCategory.Nodes(lngIndex).Text=c_strunassignedtreCategory.Nodes(lngIndex).Selected=‘*Noneedtokeeplooking;getoutoftheEndIfNext使用Do...loop当一个循环开始运行时,有时并不知道这个循环需要运行的准确次数。你可能启动一个For...Next循环,并知道它的上限大于它需要重复运行的次数(如果你知道该值,请查找该循ExitFor语句退出该循环。不过这样做的效率极低,常常无法实现,并且明显是错的。需要创建一个循环,但是你不知道它要执行多少次,那么请使用Do...Loop。Do...Loop结构有着许多不同的形式。最基本的形式采用下面的句法:[statements若要规定终止Do循环所需的条件,这通常是在循环的开始处或结尾处设置的。另外,也可以规定当满足某个条件时使循环继续运行,或者等到满足某个条件时使循环继续运行。这些选项使你在编写循环代码时能够具备更大的灵活性。下面是Do循环的句法,它使用While关键字DoWhileconditi[statements下面是使用该句法的一个简单的Do循环‘*PopulateaTreeviewcontrolwithitemsfromthe‘*codesDoWhileNotSetvntNode=treMarketing.Nodes.Add(intNodeIndex,tvwChild,,rstCodes![MarketingCode],该循环就继续运行。请注意,当循环初次启动时,如果计算的条件值是False,那么Do与LoopUntil关键字用于使Do循环连续运行,直到满足一个条件时再终止运行。下面的代码显示了用Until‘*PopulateaTreeviewcontrolwithitemsfromthe‘*codesDoUntilSetvntNode=treMarketing.Nodes.Add(intNodeIndex,tvwChild,,rstCodes![MarketingCode],这个代码例子与前面这个代码的作用完全相同,但是它提供了一个更好的解决方案,因为它不需要使rstCodesEOF的值变反。若要使用DoWhile循环,就必须使用Not可以在Loop语句()中使用While或Until关键字,而不是将它们作为Do语句的一部分。当你将它们放入Loop语句中时,条件是在循环的结尾处计算,而不是在开始处计算。这可以确保该循环至少总能执行一次。当你创建的循环是在它的结尾处检查退出条件时,千万要谨慎,请看下例:‘*PopulateaTreeviewcontrolwithitemsfromthe‘*codesSetvntNode=treMarketing.Nodes.Add(intNodeIndex,tvwChild,,rstCodes![MarketingCode],LoopUntil请注意,这个代码非常有可能运行失败。不管记录集是否位于文件的结尾,它至少会运行一次。当循环启动时,如果记录集位于文件的结尾,那么如果试图MarketingCode域,就会导致运行期错误。请使用ExitDo语句。下面这个过程创建了一个不带ExitDo语句的无限循环。在每次运行该循它删除。当不再能够找到该字符串时,便退出该循环。请注意,使用ExitDo语句通常不如将‘*Thevalue“ContactNumber”mightappearmultipletimesinthe‘*box.usealooptoremovealloccurrencesofthisvalue.‘*SelectListItemusestheAPItoperformaquicksearch.lngIndex=SelectListItem(lstAvailableFields,“ContactNumber”)‘*Checktoseewhetherthevalue“ContactNumber”wasfound.IflngIndex>-1‘*Thevaluewasfound;removeitfromthelist.lstAvailableFields.RemoveItemlngIndex‘*Itemnotfound.Alloccurrenceshavebeenremoved,‘*exittheEndIf一般来说,用于确定何时退出循环的表达式要使用一个变量,你可以在Do循环中的某个除非你有理由使用别的操作方法,否则请在循环的开始处计算Do循环的退出条件。你常常可以选择究竟在循环的开始处还是结尾处放置退出条件。但是,在循环的开始处计算退出条件,这样的循环比较容易理解,如果退出条件是Fals,那么这些循环一次也不会执行。IfNot(rstReports.EOF)‘*LoopthroughtheRecordsetofreports,addingeachreportto‘*ListViewSetobjItem=objItem.Text=objItem.SmallIcon=LoopUntilrstReports.End‘*LoopthroughtheRecordsetofreports,addingeachreportto‘*ListViewDoUntilSetobjItem=objItem.Text=objItem.SmallIcon=当你在While与Until之间进行选择时,请使用能实现最简单的条件的这个关键字。在大多数循环中,你既可以使用While,也可以使用Until。但是,根据具体情况,其中的一个关键字(不是另一个关键字)Not运算符来计算表达式的相反值。你应该尽可能使用简单表达式的值(而不是它的相反值。PrivateSub‘*Purpose:Fillthecontactscomboboxwithall forthecurrentOnErrorGoToDimstrSQL AsStringDimrstContactAsRecordset‘*RetrievethenameofallcontactsforthestrSQL=“SELECT[ContactName]FROMtblContacts“&“WHERE[AccountNumber]=“&m_lngAccountNumber&““&“ORDERBY[ContactSetrstContact=dbSales.OpenRecordset(strSQL,‘*PopulatethecomboDoWhileNot(rstContact.EOF)cboContacts.AddItemrstContact![ContactName]‘*ChecktoseewhetherrstContactissettoan‘*ofaIfNot(rstContactIsNothing)SetrstContact=NothingEndIfExitCallShowError(Me.Name,“cboContacts_Requery",Err.Number,_ResumeEndPrivateSub‘*Purpose:Fillthecontactscomboboxwithall forthecurrentOnErrorGoToDimstrSQL AsStringDimrstContactAsRecordset‘*RetrievethenameofallcontactsforthestrSQL=“SELECT[ContactName]FROMtblContacts“&“WHERE[AccountNumber]=“&m_lngAccountNumber&““&“ORDERBY[ContactSetrstContact=dbSales.OpenRecordset(strSQL,‘*PopulatethecomboDoUntilcboContacts.AddItemrstContact![ContactName]‘*ChecktoseewhetherrstContactissettoan‘*ofaIfNot(rstContactIsNothing)SetrstContact=NothingEndIfExitCallShowError(Me.Name,“cboContacts_Requery",Err.Number,_ResumeEnd尽可能使用Do循环或For...ext循环,而不要使用Goo和一个标注。在许多情况下,你很想用Goo和一个标注来创建循环。但是这种方法创建的循环很难理解,而运行效率往往不高。PrivateFunctionStripDoubleQuotes(ByValstrStringAsString)As‘*Purpose:Locatealldoublequoteswithinastringand themtosingle‘*Accepts:strString-thestringinwhichtosearch double‘*Returns:ThestringpassedhereasstrString,with quotesrecedbysingleConstc_DoubleQuote““““Constc_SingleQuote=“‘“DimintLocationAs‘*LookforadoubleintLocation=InStr(strString,‘*Ifadoublequoteisfound,receitwithasingleIfintLocation>0‘*Adoublequotehasbeenfound.Receit‘*asingleMid$(strString,intLocation,1)=‘*LookforanotherdoubleGoTo‘*Nomoredoublequoteswerefound.Returnthenewstring.StripDoubleQuotes=strStringEndEndPrivateFunctionStripDoubleQuotes(ByValstrStringAsString)As‘*Purpose:Locatealldoublequoteswithinastringand themtosingle‘*Accepts:strString-thestringinwhichtosearch double‘*Returns:ThestringpassedhereasstrString,with quotesrecedbysingleConstc_DoubleQuote=""""Constc_SingleQuote="'"DimintLocationAsInteger‘*LookforadoubleintLocation=InStr(strString,‘*Ifadoublequoteisfound,receitwithasingleIfintLocation>0‘*Adoublequotehasbeenfound.Receit‘*asingleMid$(strString,intLocation,1)=EndLoopWhileintLocation>‘*ReturntheStripDoubleQuotes=End用Do...Loop取代While...Wend循环已经们使用了很长的时间,它早就过时了。Do...Loop具有更大的灵活性,因此你应该改用Do...Loop循环(另外,Wend听起来让人感到很奇怪。While...Wend循WhileconditiWhile...Wend循环的运行特性与下面这个Do循环完DoWhileconditi[statements关于While...end循环没有东西要讲了。它的退出条件是在循环开始时计算的,如果计算的条件是True,那么While...Wend循环中的代码就执行。当执行到end语句时,代码就回到WhileForEach...Next循环是个功能强大的循环,而编程员却常常并不重视它们。它能够循环运行一个数组或对象集合的所有成员。将ForEach...Next循环用于对象集合的许多编程员并不知道它也可以用于数组,这是幸运的,因为将ForEach...Next用于数组会导致代码运行速度明显ForEach...Next须是ariant、Object或某些特定的对象类型,然后启动该循环。在每次运行该循环时,你的单元变量便对象集合的一个元素。对元变量进的操作,就能直接操作合中的该元素。使用ForEach...Next循环时的运行速度往往比使用For...NextFo...Nex下面是ForEach...NextForEachelementIn[statements][ExitFor][statementsNext[element你定义的单元变量必须使用Variant或Object(通用或)数据类型。应该使用最适合(集合)中的所有对象的特定对象类型。例如,当你循环运行窗体上的Controls(控件)集合时,可以使用ariant、Object或Control作为数据类型。但是,除非你能确保窗体上只有特定类型的控件,否则就不能使用 、 或 boBox数据类型。因此你的合乎逻辑的选择是Control(控件)数据类型。PublicPropertyGetSpecialIsFormDirty(frmFormAsForm)AsBoolean‘*Purpose:Determinewhetheranyofthedataontheformhas ‘*Accepts:frmForm-thenameoftheformto‘*Returns:Trueifevenonecontrol’s hanged isTrue;otherwise‘* :Errorsaretrappedbecauseattemptingto theD hangedpropertyofacontrolthatdoesn’t haveone(suchasaFrame)causesarun-timeerror.OnErrorResumeNextDimintIndex AsIntegerDim AsConstc_NoSuchProperty=Constc_NoError=‘*AssumethattheformisSpecialIsFormDirty=‘*LoopthroughallcontrolsontheForintIndex=0TofrmForm.Controls.Count-1 hanged= ‘*Determinethetypeoferror(ifany)thatwasSelectCaseCaseIs=‘*Thiscontrolhasa hangedIf hangedThenGoToCaseIs=‘*Thiscontroldoesnothavea hangedCase‘*Legitimateerror.SendtoerrorGoToEndSelectNextSpecialIsFormDirty=ExitCallShowError(“clsApplication",“Get_IsFormDirty",Err.Number,_GoToEndPublicPropertyGetSpecialIsFormDirty(frmFormAsForm)AsBoolean‘*Purpose:Determinewhetheranyofthedataontheformhas ‘*Accepts:frmForm-thenameoftheformto‘*Returns:Trueifevenonecontrol’s hanged isTrue;otherwise‘* :Errorsaretrappedbecauseattemptingto theD hangedpropertyofacontrolthatdoesn’t haveone(suchasaFrame)causesarun-timeerror.OnErrorResumeNextDim AsDim AsConstc_NoSuchProperty=Constc_NoError=‘*AssumethattheformisSpecialIsFormDirty=‘*LoopthroughallcontrolsontheForEachctlIn‘*Resettheerror hanged= ‘*Determinethetypeoferror(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2030年中国液化石油气罐车产业未来发展趋势及投资策略分析报告
- 2024-2030年中国液化气瓶除锈机产业未来发展趋势及投资策略分析报告
- 2024-2030年中国海藻糖行业市场调查分析及投资价值研究报告
- 2024年淡水养殖产品种苗项目提案报告
- 2022年大学化学专业大学物理下册期中考试试卷-附解析
- 2022年大学生物科学专业大学物理二模拟考试试题A卷-附解析
- 2022年郑州市重点中学数学九上期末复习检测试题含解析
- UPS系统运行管理方案
- 别墅庭院水池施工方案
- 高温天气环保施工安全方案
- 语音厅策划方案
- 人教版五年级上册数学简便计算300题及答案
- 2024年家庭教育指导师考试(重点)题库及答案(含各题型)
- 阿里巴巴福利分析课件
- 广西汽车站案例分析报告
- 抖音认证承诺函
- 上呼吸道感染呼吸查房
- 化学品作业场所安全警示标志双氧水
- 肿瘤细胞的免疫逃逸机制
- 口腔科诊疗技术操作规范2023版
- 2024年中粮集团有限公司招聘笔试参考题库含答案解析
评论
0/150
提交评论