Nazima
Nazima

Reputation: 291

How to remove empty rows from DataTable

I am working on importing data from an Excel sheet to database. The Excel sheet contains few empty rows and I want to remove those empty rows, then insert cleared data into database.
I have written a code by referring other code, this is the code for inserting values:

OleDbConnection cnn = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + txtExcelFile.Text + "';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'");
//DataTable dt = new DataTable();

try
{
    cnn.Open();
    OleDbDataAdapter data = new OleDbDataAdapter("select * from [Customers$]", cnn);
    data.Fill(dsExcel);
    dgvCustomers.ColumnHeadersVisible = false;

    SqlConnection connection = new SqlConnection("Data Source=COMPUTER-8EB749;Initial Catalog=KITS;Integrated Security=true");
    connection.Open();
    for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++)
    {
        string ID = ds.Tables[0].Rows[i][0].ToString();
        Int16 CustID = Convert.ToInt16(ID);
        string CustName = dsExcel.Tables[0].Rows[i][1].ToString();
        string CardScheme = dsExcel.Tables[0].Rows[i][2].ToString();
        string Outlet = dsExcel.Tables[0].Rows[i][3].ToString();
        string TerminalNum = dsExcel.Tables[0].Rows[i][4].ToString();
        Int32 Terminal = Convert.ToInt32(TerminalNum);
        string Date1 = dsExcel.Tables[0].Rows[i][5].ToString();
        DateTime Date = Convert.ToDateTime(Date1);
        string Time = dsExcel.Tables[0].Rows[i][6].ToString();
        DateTime DateTime = Convert.ToDateTime(Time);
        string Amount1 = ds.Tables[0].Rows[i][7].ToString();
        double Amount = Convert.ToDouble(Amount1);

        SqlCommand com = new SqlCommand("insert into Customer(CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount) values ('" + CustID + "','" + CustName + "','" + CardScheme + "','" + Outlet + "','" + Terminal + "','" + Date + "','" + DateTime + "','" + Amount + "')", connection);
        com.ExecuteNonQuery();
    }
    connection.Close();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}
finally
{
    MessageBox.Show("Data Inserted Successfully.");
}

Can anyone say me how can I remove empty rows so that i can insert only data?!

Excel Sheet

Upvotes: 16

Views: 99058

Answers (16)

Kennedy Ngure
Kennedy Ngure

Reputation: 11

for (int i = dt.Rows.Count - 1; i >= 0; i--) {
    if (dt.Rows[i][1] == DBNull.Value) {
        dt.Rows[i].Delete();
    }
}
dt.AcceptChanges();

Upvotes: 1

Sathish
Sathish

Reputation: 69

To remove Empty Rows from DataTable:

dt.Rows.Cast<DataRow>().ToList().FindAll(Row =>
{ return String.IsNullOrEmpty(String.Join("", Row.ItemArray)); }).ForEach(Row =>
{ dt.Rows.Remove(Row); });

Upvotes: 0

Karthick Ganesan
Karthick Ganesan

Reputation: 91

This will remove all empty rows from the data table:

DataTable dt = dt.Rows
                 .Cast<DataRow>()
                 .Where(row => !row.ItemArray.All(f => f is DBNull))
                 .CopyToDataTable();

OR

DataTable dt = dt.Rows
                 .Cast<DataRow>()
                 .Where(row => !row.ItemArray.All(f => f is DBNull || 
                                  string.IsNullOrEmpty(f as string ?? f.ToString())))
                 .CopyToDataTable();

Upvotes: 6

Muflix
Muflix

Reputation: 6778

Based on existing answers I use following

public static bool AllColumnsEmpty(this DataRow row)
{
    if (row == null)
    {
        return true;
    }
    else
    {
        foreach (var value in row.ItemArray)
        {
            if (value != null && value.ToString() != "")
            {
                return false;
            }
        }
        return true;
    }
}

public static void RemoveEmptyRows(this DataTable data)
{
    var rowsToDelete = data.Rows.Cast<DataRow>()
        .Where(row => row.AllColumnsEmpty())
        .ToList();

    rowsToDelete.ForEach(row => data.Rows.Remove(row));
}

Usage is then

someDatatable.RemoveEmptyRows();

Upvotes: 0

karunakar bhogyari
karunakar bhogyari

Reputation: 679

This worked for me. If we do not check rows and directly do CopyToDataTable() then you may get an exception when the data table has empty rows.

var rows = tbl.Rows.Cast<DataRow>()
                            .Where(row => !row.ItemArray.All(field => field is DBNull || String.IsNullOrWhiteSpace(field as string ?? field.ToString())));

if (rows.Any())
    tbl = rows.CopyToDataTable();

Upvotes: 0

Sharif Lotfi
Sharif Lotfi

Reputation: 574

I change a little in @Levitikon post https://stackoverflow.com/a/9233696/5848472 with @shA.t comment , and this code remove all empty Rows and Columns in datatable:

dt = ds.Tables[tablename].Rows
    .Cast<DataRow>()
    .Where(row => !row.ItemArray.All(field => field is DBNull || 
           string.IsNullOrWhiteSpace(field as string ?? field.ToString())))
    .CopyToDataTable();
