iteration 敏捷_VB Classic和VBA中的Next Iteration功能

iteration 敏捷

介绍 (Introduction)

我需要跳过一些旧的生产代码中For ... Next循环中的一些文件处理,并希望VB(经典)的语句可以下降到当前迭代的末尾,而绕开导致我的语句麻烦。 在某些语言中,我将使用Continue或Iterate语句。 虽然我可以用通常的VB程序结构和语句(有些杂乱)来完成此操作,但我仍记得我在EE文章中看到的一个巧妙技巧,它可能是理想的解决方案,并且是我的编程结构的新成员。

If you are a beginner or interested in VB programming history, I've included examples of Next Iteration implementations in the Next Iteration in Classic VB section following the Conclusion.

如果您是初学者或对VB编程历史感兴趣,我将在结论后的“

Harfang's Smart Combobox article used a neat trick with the Do statement.  His trick is to create a single-execution Do...Loop (what I'm calling a Do Group) with multiple Exit Do statements.  I used his trick to create a well-structured 'next-iteration' functionality.

Harfang的Smart Combobox文章在Do语句中使用了巧妙的技巧。 他的窍门是创建带有多个Exit Do语句的单执行Do ... Loop(我称为Do组)。 我使用他的技巧来创建结构良好的“下一个迭代”功能。

Note: The Continue Statement was a new feature introduced in VB.NET 2005

注意:

背景 (Background)

我的VB经典应用程序之一绘制了从CSV文件读取的数据,这些文件是由单独的C ++应用程序创建的。 最近,我们添加了一项新功能,该功能可将不同(CSV)数据呈现为2D动画。 这是与绘图不同的功能。 这项新功能的测试进展顺利。 上周末,测试人员报告了图形功能存在问题。 它失败了并使整个应用程序崩溃。 由于我在数个版本中都没有接触过图形代码,因此令我震惊的是,该代码突然开始给我们带来问题。

问题确定 (Problem Determination)

测试人员向我发送了一个测试文件目录(来自C ++应用程序的输出),因此我在开发PC上开始了绘图过程。 果然,该应用程序失败,并在绘图例程中出现下标超出范围的错误。 在将问题追溯到数据输入例程之前,我花了一些时间才能运行。 当我们添加了新的2D动画功能时,我们还将CSV文件引入了该应用程序先前版本中不存在的目录中。 图形代码正在读取“电影”文件,就像它们是图形数据集一样!

In the following code snippet, a file list control's files are being opened and the data being read into the application's data structures.  Part of the processing is the classification of data, based on the file name pattern (*AMP* or *PHASE*).  

在下面的代码片段中,正在打开文件列表控件的文件,并将数据读到应用程序的数据结构中。 处理的一部分是根据文件名模式(* AMP *或* PHASE *)对数据进行分类。

'open the csv files and glom the column headers and read the data
For intFileLoop = 0 To flstDAT_Files.ListCount - 1
  intFilenum = FreeFile
  Open strPath & "\" & flstDAT_Files.List(intFileLoop) For Input As #intFilenum

  'Process file header line

  'Assign processing type, based on file name  

  'Other file data processing takes place here, based on processing type

Next intFileLoop

问题解决 (Problem Resolution)

我需要排除这些“电影”文件的读取。 Select Case语句似乎包含正确的选择逻辑。 现在,我不得不在For ... Next循环中重组代码。 这是哈尔方trick俩发挥作用的地方。

Even though I do a lot of VB coding, my favorite language is REXX.  One of the nice programming structures in that language is an ITERATE statement.  When executed within one of the looping structures (Do...End), the execution immediately drops down to the End statement, bypassing all code following the ITERATE statement.

即使我做了很多VB编码,但我最喜欢的语言是REXX。 用该语言编写的一种不错的编程结构是ITERATE语句。 在其中一个循环结构(Do ... End)中执行时,执行立即下降到End语句,绕过ITERATE语句之后的所有代码。

