I have a table named orders.
I want to display Order Date, Sum of the product quantity ordered and the product_name.
Here is the data I want to display:
Data to Display
As above, I want product names to be displayed horizontally, with the sum of the product orders displayed vertically by date.
I am using C# and an MS Access database.
I am able to display the data in gridview row-wise. Here is the code:
private void btn_all_orders_Click(object sender, EventArgs e)
{
try
{
connection.open
OleDbCommand command = new OleDbcommand();
command.connection = connection;
string query = "select order_date as 'Order Date', product_name as
'Items', Sum(order_quantity) as 'No of Orders' from order where cust_id =
'" + txt_cust_id.Text + "' group by order_date, product_name";
command.commandText = query;
OleDbDataAdapter da = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
datagridview.DataSource = dt;
connectionn.Close();
}
catch (Exception ex)
{
Messagebox.Show("Error " + ex);
connection.Close();
}
}
How do I change this to achieve the goal described above?
I think you are asking for is this:
What you will need to do is ADD a Column to your to your datatable.
Then add an expression to that column it.
da.Fill(dt);
dt.Columns.Add("TOTAL");
dt.Columns("Total").Expression = "Count(Product1) + Count(Product2) + Count(Product3)";
datagridview.DataSource = dt;
connectionn.Close();
The totals on the bottom are coming from your SelectQuery => Sum(order_quantity). You can modify the query to get rid of that.
Some info
Of course the query could be changed so that it returns a computed column back and then you do not need to do it in the datatable.
Actual SQL for changing the query so that it returns a computed column back - https://stackoverflow.com/questions/3932205/to-calculate-sum-two-alias-named-columns-in-sql
The code above is pseudo - untested code - so please read the links.
EDIT
You could also look here : Display Data Vertically in the DataGridview
Too much code to post but basically the real work is done by flipping the dataset - as Mr. Gamal did.
public DataSet FlipDataSet(DataSet my_DataSet)
{
DataSet ds = new DataSet();
foreach (DataTable dt in my_DataSet.Tables)
{
DataTable table = new DataTable();
for (int i = 0; i <= dt.Rows.Count; i++)
{ table.Columns.Add(Convert.ToString(i)); }
DataRow r;
for (int k = 0; k < dt.Columns.Count; k++)
{
r = table.NewRow();
r[0] = dt.Columns[k].ToString();
for (int j = 1; j <= dt.Rows.Count; j++)
{ r[j] = dt.Rows[j - 1][k]; }
table.Rows.Add(r);
}
ds.Tables.Add(table);
}
return ds;
}
Related
I'm Prateek, trying to create an application that takes user inputs from the controls that are being generated dynamically such as a TextBox or a DropDownList.
These controls are generated from the database values itself i.e., I'm storing all the values that are to be created in a table named 'usertasks'.
Now, everything is working fine and controls are dynamically generated, the user inputs are stored in another table named 'taskEntries'. The problem I'm facing is with the values being fetched:
The above image is of a table to save what kind of controls the user wants to create and their labels.
Another image to show how data is being stored right now:
How I want the data to be fetched:
Kindly let me know how do I do it in asp.net c#.
What I tried?
//Below code to get all data into a DataTable
protected void getData()
{
using (SqlConnection con = new SqlConnection(ConnectionManager.ConString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("select (cdate + ', ' + ctime) as 'Date', taskID as 'Task ID', deptID as 'Department ID', empID as 'Employee ID', question as 'Question', userInput as 'Input' from taskEntries", con))
{
DataTable dt = new DataTable();
sda.Fill(dt);
ViewState["dt"] = dt;
BindGrid(dt, false);
}
con.Close();
}
ConvertRowsToColumns();
}
//Below code to bind the gridview
private void BindGrid(DataTable dt, bool rotate)
{
grdUserData.ShowHeader = !rotate;
grdUserData.DataSource = dt;
grdUserData.DataBind();
if (rotate)
{
foreach (GridViewRow row in grdUserData.Rows)
{
row.Cells[0].CssClass = "header";
}
}
}
//Below code to convert the rows to columns
private void ConvertRowsToColumns()
{
DataTable dt = (DataTable)ViewState["dt"];
DataTable dt2 = new DataTable();
for (int i = 0; i <= dt.Rows.Count; i++)
{
String Question = Convert.ToString(dt.Rows[i]["question"]);
String InputType = Convert.ToString(dt.Rows[i]["inputType"]);
dt2.Columns.Add(Question);
dt2.Columns.Add(InputType);
}
for (int i = 0; i < dt.Columns.Count; i++)
{
dt2.Rows.Add();
dt2.Rows[i][0] = dt.Columns[i].ColumnName;
}
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
dt2.Rows[i][j + 1] = dt.Rows[j][i];
}
}
BindGrid(dt2, true);
}
My program able to read excel into datatable using epplus C# and there's a barcode column with data. I need to add & get bookcode data column from SQL Server based on data in barcode column. How will the SQL query be able to get each cell data row from the barcode column? I am confused to get the data by column or row.
I managed to get the SQL Server connection and 1 bookcode so far. I think I have to do looping to get all the bookcode for all the barcode column data but I'm not sure with the sequence in my coding and SQL connection. I believe I almost there to get it, hope you guys can assists me as this is my first project in C# :)
public void filldatagridview(ExcelWorksheet workSheet)
{
DataTable dt = new DataTable();
// Create the data column
for (int col = workSheet.Dimension.Start.Column; col <= workSheet.Dimension.End.Column; col++)
{
dt.Columns.Add(col.ToString());
}
// for (int row = workSheet.Dimension.Start.Row; row <= workSheet.Dimension.End.Row; row++)
for (int row = 12; row <= 26; row++)
{
DataRow newRow = dt.NewRow(); //Create a row
int i = 0;
for (int col = workSheet.Dimension.Start.Column; col <= workSheet.Dimension.End.Column; col++)
{
newRow[i++] = workSheet.Cells[row, col].Text;
}
dt.Rows.Add(newRow);
}
dt.Columns.RemoveAt(0); //remove No
dt.Columns.RemoveAt(0); //remove article
//Get BookCode
SqlConnection conn = new SqlConnection("Server=10.0.0.10;Database=;UserID=;Trusted_Connection=False");
string query = "SELECT BookCode FROM Inventory WHERE Barcode='" + dt.Rows[1]["3"].ToString().Trim() + "'"; //3 is column for barcode
// looping logic here?
for (int i = 0; i < dt.Rows.Count; i++)
{
}
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
dataGridView2.DataSource = dt;
conn.Close();
da.Dispose();
}
UPDATED:
Able to get data from sql server based on barcode column in "3" as attached in the following image:
Currently facing problem with the order I receive from database in BOOKCODE column. Where supposedly it should follow like in this image:
I am working on a Tool Crib system. I need to have a way to fill my dataGridView with past Purchase Orders.PO List on the left side to fill DataGridView. I have used this before to fill gridViews:
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
string orderNumber = lbOrders.SelectedItem.ToString();
string query = "SELECT PartNumber from PurchaseOrders WHERE PONumber LIKE '%" + orderNumber + "%' ";
cmd.CommandText = query;
//OleDbDataReader reader = cmd.ExecuteReader();
cmd.ExecuteNonQuery();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
However I don't know how to fill an existing dataGridView table. As in I don't know how to use the columns that I already have to create Purchase Orders. The da.Fill(dt) just adds all new columns and I end up with and extra column and a lot of empty cells.
Extra Column for PartNumber
I tried to just fill the Item column with this code:
string query = "SELECT PartNumber from PurchaseOrders WHERE PONumber LIKE '%" + orderNumber + "%' ";
cmd.CommandText = query;
OleDbDataReader reader = cmd.ExecuteReader();
//cmd.ExecuteNonQuery(); //not using this code
//OleDbDataAdapter da = new OleDbDataAdapter(cmd); //not using this code
//DataTable dt = new DataTable(); //not using this code
//da.Fill(dt); //not using this code
//dataGridView1.DataSource = dt; //not using this code
List<string> result = new List<string>();
for (int i = 0; i < result.Count - 1; i++)
while (reader.Read())
{
result.Add(reader.GetString(0));
//dataGridView1.Rows[0].Cells["Item"].Value = (reader["PartNumber"]).ToString(); //not using this code
}
for (int i = 0; i < result.Count-1; i++)
{
foreach (var item in result)
{
dataGridView1.Rows[i].Cells["Item"].Value = result[i];
}
}
con.Close();
This code sort of worked for me. However, it kept saying that my index was out of range and would never fill the "Item" column correctly/completely. The other downside to this is that I still needed to bring in the Quantity. I have the grid bring in the other information when there is a change to a cell value. It looks at the database of items to get description and price, so all I need to do is to be able to fill the Item and quantity columns.
I've been at this for a few hours now and I need help.
Summary: I need a way to fill my Item, and Quantity columns with part numbers and quantities stored in an Access DataBase - DB Columns are [PO#, PartNumber, Quantity]
Sorry if this seems like a lot / not enough information. I just need help.
I have two datagridviews in one from. I need to get data from database to datagridview1 (using Select *from database...) then I want to add data from datagriwview to datagridview2 using Selected Rows.
First I wanted to solve this problem to get Selected Row's ID, when I select row in datagridview it shows in datagridview2, but when I select another row, it is updating in datagridview, it does not add as new row. I tried several ways but did not solve this problem, Is there anyone help me to solve this problem? Thanks
private void dataGridView1_CellDoubleClick_1(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32
(dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells["id"].Value);//3
try
{
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + id.ToString() + "'";
conn.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
dataGridView2.DataSource = dt;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Is quite simple the explanation: everytime that you make a double click to a datagridview1's cell you replace the old datatable with a new one. If you want append the result you can do something like this:
MySqlConnection conn = new MySqlConnection(connection);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + id.ToString() + "'";
conn.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
if(dataGridView2.DataSource != null) {
DataTable pr = dataGridView2.DataSource as DataTable;
pr.Merge(dt);
dataGridView2.DataSource = pr;
}
else
dataGridView2.DataSource = dt;
Since you have all information in datagridview1 you should just copy the contents of the selected row into a new row for datagridrow2.
The DataGridView is based on a DataSet which contains DataTables.
The DataTable contains rows.
You cannot move a row from one table to annother.
Instead you have to create a new row and insert into the DataTable of DataGridView2
private void dataGridView1_CellDoubleClick_1(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1.CurrentRow.Cells["Id"].Value != null)
{
int Id = Convert.ToInt32(dataGridView1.CurrentRow.Cells["Id"].Value);
MySqlConnection start = new MySqlConnection(baglanti);
MySqlCommand command = start.CreateCommand();
command.CommandText = "SELECT id, muayine_adi, sabit_qiymet FROM tibbi_xidmetler WHERE id = '" + Id + "'";
start.Open();
MySqlDataAdapter oxu = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
oxu.Fill(dt);
if (dt != null && dt.Rows.Count > 0)
{
int idx = dataGridView2.Rows.Count - 1;
dataGridView2.Rows.Add(dt.Rows.Count);
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
int rVal = (idx + i) + 1;
dataGridView2.Rows[rVal].Cells["id"].Value = dt.Rows[i]["id"].ToString();
dataGridView2.Rows[rVal].Cells["muayine_adi"].Value = dt.Rows[i]["muayine_adi"].ToString();
dataGridView2.Rows[rVal].Cells["sabit_qiymet"].Value = dt.Rows[i]["sabit_qiymet"].ToString();
}
}
start.Close();
}
}
In my database web application, I am trying to add data to a column in gridView from a SQL table using the following code snippet
public void GetRowHeaders(GridView gridViewSample)
{
string commandstr = #"SELECT ID FROM WhiteBoardTest WHERE ID!=0 ORDER BY ID";
SqlCommand rowHeaderCmd = new SqlCommand(commandstr, sqlcon);
sqlcon.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = rowHeaderCmd;
da.Fill(dt);
for (int i = 0; i < dt.Columns.Count; i++)
{
for (int j = 0; j < dt.Rows.Count; j++)
{
gridViewSample.Rows[0].Cells[j].Text = dt.Rows[j][i].ToString();
}
}
sqlcon.Close();
}
When I ran the above code, I got the error saying
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection
I understand that the exception has occurred because the gridView has no rows or columns available.
Can anyone suggest me how to add rows to a column and also I am not using SqlDataSource because I would like add one more column to the gridView from a different table.
I would just include the extra column in your select statement and just bind to the gridview - unless there's a specific reason for not doing that. note the new sql!
public void GetRowHeaders(GridView gridViewSample)
{
string commandstr = #"SELECT a.*, b.somecolumn FROM tablea as a inner join tableb as b on b.someid= a.someid WHERE ID!=0 ORDER BY ID";
SqlCommand rowHeaderCmd = new SqlCommand(commandstr, sqlcon);
sqlcon.Open();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = rowHeaderCmd;
da.Fill(dt);
gridViewSample.DataSource = dt;
gridviewSample.DataBind();
sqlcon.Close();
}
Or you could populate a collection of some class ( remember to use properties for gridviews databind), a List maybe, and just databind that to the grid.
Dayakar, what you can do is add additional column and data to DataTable itself and then bind it to the gridview. below is a example code.
private void SetupGridView()
{
var dt = GetDataTable();
// add addition column
dt.Columns.Add(new DataColumn() {ColumnName = "Id2", DataType = typeof (int)});
// add additional data
for (var i = 0; i < dt.Rows.Count; i++)
{
dt.Rows[i]["Id2"] = Convert.ToInt32(dt.Rows[i][0])*2;
}
GridView1.DataSource = dt;
GridView1.DataBind();
}
You can also merge two datatables to create one datatable and then bind it to gridview. Refer http://msdn.microsoft.com/en-us/library/fk68ew7b.aspx