Question DataTable frustration

Status
Not open for further replies.

demausdauth

Well-known member
Joined
Mar 24, 2008
Messages
281
Location
Minnesota
Programming Experience
3-5
VS2005 SP1

I have a datatable that is not created from a database, in other words i have created the columns and added them to a datatable object. Then I fill the rows and add them to the datatable. Now i need to delete some of the rows but not others.

VB.NET:
 For Each drCheck As DataRow In dtAttach.Rows
                If Not drCheck("AttachType").ToString.ToUpper = "A" AndAlso My.Computer.FileSystem.FileExists(drCheck("PathName") & "\" & drCheck("Attachment")) Then
                    'file is not attachtype 'A' and it exsists in the acordforms directory
                    My.Computer.FileSystem.DeleteFile(drCheck("PathName") & "\" & drCheck("Attachment"), FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.DeletePermanently)
                    drCheck.Delete()
                End If
            Next
            dtAttach.AcceptChanges()

One would think this would work and it is the most common solution that I have found in searching. This will however error out on the 'Next' with IndexOutOfRange exception.


Did I miss something. Anybody got any ideas out there?
 
You are deleting a row from the dataTable which alters the number of rows. Any time you are deleting an item from a collection while enumerating that collection you should start at the end and go backwards through the collection.
VB.NET:
For i as Integer = dtAttach.Rows.Count -1 to 0 Step -1
    If Not dtAttach.Rows(i).Item("AttachType") ...
Next i
 
And I just remembered about the Select method of the dataTable. If you have a large number of rows to iterate, it would be best to use the Select method to find the rows that don't have AttachType = "A" then you have a possibly smaller collection to iterate.
VB.NET:
Dim selectedRows as DataRow() = dtAttach.Select("AttachType <> 'A'")
'please verify the above SQL statement, I'm writing this from memory so it could be incorrect
For Each drCheck as DataRow In selectedRows
    'use the Path.Combine function, it's more robust than adding the "\"
    Dim fileName as String = IO.Path.Combine(drCheck("PathName"), drCheck("Attachment"))
    If My.Computer.FileSystem.FileExists(fileName) Then
        My.Computer.FileSystem.DeleteFile(fileName, FileIO.UIOption.OnlyErrorDialogs, _
          FileIO.RecycleOption.DeletePermanently)
        drCheck.Delete
    End If
Next
Notice that I didn't have to step through this collection backwards. This is because calling the Delete method on drCheck doesn't affect the 'selectedRows' collection returned by the dataTable.Select method as it does the dataTable.Rows property/collection. (The Delete method marks a row for deletion and removes it from the dataTable.Rows collection).
 
Either way will work, and your sql was correct, the datatable in question is small (at most 20 rows) but I do think that the second method you provided will work best. Thanks paszt.
 
Status
Not open for further replies.
Back
Top