创建Do组-技巧 (Creating the Do Group -- the TRICK)

该“技巧”以VB结构之一Do ... Loop对开始。
  Do 
    'your VB statements here
  Loop 

Do statement or the Loop statement.  

Do语句或Loop语句。

Since we want this Do Group to be executed at least once, we need to add the condition to the

由于我们希望该“执行组”至少执行一次,因此需要将条件添加到

Loop statement. 循环语句。

Since we want this Do Group to be executed at most one time, we need to supply a terminating condition.

由于我们希望此“执行组”最多执行一次,因此我们需要提供终止条件。

NOTE: I'm going to use a While clause, which means the terminating condition must be False.  If I were to use an Until clause, the terminating condition would be True.

注意:我将使用While子句,这意味着终止条件必须为直到子句,则终止条件将为

  Do 
    'your VB statements here, including one or more Exit Do statements
  Loop While False

Exit Do statement to gracefully exit from this single-execution Do...Loop structure.

Exit Do语句可从此单执行Do ... Loop结构正常退出。

Since I'm creating an ITERATE functionality, I need to place my Do Group inside some other looping structure.

由于我正在创建ITERATE功能,因此需要将Do Group放置在其他循环结构中。

Example use with For...Next:

Dim lngLoop As Long

For lngLoop = 1 To 10

  Do '<<Do Group
    If lngLoop = 3 Then Exit Do 'Group
    Debug.Print lngLoop
  Loop While False '>>Do Group

Next

For Example Notes:

例如注释:

This example will execute the Debug.Print statement for all lngLoop values except 3.

本示例将对除3之外的所有lngLoop值执行Debug.Print语句。

Since the For...Next structure takes care of the initialization, iteration variable changes, and termination, you could use a code template without any consideration for placing statements between the For and the Do statements or between the Loop and Next statements.

由于For ... Next结构负责初始化,迭代变量更改和终止,因此您可以使用代码模板而无需考虑在For和Do语句之间或Loop与Next语句之间放置语句。

Example use with Do...Loop:

Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("Select * From Patients Where Active = True")

Do Until rs.EOF
  
  Do '<<Do Group
    If rs.Fields("QC") = True Then Exit Do 'Group
    Debug.Print rs.Fields("PatientName")
  Loop While False '>>Do Group
  
  rs.MoveNext 

Loop

Do Example Notes:

做示例注释:

This example will execute the Debug.Print statement for all records except the quality control records (QC=True) in the recordset.

本示例将对除记录集中的质量控制记录(QC = True)以外的所有记录执行Debug.Print语句。

Since the Do...Loop structure only checks termination conditions, you would use a code template with some empty lines for placing statements between the Do and the Do (group) statements or between the Loop (group) and Loop statements.  In this example, we need to navigate to the next record in the recordset.

由于Do ... Loop结构仅检查终止条件,因此将使用带有一些空行的代码模板在Do和Do(组)语句之间或Loop(组)和Loop语句之间放置语句。 在此示例中,我们需要导航到记录集中的下一条记录。

ITERATE功能现已投入生产 (The ITERATE Feature Now in Production)

这是代码的生产版本,具有重新定位和修改的Select Case结构-现在,它具有新的Case Else子句。 我还将代码放置在Do Group结构内的For ... Next循环中。
'open the csv files and glom the column headers and read the data
For intFileLoop = 0 To flstDAT_Files.ListCount - 1
  Do '<< Do Group
    'Assign processing type, based on file name  

    If Not ValidFileType Then Exit Do 'ITERATE => Next intFileLoop
    
    intFilenum = FreeFile
    Open strPath & "\" & flstDAT_Files.List(intFileLoop) For Input As #intFilenum

    'Process file header line

    'Other file data processing takes place here, based on processing type

  Loop While False '>>Do Group

Next intFileLoop

替代解决方法 (Alternative Work-around)

