views:

34

answers:

2

I'm writing a small app to do a little processing on some cells in a CSV file I have. I've figured out how to read and write CSV files with a library I found online, but I'm having trouble: the library parses CSV files into a DataTable, but, when I try to change a cell of the table, it isn't saving the change in the table!

Below is the code in question. I've separated the process into multiple variables and renamed some of the things to make it easier to debug for this question.

Code

Inside the loop:

string debug1 = readIn.Rows[i].ItemArray[numColumnToCopyTo].ToString();
string debug2 = readIn.Rows[i].ItemArray[numColumnToCopyTo].ToString().Trim();
string debug3 = readIn.Rows[i].ItemArray[numColumnToCopyFrom].ToString().Trim();
string towrite = debug2 + ", " + debug3;
readIn.Rows[i].ItemArray[numColumnToCopyTo] = (object)towrite;

After the loop:

readIn.AcceptChanges();

When I debug my code, I see that towrite is being formed correctly and everything's OK, except that the row isn't updated: why isn't it working? I have a feeling that I'm making a simple mistake here: the last time I worked with DataTables (quite a long time ago), I had similar problems.

If you're wondering why I'm adding another comma in towrite, it's because I'm combining a street address field with a zip code field - I hope that's not messing anything up.

My code is kind of messy, as I'm only trying to edit one file to make a small fix, so sorry.

A: 

Perhaps you need to call AcceptChanges() for the DataTable? What is the library?

Steve
Oops, forgot to include the AcceptChanges code in my code sample above, but it doesn't change anything. The library I found is at http://knab.ws/blog/index.php?/archives/10-CSV-file-parser-and-writer-in-C-Part-2.html
Maxim Zaslavsky
+2  A: 

The easiest way to edit individual column values is to use the DataRow.Item indexer property:

readIn.Rows[i][numColumnToCopyTo] = (object)towrite;

This isn't well-documented, but DataRow.ItemArray's get accessor returns a copy of the underlying data. Here's the implementation, courtesy of Reflector:

public object[] get_ItemArray() {
    int defaultRecord = this.GetDefaultRecord();
    object[] objArray = new object[this._columns.Count];
    for (int i = 0; i < objArray.Length; i++) {
        DataColumn column = this._columns[i];
        objArray[i] = column[defaultRecord];
    }
    return objArray;
}

There's an awkward alternative method for editing column values: get a row's ItemArray, modify those values, then modify the row to use the updated array:

object[] values = readIn.Rows[i].ItemArray;
values[numColumnToCopyTo] = (object)towrite;
readIn.Rows.ItemArray = values;
Jeff Sternal
Great, thanks so much!
Maxim Zaslavsky