In DataGridView I have two ComboBox columns:
private string controlFrom= "cmbMachineAndOpIDFrom";
private string controlTo = "cmbMachineAndOpIDTo";
I want to check those two-columns combination for duplicates. If duplicate exists or null the record must be cancelled with message for the user. I try to use RowValidating event for that:
private void dgvTransfers_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
string columName = dgvTransfers.Columns[e.ColumnIndex].Name;
e.Cancel = IsDuplicateExists(columName);
}
The code of IsDuplicateExist:
private bool IsDuplicateExists(string colName)
{
bool res = false;
int existingRowID = 0;
if (colName.Equals(controlFrom) || colName.Equals(controlTo))
{
int cmbFrom = Convert.ToInt32(Helper.GetSelectedRowValueInDGV(dgvTransfers, controlFrom));
int cmbTo = Convert.ToInt32(Helper.GetSelectedRowValueInDGV(dgvTransfers, controlTo));
if (cmbFrom == 0 || cmbTo == 0)
{
res = true;
}
//Check for duplicates
existingRowID = Helper.GetDuplicatedRowIndex(cmbFrom, cmbTo, dgvTransfers, controlFrom, controlTo);
if (existingRowID > 0)
{
//Already exists
GoToDublicatedRecord(existingRowID, dgvTransfers);
res = true;
}
}
return res;
}
I always get 0 value for cmbFrom and cmbTo using method GetSelectedRowValueInDGV:
public static string GetSelectedRowValueInDGV(DataGridView dgvName, string columnName)
{
string res = "0";
if (dgvName.SelectedRows.Count > 0)
{
var vl = dgvName.SelectedRows[0].Cells[columnName].Value;
if (vl.ToString()!=string.Empty && vl != null && vl != DBNull.Value)
{
res = dgvName.SelectedRows[0].Cells[columnName].Value.ToString();
}
}
return res;
}
So first question is why I do not get selected cell value?
Here comes the second part of problem. Since both values are zeroes I get e.Cancel = true. Here I expect editing to be cancelled but instead I get error
'Operation did not succeed because the program cannot commit or quit a
cell value change.'
at row dgvName.DataSource = dt; in CellValueChanged event where GetDataForGridView is called to get data from SQL SP:
public static bool GetDataForGridView(DataGridView dgvName, string storedProcedureName, params SqlParameter[] arrParam)
{
DataTable dt = new DataTable();
bool result;
// Open the connection
using (SqlConnection sqlConn = new SqlConnection(strConn))
{
try
{
sqlConn.Open();
// Define the command
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = sqlConn;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = storedProcedureName;
// Handle the parameters
if (arrParam != null)
{
foreach (SqlParameter param in arrParam)
{
sqlCmd.Parameters.Add(param);
}
}
// Define the data adapter and fill the dataset
using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd))
{
da.Fill(dt);
result = true;
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
result = false;
}
dgvName.AutoGenerateColumns = false;
dgvName.DataSource = dt;
sqlConn.Close();
}
return result;
}
UPDATED
Here is how both Comboboxes are populated:
private void FrmTransfers_Load(object sender, EventArgs e)
{
Helper.GetDataForGridView(dgvTransfers, "pp_sp_Transfers", null);
PopCombo(cmbMachineAndOpIDFrom, "MachineAndOpID",0,0);
PopCombo(cmbMachineAndOpIDTo, "MachineAndOpID",0,0);
}
private void PopCombo(DataGridViewComboBoxColumn combo, string valMember, int parValue1, int parValue2)
{
DataTable dtMO = Helper.ExecuteDataTable("pp_sp_MachineAndOp",
new SqlParameter("#MachineAndOpID", SqlDbType.Int) { Value = parValue1 },
new SqlParameter("#Seq", SqlDbType.Int) { Value = parValue2 });
//Add field to be displayed
dtMO.Columns.Add("ToShow", typeof(string), "'Seq: ' + Seq + ' ID: ' + MachineAndOpID + ' (' + OperationID + ') ' + Operation + ' + ' + Machine");
// bind data table into combo box.
combo.DataSource = dtMO;
combo.DisplayMember = "ToShow";
combo.ValueMember = valMember;
}
The Below Code Returns the following data into text file from the database.
Output
InvoiceNo InvoiceDate Amount Vat Total
001 1/1/2018 200 10 210
002 2/1/2018 300 15 315
What i am looking for is to get Amount,Vat and Total in separate line with the same invoice info so Desired out will be like below
Desired out
001 1/1/2018 200
001 1/1/2018 10
001 1/1/2018 210
002 2/1/2018 300
002 2/1/2018 15
002 2/1/2018 315
Code
private void button1_Click(object sender, EventArgs e)
{
string datetime = DateTime.Now.ToString("yyyyMMddHHmmss");
string LogFolder = #"C:\Log\";
try
{
string FileNamePart = "Invoice";
string DestinationFolder = #"C:\Destination\";
string TableName = "Invoice";
string FileDelimiter = ",";
string FileExtension = ".txt";
SqlConnection SQLConnection = new SqlConnection();
SQLConnection.ConnectionString = "Data Source = .\\SQLEXPRESS; Initial Catalog =Backoffice; "
+ "Integrated Security=true;";
string query = "Select * From " + TableName;
SqlCommand cmd = new SqlCommand(query, SQLConnection);
SQLConnection.Open();
DataTable d_table = new DataTable();
d_table.Load(cmd.ExecuteReader());
SQLConnection.Close();
string FileFullPath = DestinationFolder + "\\" + FileNamePart + "_" + datetime + FileExtension;
StreamWriter sw = null;
sw = new StreamWriter(FileFullPath, false);
int ColumnCount = d_table.Columns.Count;
for (int ic = 0; ic < ColumnCount; ic++)
{
sw.Write(d_table.Columns[ic]);
if (ic < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
foreach (DataRow dr in d_table.Rows)
{
for (int ir = 0; ir < ColumnCount; ir++)
{
if (!Convert.IsDBNull(dr[ir]))
{
sw.Write(dr[ir].ToString());
}
if (ir < ColumnCount - 1)
{
sw.Write(FileDelimiter);
}
}
sw.Write(sw.NewLine);
}
sw.Close();
MessageBox.Show("Done..");
}
catch (Exception exception)
{
}
}
How can I archives geting Amount,Vat and Total in separate line with Thanks.
Edit
I was thinking about this answer and I realized I assumed you would want to use this invoice data elsewhere. If you don't need to use the data elsewhere, you can just use this block of code. It doesn't store the data returned from the sql call in an object.
try {
var invoices = new List<Invoice>();
using (var SQLConnection = new SqlConnection(ConnectionString)) {
SQLConnection.Open();
using (var cmd = new SqlCommand(query, SQLConnection))
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
// Note: You should handle nulls if the sql columns are nullable
var number = (int)reader["InvoiceNo"];
var date = (DateTime)reader["InvoiceDate"];
var amount = (int)reader["Amount"];
var vat = (int)reader["Vat"];
var total = (int)reader["Total"];
var iNumAndDate = $"{number}{FileDelimiter}{date.ToString("M/dd/yyyy")}{FileDelimiter}";
sw.Write($"{iNumAndDate}{amount}");
sw.Write($"{iNumAndDate}{vat}");
sw.Write($"{iNumAndDate}{total}");
sw.Write(sw.NewLine);
}
}
}
}
catch (Exception exception) {
// TODO: Handle exceptions
}
Original:
First, I would make a class to store each Invoice, we'll call it Invoice
class Invoice
{
public int Number { get; set; }
public DateTime Date { get; set; }
public int Amount { get; set; }
public int Vat { get; set; }
public int Total { get; set; }
}
Then, just store your data from the dB in a List<Invoice> and then loop through this list to write to the file.
try {
var invoices = new List<Invoice>();
using (var SQLConnection = new SqlConnection(ConnectionString))
{
SQLConnection.Open();
using (var cmd = new SqlCommand(query, SQLConnection))
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
invoices.Add(new Invoice {
// Note: You should handle nulls if the sql columns are nullable
Number = (int)reader["InvoiceNo"],
Date = (DateTime)reader["InvoiceDate"],
Amount = (int)reader["Amount"],
Vat = (int)reader["Vat"],
Total = (int)reader["Total"]
});
}
}
}
using (sw = new StreamWriter(FileFullPath, false))
{
foreach (var invoice in invoices)
{
var iNumAndDate = $"{invoice.Number}{FileDelimiter}{invoice.Date.ToString("M/dd/yyyy")}{FileDelimiter}";
sw.Write($"{iNumAndDate}{invoice.Amount}");
sw.Write($"{iNumAndDate}{invoice.Vat}");
sw.Write($"{iNumAndDate}{invoice.Total}");
sw.Write(sw.NewLine);
}
}
}
catch (Exception exception)
{
// TODO: Handle exceptions
}
You could do something like this :
foreach (DataRow dr in d_table.Rows)
{
StringBuilder builder = new StringBuilder();
for (int ir = 0; ir < 3; ir++)
{
if (!Convert.IsDBNull(dr[ir]))
{
builder.Append(dr[ir].ToString());
}
builder.Append(FileDelimiter);
}
var lineStart = builder.ToString();
for (int ir = 3; ir < 6; ir++)
{
if (!Convert.IsDBNull(dr[ir]))
{
sw.Write(lineStart);
sw.Write(dr[ir].ToString());
sw.Write(sw.NewLine);
}
}
}
i am uploading an excel file which has a date column having this format "dd-mm-yyyy". I am trying to convert it on fly into this format mm/dd/yyyy.
string[] dsplit = row[6].ToString().Split('-');
obj.ExpiryDate = string.Format("{0}/{1}/{2}", dsplit[1], dsplit[0], dsplit[2]).ToDate();
but it throws error, some hidden error.
Here is the whole code. I have tried a alot and nothing works expectedly
protected void SaveEmployeefrom_Click(object sender, EventArgs e)
{
uploadExcelfile();
}
public List<ClsEmployee> uploadExcelfile()
{
List<ClsEmployee> list = new List<ClsEmployee>();
DataTable tb = new DataTable();
try
{
if (employeeregistration.HasFile)
{
string name = DateTime.Now.ToString("hhmmss_ddmmyy");
name = name + employeeregistration.FileName;
employeeregistration.SaveAs(Server.MapPath("~/ExcelFiles/") + name);
string path = System.IO.Path.GetFullPath(Server.MapPath("~/ExcelFiles/") + name);
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
if (Path.GetExtension(path) == ".xls")
{
excelconnection = new OleDbConnection(connString);
excelconnection.Open();
}
else if (Path.GetExtension(path) == ".xlsx")
{
excelconnection = new OleDbConnection(connString);
excelconnection.Open();
}
OleDbCommand cmd = new OleDbCommand("SELECT [Name],[ID],[Mobile No],[Phone],[Emirates],[Nationality],[ExpiryDate],[Address] FROM [sheet1$]", excelconnection);
OleDbDataAdapter oleda = new OleDbDataAdapter(cmd);
oleda.Fill(tb);
foreach (DataRow row in tb.Rows)
{
if (!string.IsNullOrEmpty(row[6].ToString()))
{
ClsEmployee obj = new ClsEmployee();
obj.ID = 0;
// obj.Employer_ID=row[0].ToInt32();
obj.EmployeeName = row[0].ToString();
obj.EmployeeUniqueID = row[1].ToString();
obj.MobileNumber = row[2].ToString();
obj.PhoneNumber = row[3].ToString();
obj.Emirates = row[4].ToString();
obj.Nationality = row[5].ToString();
//from excel its dd-mm-yyyy
string[] dsplit = row[6].ToString().Split('-');
obj.ExpiryDate = string.Format("{0}/{1}/{2}", dsplit[1], dsplit[0], dsplit[2]).ToDate();
// obj.ExpiryDate = row[6].ToDate(); //mm-dd-yyyy
obj.Address = row[7].ToString();
list.Add(obj);
}
}
excelconnection.Dispose();
if (File.Exists(path))
{
File.Delete(path);
}
int total = tb.Rows.Count;
if (total>0)
{
GV_Employee.DataSource = null;
GV_Employee.DataSource = list;
GV_Employee.DataBind();
GV_Employee.Visible = true;
ResultLabel.ResultLabelAttributes("Uploaded successfull !!!", ProjectUserControls.Enums.ResultLabel_Color.Yellow);
ResultPanel.Controls.Add(ResultLabel);
}
else
{
ResultLabel.ResultLabelAttributes("No Record In Excel Sheet !!!", ProjectUserControls.Enums.ResultLabel_Color.Red);
ResultPanel.Controls.Add(ResultLabel);
}
//txtSerialQuantity.Text = total.ToString();
////// trbtnCheckAll.Visible = true;
////div_automatic.Visible = true;
////lbl_totalSelected.Text = "Total Selected = " + total.ToString();
}
}
catch (Exception x)
{
x.ToString(); //ResultLabel.ResultLabelAttributes(x.Message, ProjectUserControls.Enums.ResultLabel_Color.Red);
ResultLabel.ResultLabelAttributes(x.Message, ProjectUserControls.Enums.ResultLabel_Color.Red);
ResultPanel.Controls.Add(ResultLabel);
}
return list;
}
protected void Button1_Click(object sender, EventArgs e)
{
ClsEmployee obj1 = new ClsEmployee();
List<ClsEmployee> list = new List<ClsEmployee>();
try
{
foreach (GridViewRow item in GV_Employee.Rows)
{
ClsEmployee obj = new ClsEmployee();
obj.ID = 0;
obj.Employer_ID = cmbEmployer.SelectedValue.ToInt32();// ((Literal)GV_Employee.Rows[1].FindControl("Ltrl_EmployerID")).Text.ToInt32();
obj.EmployeeName = ((Literal)item.FindControl("Ltrl_Name")).Text.ToString();
obj.EmployeeUniqueID = ((Literal)item.FindControl("Ltrl_EmployeeUniqueID")).Text.ToString();
obj.MobileNumber = ((Literal)item.FindControl("Ltrl_Mobile")).Text.ToString();
obj.PhoneNumber = ((Literal)item.FindControl("Ltrl_PhoneNo")).Text.ToString();
obj.Emirates_ID = ((Literal)GV_Employee.Rows[1].FindControl("Ltrl_Emirates")).Text.ToInt32();
obj.Nationality_ID = ((Literal)GV_Employee.Rows[1].FindControl("Ltrl_Nationality")).Text.ToInt32();
obj.ExpiryDate = ((Literal)item.FindControl("Ltrl_Expiry")).Text.ToDate();
obj.Address = ((Literal)item.FindControl("Ltrl_Address")).Text.ToString();
obj.LFMD = "";
obj.RFMD = "";
obj.PinCode = "";
obj.IsFingerAuth = false;
obj.IsActive = true;
list.Add(obj);
}
obj1.SaveEmployeefromExcelFile(list);
ResultLabel.ResultLabelAttributes("Save successfull !!!", ProjectUserControls.Enums.ResultLabel_Color.Yellow);
ResultPanel.Controls.Add(ResultLabel);
GV_Employee.DataSource = null;
GV_Employee.Visible = false;
}
catch (Exception ex)
{
ResultLabel.ResultLabelAttributes(ex.ToString(), ProjectUserControls.Enums.ResultLabel_Color.Red);
ResultPanel.Controls.Add(ResultLabel);
}
}
Try this code.
DateTime dt = DateTime.Parse(row[6].toString());
string date = dt.ToString("dd/MM/yyyy");
I assume row[6] is a DateTime when you get from excel, you just need;
row[6].ToString("MM/dd/yyyy", CultureInfo.InvariantCulture);
Convert a DateTime to string and splitting it a generally bad idea. mm specifier is for minutes, MM is for months by the way.
Try This..
String MyString = "12-30-2014"; // get value from text field
DateTime MyDateTime = new DateTime();
MyDateTime = DateTime.ParseExact(MyString, "MM-dd-yyyy",null);
String MyString_new = MyDateTime.ToString("dd-MM-yyyy");
So I grab each row in a foreach loop and calculate the price of it. I managed to do that but I can't seems to figure out how to store ALL the calculated rows into a single variable and insert 1 calculated answer into a database.
private void btnSubmitConsultation_Click(object sender, EventArgs e)
{
string cMedication = string.Empty;
string cQuantity = string.Empty;
string cAppointment = string.Empty;
foreach (DataGridViewRow row in this.dataPrescription.Rows)
{
cMedication = row.Cells[0].Value.ToString();
cQuantity = row.Cells[1].Value.ToString();
cAppointment = txtAppointmentID.Text;
if (cAppointment == "NO APPOINTMENT HAS BEEN MADE")
{
MessageBox.Show("Please make an appointment first at the Nurse counter", "WARNING");
}
else
{
this.calculateTotal(cMedication, cQuantity, cAppointment);
}
}
}
private void calculateTotal(string cMedication, string cQuantity, string cAppointment)
{
string strConnectionString = ConfigurationManager.ConnectionStrings["HConnection"].ConnectionString;
SqlConnection con = new SqlConnection(strConnectionString);
string insertPayment = "INSERT INTO PAYMENT (amount, appointmentID) " +
"VALUES (#insertAmount, #insertAppointment)";
using (SqlConnection connection = new SqlConnection(strConnectionString))
{
using (SqlCommand cmdPayment = new SqlCommand(insertPayment, connection))
{
string strPrice = "SELECT medicationPrice FROM MEDICATION WHERE medicationName= #getName";
SqlCommand cmdPrice = new SqlCommand(strPrice, con);
cmdPrice.Parameters.AddWithValue("#getName", cMedication);
con.Open();
SqlDataReader readPrice = cmdPrice.ExecuteReader();
if (readPrice.Read())
{
string getPrice = readPrice["medicationPrice"].ToString();
double doublePrice = Convert.ToDouble(getPrice);
double doubleQuantity = Convert.ToDouble(cQuantity);
double result = doublePrice * doubleQuantity;
for (int i = 0; i < dataPrescription.Rows.Count; i++)
{
double total = result * i;
string answer = result.ToString();
MessageBox.Show(answer);
cmdPayment.Parameters.AddWithValue("#insertAmount", answer);
}
}
readPrice.Close();
con.Close();
cmdPayment.Parameters.AddWithValue("#insertAppointment", txtAppointmentID.Text);
connection.Open();
cmdPayment.ExecuteNonQuery();
connection.Close();
}
}
}
You have to change the command text to be the insert statement.
connection.Open();
cmdPayment.CommandText = insertPayment;
cmdPayment.ExexuteNonQuerry();
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?!
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();
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.
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();
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.
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;
}
To check Empty Rows
Foreach(DataRow as row in datable.Rows) {
var isEmpty = row.ItemArray.All(c => c is DBNull);
if(!isEmpty) {
//Your Logic
}
}
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();
}
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;
}
for (int i = dt.Rows.Count - 1; i >= 0; i--) {
if (dt.Rows[i][1] == DBNull.Value) {
dt.Rows[i].Delete();
}
}
dt.AcceptChanges();
return dt;
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
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;
}
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();
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);
}
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();
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();
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); });