How do i minus data from the program to the database?
I have quantity and description in my database.
The quantity will be 100, and the description of it will be A.
When i type in my program like this (after run the program):
The quantity is 50. and the description of it is A.
The database:
The quantity will be 50 (because minus with the database and my program "100 - 50 = 50", and the description still remains same as A.
How do i do that?
Thanks in advance!
Edit:
I already did like this:
if (textBoxCodeContainer[index].TextLength != 0)
{
this.textBoxQuantityContainer[index].Value = Convert.ToDecimal(dReader["Quantity"].ToString());
this.textBoxDescContainer[index].Text = dReader["Description"].ToString();
this.textBoxSubTotalContainer[index].Text = dReader["Price"].ToString();
}
if (textBoxQuantityContainer[index].Value != 0)
{
if (textBoxQuantityContainer[index].Value >= Convert.ToDecimal(dReader["Quantity"].ToString()))
{
decimal newVal = textBoxQuantityContainer[index].Value - Convert.ToDecimal(dReader["Quantity"].ToString());
cmd = new OleDbCommand("UPDATE [Seranne] SET [Quantity] ='" + newVal + "' WHERE [Code] IN (");
}
}
But when i run the program, the quantity loaded exactly the same like in the database, but it can't change, when i type quantity is 50, the program will automatically return to 100 (which is same exactly the quantity in the database)
Why is it like that?
Note: for textbox quantity, i use the Numeric Up Down.
Edit: The full code is on below:
private void UpdateDatas()
{
int codeValue = 0;
int index = 0;
if (firstForm.textBox1.Text == "Seranne")
{
string query = "SELECT [Quantity], [Description], [Price] FROM [Seranne] WHERE [Code] IN (";
OleDbDataReader dReader;
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
if (int.TryParse(this.textBoxCodeContainer[0].Text, out codeValue))
{
query = query + codeValue.ToString();
}
for (int i = 1; i < 17; i++)
{
if (int.TryParse(this.textBoxCodeContainer[i].Text, out codeValue))
{
query = query + "," + codeValue.ToString();
}
}
query = query + ")";
OleDbCommand cmd = new OleDbCommand(query, conn);
cmd.Parameters.Add("Code", System.Data.OleDb.OleDbType.Integer);
cmd.Parameters.Add("Quantity", System.Data.OleDb.OleDbType.Integer);
dReader = cmd.ExecuteReader();
while (dReader.Read())
{
if (textBoxCodeContainer[index].TextLength != 0)
{
this.textBoxQuantityContainer[index].Value = Convert.ToDecimal(dReader["Quantity"].ToString());
this.textBoxDescContainer[index].Text = dReader["Description"].ToString();
this.textBoxSubTotalContainer[index].Text = dReader["Price"].ToString();
}
if (textBoxQuantityContainer[index].Value != 0)
{
if (textBoxQuantityContainer[index].Value >= Convert.ToDecimal(dReader["Quantity"].ToString()))
{
decimal newVal = textBoxQuantityContainer[index].Value - Convert.ToDecimal(dReader["Quantity"].ToString());
cmd = new OleDbCommand("UPDATE [Seranne] SET [Quantity] ='" + newVal + "' WHERE [Code] IN (");
}
}
index += 1;
}
dReader.Close();
conn.Close();
}
}
private void UpdatePrice()
{
int totalPrice = 0;
int quantity = 0;
int price = 0;
for (int i = 0; i < 17; i++)
{
if (textBoxQuantityContainer[i].Value > 0)
{
quantity = (int)textBoxQuantityContainer[i].Value;
price = Convert.ToInt32(textBoxSubTotalContainer[i].Text);
textBoxTotalContainer[i].Text = (quantity * price).ToString();
}
else
{
textBoxSubTotalContainer[i].Text = "";
textBoxTotalContainer[i].Text = "";
}
}
for (int i = 0; i < 17; i++)
{
if (textBoxTotalContainer[i].TextLength != 0)
{
totalPrice += Convert.ToInt32(textBoxTotalContainer[i].Text);
}
}
textBoxAllTotalContainer.Text = totalPrice.ToString("n2");
}
private void textBox_TextChanged(object sender, EventArgs e)
{
UpdateDatas();
UpdatePrice();
}
}
}
Here is the screenshot:
"Code" displayed in the screenshot above is refer to the database, and also the "Quantity", whenever i type the code that already have in the database, the remaining box are filled up. But, when i change the "Quantity" from 100 to 50, it is automatically like refresh the program to back to 100 again.
cmd = new oledbcommand("select qty from tablename where pid=103");
qtyval = convert.ToInt32(cmd.ExecuteScalar());
if (qtyval != 0 )
{
if (qtyval >= convert.toint32(txtqty.text))
{
newval = qtyval - convert.ToInt32(txtqty.text);
cmd = new oledbcommand("update tablename set qty="+newval+" where pid=103");
}
}
cmd = new OleDbCommand("UPDATE [Seranne] SET [Quantity] ='" + newVal + "' WHERE [Code] IN (");
[This can't be your actual code because it is missing a closing quote and bracket. Please always just copy and paste your actual code.]
WHERE [Code] IN (")
You are attempting to update where the Code is an empty string? It is far more likely to be NULL, so this is one reason why it won't update. However, you haven't executed this cmd, so it won't change anything.
[Do you really intend to update ALL records which don't have a Code ?]
You should also print-out cmd and attempt to execute it from within Access as part of your debugging steps.
Lastly, why are you quoting the Quantity with apostrophes? Presumably, it is a numeric field.
Related
i want to delete one or more selected items in checkedlistbox. But i dont know how i must to do that. Pls help
here my codes;
private void button2_Click(object sender, EventArgs e)
{
checkedListBox1.Items[checkedListBox1.SelectedIndex].ToString();
SqlCommand del = new SqlCommand("DELETE FROM TABLE1 WHERE personID='" +
personID[checkedListBox1.SelectedIndex] + "' ", con);
con.Open();
for (int i = 0; i < checkedListBox1.Items.Count - 1; i++)
{
if(checkedListBox1.CheckedItems[i]) //this line does not work
{
del.ExecuteNonQuery();
}
}
con.Close();
}
You should use a parameter for security reason.
Next you can set it in the loop with the desired id.
con.Open();
var command = new SqlCommand("DELETE FROM TABLE1 WHERE personID=? ", con);
var param = del.Parameters.Add("#ID", SqlDbType.Int /* or any relevant type */);
foreach ( var item in checkedListBox1.SelectedItems )
{
param.Value = ((TheTypeOfTheItems)item).NameOfTheID;
command.ExecuteNonQuery();
}
con.Close();
Perhaps you can construct only one query by adding some OR to the WHERE clause and execute it one time after the loop.
if ( checkedListBox1.SelectedItems.Count > 0 )
{
con.Open();
var command = new SqlCommand("DELETE FROM TABLE1 WHERE ", con);
var id = ( (TheTypeOfTheItems)checkedListBox1.SelectedItems[index] ).NameOfTheID;
command.CommandText += "personID =? ";
command.Parameters.Add("#ID" + index, SqlDbType.Int).Value = id;
if ( checkedListBox1.SelectedItems.Count > 1 )
for ( int index = 1; index < checkedListBox1.SelectedItems.Count; index++ )
{
command.CommandText += "OR ";
var id = ( (TheTypeOfTheItems)checkedListBox1.SelectedItems[index] ).NameOfTheID;
command.CommandText += "personID =? ";
command.Parameters.Add("#ID" + index, SqlDbType.Int).Value = id;
}
command.ExecuteNonQuery();
con.Close();
}
Note: I can't test the code and I used params with odbc and not sql server.
Need your help. I have to get csv file from user and update database columns according to that file.
For Example:
File has following fields:
Name | Description | Date
Another file has:
Name | Price
Please Guide me how i could do this in c# using sql 2008.
From checkboxes user can select columns which he wants to update.
else if (count == 4 && dataGridView1.ColumnCount - 1 == 4)
{
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
int id = Convert.ToInt32(dataGridView1.Rows[i].Cells["Id"].Value);
ItemsC.UpdateDatacolumns(id, columnsList[1], dataGridView1.Rows[i].Cells[1].Value.ToString(), columnsList[2], dataGridView1.Rows[i].Cells[2].Value.ToString(), columnsList[3], dataGridView1.Rows[i].Cells[3].Value.ToString());
}
}
else if (count == 5 && dataGridView1.ColumnCount - 1 == 5)
{
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
int id = Convert.ToInt32(dataGridView1.Rows[i].Cells["Id"].Value);
ItemsC.UpdateDatacolumns(id, columnsList[1], dataGridView1.Rows[i].Cells[1].Value.ToString(), columnsList[2], dataGridView1.Rows[i].Cells[2].Value.ToString(), columnsList[3], dataGridView1.Rows[i].Cells[3].Value.ToString(), columnsList[4], dataGridView1.Rows[i].Cells[4].Value.ToString());
}
}
In Backend Just Override Update Method:
public static bool UpdateDatacolumns(int id, string column, string value, string column2, string value2)
{
SqlConnection conn = database.getConnection();
string query = "update destinationItemTable set " + column + "= #value ," + column2+" =#value2 where Id=#id";
try
{
var p1 = new SqlParameter("#id", id);
var p2 = new SqlParameter("#value", value);
var p3 = new SqlParameter("#value2", value2);
var cmd = new SqlCommand { CommandText = query, CommandType = CommandType.Text };
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
cmd.Parameters.Add(p3);
cmd.Connection = conn;
conn.Open();
bool result = (cmd.ExecuteNonQuery() > 0);
cmd.Dispose();
return result;
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
Any comments on this code pieces to make it more professional will be gladly accepted. This is why I opened this topic. But the main concern is this; I need to pass item ids, store ids, and start date and end date to get sale records. One of the problem is because of SQL parameter limit (2100), I cannot send more than 2100 parameters to the statement. Now I am trying to receive records store by store (store number is more than 4000 and also item amount). But I could not figure out a good way to do it.
Any one who spent time to help appreciated.
This is data access:
public List<SalesList> ExecuteSales(List<string> items, int storeID, int W1,int W2,int vendorID,int retailerID)
{
SqlCommand command = new SqlCommand();
string statement = "SELECT I.ITEM_NBR,I.ITEM_DESC1,I.ITEM_DESC2,I.VENDOR_STK_NBR,SUM(SA.POS_QTY) AS POS_QTY,SUM(SA.POS_SALES) AS POS_SALES "
+ "FROM SALES_FTBL SA,ITEM_TBL I "
+ "WHERE SA.RETAILER_ID=I.RETAILER_ID "
+ "AND SA.RETAILER_ID = #RetailerID "
+ "AND SA.VENDOR_NBR = #VendorID "
+ "AND SA.STORE_NBR = #StoreID "
+ "AND SA.ITEM_NBR=I.ITEM_NBR "
+"AND SA.ITEM_NBR IN (";
command.Parameters.AddWithValue("#RetailerID", retailerID);
command.Parameters.AddWithValue("#VendorID",vendorID);
command.Parameters.AddWithValue("#StoreID", storeID);
for (int i = 0; i < items.Count; i++)
{
if (i > 0)
{
statement += ", ";
}
string paramStr = "#itemNo" + i;
statement += paramStr;
command.Parameters.Add(paramStr, System.Data.SqlDbType.Int);
command.Parameters[paramStr].Value = items[i];
}
statement += ") ";
//statement += "AND STORE_NBR IN (";
//for (int i = 0; i < stores.Count; i++)
//{
// if (i > 0)
// {
// statement += ", ";
// }
// string paramStr = "#storeNo" + i;
// statement += paramStr;
// command.Parameters.Add(paramStr, System.Data.SqlDbType.Int);
// command.Parameters[paramStr].Value = stores[i];
//}
//statement += ") ";
statement += "AND WEEK IN (";
for (int i = 0; i <1; i++)
{
if (i > 0)
{
statement += ", ";
}
string paramStr = "#W" + i;
statement += paramStr;
command.Parameters.Add(paramStr, System.Data.SqlDbType.Int);
command.Parameters[paramStr].Value = W1;
}
W1=W1+1;
for (int counter=W1; counter < W2;counter++ )
{
if (counter > 0)
{
statement += ", ";
}
string paramStr = "#W" + counter;
statement += paramStr;
command.Parameters.Add(paramStr, System.Data.SqlDbType.Int);
command.Parameters[paramStr].Value = W1++;
}
statement += ") ";
statement += "GROUP BY I.ITEM_NBR,I.VENDOR_STK_NBR,I.ITEM_DESC1,I.ITEM_DESC2 Order By I.ITEM_DESC2 ";
command.CommandText = statement;
command.Connection = connection;
List<SalesList> sales = new List<SalesList>();
SalesList sale;
string itemDescription;
string desc1;
string desc2;
int count = 0;
try
{
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
sale = new SalesList();
sale.ItemNumber = Convert.ToInt32(reader["ITEM_NBR"].ToString().TrimEnd());
if (reader["ITEM_DESC1"] != null)
{
desc1 = reader["ITEM_DESC1"].ToString().TrimEnd();
}
else { desc1 = ""; }
if (reader["ITEM_DESC2"] != null)
{
desc2 = reader["ITEM_DESC2"].ToString().TrimEnd();
}
else { desc2 = ""; }
if (!desc1.Equals(desc2) || !desc2.Equals(desc1))
{ itemDescription = desc1 + " " + desc2; }
else { itemDescription = desc2; }
sale.ItemDescription2 = itemDescription;
sale.PosQuantity = Convert.ToInt32(reader["POS_QTY"].ToString().TrimEnd());
sale.VendorStockNumber = reader["VENDOR_STK_NBR"].ToString().TrimEnd();
if (reader["POS_SALES"].ToString() != "")
{
sale.PosSales = Convert.ToDouble(reader["POS_SALES"].ToString().TrimEnd());
}
else { sale.PosSales = 0; }
sales.Add(sale);
}
}
catch (SqlException se)
{
Debug.WriteLine("---------- DEBUG INFORMATION ----------");
Debug.WriteLine(se.Message);
Debug.WriteLine("=======================================");
throw se;
}
finally
{
connection.Close();
}
return sales;
}
And this is business layer :
private List<SalesList> ExecuteSales(List<string> items, List<string> stores, string date1, string date2, int vendorID, int retailerID) {
int W1 = CalculateWeek(date1);
int W2 = CalculateWeek(date2);
SalesListDL salesListDO = new SalesListDL();
List<SalesList> sales = new List<SalesList>();
List<SalesList> salesX = new List<SalesList>();
for (int counter = 0; counter < stores.Count; counter++)
{
int storeID = Convert.ToInt32(stores[counter]);
salesX = salesListDO.ExecuteSales(items, storeID, W1, W2, vendorID, retailerID);
if (salesX.Count > 0)
{
foreach (SalesList saleX in salesX.ToList())
{
int index = sales.FindIndex(item => item.ItemNumber == saleX.ItemNumber);
if (index > 0)
{
sales[index].PosQuantity = +saleX.PosQuantity;
sales[index].PosSales = +saleX.PosSales;
salesX.Remove(saleX);
}
else { sales.Add(saleX); }
}
}
}
return sales;
}
Table valued parameters is the way to go if this is indeed the way you need to approach this topic.
First, switch to a stored procedure since you're using SQL 2008 or
newer.
Second, read up on the using statement for disposing of your
sql items.
Psuedo data layer:
public List<SalesList> ExecuteSales(List<string> items, int storeID, int W1, int W2, int vendorID, int retailerID)
{
var sales = new List<SalesList>();
var table = new DataTable();
table.Columns.Add("ItemNumber");
foreach (var item in items)
{
table.Rows.Add(item);
}
using (var connection = new SqlConnection("ConnectionString"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "cp_ExecuteSales";
command.Parameters.AddWithValue("#RetailerID", retailerID);
command.Parameters.AddWithValue("#VendorID", vendorID);
command.Parameters.AddWithValue("#StoreID", storeID);
var tvp = new SqlParameter("#ItemIds", SqlDbType.Structured)
{
TypeName = "tvpItems",
Value = table
};
command.Parameters.Add(tvp);
using (var reader = command.ExecuteReader())
{
//DoWork
}
}
}
return sales;
}
Create the tvp:
CREATE TYPE [dbo].[tvpItems] AS TABLE(
[ItemNumber] [int] NULL
)
Create the stored proc:
CREATE PROCEDURE cp_ExecuteSales
#RetailerID VARCHAR(50),
#VendorID VARCHAR(50),
#StoreID VARCHAR(50),
#ItemIds tvpItems READONLY
AS
SELECT I.ITEM_NBR
,I.ITEM_DESC1
,I.ITEM_DESC2
,I.VENDOR_STK_NBR
,SUM(SA.POS_QTY) AS POS_QTY
,SUM(SA.POS_SALES) AS POS_SALES
FROM SALES_FTBL SA
INNER JOIN ITEM_TBL I ON SA.RETAILER_ID = I.RETAILER_ID
AND SA.ITEM_NBR = I.ITEM_NBR
INNER JOIN #ItemIds ID ON SA.ITEM_NBR = ID.ItemNumber
WHERE SA.RETAILER_ID=I.RETAILER_ID
AND SA.RETAILER_ID = #RetailerID
AND SA.VENDOR_NBR = #VendorID
AND SA.STORE_NBR = #StoreID
AND SA.ITEM_NBR=I.ITEM_NBR
If you need to add a second set of number parameters, then you can pass multiple parameters of different types to the database. In the past, we've created several generic types to support varying list of data types rather than having to manage a lot of table types.
CREATE TYPE [dbo].[IntList] AS TABLE(
[Value] [Int] NULL
)
Important things to remember:
The parameter type for a tvp must be SqlDbType.Structured
The TypeName for the parameter must match the Table Value Parameter
type name.
The Table Value Parameter parameter in the stored procedure must be
declared as READONLY
I would like to minus the data from the database with the value that I give when I run the program. Everything works, but I keep stuck at the newVal. I already did it like this, but the newVal keep appear 0 (because I declared decimal newVal = 0, but on this question, I just used decimal newVal;). Two more problems: if I move the newVal = ... to the top, it is useless, because one of the calculations in the newVal is reading data from the database (since I want database minus with the new value given when i run the program, required dReader = cmd.ExecuteReader();), but if I put the newVal at the bottom after reading data, it is useless as well, because I set the Quantity = ? and the value of ? is newVal.. Well, here is the code:
private void AddObjects(object sender, EventArgs e, Form theForm)
{
button1.Visible = true;
textBoxQuantityContainer = new List<NumericUpDown>();
textBoxCodeContainer = new List<NumericTextBox>();
textBoxDescContainer = new List<TextBox>();
textBoxSubTotalContainer = new List<TextBox>();
textBoxTotalContainer = new List<TextBox>();
textBoxAllTotalContainer = new TextBox();
OleDbDataReader dReader;
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT [Code] FROM [Seranne]", conn);
dReader = cmd.ExecuteReader();
AutoCompleteStringCollection codesCollection = new AutoCompleteStringCollection();
while (dReader.Read())
{
string numString = dReader[0].ToString().PadLeft(4, '0');
codesCollection.Add(numString);
}
dReader.Close();
conn.Close();
if (firstForm.comboBox1.SelectedIndex == 0)
{
label1.Text = "Code:";
label1.Location = new Point(60, 125);
label2.Text = "Welcome to the Selling System.";
label2.Location = new Point(600, 30);
label3.Text = "Quantity:";
label3.Location = new Point(155, 125);
label4.Text = "Description:";
label4.Location = new Point(580, 125);
label5.Text = "Sub Total on Rp:";
label5.Location = new Point(1020, 125);
label6.Text = "Total on Rp:";
label6.Location = new Point(1210, 125);
label7.Text = "Total on Rp:";
label7.Location = new Point(1080, 580);
}
else if (firstForm.comboBox1.SelectedIndex == 1)
{
label1.Text = "Kode:";
label1.Location = new Point(60, 125);
label2.Text = "Selamat datang di Selling System.";
label2.Location = new Point(600, 30);
label3.Text = "Banyaknya:";
label3.Location = new Point(145, 125);
label4.Text = "Keterangan:";
label4.Location = new Point(580, 125);
label5.Text = "Sub Total di Rp:";
label5.Location = new Point(1020, 125);
label6.Text = "Total di Rp:";
label6.Location = new Point(1210, 125);
label7.Text = "Total di Rp:";
label7.Location = new Point(1080, 580);
}
//****TextBox for Code****
for (int y = 0; y <= 16; y++)
{
textBoxCodeContainer.Add(new NumericTextBox());
textBoxCodeContainer[y].Size = new Size(100, 50);
textBoxCodeContainer[y].Location = new Point(25, 150 + (y * 25));
textBoxCodeContainer[y].TextChanged += new System.EventHandler(this.textBox_TextChanged);
textBoxCodeContainer[y].AutoCompleteMode = AutoCompleteMode.Suggest;
textBoxCodeContainer[y].AutoCompleteSource = AutoCompleteSource.CustomSource;
textBoxCodeContainer[y].AutoCompleteCustomSource = codesCollection;
theForm.Controls.Add(textBoxCodeContainer[y]);
}
//****TextBox for Quantity****
for (int y = 0; y <= 16; y++)
{
textBoxQuantityContainer.Add(new NumericUpDown());
textBoxQuantityContainer[y].Size = new Size(100, 50);
textBoxQuantityContainer[y].Location = new Point(125, 150 + (y * 25));
textBoxQuantityContainer[y].TextChanged += new System.EventHandler(this.textBox_TextChanged);
textBoxQuantityContainer[y].Maximum = 1000;
theForm.Controls.Add(textBoxQuantityContainer[y]);
}
//****TextBox for Description****
for (int y = 0; y <= 16; y++)
{
textBoxDescContainer.Add(new TextBox());
textBoxDescContainer[y].Size = new Size(750, 50);
textBoxDescContainer[y].Location = new Point(225, 150 + (y * 25));
theForm.Controls.Add(textBoxDescContainer[y]);
}
//****TextBox for Sub Total****
for (int y = 0; y <= 16; y++)
{
textBoxSubTotalContainer.Add(new TextBox());
textBoxSubTotalContainer[y].Size = new Size(175, 50);
textBoxSubTotalContainer[y].Location = new Point(975, 150 + (y * 25));
theForm.Controls.Add(textBoxSubTotalContainer[y]);
}
//****TextBox for Total****
for (int y = 0; y <= 16; y++)
{
textBoxTotalContainer.Add(new TextBox());
textBoxTotalContainer[y].Size = new Size(175, 50);
textBoxTotalContainer[y].Location = new Point(1150, 150 + (y * 25));
textBoxTotalContainer[y].TextChanged += new System.EventHandler(this.textBox_TextChanged);
theForm.Controls.Add(textBoxTotalContainer[y]);
}
//****TextBox for Total All****
textBoxAllTotalContainer.Size = new Size(175, 50);
textBoxAllTotalContainer.Location = new Point(1150, 575);
textBoxAllTotalContainer.TextChanged += new System.EventHandler(this.textBox_TextChanged);
theForm.Controls.Add(textBoxAllTotalContainer);
}
private void UpdateDatas()
{
int codeValue = 0;
int index = 0;
string query = "SELECT [Quantity], [Description], [Price] FROM [Seranne] WHERE [Code] IN (";
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
if (int.TryParse(this.textBoxCodeContainer[0].Text, out codeValue))
{
query = query + codeValue.ToString();
}
for (int i = 1; i < 17; i++)
{
if (int.TryParse(this.textBoxCodeContainer[i].Text, out codeValue))
{
query = query + "," + codeValue.ToString();
}
}
query = query + ")";
OleDbCommand cmd = new OleDbCommand(query, conn);
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
while (dReader.Read())
{
if (textBoxCodeContainer[index].TextLength != 0)
{
this.textBoxQuantityContainer[index].Maximum = Convert.ToInt32(dReader["Quantity"].ToString());
this.textBoxDescContainer[index].Text = dReader["Description"].ToString();
this.textBoxSubTotalContainer[index].Text = dReader["Price"].ToString();
}
index += 1;
}
dReader.Close();
conn.Close();
}
private void UpdatePrice()
{
int totalPrice = 0;
int quantity = 0;
int price = 0;
for (int i = 0; i < 17; i++)
{
if (textBoxQuantityContainer[i].Value > 0)
{
quantity = (int)textBoxQuantityContainer[i].Value;
price = Convert.ToInt32(textBoxSubTotalContainer[i].Text);
textBoxTotalContainer[i].Text = (quantity * price).ToString();
}
else
{
textBoxSubTotalContainer[i].Text = "";
textBoxTotalContainer[i].Text = "";
}
}
for (int i = 0; i < 17; i++)
{
if (textBoxTotalContainer[i].TextLength != 0)
{
totalPrice += Convert.ToInt32(textBoxTotalContainer[i].Text);
}
}
textBoxAllTotalContainer.Text = totalPrice.ToString("n2");
}
private void UpdateQuantity()
{
int index = 0;
int codeValue = 0;
decimal newVal;
List<int> integers = new List<int>();
foreach (var tb in textBoxCodeContainer)
{
if (int.TryParse(tb.Text, out codeValue))
{
integers.Add(codeValue);
}
}
string command = "UPDATE [Seranne] SET [Quantity]=? WHERE [Code] IN(" + string.Join(", ", integers) + ")";
OleDbConnection conn = new OleDbConnection(connectionString);
OleDbCommand cmd = new OleDbCommand(command, conn);
cmd.Parameters.Add("Quantity", System.Data.OleDb.OleDbType.Integer);
cmd.Parameters["Quantity"].Value = this.newVal.ToString();
OleDbDataReader dReader;
conn.Open();
dReader = cmd.ExecuteReader();
while (dReader.Read())
{
if (textBoxQuantityContainer[index].Value != 0)
{
newVal = (Convert.ToInt32(dReader["Quantity"].ToString()) -
textBoxQuantityContainer[index].Value);
int numberOfRows = cmd.ExecuteNonQuery();
}
index += 1;
}
if (newVal == 0)
{
System.Media.SoundPlayer sounds = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sounds.Play();
MessageBox.Show("Cannot Update", "Error");
}
else
{
System.Media.SoundPlayer sound = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sound.Play();
MessageBox.Show("Was Updated Successfully", "Success");
}
dReader.Close();
conn.Close();
}
private void textBox_TextChanged(object sender, EventArgs e)
{
UpdateDatas();
UpdatePrice();
}
private void button1_Click(object sender, EventArgs e)
{
UpdateQuantity();
}
Thanks a bunch
Good day, i got several things here:
1) cmd.Parameters["Quantity"].Value = this.newVal.ToString(); conversion to string is not needed here, because the Value is an object. You already defined that it should be handled as integer.
2) Replace the ? within you query to #Quantity, so it will be filled by the query execution.
3) When updating you don't need to execute it as a reader. use the int numberOfRows = cmd.ExecuteNonQuery(); without the loop. It will update all items.
4) You should execute the if (textBoxQuantityContainer[index].Value != 0 && textBoxQuantityContainer[index].Value >=
Convert.ToInt32(dReader["Quantity"].ToString()))
{ when building the integers list, this way you are only updating the right quantities.
If you only want to update certain rows, you'll have to expand your where clause:
cmd.Parameters.Add("MinimumQuantity", System.Data.OleDb.OleDbType.Integer).Value = minimumQuantity;
string command = "UPDATE [Seranne]
SET [Quantity]=#Quantity
WHERE [Code] IN(" + string.Join(", ", integers) + ")
AND [Quantity] > #MinimumQuantity
The higest risk is: You assume that the order and count of the records are the same between your textBoxCodeContainer and the database.
What is the relation between a textbox and a row. How do you know what textbox links to which row?
I could give you a push in the right direction, if you show me some more code (like where/how is textBoxCodeContainer defined)
UPDATE:
I made some code the read and manipulate your database, this is not tested since i don't have any database here.
I would create these classes, 1 is a data class Product and one is a Handler class ProductHandler.
The data class only contains the data (not in presentation format) The data handler knows how to read and write them.
public class Product
{
public int Code { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
}
public class ProductHandler
{
public ProductHandler(string connectionString)
{
ConnectionString = connectionString;
}
public bool AddProduct(Product product)
{
return AddProducts(new Product[] { product }) > 0;
}
public int AddProducts(IEnumerable<Product> products)
{
int rowsInserted = 0;
using (OleDbConnection conn = new OleDbConnection(ConnectionString))
{
conn.Open();
string query = "INSERT INTO [Seranne] (Code, Description, Quantity) VALUES(#Code, #Description, #Quantity)";
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.Add("Code", OleDbType.Integer);
cmd.Parameters.Add("Description", OleDbType.VarChar);
cmd.Parameters.Add("Quantity", OleDbType.Integer);
foreach (var product in products)
{
cmd.Parameters["Code"].Value = product.Code;
cmd.Parameters["Description"].Value = product.Description;
cmd.Parameters["Quantity"].Value = product.Quantity;
rowsInserted += cmd.ExecuteNonQuery();
}
}
}
return rowsInserted;
}
public bool UpdateProduct(Product product)
{
return UpdateProducts(new Product[] { product }) > 0;
}
public int UpdateProducts(IEnumerable<Product> products)
{
int rowsUpdated = 0;
using (OleDbConnection conn = new OleDbConnection(ConnectionString))
{
conn.Open();
string query = "UPDATE [Seranne] SET Description = #Description, Quantity = #Quantity WHERE [Code] == #Code)";
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.Add("Code", OleDbType.Integer);
cmd.Parameters.Add("Description", OleDbType.VarChar);
cmd.Parameters.Add("Quantity", OleDbType.Integer);
foreach (var product in products)
{
cmd.Parameters["Code"].Value = product.Code;
cmd.Parameters["Description"].Value = product.Description;
cmd.Parameters["Quantity"].Value = product.Quantity;
rowsUpdated += cmd.ExecuteNonQuery();
}
}
}
return rowsUpdated;
}
public bool DeleteProduct(Product product)
{
return DeleteProducts(new int[] { productCode }) > 0;
}
public int DeleteProducts(IEnumerable<Product> products)
{
using (OleDbConnection conn = new OleDbConnection(ConnectionString))
{
conn.Open();
string productCodeStr = string.Join(", ", products.Select(item => item.Code));
string query = string.Format("DELETE FROM [Seranne] WHERE [Code] in ({0})", productCodeStr);
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
int rowsDeleted = cmd.ExecuteNonQuery();
return rowsDeleted;
}
}
}
public IEnumerable<Product> ReadAllProducts()
{
List<Product> result = new List<Product>();
using (OleDbConnection conn = new OleDbConnection(ConnectionString))
{
conn.Open();
using (OleDbCommand cmd = new OleDbCommand("SELECT [Code], [Description], [Quantity] FROM [Seranne]", conn))
using (OleDbDataReader dReader = cmd.ExecuteReader())
while (dReader.Read())
{
Product product = new Product();
product.Code = Convert.ToInt32(dReader["Code"]);
product.Description = Convert.ToString(dReader["Description"]);
product.Quantity = Convert.ToInt32(dReader["Quantity"]);
result.Add(product);
}
}
return result;
}
public string ConnectionString { get; private set; }
}
Some example code:
ProductHandler _productHandler = new ProductHandler("connectionstring here or from config");
public void Example()
{
_productList.Clear();
_productList.AddRange(_productHandler.ReadAllProducts());
// displaying
foreach (var product in _productList)
Trace.WriteLine(string.Format("code: {0}, description: {1}, quantity: {2}", product.Code, product.Description, product.Quantity);
// updating
var selectedProduct = _productList.FirstOrDefault(item => item.Code == 15);
if(selectedProduct!= null)
{
selectedProduct.Quantity = 50;
_productHandler.UpdateProduct(selectedProduct);
}
// deleting
_productHandler.DeleteProducts(_productList.Where(item => item.Quantity < 5));
}
How to link the textboxes to the right product:
I would create a UserControl that contains a Product property and the TextBoxes and handles when textbox_changed events occurs. Those event handlers manipulate the Product instance.
You only generate 16 controls and bind a product to it. When you press a button, you only need to save the changed products.
i have a problem here.
Here is my case:
I want to update the Quantity value from program based on the value given from program and minus it to the database. For example: i have 100 in Quantity in the database, once i run the program and update the Quantity to 50, the Quantity in the database should be 50.
Here is my problem:
I already can update Quantity value from program to the database, but no matter what's the value that i gave to Quantity in the program, the Quantity value in the database always updating to 0.
Here is the code:
private void UpdateQuantity()
{
int index = 0;
int codeValue = 0;
List<int> integers = new List<int>();
foreach (var tb in textBoxCodeContainer)
{
if (int.TryParse(tb.Text, out codeValue))
{
integers.Add(codeValue);
}
}
string command = "UPDATE [Seranne] SET [Quantity]= " + newVal + " WHERE [Code] IN(" + string.Join(", ", integers) + ")";
OleDbConnection conn = new OleDbConnection(connectionString);
OleDbDataReader dReader;
OleDbCommand cmd = new OleDbCommand(command, conn);
conn.Open();
cmd.Parameters.Add("Quantity", System.Data.OleDb.OleDbType.Integer);
dReader = cmd.ExecuteReader();
while(dReader.Read())
{
if (textBoxQuantityContainer[index].Value != 0 && textBoxQuantityContainer[index].Value >= Convert.ToDecimal(dReader["Quantity"].ToString()))
{
newVal = Convert.ToDecimal(dReader["Quantity"].ToString()) - textBoxQuantityContainer[index].Value;
cmd.ExecuteNonQuery();
}
index += 1;
}
if (newVal == 0)
{
System.Media.SoundPlayer sounds = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sounds.Play();
MessageBox.Show("Cannot Update", "Error");
}
else
{
System.Media.SoundPlayer sound = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sound.Play();
MessageBox.Show("Was Updated Successfully", "Success");
}
dReader.Close();
conn.Close();
}
The newVal value keep appear 0. Because the newVal keep 0, the program show this when i click "Update" button in the program:
if (newVal == 0)
{
System.Media.SoundPlayer sounds = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sounds.Play();
MessageBox.Show("Cannot Update", "Error");
}
But when i check in the database, the Quantity value is changed to 0, no matter what is the value that i was given in the program and the newVal keep 0. So, i think the because of newVal is keep appear 0, then the database recognized it and update it based on the newVal, and this code seems not working:
if (textBoxQuantityContainer[index].Value != 0 && textBoxQuantityContainer[index].Value >= Convert.ToDecimal(dReader["Quantity"].ToString()))
{
newVal = Convert.ToDecimal(dReader["Quantity"].ToString()) - textBoxQuantityContainer[index].Value;
cmd.ExecuteNonQuery();
}
Could you guys help me out? Thanks in advance!
EDIT Code:
private void UpdateQuantity()
{
int index = 0;
int codeValue = 0;
string command;
List<int> integers = new List<int>();
foreach (var tb in textBoxCodeContainer)
{
if (int.TryParse(tb.Text, out codeValue))
{
integers.Add(codeValue);
}
}
OleDbConnection conn = new OleDbConnection(connectionString);
OleDbDataReader dReader;
OleDbCommand cmd = new OleDbCommand(command, conn); // error: use of unassigned local variable, if i put "string command = '' ", the program will run, but the command not recognized by system, and the error will be: Command text was not set for the command object.
conn.Open();
cmd.Parameters.Add("Quantity", System.Data.OleDb.OleDbType.Integer);
dReader = cmd.ExecuteReader();
while(dReader.Read())
{
if (textBoxQuantityContainer[index].Value != 0 && textBoxQuantityContainer[index].Value >= Convert.ToDecimal(dReader["Quantity"].ToString()))
{
newVal = Convert.ToDecimal(dReader["Quantity"].ToString()) - textBoxQuantityContainer[index].Value;
command = "UPDATE [Seranne] SET [Quantity]= " + newVal + " WHERE [Code] IN(" + string.Join(", ", integers) + ")";
cmd.ExecuteNonQuery();
}
index += 1;
}
if (newVal == 0)
{
System.Media.SoundPlayer sounds = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sounds.Play();
MessageBox.Show("Cannot Update", "Error");
}
else
{
System.Media.SoundPlayer sound = new System.Media.SoundPlayer(#"C:\Windows\Media\Windows Notify.wav");
sound.Play();
MessageBox.Show("Was Updated Successfully", "Success");
}
dReader.Close();
conn.Close();
}
change the following like this in while loop,
newVal = Convert.ToDecimal(dReader["Quantity"].ToString()) - textBoxQuantityContainer[index].Value;
string command = "UPDATE [Seranne] SET [Quantity]= " + newVal + " WHERE [Code] IN(" + string.Join(", ", integers) + ")";
cmd.ExecuteNonQuery();
after your while loop , since the 'newVal' is 0 when it was used in query and was updated later on.