You have a couple of issues with your code.
Firstly you are attempting to show Form2 within the loop and secondly you are showing it in a modeless state. In other words processing of the loop continues after the Form2.Show line.
@Ralf_Meier has given an excellent suggestion of using a
DataGridView[
^]. It simplifies all of the code for working out the size of the controls, the positions, adding them to a collection.
Here is a working example. I've made some other adjustments to the code as well so watch out for the comments explaining why.
Public Class Form1
Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim xlApp As Application
Dim xlWorkBook As Workbook
Dim xlWorkSheet As Worksheet
Dim range As Range
OpenFileDialog1.Filter = "Excel files (*.xls*)|*.xls*|All files (*.*)|*.*"
OpenFileDialog1.FileName = ""
If OpenFileDialog1.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
Exit Sub
End If
Dim sr As New IO.StreamReader(OpenFileDialog1.FileName)
MessageBox.Show("You have selected" + OpenFileDialog1.FileName)
Dim listOfResults = New List(Of String)()
xlApp = New Excel.Application
xlWorkBook = xlApp.Workbooks.Open(OpenFileDialog1.FileName)
xlWorkSheet = xlWorkBook.Worksheets(1)
range = xlWorkSheet.UsedRange
For rCnt = 1 To range.Rows.Count
For cCnt = 14 To range.Columns.Count
Dim tst As String = xlWorkSheet.Cells(rCnt, cCnt).Value.ToString()
If (New String() {"4", "5", "6", "7", "8", "9", "10"}).Contains(tst) Then
Dim foo As String = range.Cells(rCnt, "E").Value.ToString()
listOfResults.Add(foo)
End If
Next
Next
xlWorkBook.Close()
xlApp.Quit()
releaseObject(xlApp)
releaseObject(xlWorkBook)
releaseObject(xlWorkSheet)
If listOfResults.Count > 0 Then
Form2.PopulateForm2(listOfResults)
End If
Form2.ShowDialog()
End Sub
And Form2...
Public Class Form2
Public Sub PopulateForm2(results As List(Of String))
DataGridView1.Columns.Clear()
DataGridView1.Columns.Add(New DataGridViewColumn())
DataGridView1.Columns.Add(New DataGridViewButtonColumn())
DataGridView1.AllowUserToAddRows = False
DataGridView1.Rows.Clear()
For count As Integer = 0 To results.Count - 1
Dim dr As DataGridViewRow = New DataGridViewRow()
Dim dc As DataGridViewCell = New DataGridViewTextBoxCell()
dc.Value = results(count)
dr.Cells.Add(dc)
Dim button As DataGridViewButtonCell = New DataGridViewButtonCell()
button.Value = "Print"
dr.Cells.Add(button)
DataGridView1.Rows.Add(dr)
Next
End Sub
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
If e.ColumnIndex = 1 Then
Dim dgv = CType(sender, DataGridView)
MessageBox.Show(String.Format("button {0} clicked. Associated Text is {1}", e.RowIndex.ToString(), dgv.Rows(e.RowIndex).Cells(0).Value))
End If
End Sub
End Class
Notice I haven't had to wire up a button click event - I've used the CellContentClick event for the DataGridView and just checked that the User has clicked on my Button cell (ColumnIndex = 1)