PaulHews suggested I post an example of restructured production code.  In this example, there is a single If...EndIf protecting the file processing code.  Any number of prior conditions might be checked, in addition to ValidFileType, that could set the strDataType variable.  If your condition-checking is not dependent on prior validation, what I'll call 'flat', then this is actually a preferred work-around to the problem.  It is simpler to understand and maintain. PaulHews建议我发布一个重组的生产代码示例。 在此示例中,只有一个If ... EndIf保护文件处理代码。 除ValidFileType外,还可以检查任何其他可以设置strDataType变量的先决条件。 如果您的条件检查不依赖于先前的验证(我称之为“扁平化”),那么实际上这是解决该问题的首选方法。 它更易于理解和维护。
'open the csv files and glom the column headers and read the data
For intFileLoop = 0 To flstDAT_Files.ListCount - 1
  'Assign data type, based on file name  
  
  'Set a flag variable to prevent later processing
  If Not ValidFileType(flstDAT_Files.List(intFileLoop)) Then 
    strDataType = DoNotProcessFile
  End If

  If strDataType <> DoNotProcessFile Then
    intFilenum = FreeFile
    Open strPath & "\" & flstDAT_Files.List(intFileLoop) For Input As #intFilenum

    'Process file header line

    'Other file data processing takes place here

  End If
    
Next intFileLoop

Notes:

笔记:

DoNotProcessFile is some constant that will never equal an expected file data type value.

DoNotProcessFile是一个永远不会等于预期文件数据类型值的常数。

ValidFileType is a boolean function that will validate the file name as valid for processing.

ValidFileType是一个布尔函数,它将验证文件名是否有效以进行处理。

结论 (Conclusion)

这是可以结合到VBA例程中的新功能。 在VB迭代结构中使用Do组(For ... Next,For Each ... Next,Do ... Loop)将使您的代码干净,不会缩进,结构良好且没有Go To语句。

If you found this article helpful, please click the Yes link below.

如果您发现本文有帮助,请单击下面的“是”链接。

______________________________________________________________________________

__________________________ __________ __________ __________ __________ __________ __

经典VB中的下一个迭代-应避免的技术 (Next Iteration in Classic VB -- techniques to be avoided)

三个VB循环结构(For ... Next,For Each ... Next,Do ... Loop)非常有效且可靠地执行其功能。 但是,有时您不想处理要迭代的集合(集合)中的一个或多个项目。 初学者和自学成才的程序员已使用以下技术。

Increment the Iteration Variable

增加迭代变量

NOTE: Changing the iteration variable value inside a For...Next loop is a bad programming practice and should be avoided at all costs.

In this example, a row is 'skipped' by incrementing the interation variable, lngLoop.

在此示例中,通过增加插入变量lngLoop来“跳过” 一行

Dim lngLoop As Long
For lngLoop = 1 To ActiveSheet.Rows.Count
  If IsNumeric(ActiveSheet.Cells(lngLoop, 1).Value) Then
    lngLoop = lngLoop + 1 'skip the separator row
  End If

  'Process the cells on this row
  ActiveSheet.Cells(lngLoop, 3).Value = Sqr((ActiveSheet.Cells(lngLoop, 1).Value ^ 2) + (ActiveSheet.Cells(lngLoop, 2).Value ^ 2))

Next

Use a Go To

使用转到

One of the first lessons taught in structured programming classes is "never use a Go To."  While this is an excellent rule-of-thumb, we frequently encounter the Go To statements of other programmers, posted online or inherited at our workplace.  Many VB Programmers have found the GoTo statement quite convenient for skipping over code they don't want to execute.

在结构化编程课程中教授的第一课是“从不使用Go To”。 尽管这是一个很好的经验法则,但我们经常遇到其他程序员的

In this example, we see a programmer is clearing/resetting controls on a form, looping through the Controls collection.  I imagine that this code started out without the GoTo statements.  Then the programmer realized (or was told) that once a control is processed, there is no need to compare its type in the subsequent IF statements.

