Home » excel » vb.net – Exit condition not triggering in Do Until loop

vb.net – Exit condition not triggering in Do Until loop

Posted by: admin April 23, 2020 Leave a comment

Questions:

I’m trying to write an application that takes a report (Excel worksheet), manipulates a row, then goes to the next row, then the next row, etc., then exits the Do Until loop once the first two cells in the next row are empty (indicating that there are no more rows to process), like so:

Imports Excel = Microsoft.Office.Interop.Excel

Dim MSExcel As New Excel.Application
MSExcel.Visible = True

Dim WorkbookA As Excel.Workbook
Dim WorksheetA As Excel.Worksheet

Dim i As Integer = 2 'Skipping header row
Dim Split() As String
Dim SomeStrings() As String = {"StringA", "StringB"} 'etc... an array of strings

WorkbookA = MSExcel.Workbooks.Open(TextBox1.Text)
WorksheetA = WorkbookA.Sheets.Item(1)

Do Until WorksheetA.Cells(i, 1).Value = "" And WorksheetA.Cells(i, 2).Value = ""

'~~If Column A cell does not contain 'valueA' or Column E cell does not contain 'valueB', delete the row
        Do Until InStr(WorksheetDisplay.Cells(i, 1).Value, "ValueA") <> 0 And InStr(WorksheetDisplay.Cells(i, 5).Value, "ValueB") <> 0 _
            And InStr("somenumbershere", Strings.Left((WorksheetDisplay.Cells(i, 3).Value), 1)) <> 0 'Only keeps entries that begin with a certain number
            WorksheetDisplay.Rows(i).Delete() 'Otherwise we delete the row
        Loop

        For Each Str As String In SomeStrings
            If Str = WorksheetDisplay.Cells(i, 3).Value Then
                Split = Strings.Split(WorksheetDisplay.Cells(i, 3).Value, " ")
                WorksheetDisplay.Cells(i, 3).Value = Split(0) & " some text here"
            End If
        Next

        i = i + 1

Loop

However the program never stops running.

Any idea why?

How to&Answers:

In your inner do until..loop where you are checking for three different conditions, if all 3 of those conditions are not met, your code will keep deleting the top row of the worksheet. This causes Excel to keep adding rows to the bottom of the worksheet.

So, this inner do loop has the potential to run forever, preventing the outer do loop from ever evaluating the existence of blank cells. A better arrangement of logic might be:

Do Until WorksheetA.Cells(i, 1).Value = "" And WorksheetA.Cells(i, 2).Value = ""
  If InStr(WorksheetDisplay.Cells(i, 1).Value, "ValueA") <> 0 And InStr(WorksheetDisplay.Cells(i, 5).Value, "ValueB") <> 0 _
            And InStr("somenumbershere", Strings.Left((WorksheetDisplay.Cells(i, 3).Value), 1)) <> 0 'Only keeps entries that begin with a certain number
    WorksheetDisplay.Rows(i).Delete() 'Otherwise we delete the row
    'Decrement i so that the row that used to be beneath the row just deleted is not skipped.
    i = i - 1
  Else
    For Each Str As String In SomeStrings
      If Str = WorksheetDisplay.Cells(i, 3).Value Then
        Split = Strings.Split(WorksheetDisplay.Cells(i, 3).Value, " ")
        WorksheetDisplay.Cells(i, 3).Value = Split(0) & " some text here"
      End If
    Next
  End If
  i = i + 1
Loop

I haven’t run this code, since I don’t know what kind of dataset you have to test against; but basically, if you delete a row, you need to get back to the outer do loop to check if you have run out of data, and stop execution if you have.