I have a Stock Configuration Application and every stock I have amount of items. Every each item, to show in my GridView I have to add some column to my database View. Here is my code:
EuroPOS_BusinessLayer.Item b = new EuroPOS_BusinessLayer.Item();
DataTable dt = b.ListViewByID(Convert.ToInt32(grdSearchForItems.DataKeys[grdSearchForItems.SelectedIndex].Values["item_id"]));
dt.Columns.Add("countedStorage", typeof(Int32));
dt.Columns.Add("countedStorageText", typeof(String));
dt.Columns.Add("countedQuantity", typeof(Decimal));
dt.Columns.Add("countedDescription");
if (!dt.Columns.Contains("PROC"))
dt.Columns.Add("PROC");
dt.Rows[0]["countedStorage"] = Convert.ToInt32(ddlItemSelectedStorage.SelectedValue);
dt.Rows[0]["countedStorageText"] =(ddlItemSelectedStorage.SelectedItem.Text);
dt.Rows[0]["countedQuantity"] = Convert.ToDecimal(txtItemCountedQuantity.Text);
dt.Rows[0]["countedDescription"] = txtItemDescription.Text;
dt.Rows[0]["PROC"] = "INS";
DataTable _tblItems = (DataTable)ViewState["TblItems"];
if (_tblItems == null)
{
_tblItems = dt;
}
else
{
DataRow dr = _tblItems.Select("item_id = " + grdSearchForItems.DataKeys[grdSearchForItems.SelectedIndex].Values[0] + " AND countedStorage = " + ddlItemSelectedStorage.SelectedValue).FirstOrDefault();
if (dr != null)
{
dr["countedQuantity"] = txtItemCountedQuantity.Text;
dr["countedDescription"] = txtItemDescription.Text;
if (dr.Table.Columns.Contains("IdNumber") && dr["IdNumber"] != DBNull.Value)
dr["PROC"] = "UPD";
}
else
{
_tblItems.Merge(dt);
}
}
After through tough research, I can not find a solution for that. Can you please help me?
Edit: I tried table1.Merge(TempTable, True, MissingSchemaAction.Ignore) but does not work!
You have a datatype missmatch:
In one case decimal:
dt.Rows[0]["countedQuantity"] = Convert.ToDecimal(txtItemCountedQuantity.Text);
And the other string:
dr["countedQuantity"] = txtItemCountedQuantity.Text;
The view expects one of the two, so stick to the same in both cases.
Related
I'm putting together a project that has a form to fill out which then populates a query from a separate data table. It will always only grab one row based on the inputs, which is then used for a price calculation. I have two places in the code using the same setup. The first one uses a single combo box for the query and it works great, but the second part uses two combo boxes to make an "AND" query and I can't figure out why it isn't working, it doesn't seem to recognize the selections and place them into the calculation. Below is the code for that part, any help would be appreciated!
private void plant_AmountTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
try
{
plantamountResult = Convert.ToDecimal(plant_AmountTextBox.Text);
}
catch (Exception)
{
MessageBox.Show("Please enter a valid amount");
}
try
{
DataRowView rowviewpml = material_NameComboBox.SelectedItem as DataRowView;
materialNameSelection = "";
if (rowviewpml != null)
{
materialNameSelection = rowviewpml.Row["Material_Species"] as string;
}
DataRowView rowviewst = stockComboBox.SelectedItem as DataRowView;
stockSelection = "";
if (rowviewst != null)
{
stockSelection = rowviewst.Row["Stock_Type"] as string;
}
string mcSearch = "Material_Species = '" + materialNameSelection + "' AND Stock_Type = '" + stockSelection + "'";
Plant_Material_PricingTableAdapter pmpTA = new Plant_Material_PricingTableAdapter();
DataTable pmpDT = pmpTA.GetData();
DataRow[] pmpRow = pmpDT.Select(mcSearch);
foreach(DataRow row in pmpRow)
{
materialEstCost = Convert.ToDouble(pmpRow[0]["Previous_FY_Quotes"]);
}
plantestCostCalc.Text = "$" + ((decimal)materialEstCost * plantamountResult).ToString();
}
catch
{
plantestCostCalc.Text = "0";
}
}
Working on a windows form application that reads in data from csv files and adds the data to a Datagridview. I ran into an issue with all of the rows being added to the datable and being displayed on the datagridview. The datagridview displays the datarows from the first two if conditions and OneRow if condition only. It will not add the rows from the twoRow if condition if the datable and datagridview rows are populated with the OneRow if condition rows. But i want the rows from both OneRow and TwoRow to be displyed. Also the rows from TwoRow do populate the datatable and datagridview when I comment(/**/) out the OneRow if condition. But I need both to populate the table. Thanks in advance!
Construct.MainDataTable.Columns.Add("Date", typeof(DateTime));
Construct.MainDataTable.Columns.Add("Time");
Construct.MainDataTable.Columns.Add("Serial");
Construct.MainDataTable.Columns.Add("Type");
Construct.MainDataTable.Columns.Add("level");
Construct.MainDataTable.Columns.Add("price");
Construct.MainDataTable.Columns.Add(" Limit");
Construct.MainDataTable.Columns.Add("last Limit");
Construct.MainDataTable.Columns.Add("Data");
..........................
...............................................
DataRow oneRow = Construct.MainDataTable.NewRow();
DataRow twoRow = Construct.MainDataTable.NewRow();
dataGridView2.AllowUserToAddRows = false;
if (line.Split(',')[2].Equals("Time"))
{
time = line.Split(',')[3];
date = line.Split(',')[1];
}
if (line.Split(',')[2].Equals("Level"))
{
level = line.Split(',')[3];
}
//OneROw(IF condition)
if ((Convert.ToDecimal(line.Split(',')[8])) < (Convert.ToDecimal (line.Split(',')[12])))
{
type = line.Split(',')[1];
serial = line.Split(',')[7];
price = line.Split(',')[3];
Limit = line.Split(',')[8];
lastLimit = line.Split(',')[10];
Data = line.Split(',')[12];
oneRow["Date"] = date;
oneRow["Time"] = time;
oneRow["Serial"] = serial;
oneRow["Type"] = type;
oneRow["level"] = level;
oneRow["price"] = price;
oneRow[" Limit"] = Limit;
oneRow["last Limit"] = lastlimit;
oneRow["Data"] = Data;
Construct.MainDataTable.Rows.Add(oneRow);
}
//TwoROw(IF condition)
if ((line.Contains('"')) && ((line.Contains("NG"))))
{
price = line.Split(',')[3];
type = line.Split(',')[1];
serial = line.Split(',')[7];
Limit = line.Split('"')[7];
var valLimit = Limit.Split(',').Select(a => Convert.ToInt32(a, 16));
var limitJoin = String.Join(",", valLimit);
lastlimit = line.Split('"')[1];
var vallastLimit = lastlimit.Split(',').Select(d => Convert.ToInt32(d, 16));
var lastJoin = String.Join(",", vallastLimit);
Data = line.Split('"')[5];
var valDatas = Data.Split(',').Select(s => Convert.ToInt32(s, 16));
var dataJoin = String.Join(",", valDatas);
twoRow["Date"] = date;
twoRow["Time"] = time;
twoRow["Serial"] = serial;
twoRow["Type"] = type;
twoRow["level"] = level;
twoRow["price"] = price;
twoRow["Limit"] = limitJoin;
twoRow["last Limit"] = lastJoin;
twoRow["Data"] = dataJoin;
Construct.MainDataTable.Rows.Add(twoRow);
}
dataGridView2.DataSource = Construct.MainDataTable;
Can't add a comment because I don't have enough karma so I ask my questions here: So, if I understood your problem you can't add data from one .csv file if it have more then one row? Why are you using 2 different if conditions for row in .csv file?
If you have empty data in row never mind you can still place them to your DataTable column, so you can use loop to add data from .csv to your DataTable. Try some thing like this:
public static DataTable CsvToDataTable(string csv)
{
DataTable dt = new DataTable();
string[] lines = csv.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
Regex onlyDeimiterComma = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
for (int i = 0; i < lines.Length; i++)
{
DataRow row = dt.NewRow();
string[] cells = onlyDeimiterComma.Split(lines[i]);
for (int j = 0; j < cells.Length; j++)
{
if (i == 0)
{
if (j == 0)
{
dt.Columns.Add(cells[j], typeof(DateTime));
}
else
{
dt.Columns.Add(cells[j]);
}
}
else
{
row[j] = cells[j];
}
}
dt.Rows.Add(row);
}
return dt;
}
Just call this method anywhere in your code and give it string read from your .csv file.
You can try to compile this code here and see how it works on .csv data with different data (empty columns, quoted text, quoted commas)
UPD: If you need to fill DataTable from two different .csv files you can still use code above. Just call it twice for both files and then Merge two DataTable, like this:
DataTable dt = CsvToDataTable(csvFileOne);
DataTable dtTwo = CsvToDataTable(csvFileTwo);
dt.Merge(dtTwo);
I try to develop a c# application(gathering products by their barcodes) to windows ce handheld device with compact framework 3.5
I have a datagrid and datagrid is bind with a datatable by sql. There are 4 columns in my datagrid, 3rd column represents the quantity of the products needs to be collected, and last column comes with the default value 0(quantity collected). Whenever user enters a product code, quantity of the product increases 1 by 1.
I want to make background color of the row blue when user enters corresponding product code(to show which product is being collected)
and also I want to make background color green if user collects the needed products.
I tried coloring row by selected index but it does not work. When selection gone , colours are gone.
Here is a picture of screen when needed quantity of product was collected.
Here is when I want to see the processed row.
Below is my code of the keypress event of the textbox(entering of product code)
private void txtUrunkod_KeyPress(object sender, KeyPressEventArgs e)
{
foreach (System.Data.DataColumn col in dt.Columns) col.ReadOnly = false;
if (e.KeyChar == (char)Keys.Enter)
{
islemkod = txtUrunkod.Text;
islemkod.Trim();
if (islemkod.Contains('/'))
{
serikodbol = islemkod.Split('/');
urunKodum = serikodbol[0];
DataRow row = dt.Select("urunkodu='" + urunKodum + "'").FirstOrDefault();
int guncelle = Convert.ToInt32(row[3]);
guncelle++;
row[3] = guncelle;
}
else if (islemkod.Length == 8)
{
SqlCommand cmd = new SqlCommand("exec MY_TOPUK_BILGI_GETIR '" + islemkod + "'", conStr);
conStr.Open();
SqlDataReader dr = cmd.ExecuteReader();
uk = new DataTable();
uk.Load(dr);
conStr.Close();
//toplamaGrid.Select(0);
foreach (DataRow row2 in uk.Rows)
{
urunKodum = row2[0].ToString();
}
DataRow row = dt.Select("urunkodu='" + urunKodum + "'").FirstOrDefault();
int guncelle = Convert.ToInt32(row[3]);
guncelle++;
row[3] = guncelle;
int index = -1;
bool found = false;
foreach (DataRow datr in dt.Rows)
{
index++;
string d = datr["urunkodu"].ToString();
if (datr[0].ToString() == urunKodum)
{
found = true;
break;
}
}
if (found && !row[2].Equals(row[3]))
{
toplamaGrid.Select(index);
toplamaGrid.SelectionBackColor = Color.Blue;
}
else if (row[2].Equals(row[3]))
{
toplamaGrid.Select(index);
toplamaGrid.SelectionBackColor = Color.Green;
//toplamaGrid.UnSelect(index);
}
}
else if (islemkod.Length == 7 && islemkod[0] == 'P')
{
}
else//islemkod.Length != 8 && !islemkod.Contains('/')
{//
urunKodum = txtUrunkod.Text;
txtUrunkod.Visible = false;
lblurunkod.Visible = false;
txtifAdres.Visible = true;
lbladressor.Visible = true;
txtifAdres.Focus();
}
updated = true;
txtUrunkod.Text = "";
sonindex = 0;
}
}
I couldnt find many info about this. Any help will be important. Thanks for any help!
First of all I experienced the same problem. Make use of DataGridFormatCellEventArgs for coloring the solution.
explained here Add the DataGrid file to your code in the link. (DataGridFormatCellEventArgs.cs and FormattableTextBoxColumn.cs) These files contain the Paint class that was used to do the coloring.
different example
I hope I could help. If you experience difficulties, I can give an example from my own code.
Actually, i have two data tables. Here is the code for reference. Actually Relationship holds the sub string values(Code not mentioned here). So i am splitting the data's to store in two table's based on the condition.
if (child.Relationship.Contains("P"))
{
var newRow = dataTable.NewRow();
newRow["EmployeeNo"] = child.EmployeeNo;
newRow["FirstName"] = child.FirstName;
newRow["MiddleName"] = child.MiddleName;
newRow["LastName"] = child.LastName;
newRow["FullName"] = child.FullName;
newRow["MemberIc"] = child.MemberIc;
dataTable.Rows.Add(newRow);
}
else
{
var newRow1 = dataTable1.NewRow();
newRow1["EmployeeNo"] = child.EmployeeNo;
newRow1["FirstName"] = child.FirstName;
newRow1["MiddleName"] = child.MiddleName;
newRow1["LastName"] = child.LastName;
newRow1["FullName"] = child.FullName;
newRow1["MemberIC"] = child.MemberIC;
dataTable1.Rows.Add(newRow1);
}
So, whenever the MemberIc in the second data table is empty. I need to copy the MemberIc from first data table(only if EmployeeNo Matches) based on the EmployeeNo.
How can i copy the value ? Any help appreciated. Thanks in advance !!!
Here you go.
var rows = datatable.Select("EmployeeNo = " + child.EmployeeNo);
var memberIC = 0;
if(rows.length > 0)
{
memberIC = rows[0].Field<int>("memberIC");
}
if (child.Relationship.Contains("P"))
{
var newRow = dataTable.NewRow();
newRow["EmployeeNo"] = child.EmployeeNo;
newRow["FirstName"] = child.FirstName;
newRow["MiddleName"] = child.MiddleName;
newRow["LastName"] = child.LastName;
newRow["FullName"] = child.FullName;
newRow["MemberIc"] = child.MemberIc;
dataTable.Rows.Add(newRow);
}
else
{
var newRow1 = dataTable1.NewRow();
newRow1["EmployeeNo"] = child.EmployeeNo;
newRow1["FirstName"] = child.FirstName;
newRow1["MiddleName"] = child.MiddleName;
newRow1["LastName"] = child.LastName;
newRow1["FullName"] = child.FullName;
newRow1["MemberIC"] = child.MemberIC == 0 ? memberIC : child.MemberIC;
dataTable1.Rows.Add(newRow1);
}
This has nothing to do with C#, ADO.NET or datatable. This is a simple logic of what to check and where to check.
I am accessing a database with c#. Now I have to make some calculations with data that I get from some tables and write it into other existing tables. This works quite good in most cases, but for complex operations it takes a huge amount of time. Now I want to know what would be good practice to speed up my querys and get to my results. Here is what I do:
I get a data table that contains 3 values (lom(unique id), laktanfang, laktende) that contains about 700 rows.
For each row in this table I do a query from another table. This results in another data table containing 2 values (lom(unique id), behanddatum)
Now I check if the the value of behanddatum is in between laktanfang and laktende --> yes: Add the row to the data table that gets returned by my function --> no: go on
In the end I have to get the number of positive results from my data table
Here is the code I currently use. I hope it's not too confusing.
public DataTable HoleAbgeschlosseneLaktationenMitDiagnosen(DateTime daAnfang, DateTime daEnde, string[] stDiagnosen = null)
{
DataTable dtRet = new DataTable();
dtRet.Columns.Add("lom", typeof(string));
dtRet.Columns.Add("laktanfang", typeof(DateTime));
dtRet.Columns.Add("laktende", typeof(DateTime));
DataTable dtAbgänge = HoleAbgängeVonEinzeltierZugang(daEnde, daAnfang);
//Abgeschlossene Laktationen für abgegegangene Tiere
foreach (DataRow dr in dtAbgänge.Rows)
{
if (dr != null)
{
DateTime daAbgangsdatum = dr.Field<DateTime>("abgangsdatum");
string stLom = dr.Field<string>("lom");
DataTable dtKalbungVorAbgang = HoleLetzteKalbungFuerTier(stLom, daAbgangsdatum);
if (dtKalbungVorAbgang.Rows.Count > 0 && !dtKalbungVorAbgang.Rows[0].IsNull("kalbedatum"))
{
DateTime daKalbedatum = (DateTime)dtKalbungVorAbgang.Rows[0]["kalbedatum"];
int inLaktation = (int)dtKalbungVorAbgang.Rows[0]["laktation"];
if (PrüfeObDiagnoseInZeitraumAufgetreten(stLom, stDiagnosen, daKalbedatum, daAbgangsdatum) || stDiagnosen == null)
{
DataRow drLaktAbgang = dtRet.NewRow();
drLaktAbgang["lom"] = stLom;
drLaktAbgang["laktanfang"] = daKalbedatum;
drLaktAbgang["laktende"] = daAbgangsdatum;
dtRet.Rows.Add(drLaktAbgang);
}
if (daKalbedatum >= daAnfang && inLaktation > 1)
{
DataTable dtVorherigeKalbung = HoleLetzteKalbungFuerTier(stLom, daKalbedatum.AddDays(-1));
DateTime daVorhKalbung = (DateTime)dtVorherigeKalbung.Rows[0]["kalbedatum"];
if (dtVorherigeKalbung.Rows.Count > 0 && !dtVorherigeKalbung.Rows[0].IsNull("kalbedatum"))
{
if (PrüfeObDiagnoseInZeitraumAufgetreten(stLom, stDiagnosen, daKalbedatum, daAbgangsdatum) || stDiagnosen == null)
{
DataRow drLaktVorhKalbung = dtRet.NewRow();
drLaktVorhKalbung["lom"] = stLom;
drLaktVorhKalbung["laktanfang"] = daVorhKalbung;
drLaktVorhKalbung["laktende"] = daKalbedatum;
dtRet.Rows.Add(drLaktVorhKalbung);
}
}
}
}
}
}
DataTable dtKalbungen = HoleKalbungenFürLebendTiere(daEnde, daAnfang);
//Abgeschlossene Laktationen für lebende Tiere
foreach (DataRow dr in dtKalbungen.Rows)
{
DateTime daKalbedatumLetzte = dr.Field<DateTime>("kalbedatum");
string stLom = dr.Field<string>("lom");
int inLaktation = dr.Field<int>("laktation");
if (inLaktation > 1)
{
DataTable dtKalbungVorErster = HoleLetzteKalbungFuerTier(stLom, daKalbedatumLetzte.AddDays(-1));
if (!dtKalbungVorErster.Rows[0].IsNull("kalbedatum"))
{
DateTime daKalbedatum = (DateTime)dtKalbungVorErster.Rows[0]["kalbedatum"];
if (PrüfeObDiagnoseInZeitraumAufgetreten(stLom, stDiagnosen, daKalbedatum, daKalbedatumLetzte) || stDiagnosen == null)
{
DataRow drLaktKalbung = dtRet.NewRow();
drLaktKalbung["lom"] = stLom;
drLaktKalbung["laktanfang"] = daKalbedatum;
drLaktKalbung["laktende"] = daKalbedatumLetzte;
dtRet.Rows.Add(drLaktKalbung);
}
inLaktation = (int)dtKalbungVorErster.Rows[0]["laktation"];
if (daKalbedatum >= daAnfang && inLaktation > 1)
{
DataTable dtVorherigeKalbung = HoleLetzteKalbungFuerTier(stLom, daKalbedatum.AddDays(-1));
if (dtVorherigeKalbung.Rows.Count > 0 && !dtVorherigeKalbung.Rows[0].IsNull("kalbedatum"))
{
DateTime daVorhKalbung = (DateTime)dtVorherigeKalbung.Rows[0]["kalbedatum"];
if (PrüfeObDiagnoseInZeitraumAufgetreten(stLom, stDiagnosen, daVorhKalbung, daKalbedatum) || stDiagnosen == null)
{
DataRow drLaktVorhKalbung = dtRet.NewRow();
drLaktVorhKalbung["lom"] = stLom;
drLaktVorhKalbung["laktanfang"] = daVorhKalbung;
drLaktVorhKalbung["laktende"] = daKalbedatum;
dtRet.Rows.Add(drLaktVorhKalbung);
}
}
}
}
}
}
return dtRet;
}
private bool PrüfeObDiagnoseInZeitraumAufgetreten(string stLom, string[] stDiagnosen, DateTime daAnfang, DateTime daEnde)
{
SqlCommand cmd = new SqlCommand();
DataTable dtDiagnosenGefunden = new DataTable();
cmd.CommandText = "SELECT diagnose " +
"FROM b_milch_hms_diagnose " +
"WHERE lom=#lom AND behanddatum >= #datumanfang AND behanddatum <= #datumende";
if (stDiagnosen != null)
{
int i = 0;
foreach (string st in stDiagnosen)
{
if (st != "")
{
if (i == 0)
cmd.CommandText += " AND diagnose LIKE #gesuchte_diagnose" + i;
else
cmd.CommandText += " OR diagnose LIKE #gesuchte_diagnose" + i;
cmd.Parameters.AddWithValue("#gesuchte_diagnose" + i, st + "%");
}
i++;
}
}
cmd.Parameters.AddWithValue("#lom", stLom);
cmd.Parameters.AddWithValue("#datumanfang", daAnfang);
cmd.Parameters.AddWithValue("#datumende", daEnde);
dtDiagnosenGefunden = w_milch.FühreSqlAus(cmd);
if (dtDiagnosenGefunden.Rows.Count > 0 && !dtDiagnosenGefunden.Rows[0].IsNull("diagnose"))
return true;
return false;
}
I hope you can help me to improve this function to work more efficient or at least give me some hints.
Thanks in advance
You have created a N+1 problem. One way to solve this would be to change HoleAbgängeVonEinzeltierZugang so that it joins in the data you need from the b_milch_hms_diagnose table.
If you are using .NET 4.0, you can also try to use parallel foreach and see the impact it has on the loop execution time. (This is a more general advice you could apply to many examples)
_dtAbgänge.Rows.AsParallel().ForEach(dr=>
{
//do work
});