在此示例中,我们看到程序员正在清除/重置表单上的控件,从而遍历Controls集合。 我认为这段代码开始时没有GoTo语句。 然后,程序员意识到(或被告知)一旦处理了控件,就无需在后续的

Dim ctlThing As Control

For Each ctlThing In Me.Controls
  
  If TypeOf ctlThing Is TextBox Then
    ctlThing.Text = vbNullString
    ctlThing.BackColor = vbWhite
    GoTo nextControl
  End If
  If TypeOf ctlThing Is ComboBox Then
    ctlThing.Clear
    ctlThing.Text = vbNullString
    ctlThing.BackColor = vbWhite
    GoTo nextControl
  End If
  If TypeOf ctlThing Is Label Then
    If ctlThing.Tag Like "*reset;*" Then
      ctlThing.Caption = vbNullString
    End If
    GoTo nextControl
  End If
  If TypeOf ctlThing Is Menu Then
    If ctlThing.Checked Then
      ctlThing.Checked = False
    End If
    GoTo nextControl
  End If
  If TypeOf ctlThing Is CheckBox Then
    ctlThing.Value = vbUnchecked
    GoTo nextControl
  End If
  If TypeOf ctlThing Is OptionButton Then
    ctlThing.Value = False
    GoTo nextControl
  End If
  If TypeOf ctlThing Is ListBox Then
    ctlThing.Clear
    GoTo nextControl
  End If
  If TypeOf ctlThing Is CommandButton Then
    If ctlThing.Style = vbButtonGraphical Then
      ctlThing.Picture = LoadPicture()
    End If
    GoTo nextControl
  End If
  
nextControl:
Next

Note: I have even encountered a form of this GoTo method using error-handling routines, using the Resume statement like a GoTo.  It is painful enough to remember.  I couldn't bring myself to replicate it in this article.  It was a nightmare to behold.

注意:我什至遇到过使用错误处理例程(例如GoTo)的Resume语句使用此GoTo方法的一种形式。 要记住它是很痛苦的。 在这篇文章中,我无法自己复制它。 真是一场噩梦。

Use If...Else

使用If ... Else

In this example, the items on the CSV file's (current) row are validated prior to being inserted into the active worksheet.  

在此示例中,CSV文件(当前)行上的项目在插入活动工作表之前先经过验证。

Notice that each IF statement's validation increases the indentation level.  It wouldn't take too many more input columns before the IF statements aren't visible without scrolling!

请注意,每个IF语句的验证都会增加缩进级别。 在不滚动而看不到IF语句之前,不需要太多输入列!

Dim vInputs(1 To 4) As Variant
Dim intFN As Integer
Dim lngRow As Long
intFN = FreeFile
Open "C:\Temp\2Bimported.csv" For Input As #intFN
Do Until EOF(intFN)
    
    Input #intFN, vInputs(1), vInputs(2), vInputs(3), vInputs(4)
    If IsDate(vInputs(1)) Then
    Else
        If (vInputs(2) = "NEW" Or vInputs(2) = "UPD") Then
            If IsNumeric(vInputs(2)) Then
                If Len(Trim(vInputs(4))) <> 0 Then
                    lngRow = lngRow + 1
                    ActiveSheet.Range(Cells(lngRow, 1), Cells(lngRow, 4)) = vInputs
                End If
            End If
        End If
    End If

Loop
Close #intFN

Note: When I see code like this, I usually try to refactor it, moving the validation into a separate function that receives the vInputs array as a parameter and returns a string/collection of validation error messages.  If there were no errors returned, then the update takes place.

注意:当我看到这样的代码时,我通常会尝试重构它,将验证移到一个单独的函数中,该函数接收vInputs数组作为参数并返回验证错误消息的字符串/集合。 如果没有错误返回,则进行更新。

翻译自: https://www.experts-exchange.com/articles/2755/Next-Iteration-functionality-in-VB-classic-and-VBA.html

iteration 敏捷

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值