i am working with an application(c# wpf, sql)
What i want to do with this program is that when i retrieve data from SQL database( Product, Price , qty) and show in datagrid the program should update automatically the column named total
The code I used to retrieve data is shown below
SqlCommand cmd = new SqlCommand("SELECT * From evid", conn);
DataTable dt = new DataTable("dtList");
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
dtg.ItemsSource = dt.DefaultView;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapt.Fill(ds);
conn.Close();
And the code i used to do the calculation is shown bleow:
int a = Convert.ToInt32(dtg.Columns[0]);
int b = Convert.ToInt32(dtg.Columns[1]);
int c = Convert.ToInt32(dtg.Columns[2]);
c = a * b;
I also want that from example when i update the column quantity from 1 to 2 ; the column total should update itself
Thanks to everyone
It would probably be easier, rather than attempting to calculate the new columns data on c#, to do it in the SQL query.
Firstly this will be less stressful on the system than having to calculate multiple rows of variables, secondly it will be more efficient code-wise.
c = a * b; //This assumed that those two columns are simply variables, which is not how DataTable rows work.
In your sql, according to the information you provided, I recommend something along these lines:
SELECT
Product,
Price,
Quantity,
SUM(Price * Quantity) as Calculation
FROM
evid
GROUP BY
Product,
Price,
Quantity
This SQL query would go into your SqlCommand:
SqlCommand cmd = new SqlCommand("--Query above--", conn);
From there you can simply add the calculation as a new datatable column.
UPDATE
Apologies everyone, I misread the question. You made me curious about figuring a solution to this problem. I whipped up some code which solves the issue you have and will explain as below:
Firstly in order to make it work I had to change your method of filling the table, using DataGrid.Fill(DataTable) wouldn't work as I had to use a custom expression as a data source.
I handled this all programatically for the sake of easy readability, however this should be easy enough to convert to WPF if you wish.
The code:
SqlConnection sqlConn = new SqlConnection("server = ServerName; " + "Trusted_Connection = yes; " + "database = ReportPool; " + "connection timeout = 120");//Sql connection
SqlCommand sqlCmd = new SqlCommand(String.Format("SELECT {0} FROM {1}",//SQl command
"Product, Price, Quantity",
"ReportPool.dbo.TestTable"
), sqlConn);
DataTable dataTable = new DataTable();//Created a new DataTable
DataColumn dc = new DataColumn();//Made a new DataColumn to populate above DataTable
dc.DataType = System.Type.GetType("System.String");//Defined the DataType inside, this can be [[int]] if you want.
dc.ColumnName = "Product";//Gave it a name (important for the custom expression - can only be one word so use underscores if you need multiple words)
DataColumn dc2 = new DataColumn();
dc2.DataType = System.Type.GetType("System.Decimal");
dc2.ColumnName = "Price";
DataColumn dc3 = new DataColumn();
dc3.DataType = System.Type.GetType("System.Decimal");
dc3.ColumnName = "Quantity";
DataColumn dc4 = new DataColumn();
dc4.DataType = System.Type.GetType("System.Decimal");
dc4.ColumnName = "CalculatedColumn";
dc4.Expression = "Price * Quantity";//Multiplying the Price and Quantity DataColumns
dataTable.Columns.Add(dc);//Add them to the DataTable
dataTable.Columns.Add(dc2);
dataTable.Columns.Add(dc3);
dataTable.Columns.Add(dc4);
dataGridControl.ItemsSource = dataTable.DefaultView;//Set the DataGrid ItemSource to this new generated DataTable
sqlConn.Open();//Open the SQL connection
SqlDataReader reader = sqlCmd.ExecuteReader();//Create a SqlDataReader
while (reader.Read())//For each row that the SQL query returns do
{
DataRow dr = dataTable.NewRow();//Create new DataRow to populate the DataTable (which is currently binded to the DataGrid)
dr[0] = reader[0];//Fill DataTable column 0 current row (Product) with reader[0] (Product from sql)
dr[1] = reader[1];
dr[2] = reader[2];
dataTable.Rows.Add(dr);//Add the new created DataRow to the DataTable
}
Hopefully you can now solve the issue you've been experiencing, feel free to comment if you need any help interpreting this code or just need more assistance.
Apologies for the late update.
Related
Hi so I've only just began creating a exam scheduling system and I have an issue when inserting a Excel table into my data grid view. I've created some rows and columns for time however when i insert new data it pads with empty cells and inserts below instead of going into the existing ones. Any help is appreciated.
string PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtPath.Text + ";Extended Properties=\"Excel 8.0; HDR = Yes;\";";
OleDbConnection MyConnection = new OleDbConnection(PathConn);
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", MyConnection);
DataTable dt = new DataTable();
dt.Columns.Add("Time");
DataRow dr = dt.NewRow();
dr["Time"] = "9:00";
dt.Rows.Add(dr);
DataRow dr1 = dt.NewRow();
dr1["Time"] = "10:00";
dt.Rows.Add(dr1);
`etc`
myDataAdapter.Fill(dt);
DataGridView1.DataSource = dt;
It is unclear what you are trying to achieve. In reference to the posted code, you are correct that the table will have “empty” cells for the top two rows except for the first column with the “9:00 and 10:00” values. In addition, there will be “empty” cells in the first column after the first two rows. This is because you are adding the columns AND rows for the “time” values “BEFORE” you are filling it with the data.
I recommend you ADD the data FIRST, then add the “time” column. Then instead of “adding” new rows for the time values… use the “existing” rows that are there from when you read the original data.
Example: first fill the table with the data… myDataAdapter.Fill(dt);… then add the “time” column as the first column in the existing table. It may look something like…
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", MyConnection);
DataTable dt = new DataTable();
myDataAdapter.Fill(dt);
DataColumn timeCol = new DataColumn("Time", typeof(string));
dt.Columns.Add(timeCol);
timeCol.SetOrdinal(0);
dt.Rows[0].SetField("Time", "9:00");
dt.Rows[1].SetField("Time", "10:00");
dataGridView1.DataSource = dt;
Several days ago, I just known about SqlCommandBuilder Class. So, Now i try to do CRUD Operation with SqlDataAdapter.Update(DataTable) Method
I had tried this :
I Have Table Named "Student" with 3 Columns, "idstudent","Name","Class"
//Assume We Have Open SqlConnection
//conn = SqlConnection Variabel
SqlCommand cmd = new SqlCommand("SELECT * FROM Student", conn);
SqlDataAdater da = new SqlDataAdater(cmd);
SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da);
DataTable dt = new DataTable();
da.Fill(dt);
//Then, I try to insert with SqlDataAdapter.Update(DataTable) Method
dt.Rows.Add('1','AnyName','2');
da.Update(dt);
Finally, My question is how to insert data like below :
dt.Rows.Add
(
'idstudent' => '2',
'Name' => 'Ruka',
'Class' => '3'
);
//Then Finally Update
da.Update(dt);
What i want to do is like Laravel Create() parameters. We say what column we wanted to insert value
I had read about lambda expression but it's not help me to do what i want.
Try this approach
var row = dt.NewRow();
row["idstudent"] = 2;
row["Name"] = "Ruka";
row["Class"] = 3;
dt.Rows.Add(row);
You can also add rows by doing this
dt.Rows.Add(new object[] {"blah", "blah2", "blah3"});
For example, I have a Combo box with these contents coming from the database using SqlCommand, SqlDataAdapter and DataTable:
Japan
UK
USA
Philippines
Now, I want to add another choices. It should look like this:
----ALL----
Japan
UK
USA
Philippines
If I chose Japan, it will filter and show all the landmarks in the country like Mt. Fuji, Tokyo Tower.
If I chose UK, it will filter and show Big Ben, Westminster, Olympic Stadium.
If I chose USA, it will show fat people, Kim Kardashian.
IF I CHOSE ----ALL----, IT WILL SHOW ALL THE LANDMARKS FROM ALL COUNTRIES.
How do I do this? I'm using C# & SQL Server.
EDIT:
This is how I fill a combo box.
_con.Open();
SqlCommand _viewLandmarks = new SqlCommand("dbo.SelectDevices_AddingForm", _con);
_viewDevices.CommandType = CommandType.StoredProcedure;
_viewDevices.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(_viewLandmarks);
DataTable dTable = new DataTable("LANDMARK");
da.Fill(dTable);
comboModel.DataSource = dTable;
comboModel.DisplayMember = "Landmark";
comboModel.ValueMember = "LandmarkID";
_con.Close();
As said in comments it is just a matter to add a fake record in your returned datatable
_con.Open();
SqlCommand _viewLandmarks = new SqlCommand("dbo.SelectDevices_AddingForm", _con);
_viewDevices.CommandType = CommandType.StoredProcedure;
_viewDevices.ExecuteNonQuery();
SqlDataAdapter da = new SqlDataAdapter(_viewLandmarks);
DataTable dTable = new DataTable("LANDMARK");
da.Fill(dTable);
DataRow fakeRow = dTable.NewRow();
fakeRow["Landmark"] = "(ALL)";
fakeRow["LandmarkID"] = -1;
dTable.Rows.Add(fakeRow);
comboModel.DataSource = dTable;
comboModel.DisplayMember = "Landmark";
comboModel.ValueMember = "LandmarkID";
_con.Close();
I have added the open/close parenthesys around ALL to to force the new added row to the beginning of your datatable (assuming that it is sorted by Landmark).
Notice also that this approach assumes also that your fields are all NULLABLE. If one or more fields doesn't allow null values you need to set an appropriate value before adding the fakeRow to the Datatale rows collection
Just add a row in your datatable before binding and set the value to All.
Below is a example of binding the combo box
private void BindCombo()
{
DataTable dataTable = GetDataTable();
DataRow row = dataTable.NewRow();
row["Value"] = "0";
row["Name"] = "All";
dataTable.Rows.InsertAt(row, 0);
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "Value";
comboBox1.DataSource = dataTable;
}
Im trying to read in 3 columns of info (student id, name, subject) into a datatable from a database using a oledb connection. It loads fine and i can get it into a datatable no problem. I then output the datable to a datagridview. Now what i cant figure out how to do is to add 2 more columns after the 3 columns read from the database into the same table and display the now 5 column table to the datagridview. THe two columns of info will come from a list. Can anyone provide an example on how to do this?
Thanks
Now this is heavily abbreviated, and makes many assumptions (i.e. the order of items returned from the query is the same as the order of items in your lists). But this is the basic idea.
string columnFourName = "Col4";
string columnFourName = "Col5";
List<object> columnFourItems = new List<object>()
List<object> columnFiveItems = new List<object>()
SqlConnection oConn = new SqlConnection("SomeConnstring);
oConn.Open();
SqlCommand oComm = new SqlCommand("SELECT * FROM Stuff", oConn);
SqlDataAdapter sda = new SqlDataAdapter(oComm);
DataTable dt = new DataTable();
sda.Fill(dt);
dt.Columns.Add(columnFourName, typeof(object));
dt.Columns.Add(columnFiveName, typeof(object));
for (int row = 0; row < dt.Rows.Count; row++)
{
dt.Rows[row][3] = columnFourItems[row];
dt.Rows[row][4] = columnFiveItems[row];
}
Run time error Cannot find column 0. below is my code
string connectiostring = (string)ConfigurationSettings.AppSettings["NorthwindConnectionString"];
SqlConnection conn = new SqlConnection(connectiostring);
SqlCommand cmd = new SqlCommand("select * from Employees", conn);
conn.Open();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet data = new DataSet();
adapter.Fill(data,"Employees");
data.Tables["Employees"].Columns.Add("Testcolumn");
DataTable t1 = new DataTable("Employees");
DataRow newrow = t1.NewRow();
newrow[0] = "10";\\this the line i am getting error
newrow[1] = "Pradeep";
newrow[2] = "Kumar";
data.Tables["Employees"].Rows.Add(newrow);
GridView2.DataSource = data;
GridView2.DataBind();
Please help me
Thanks,
You haven't added the columns to the DataTable.
t1.Columns.Add(new DataColumn
{
DataType = string,
ColumnName = "First Name"
});
repeat this for each column supplying the correct type for each.
Create a function that adds columns before trying to add rows.. Call the method at InitializeComponents..
ex.
private void InitTbl(DataTable myTbl)
{
myTbl.Columns.Add(new DataColumn("id"));
myTbl.Columns.Add(new DataColumn("fname"));
myTbl.Columns.Add(new DataColumn("lname"));
}
You need to add some columns to the table first:
DataTable t1 = new DataTable("Employees");
t1.Columns.Add("column1", typeof(string));
t1.Columns.Add("column2", typeof(string));
t1.Columns.Add("column3", typeof(string));
DataRow newrow = t1.NewRow();
...
I think maybe this is actually your problem.
DataTable t1 = new DataTable("Employees")
This creates a brand new table object that is not part of your dataset.
So you should be replace it with this
DataTable t1 = data.Tables["Employees"]
Which gets the table from the dataset and points the t1 variable at that table.