foreach (var column in dt.Columns.Cast<DataColumn>().ToArray())
    {
        if (dt.AsEnumerable().All(dr => dr.IsNull(column)))
            dt.Columns.Remove(column);
    }

Upvotes: 0

LostCause
LostCause

Reputation: 151

I modified Cfrim's answer. You need to check for both empty and whitespace strings. The white space comes from the deleted cells and the empty space comes from deleted data.

private DataTable StripEmptyRows(DataTable dt)
        {
            List<int> rowIndexesToBeDeleted = new List<int>();
            int indexCount = 0;
            foreach(var row in dt.Rows)
            {
                var r = (DataRow)row;
                int emptyCount = 0;
                int itemArrayCount = r.ItemArray.Length;
                    foreach (var i in dr.ItemArray)
                    {
                        if (string.IsNullOrEmpty(i.ToString()) || string.IsNullOrWhiteSpace(i.ToString()))
                            emptyCount++;
                    }

                if(emptyCount == itemArrayCount) rowIndexesToBeDeleted.Add(indexCount);

                indexCount++;
            }

            int count = 0;
            foreach(var i in rowIndexesToBeDeleted)
            {
                dt.Rows.RemoveAt(i-count);
                count++;
            }

            return dt;
        }

Upvotes: 1

Jomba
Jomba

Reputation: 1

this works perfect for me:

dt.Load(cmd.ExecuteReader());
var x = dt.Rows.Cast<DataRow>()
   .Where(row => !Array.TrueForAll(row.ItemArray, value => 
   { return value.ToString().Length == 0; }
   ));

dt = x.CopyToDataTable();

Upvotes: 0

Levitikon
Levitikon

Reputation: 7847

This will remove all rows that which each of it's columns contain either nothing or white space:

dataTable = dataTable.Rows
    .Cast<DataRow>()
    .Where(row => !row.ItemArray.All(field => field is DBNull || 
                                     string.IsNullOrWhiteSpace(field as string)))
    .CopyToDataTable();

Upvotes: 78

Muhammad hanif
Muhammad hanif

Reputation: 31

To check Empty Rows

Foreach(DataRow as row in datable.Rows) {
    var isEmpty = row.ItemArray.All(c => c is DBNull);
    if(!isEmpty) {
        //Your Logic
    }
}

Upvotes: 2

Cfrim
Cfrim

Reputation: 980

I've made this private method that does the trick. It takes a DataTable as argument and returns the same DataTable without empty rows.

private DataTable StripEmptyRows(DataTable dt)
    {
        List<int> rowIndexesToBeDeleted = new List<int>();
        int indexCount = 0;
        foreach(var row in dt.Rows)
        {
            var r = (DataRow)row;
            int emptyCount = 0;
            int itemArrayCount = r.ItemArray.Length;
            foreach(var i in r.ItemArray) if(string.IsNullOrWhiteSpace (i.ToString())) emptyCount++;

            if(emptyCount == itemArrayCount) rowIndexesToBeDeleted.Add(indexCount);

            indexCount++;
        }

        int count = 0;
        foreach(var i in rowIndexesToBeDeleted)
        {
            dt.Rows.RemoveAt(i-count);
            count++;
        }

        return dt;
    }

Upvotes: 2

Nitin Suryawanshi
Nitin Suryawanshi

Reputation: 1

public static DataTable RemoveEmptyRows(DataTable dt) 
{ 
    List removeRowIndex = new List(); 

    foreach (DataRow dRow in dt.Rows) 
    { 
        for (int index = 0; index < dt.Columns.Count; index++) 
        { 
            if (string.IsNullOrEmpty(dRow[index].ToString().Trim())) 
            { 
                removeRowIndex.Add(dRow); 
                break; 
            } 
            else if (dRow[index] == DBNull.Value) 
            { 
                removeRowIndex.Add(dRow); 
                break; 
            } 
        } 
    } 

    foreach (DataRow rowIndex in removeRowIndex) 
    { 
        dt.Rows.Remove(rowIndex); 
    } 

    return dt; 
}

Upvotes: 0

Noora
Noora

Reputation: 21

try
{
    OpenOleDBConnection();
    OleDbDataAdapter dataAdapter = new OleDbDataAdapter("select * from [" + SelectedSheet + "]", Connection);

    dataAdapter.Fill(DataTable);

    if ((DataTable != null) && (DataTable.Rows != null) && (DataTable.Rows.Count > 0))
    {
        List<System.Data.DataRow> removeRowIndex = new List<System.Data.DataRow>();
        int RowCounter = 0;
        foreach (System.Data.DataRow dRow in DataTable.Rows)
        {                            
            for(int index = 0; index < DataTable.Columns.Count; index++)
            {
                if (dRow[index] == DBNull.Value)  
                {
                    removeRowIndex.Add(dRow);
                    break;
                }
                else if (string.IsNullOrEmpty(dRow[index].ToString().Trim()))
                {
                    removeRowIndex.Add(dRow);
                    break;
                }
            }
            RowCounter++;
        }
        // Remove all blank of in-valid rows
        foreach (System.Data.DataRow rowIndex in removeRowIndex)
        {
            DataTable.Rows.Remove(rowIndex);
        }
    }
}
catch(Exception e)
{
    WPFMessageBox.Show(e.Message, Globalization.GetValue("Import_ImportOption_FormHeader"), WPFMessageBoxButtons.OK, WPFMessageBoxImage.Error);
}
finally
{
    CloseOleDBConnection();
}

