I'm currently developing a POS system(windows application) in C# with SQL Server as the database. In my database, I have a product table that contains the following fields: barcode(primary key) , productID,productName ,productQty ,productSize, and productUnitPrice.
In my GUI, I have a TEXTBOX for the barcode, a numericUpDown for the quantity,and a LISTVIEW(7 columns : barcode, ID, Description, Quantity, Size, Regular Price, Sale Price) for the cart.
My problem is, how do I add the product information(barcode, productID, productName, productQty, productSize, productUnitPrice) inside the LISTVIEW based on the barcode that was entered on the barcode TEXTBOX?
//Inventory Base Class
public abstract class inventoryBaseClass
{
public inventoryBaseClass()
{
}
public inventoryBaseClass(uint _id)
{
Id = _id;
}
public void OpenSqlConn()
{
try
{
sqlConnection = #"Data Source=PC10\SQLEXPRESS;Initial Catalog=POSDB;Integrated Security=True";
sqlConn = new SqlConnection(sqlConnection);
sqlConn.Open();
}
catch (Exception ex)
{
DialogResult r = MessageBox.Show(ex.Message, "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
if (r == DialogResult.OK)
Application.Exit();
}
}
}
//Point of Sales Class
public class pointOfSalesClass : inventoryBaseClass
{
public pointOfSalesClass()
{
}
public pointOfSalesClass(uint _id)
: base(_id)
{
OpenSqlConn();
string sql = #"Select Barcode, ProductID, ProductName, TotalStocks,Size, Price, SaleAmount FROM PRODUCT WHERE Barcode = +" + _id;
SqlCmd = new SqlCommand();
SqlCmd.CommandText = sql;
SqlCmd.Connection = SqlConn;
}
}
//Point of sales Form
public partial class Point_of_Sales : Form
{
//these variables will hold the values that will be retreived in the SELECT statement in the Point of Sales Class
uint barcode = 0;
string id = "";
string productName = "";
uint qty = 0;
string size = "";
double regularPrice = 0.0;
double salePrice = 0.0;
//ADD to cart(Listview) Button
private void AddItem_Click(object sender, EventArgs e)
{
//the user enters the barcode on the txtBarcode textbox and the quantity to be purchased on the numericUpDown control
//When this button is pressed, the select statement will be executed
pointOfSalesClass addToCart = new pointOfSalesClass(uint.Parse(txtBarcode.Text.ToString()));
addToCart.SqlDataRdr = addToCart.SqlCmd.ExecuteReader();
uint quantity = Convert.ToUInt16(numericQty.Value);
while (addToCart.SqlDataRdr.Read())
{
//These are the values to be retreived
barcode = Convert.ToUInt32(addToCart.SqlDataRdr["Barcode"].ToString());
id = addToCart.SqlDataRdr["ProductID"].ToString();
productName = addToCart.SqlDataRdr["ProductName"].ToString();
qty = Convert.ToUInt32(addToCart.SqlDataRdr["TotalStocks"].ToString());
size = addToCart.SqlDataRdr["Size"].ToString();
regularPrice = Convert.ToDouble(addToCart.SqlDataRdr["Price"].ToString());
salePrice = Convert.ToDouble(addToCart.SqlDataRdr["SaleAmount"].ToString());
}
//After retreiving all values in the select statement
//How do I insert the values(barcode, id, productname, quantity(from the numericUpDown control), size, regularPrice,salePrice) inside the LISTVIEW.
}
}
This should get you started:
ListViewItem item = new ListViewItem(
new string[] { barcode.ToString(), id, productName /* etc */ });
listView1.Items.Add(item);
Basically, set your listview's itemssource to an empty list, and then fill that list with whatever items have THAT barcode, hook up the textchanged event of the textbox to update that list (Watch out for performance hits tho, use LINQ to objects instead of re-querying the DB)
Related
I have 2 asp.net WebForms, WebForm1 contains a button that redirects into WebForm2 which contains a contact form that needs to be filled to proceed an order.
I have a drop down list in it that is connected to the database, and depending on which product a button on the WebForm1 is clicked, the current quantity is displayed from the specific product from the database.
After the ordering, I need to decrease/deduct the product quantity from the database depending on how many products on the drop down list were selected.
How to decrease the product quantity after the order is proceed?
Here is the code that fills several TextBoxes, inserts currency and fills the drop down list "Quantity" depending on which product on the WebForm1 the button is clicked:
protected void Page_Load(object sender, EventArgs e)
{
string productName = Request.QueryString["productname"];
txt_product13.Text = productName;
var dictionary = new Dictionary<string, object>
{
{ "#ProductName", productName }
};
var parameters = new DynamicParameters(dictionary);
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (var connection = new SqlConnection(CS))
{
connection.Open();
var sql = "SELECT * FROM ProductsDB WHERE ProductName = #ProductName";
var product = connection.QuerySingle<Product>(sql, parameters);
CultureInfo EuroCulture = new CultureInfo("fr-FR");
txt_productprice.Text = product.Price.ToString("c", EuroCulture);
for (int i = 1; i <= product.Quantity; i++)
{
dropdownlist1.Items.Add(new ListItem(i.ToString(), i.ToString()));
}
}
}
For now I have this code for decreasing, can you tell where is my mistake and why does it not decrement the quantity from database?
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
string productName = Request.QueryString["productname"];
using (var connection = new SqlConnection(CS))
{
connection.Open();
var sql = "UPDATE ProductsDB SET Quantity = WHERE ProductName = #ProductName" + dropdownlist1.SelectedValue + "'";
connection.Close();
}
UPDATE ProductsDB SET Quantity = WHERE ProductName = #ProductName" + dropdownlist1.SelectedValue + "'".
should be something like...
UPDATE ProductsDB SET Quantity = (oldValue - QtyOrdered) WHERE ProductName = #ProductName" + dropdownlist1.SelectedValue + "'".
Below these code I'm getting the wrong output in incrementing the string value in my Database column "SupplierID". I'm transferring the string value to my lbl_id in ADDSupplier Form and That's what i used to insert value to my "SupplierID".
Desired Output:
SPPL-0001
SPPL-0002
SPPL-0003
etc
Currently Output (Below these code):
SPPL-0001
SPPL-00012
SPPL-00013
etc
NOTE: When i repeat inserting data i get the currently output that i stated above but when i restart the program and the last inserted value, For example is SPPL-00013. When i open my adding form, lbl_id display the id as SPPL-0004. If i continue, it become SPPL-00045.
PS: SupplierID is varchar(50) in my database and also PRIMARY_KEY
These image shows the wrong output of mine
What i want to get help with is to correct my logic and get that desired output. Please help me. Thank you
public partial class SIMSSupplier : UserControl
{
ADDSupplier supply;
public SIMSSupplier()
{
InitializeComponent();
}
public string ID = "SPPL-000";
public void GenerateAutoID()
{
using (var con = SQLConnection.GetConnection())
{
using (var select = new SqlCommand("Select Count(SupplierID) from admin_supplier", con))
{
int i = Convert.ToInt32(select.ExecuteScalar());
i++;
supply.lbl_id.Text = ID + i.ToString();
}
}
}
private void btn_register_Click(object sender, EventArgs e)
{
supply = new ADDSupplier(this);
supply.Show();
GenerateAutoID();
}
}
public partial class ADDSupplier : MetroForm
{
SIMSSupplier _view;
public ADDSupplier(SIMSSupplier _view)
{
InitializeComponent();
this._view = _view;
}
string date = DateTime.Now.ToString("MMMM-dd-yyyy");
private void btn_ok_Click(object sender, EventArgs e)
{
_view.ID = lbl_id.Text;
using (var con = SQLConnection.GetConnection())
{
if (string.IsNullOrEmpty(txt_name.Text) || string.IsNullOrEmpty(txt_contact.Text) || string.IsNullOrEmpty(cbox_remark.Text) || string.IsNullOrEmpty(txt_address.Text))
{
CustomNotifcation.Show("Please input the required fields", CustomNotifcation.AlertType.warning);
}
else
{
using (var select = new SqlCommand("Insert into admin_supplier (SupplierID, Companyname, Contactnumber, Date, Remarks, Address) Values (#SupplierID, #Companyname, #Contactnumber, #Date, #Remarks, #Address)", con))
{
select.Parameters.Add("#SupplierID", SqlDbType.VarChar).Value = lbl_id.Text;
select.Parameters.Add("#Companyname", SqlDbType.VarChar).Value = txt_name.Text;
select.Parameters.Add("#Contactnumber", SqlDbType.VarChar).Value = txt_contact.Text;
select.Parameters.Add("#Date", SqlDbType.VarChar).Value = date;
select.Parameters.Add("#Remarks", SqlDbType.VarChar).Value = cbox_remark.Text;
select.Parameters.Add("#Address", SqlDbType.VarChar).Value = txt_address.Text;
select.ExecuteNonQuery();
CustomMessage.Show("Message: Supplier successfully added!", CustomMessage.Messagetype.Success2);
_view._Supplier();
}
}
}
}
}
You just need to use a format string instead:
string ID = "SPPL-"
supply.lbl_id.Text = ID + i.ToString("0000");
Which will result in the format being applied correctly. Right now you are appending the i variable to the ID, which is already SPPL-000, so the next one becomes SPPL-0001, etc.
I am creating an app for windows phone for which I need to create a database connection for that i have used SQLite.
From this Link i have executed the queries:http://www.codeguru.com/csharp/.net/wp7/using-sqlite-in-your-windows-phone-application.htm
this is the code:
private void btncreate_Click(object sender, RoutedEventArgs e)
{
if (MySqlLiteDB == null)
{
MySqlLiteDB = new SQLiteConnection("MyTestDB");
MySqlLiteDB.Open();
MessageBox.Show("Connection opened Successfully!!!");
}
}
private void btnpopulate_Click(object sender, RoutedEventArgs e)
{
SQLiteCommand cmd=MySqlLiteDB.CreateCommand("Create table student(id int primary key,name text,zipcode numeric(7))");
int i = cmd.ExecuteNonQuery();
int id = 0;
for (int j = 0; j < 20; j++)
{
id++;
string name = "Name" + id;
int zipcode = 98000 + id;
cmd.CommandText = "Insert into student(id,name,zipcode) values(" + id + ",\"" + name + "\"," + zipcode + ")";
i = cmd.ExecuteNonQuery();
}
MessageBox.Show("Insert successful");
}
private void btnclear_Click(object sender, RoutedEventArgs e)
{
SQLiteCommand cmd = MySqlLiteDB.CreateCommand("drop table student");
int i = cmd.ExecuteNonQuery();
MessageBox.Show("Data Cleared successfully");
}
private void btnclose_Click(object sender, RoutedEventArgs e)
{
if (MySqlLiteDB != null)
{
MySqlLiteDB.Dispose();
MySqlLiteDB = null;
MessageBox.Show("Connection closed");
}
}
but now i need to retrieve the data from database table and bind it to a grid using select statement how can i do this?
I want to show the table data in a grid is there any way to bind the data to a grid.
Add the following function and class in your code
public class student
{
public int id {get;set;}
public string name {get;set;}
public long zipcode {get;set;}
}
SelectFromStudent()
{
string query="select id,name,zipcode from student";
List<student> studentList = SelectFromTable<student>(query);
}
List<T> SelectFromTable<T>(String statement) where T : new()
{
SQLiteCommand cmd = MySqlLiteDB.CreateCommand(statement);
var lst = cmd.ExecuteQuery<T>();
return lst.ToList<T>();
}
You can't use grid bind data in windows phone application. there is another control to do such kind of operation ListBox. you can edit Itemtemplate of ListBox. ListBox has itemsource property.
I have a DataGridView created in C# windows forms and checkboxColumn added to it. The DataGridView is populated with other columns like Sno, AccountNo, Name, Salary (Sno is identitycolumn and primarykey).
I want to delete a row (using stored procedure) by selecting the checkbox and on button click which is out side DataGridView. Error at "FindControl".
Stored Procedure:
Create Procedure uspDeleteSelectedRow
As
Delete from EmpDetails where Sno=Sno
Go
private void btnDelete_Click(object sender, EventArgs e)
{
//Create String Collection to store IDs of
//records to be deleted
StringCollection idCollection = new StringCollection();
string strID = string.Empty;
//Loop through GridView rows to find checked rows
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
CheckBox chkDelete = (CheckBox)dataGridView1.Rows[i].
Cells[0].FindControl("chkSelect");
if (chkDelete != null)
{
if (chkDelete.Checked)
{
strID = dataGridView1.Rows[i].Cells[1].ToString();
idCollection.Add(strID);
}
}
}
if (idCollection.Count > 0)
{
//Call the method to Delete records
DeleteMultipleRecords(idCollection);
// rebind the GridView
dataGridView1.DataBind();
}
else
{
lblMessage.Text = "Please select any row to delete";
}
}
private void DeleteMultipleRecords(StringCollection idCollection)
{
//Create sql Connection and Sql Command
SqlConnection con = new SqlConnection(Helper.ConnectionString);
SqlCommand cmd = new SqlCommand();
string IDs = "";
foreach (string id in idCollection)
{
IDs += id.ToString() + ",";
}
try
{
string test = IDs.Substring
(0, IDs.LastIndexOf(","));
string sql = "Delete from EmpDetails" + " WHERE ID in (" + test + ")";
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
string errorMsg = "Error in Deletion";
errorMsg += ex.Message;
throw new Exception(errorMsg);
}
finally
{
con.Close();
}
}
Let say this is your stored procedure:
ALTER PROCEDURE [dbo].[sp_ToDeleteEmpDetails] #Sno int
/*
(
#parameter1 int = 5,
#parameter2 datatype OUTPUT
)
*/
AS
DELETE FROM EmpDetails
WHERE Sno = Sno
RETURN
You don't need a StringCollection to delete or call the stored procedure.
private void btnDelete_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow item in dataGridView1.Rows)
{
bool IsBool = false;
if (bool.TryParse(item.Cells[1].EditedFormattedValue.ToString(), out IsBool)) //<--Where: The ColumnIndex of the DataGridViewCheckBoxCell
{
using (SqlConnection con = new SqlConnection(Helper.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("sp_ToDeleteEmpDetails", con))
{
try {
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#sno", SqlDbType.Int).Value = item.Cells[0].EditedFormattedValue.ToString(); //<--Where: The ColumnIndex of the Primary key from your DataGridView
dataGridView1.Rows.RemoveAt(item.Cells[0].RowIndex);
con.Open();
cmd.ExecuteNonQuery();
} catch (Exception) {
throw;
}
finally
{
con.Close();
}
}
}
}
}
}
Please let me know if you have some encountered problem from my given answer.
Try this solution. In my code I have class and pass a list of it to gridview as my datasource.
//Class
public class User
{
public bool Selected { get; set; }
public string UserName { get; set; }
}
//Create a list and bind to the data grid view
private void Form1_Load(object sender, EventArgs e)
{
var users = new List<User> { new User { UserName = "Jobert", Selected = false }, new User { UserName = "John", Selected = true }, new User { UserName = "Leah", Selected = true }, new User { UserName = "Anna", Selected = false } };
dataGridView1.DataSource = users;
}
//On delete
private void btnDelete_Click(object sender, EventArgs e)
{
//get data back from the source
var source = dataGridView1.DataSource as List<User>;
var selectedItems = source.Where(x => x.Selected).ToList();
foreach (var item in selectedItems)
{
//perform the delete
}
}
UPDATED FOR CLARIFICATION
I posted a similar question a while back found here which used Matlab (and Matlab GUI).
However, now I am trying to do the same thing, but implemented through a Windows Form, C#, and a local, static database file which has been populated with data already.
The data in the database is as follows:
Compound_ID Component1 Component2 Component3 Value
int string string string int
with ~24,000 rows of data.
The first column "Compound_ID" is the primary key. The next three columns, "Component1", "Component2", and "Component3", contain one component each from a set of ~100 possible components. Each compound is made up of 3 different components from the set of 100. Order of components doesn't matter, so the Compounds are combinations (as distinct from permutations) of 3 components. Example:
Compound_ID Component1 Component2 Component3 Value
1456 a b c 10
1457 a b m 50
1458 a c g 25
etc. From this example, we know that there will never be another compound in the DB that is "a g c" or any other permutation thereof, since order doesn't matter (A list of 100 values will generate ~161,000 combinations of 3, but almost 1,000,000 permutations of 3).
The user will select some number of components (with a list of checkboxes or a spreadsheet) on the Windows Form. They will press a button on the form. The button will call a method to find all of the Compounds listed in the database which can be made from the list of components the user has selected. This data will be displayed in a dataGridView on the same form.
One way it might be done (similar to the Matlab solution described by another user in my previous post): Generate 3 logical arrays, one for each column, where "1" represents the rows containing one of the 15 components. Add the columns together, and only those rows which have a value of "3" are the rows I am looking for. Then build a new table containing those rows, and display in datagridview. Any tips on how this code might look would be helpful.
I am going to give some of the solutions already provided a try. This would involve figuring out a way to call an SQL Query from C#, which I am told I can look up, and an example has already been provided.
Thanks to everyone for your help. This is a solely independent project born of curiosity, so it is not serious business, I am just trying to figure it out. I am relatively new to C# (and definitely SQL Queries), so please excuse my ignorance. Point me to sources with a little explanation if that would be a better use of everyone's time.
Select ct.*
From costtable ct
Where ct.Col1 <> ct.Col2 and ct.Col2 <> ct.Col3 and
ct.Col1 in ('Test1', 'Test2', 'Test3') and
ct.Col2 in ('Test1', 'Test2', 'Test3') and
ct.Col3 in ('Test1', 'Test2', 'Test3')
I'm not sure about your use case, but are duplicate components possible? like Col1 and Col2 with the same value?
Here is the SqlFiddle you can play with:
http://sqlfiddle.com/#!3/46944/1/0
Something like this where #a, #b, #c are the values you seek
select
*
from
table
where
(
case col1 when #a then 1 when #b then 2 when #c then 4 else 0 end
+ case col2 when #a then 1 when #b then 2 when #c then 4 else 0 end
+ case col3 when #a then 1 when #b then 2 when #c then 4 else 0 end
) = 7
Unlike a simplistic IN solution, this will assure uniqueness of combinations
Here is the code that ended up doing what I needed. It is a combination of LittleBobbyTables's SQL query and GrayFox374's C# code to implement that query. I would upvote you both, but evidently I don't have the clout to do that yet!
class Program
{
static void Main(string[] args)
{
List<string> components = new List<string>();
components.Add("Ing1");
components.Add("Ing2");
components.Add("Ing3");
components.Add("Ing5");
components.Add("Ing9");
StringBuilder sb1 = new StringBuilder();
sb1.Append("(");
foreach (string s in components)
{
string stemp = "'" + s + "'" + ",";
sb1.Append(stemp);
}
int start = sb1.ToString().Length - 2;
sb1.Replace(",", ")", start, 2);
List<Result> results = new List<Result>();
SqlConnection con = new SqlConnection("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\dbTestCSV.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");
StringBuilder sb = new StringBuilder();
sb.Append("SELECT [Numbers], [Col1], [Col2], [Col3], [Col4], [Col5]");
sb.Append("FROM Table1 ");
sb.Append("WHERE [Col1] IN ");
sb.Append(sb1.ToString());
sb.Append(" AND [Col2] IN ");
sb.Append(sb1.ToString());
sb.Append(" AND [Col3] IN ");
sb.Append(sb1.ToString());
SqlCommand cmd = new SqlCommand(sb.ToString(), con);
try
{
con.Open();
cmd.CommandType = System.Data.CommandType.Text;
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
results.Add(new Result(Convert.ToInt32(dr[0].ToString()), dr[1].ToString(), dr[2].ToString(), dr[3].ToString(), dr[4].ToString(), dr[5].ToString()));
}
}
dr.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
finally
{
con.Close();
}
foreach (Result res1 in results)
{
Console.WriteLine(res1.PK.ToString());
}
Console.ReadLine();
//process/present results at this point
}
}
public class Result
{
public int PK { get; set; }
public string Col1 { get; set; }
public string Col2 { get; set; }
public string Col3 { get; set; }
public string Col4 { get; set; }
public string Col5 { get; set; }
public Result(int pk, string col1, string col2, string col3, string col4, string col5)
{
PK = pk; Col1 = col1; Col2 = col2; Col3 = col3; Col4 = col4; Col5 = col5;
}
}
I think this is it:
UPDATE
database table values
PKID Col1 Col2 Col3 Cost
1 Helium Oxygen Nitrogen 10
2 Hydrogen Chlorine Sodium 10
3 Chlorine Sodium Gold 10
4 Hydrogen Carbon Potassium 10
5 Carbon Silicon Boron 10
6 Uranium Cesium Plutonium 10
7 Titanium Iodine Fluorine 10
8 Helium Neon Argon 10
9 Krypton Xenon Radon 10
10 Barium Chromium Calcium 10
11 Helium Lithium Sodium 10
So if you choose Helium, Oxygen, Nitrogen, Barium, Chromium, Calcium and Uranium, you should get rows with PKIDs 1 and 10, and that's it. Right?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnFind_Click(object sender, EventArgs e)
{
List<Component> results = new List<Component>();
foreach (object itemChecked in checkedListBox1.CheckedItems)
{
var cn = new OdbcConnection(#"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\elements.mdb;Uid=Admin;Pwd=;");
StringBuilder sb = new StringBuilder();
sb.Append("SELECT [PKID], [Col1], [Col2], [Col3], [Cost] ");
sb.Append("FROM components ");
sb.Append("WHERE ? IN (Col1, Col2, Col3) ");
var cm = new OdbcCommand(sb.ToString(), cn);
try
{
cn.Open();
cm.CommandType = System.Data.CommandType.Text;
cm.Parameters.AddWithValue("?", itemChecked.ToString());
OdbcDataReader dr = cm.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
var comp = new Component(Convert.ToInt32(dr[0].ToString()),
dr[1].ToString(), dr[2].ToString(), dr[3].ToString(), Convert.ToInt32(dr[4].ToString()));
Component r = results.Find(
delegate(Component c)
{
return c.CompoundID == Convert.ToInt32(dr[0].ToString());
}
);
if (r != null)
{
//update the frequency
var obj = results.FirstOrDefault(x => x.CompoundID == comp.CompoundID);
if (obj != null) obj.Frequency++;
}
else { results.Add(comp); }
}
}
dr.Close();
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
finally { cn.Close(); }
}
//process/present results at this point
//for each result in list with freq >= 3, output to grid
IEnumerable<Component> rowsWithThreeHits = results.Where(cFreq => int.Equals(cFreq.Frequency, 3))
.Select(x => new Component { CompoundID = x.CompoundID, Component1 = x.Component1,
Component2 = x.Component2, Component3 = x.Component3, CompoundValue = x.CompoundValue });
List<Component> final = new List<Component>(rowsWithThreeHits);
dataGridView1.DataSource = final;
}
}
public class Component
{
public int CompoundID { get; set; }
public string Component1 { get; set; }
public string Component2 { get; set; }
public string Component3 { get; set; }
public int CompoundValue { get; set; }
public int Frequency { get; set; }
public Component() {}
public Component(int compoundID, string component1, string component2, string component3, int compoundValue)
{
CompoundID = compoundID;
Component1 = component1;
Component2 = component2;
Component3 = component3;
CompoundValue = compoundValue;
Frequency = 1;
}
}
I used Access because we don't use SQL Server here, but you can swap out the ODBC object for SQL objects and it works.