web-dev-qa-db-fra.com

Comment supprimer des lignes vides de DataTable

Je travaille sur l'importation de données à partir d'une feuille Excel vers une base de données. La feuille Excel contient quelques lignes vides et je souhaite supprimer ces lignes vides, puis insérer des données effacées dans la base de données.
J'ai écrit un code en faisant référence à un autre code, il s'agit du code permettant d'insérer des valeurs:

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.");
}

Quelqu'un peut-il me dire comment puis-je supprimer les lignes vides afin que je puisse insérer uniquement des données?! 

Excel Sheet

9
Nazima

Essaye ça.

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;
    }
}

Veuillez noter que je vérifie simplement si ID est null et que je n'insère pas de telles lignes car ID sera le PK de votre table.

6
naveen

Ceci supprimera toutes les lignes que chacune de ses colonnes ne contient ni rien ni espace:

dataTable = dataTable.Rows
    .Cast<DataRow>()
    .Where(row => !row.ItemArray.All(field => field is DBNull || 
                                     string.IsNullOrWhiteSpace(field as string)))
    .CopyToDataTable();
60
Levitikon
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();
}

Ici, je saute aussi les lignes si elles ont une entrée vide dans l’une des lignes.

2
Noora

J'ai créé cette méthode privée qui fait l'affaire. Elle prend un DataTable en argument et retourne le même DataTable sans lignes vides.

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;
    }
2
Cfrim

Pourquoi ne pas simplement ignorer les lignes vides directement avant de les insérer?

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

Comme ça:

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();
}
1
Andreas Ågren

J'ai modifié la réponse de Cfrim. Vous devez vérifier les chaînes vides et les espaces blancs. L'espace blanc provient des cellules supprimées et l'espace vide provient de données supprimées.

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;
        }
1
LostCause

Votre base de données a elle-même des lignes vides? C'est assez étrange. Peut être filtré pendant que vous effectuez une requête select en disant qu'une colonne de clé primaire n'est pas NULL

0
Zenwalker
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; 
}
0
Nitin Suryawanshi

Pour vérifier les lignes vides

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

cela fonctionne parfaitement pour moi:

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();
0
Jomba