Here I m also skipping the rows if they have blank entry in any of the row.

Upvotes: 2

codeandcloud
codeandcloud

Reputation: 55200

Try this.

public bool InsertRowsToDataBase()
{
    try
    {
        DataTable excelTable = new DataTable();

        string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + txtExcelFile.Text + "';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'";
        using (OleDbConnection cnn = new OleDbConnection(connString))
        {
            string query = "select * from [Customers$]";
            using (OleDbDataAdapter data = new OleDbDataAdapter(query, cnn))
            {
                data.Fill(excelTable);
            }
        }
        dgvCustomers.ColumnHeadersVisible = false;

        connString = "Data Source=COMPUTER-8EB749;Initial Catalog=KITS;Integrated Security=true";
        using (SqlConnection connection = new SqlConnection(connString))
        {
            connection.Open();
            for (int i = 0; i < excelTable.Rows.Length; i++)
            {
                //takes from the 3rd row
                if (i > 1)
                {
                    DataRow row = excelTable.Rows[i];
                    object ID = row[0];
                    if (ID != null && !String.IsNullOrEmpty(ID.ToString().Trim()))
                    {
                        Int16 CustID = Convert.ToInt16(ID);
                        string CustName = row[1].ToString();
                        string CardScheme = row[2].ToString();
                        string Outlet = row[3].ToString();
                        string TerminalNum = row[4].ToString();
                        Int32 Terminal = Convert.ToInt32(TerminalNum);
                        string Date1 = row[5].ToString();
                        DateTime Date = Convert.ToDateTime(Date1);
                        string Time = row[6].ToString();
                        DateTime DateTime = Convert.ToDateTime(Time);
                        string Amount1 = row[7].ToString();
                        double Amount = Convert.ToDouble(Amount1);

                        string columnNames = "CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount";
                        string query = String.Format("insert into Customer(0}) values ('{1}', '{2}','{3}','{4}','{5}','{6}','{7}','{8}')",
                            columnNames, CustID, CustName, CardScheme, Outlet, Terminal, Date, DateTime, Amount);
                        using (SqlCommand com = new SqlCommand(query, connection))
                        {
                            com.ExecuteNonQuery();
                        }
                    }
                }
                //this is your last row. do whatever you want with this
                DataRow lastRow = excelTable.Rows[excelTable.Rows.Count - 1];
            }
        }
        return true;
    }
    catch (Exception exception)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
        return false;
    }
}

Please note that I am just checking if ID is null and not inserting any such rows as ID will be the PK in your table.

Upvotes: 6

Andreas &#197;gren
Andreas &#197;gren

Reputation: 3929

Why not simply ignore empty rows directly before you are inserting them?

if(string.IsNullOrEmpty(ID + CustName + CardScheme /*.. and so on */))
{
    continue;
}

Like this:

for (int i = 0; i < dsExcel.Tables[0].Rows.Count; i++)
{
    string ID = ds.Tables[0].Rows[i][0].ToString();
    Int16 CustID = Convert.ToInt16(ID);
    string CustName = dsExcel.Tables[0].Rows[i][1].ToString();
    string CardScheme = dsExcel.Tables[0].Rows[i][2].ToString();
    string Outlet = dsExcel.Tables[0].Rows[i][3].ToString();
    string TerminalNum = dsExcel.Tables[0].Rows[i][4].ToString();
    Int32 Terminal = Convert.ToInt32(TerminalNum);
    string Date1 = dsExcel.Tables[0].Rows[i][5].ToString();
    DateTime Date = Convert.ToDateTime(Date1);
    string Time = dsExcel.Tables[0].Rows[i][6].ToString();
    DateTime DateTime = Convert.ToDateTime(Time);
    string Amount1 = ds.Tables[0].Rows[i][7].ToString();
    double Amount = Convert.ToDouble(Amount1);

    /*** Add this if-statement to you code! ***/
    if(string.IsNullOrEmpty(ID + CustName + CardScheme + Outlet + TerminalNum + Date1 + Time + Amount1))
    {
        continue;
    }

    SqlCommand com = new SqlCommand("insert into Customer(CustID,CustName,CardScheme,Outlet,TerminalNum,TranDate,TranDateTime,Amount) values ('" + CustID + "','" + CustName + "','" + CardScheme + "','" + Outlet + "','" + Terminal + "','" + Date + "','" + DateTime + "','" + Amount + "')", connection);
    com.ExecuteNonQuery();
}

Upvotes: 1

Zenwalker
Zenwalker

Reputation: 1919

Your DB itself has empty rows?? Thats quite strange. May be filter it while you do a select query by saying a primary key column is not NULL

Upvotes: 0

Related Questions