Home > OS >  Reading, modifying and writing a CSV with CSVHelper (variable scope with 'using' )
Reading, modifying and writing a CSV with CSVHelper (variable scope with 'using' )

Time:08-21

This is a general coding question of how I can share the same list of data between the stages of reading, modifying and writing.

I'm a novice and new to C# too, so I'm struggling. I was expecting to be able to: read the CSV into the variable records, modify one or more of the records and then write out the modified data as a new CSV, but there is a scope issue with the using function.

The code below won't compile because records is out of scope in both the foreach loop that aims to modify some data and again when I'm trying to write the modified file.

I have tried various things to make records a more global variable but they have all failed and I am out of my depth.

I'm not even sure that this is the best way to approach the problem, so any advice would be appreciated.

   private void Btn_Merge_Click(object sender, EventArgs e)
    {
        // Read the CSV into 'records'
        StreamReader reader = new StreamReader(textBox_Shopify.Text);
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            var records = csv.GetRecords<Contact>();
        }

        // We now need to find the record for a specific person and change it
        foreach (Contact customer in records)
        {
            if (customer.Email == "[email protected]")  // Hard-coded while testing
            {
                string Tags = customer.Tags;   // Get the current tags
                                               // If the Lead Marking tag is not already there, add it
                if (!Tags.Contains("Send me Lead Marketing"))
                {
                    // If there are tags already there, append a semi-colon separator
                    if (customer.Tags.Length > 0)
                    {
                        customer.Tags  = ";";
                    }
                    customer.Tags  = "Send me Lead Marketing";
                    MessageBox.Show(customer.Email   "  Tags: "   customer.Tags);  //Just while I'm testing

                }
            }
            // If the customer is not in the list, add them as a new record

            // To do...
        }

        // We can now write out the modified file
        using (var writer = new StreamWriter(@"C:\temp\Output.csv"))
        using (var outputCSV = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            outputCSV.WriteRecords(records);
        }

    }

    public class Contact
    {
        [Name("First Name")]  // This 'attribute' allows the class property First_Name to be matched to the header "First Name"
        public string First_Name { get; set; }
        [Name("Last Name")]
        public string Last_Name { get; set; }
        public string Email { get; set; }
        [Name("Accepts Email Marketing")]
        public string Accepts_Email_Marketing { get; set; }
        public string Company { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string City { get; set; }
        public string Province { get; set; }
        [Name("Province Code")]
        public string Province_Code { get; set; }
        public string Country { get; set; }
        [Name("Country Code")]
        public string Country_Code { get; set; }
        public string Zip { get; set; }
        public string Phone { get; set; }
        [Name("Accepts SMS Marketing")]
        public string Accepts_SMS_Marketing { get; set; }
        [Name("Total Spent")]
        public string Total_Spent { get; set; }
        [Name("Total Orders")]
        public string Total_Orders { get; set; }
        public string Tags { get; set; }
        public string Note { get; set; }
        [Name("Tax Exempt")]
        public string Tax_Exempt { get; set; }
     }

CodePudding user response:

@Mureinik is halfway there. Since CsvHelper will only yield records as you iterate them, you will also need to call ToList() or in some other way iterate the records within the using statement.

IEnumerable<Contact> records;

// Read the CSV into 'records'
StreamReader reader = new StreamReader(textBox_Shopify.Text);
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    records = csv.GetRecords<Contact>().ToList();
}

CodePudding user response:

You could define records in the scope of the entire method:

private void Btn_Merge_Click(object sender, EventArgs e)
{
    IEnumerable<Contact> records;

    // result of the code...
  • Related