input array is longer than the number of columns in my table - c#

I have this code:
int flag = 0;
int num = 0;
int price, totprice, qty;
string product;
private void ProductsGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
product = ProductsGV.SelectedRows[0].Cells[1].Value.ToString();
//qty = Convert.ToInt32(OrderQtyTb.Text);
price = Convert.ToInt32(ProductsGV.SelectedRows[0].Cells[3].Value.ToString());
//totprice = qty * price;
flag = 1;
}
private void button4_Click(object sender, EventArgs e)
{
if (OrderQtyTb.Text == "")
MessageBox.Show("Please Enter Quantity");
else if (flag == 0)
MessageBox.Show("Please Select Product");
else
{
num = num + 1;
qty = Convert.ToInt32(OrderQtyTb.Text);
totprice = qty * price;
DataTable table = new DataTable();
table.Rows.Add(num, product, qty, price, totprice);
OrdersGV.DataSource = table;
flag = 0;
}
}
I get an error on this line:
table.Rows.Add(num, product, qty, price, totprice);
input array is longer than the number of columns in this table
The purpose of the code is to let me input a quantity. Then I will click on the product list table and after that I will now click the "Add to Order" button. I want the button to reveal the new quantity on the OrdersGV.

The problem is this line:
DataTable table = new DataTable();
This makes a brand new table, with no columns defined at all, and the DataTable type requires you to use a well-defined schema.
You don't want to create a new DataTable here. You want to find the existing data source that is already showing in the grid, and add the row to that. If (and only if!) there is none, you need to create a DataTable object with defined Columns.

You don't need to new the DataTable. It should only be initial with the dataSource of OrdersGV:
DataTable table = OrdersGV.DataSource as DataTable;
table.Rows.Add(num, product, qty, price, totprice);

Related

How to insert data to the next row in datagridview using c#?

Good day!
Please help me on my concern. I have a code here which allows to add rows to the datagridview I created named dgvSchedule. I want to transfer data from the other datagridview dgvCalendar by double clicking the data in the cell. My problem is I can only add data on the first row in dgvSchedule and the next rows are empty.
I have attached screenshot also of my application.
Thank you.
private void dgvCalendar_DoubleClick(object sender, EventArgs e)
{
if (cmbTimeSched.Text != "")
{
string yearnow = DateTime.Now.Year.ToString();
int year = Convert.ToInt32(yearnow);
int rowIndex = dgvCalendar.CurrentCell.RowIndex;
int colIndex = dgvCalendar.CurrentCell.ColumnIndex;
if (dgvCalendar.Columns[colIndex].HeaderText != "SUN")
{
string Daynum = dgvCalendar.Rows[rowIndex].Cells[colIndex].Value.ToString();
int dayNum = Convert.ToInt32(Daynum);
int num = DateTime.Parse("" + selectMonths.Text + year).Month;
DateTime dateSelected = new DateTime(year, num, dayNum);
dgvSchedule.Rows.Add();
dgvSchedule.Rows[0].Cells[0].Value = lblIDNum.Text;
dgvSchedule.Rows[0].Cells[1].Value = cmbTimeSched.Text;
dgvSchedule.Rows[0].Cells[2].Value = dgvCalendar.Columns[colIndex].HeaderText.ToString();
dgvSchedule.Rows[0].Cells[3].Value = dateSelected.ToString("MM/dd/yyyy");
}
else
{ MessageBox.Show("You selected a date that is on SUNDAY!"); }
}
else
{ MessageBox.Show("PLEASE SELECT TIME SCHEDULE FIRST!"); }
}
MyApplication:
Because you are specifically saying to fill the record at Row[0] in dgvSchedule table.
int count=dgvSchedule.Rows.Count;
dgvSchedule.Rows[count+1].Cells[0].Value = lblIDNum.Text;
dgvSchedule.Rows[count+1].Cells[1].Value = cmbTimeSched.Text;
dgvSchedule.Rows[count+1].Cells[2].Value=
dgvCalendar.Columns[colIndex].HeaderText.ToString();
dgvSchedule.Rows[count+1].Cells[3].Value = dateSelected.ToString("MM/dd/yyyy");
My other suggestion is you can use dataset to fill the grid.
DataTable dt1 = new DataTable();
//remove all the rows of table
while (dgvSchedule.Rows.Count > 1)
{
dgvSchedule.Rows.RemoveAt(0);
}
//fill the table with updated records
cnn.Open();
MySqlDataAdapter adp = new MySqlDataAdapter("query for fetch the results from data base which you need to fill in the table", cnn);
adp.Fill(dt1);
dgvSchedule.DataSource = dt1;
adp.Dispose();
cnn.Close();

populate DataGridView from database and TextBox

Basically I want to add another column from a TextBox along with values I have queried from the database. I want my datagridview to show something like
|itemcode|Category|itemDescription|unitcost|quantity|
where itemcode, Category, itemDescription, unitcost is from database and quantity is from a text box input.
private void btnAddToCart_Click(object sender, EventArgs e)
{
con.OpenConnection();
MySqlCommand cmd = con.connection.CreateCommand();
string search = txtSearchProduct.Text;
string quantity = txtQuantity.Text;
string query = "SELECT itemcode, Category, itemDescription, unitcost FROM tblprowareproducts WHERE itemDescription LIKE ?search";
cmd.CommandText = query;
cmd.Parameters.AddWithValue("?search", "%" + search + "%");
using (MySqlDataAdapter mda = new MySqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
mda.Fill(dt);
dgvCart.DataSource = dt;
}
}
Is there a way to add another column after unitcost named quantity and the value of it comes from a TextBox?
There are different solutions for the problem, for example you can add the column to DataTable this way:
DataTable dt = new DataTable();
mda.Fill(dt);
var quantity = dt.Columns.Add("quantity", typeof(int));
quantity.DefaultValue = int.Parse(txtQuantity.Text);
dt.AsEnumerable().ToList().ForEach(r =>
{
r[quantity] = quantity.DefaultValue;
});
dgvCart.DataSource = dt;
Note 1: You may want to use TryParse to get the integer value from text.
Note 2: Default value of column applies to the column when adding the row. So to apply it to existing rows, you need to use a loop like what I did. For new rows that you add after that, it will be applied automatically.

Show total Sum of values of a Column of a DataTable

I want to show sum of total Price of items. I am facing 2 issues:
It's showing me wrong total of items price
I want to add .00 to the total price
You can check issue in the image for a clear explanation.
Here is my code:
tDisplay.Text = "Return/" + "Receipt No:" + Return_Form.setalueforText011;
label1.Text = Return_Form.setalueforText011;
OleDbConnection VCON = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\Restaurant.accdb");
DataSet dsa = new DataSet();
DataTable dt = new DataTable();
dsa.Tables.Add(dt);
OleDbDataAdapter da = new OleDbDataAdapter();
da = new OleDbDataAdapter("SELECT [Column1],[Column2],[Column3] from [Total] Where [Receipt No] = " + label1.Text + "", VCON);
da.Fill(dt);
//dataGridView1.DataSource = dt;
for (int i = 0; i < dt.Rows.Count; i++)
{
products.Add(new tblProduct() { productName = dt.Rows[i]["Column2"].ToString(),productPrice = Convert.ToDecimal(Math.Round(Convert.ToDecimal(dt.Rows[i]["Column1"].ToString())))});
label3.Text = dt.Rows[i]["Column3"].ToString();
textBox59.Text = "Rs: "+String.Format("{0:}", Total);
tblProduct selected = (tblProduct)(listBox60.SelectedItem);
Total += (decimal)selected.productPrice;
}
VCON.Close();
In your loop you add to the total always the SelectedItem row. This is always the first item so you end up doubling the value of the first item.
for (int i = 0; i < dt.Rows.Count; i++)
{
// Create and initialize a new tblProduct from the datatable row
tblProduct current = new tblProduct();
current.ProductName = dt.Rows[i]["Column2"].ToString();
current.productPrice = Convert.ToDecimal(Math.Round(Convert.ToDecimal(dt.Rows[i]["Column1"].ToString())));
// Add to your list of products
products.Add(current);
// This line is wrong because you overwrite the value at each loop
label3.Text = dt.Rows[i]["Column3"].ToString();
// Sum the price of the current tblProduct
Total += (decimal)current.productPrice;
}
// Outside the loop update your total label
textBox59.Text = "Rs: "+String.Format("{0:0.00}", Total);
If you allow me to give an advice. Do not name your controls that way. They are unreadable and not easily recognizable. Looking at this code some day from now you will have a lot of problems to remember which control is textBox59 or listBox60.
Sum
Instead of using for loop, You can simply use Compute method of data table and pass an expression to compute. For example:
var total = yourDataTable.Compute("SUM(Column1)", "");
Format
Also to format total to show 2 digits after decimal place, you can use either of these options:
The "0" Custom Numeric Format String : string.Format("{0:0.00}", total))
The Fixed-Point "F" format Specifier: string.Format("{0:F2}", total))
Update Sum on changes of data
Also to be able to show the sum automatically in a TextBox event when new items added or some items removed or some values changed, handle ListChanged event of DataTable.DefaultView and set the result as Text of the text box.
Example
// Define data table
var dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Price", typeof(int));
// Fill data
dt.Rows.Add("Product 1", 100);
dt.Rows.Add("Product 2", 200);
// Set data source of data grid view
this.dataGridView1.DataSource = dt;
// Automatically update text box, by SUM of price
textBox1.Text = $"{dt.Compute("SUM(Price)", ""):F2}";
dt.DefaultView.ListChanged += (obj, args) =>
textBox1.Text = $"{dt.Compute("SUM(Price)", ""):F2}";

how to retrieve the value of the input query textbox in C# asp.net?

example I have a textbox input, the contents of the input textbox custom query of the user what the user inputted, an example in the textbox, I try to enter text "select id, name, country from the country" .. from the sql query on the results of the 3 coloumn of the country table, I asked how to take the number of columns, the column name of the textbox custom input .. to the number of columns I want to show in the textbox and the number of rows in the gridview appropriate number of columns in a query, for the names of the columns I want to display in gridview ..
private void BindReportColumn(String report_id)
{
dt = mda.GetData("SELECT column_name,column_text,size,back_color,fore_color FROM report_column INNER JOIN report ON report_column.report_id = report.report_id and report.report_id='" + report_id + "'", connStr).Tables[0];
GridCustomColumn.DataSource = dt;
GridCustomColumn.DataBind();
}
private void addcolumn()
{
int i;
//Add the items to the gridview
DataTable dt = new DataTable();
//Assign the viewstate to the datatable
if (!IsNumeric(txtcolumn_count.Text)) txtcolumn_count.Text = "0";
dt = (DataTable)ViewState["columnreport"];
for (i = 1; i <= Convert.ToInt32(txtcolumn_count.Text); i++)
{
DataRow dr = dt.NewRow();
//dr["report_id"] = txtreport_id.Text;
dr["column_name"] = "";
dr["column_text"] = " ";
dr["size"] = 0;
dr["back_color"] = "";
dr["fore_color"] = "";
//Add the datarow to the datatable
dt.Rows.Add(dr);
//Now bind the datatable to the gridview
GridCustomColumn.DataSource = dt;
GridCustomColumn.DataBind();
//Add the details to viewstate also
ViewState["columnreport"] = dt;
}
}
thanks in advance

How to insert values row by row in a gridview using temporary table(Data Table)

I have two gridviews in my asp.net page. Where the datas are coming from two different databases. In that, one gridview has select row function. Now what I want to do is, I need to generate my 3rd gridview row by row according to the selection of the 1st gridview's 2 cells and the 2nd gridview 1st column data.(1st column data is common for all the rows).
The values in the gridview is showing as expected, But it will only hold one row data at a time. When I go ahead to select another value from the dropdownlist the gridview refreshes and the existing data will disappear and the new data appears.
How can I have the selected datas inserted row by row in a gridview?
Here are my code given below:
protected void btnAssign_Click(object sender, EventArgs e)
{
SetInitialRowToGrid();
int rowIndex = 0;
if (ViewState["TempTable"] != null)
{
// Get TempTable from viewstate
var tempTable = (DataTable)ViewState["TempTable"];
DataRow tempRow = null;
if (tempTable.Rows.Count > 0)
{
for (int i = 1; i <= tempTable.Rows.Count; i++)
{
// Get Grid's Label values
var EmpID =
(Label)grdEmp.SelectedRow.FindControl("lblEmpID");
var firstName =
(Label)grdEmp.SelectedRow.FindControl("lblFirstName");
var date = DateTime.Now.ToString();
var planID =
(Label)grdPlanID.Rows[rowIndex].Cells[1].FindControl("lblPlanID");
// Create new row and update Row Number
tempRow = tempTable.NewRow();
tempTable.Rows[0]["Emp_ID"] = EmpID.Text;
tempTable.Rows[i - 1]["First_Name"] = firstName.Text;
tempTable.Rows[i - 1]["Created_Time"] = date;
tempTable.Rows[i - 1]["Plan_ID"] = planID.Text;
rowIndex++;
}
// Add data to datatable and viewstate
tempTable.Rows.Add(tempRow);
ViewState["TempTable"] = tempTable;
// Attach Gridview Datasource to datatable
grdList.DataSource = tempTable;
grdList.DataBind();
}
}
//Set Previous Data on Postbacks
SetPreviousData();
}
SetInitialRowToGrid() code is given below:
private void SetInitialRowToGrid()
{
// Initialize and Set initial row of Datatable
var tempDataTable = new DataTable();
tempDataTable.Columns.Add("Emp_ID");
tempDataTable.Columns.Add("First_Name");
tempDataTable.Columns.Add("Created_Time");
tempDataTable.Columns.Add("Plan_ID");
tempDataTable.Rows.Add("1", "", "", "");
// Store that datatable into viewstate
ViewState["TempTable"] = tempDataTable;
// Attach Gridview Datasource to datatable
grdList.DataSource = tempDataTable;
grdList.DataBind();
}
SetPreviousData() code is given below:
private void SetPreviousData()
{
int rowIndex = 0;
if (ViewState["TempTable"] != null)
{
var tempTable = (DataTable)ViewState["TempTable"];
if (tempTable.Rows.Count > 0)
{
for (int i = 0; i < tempTable.Rows.Count; i++)
{
var EmpID =
(Label)grdEmp.SelectedRow.FindControl("lblEmpID");
var firstName =
(Label)grdEmp.SelectedRow.FindControl("lblFirstName");
var date = DateTime.Now.ToString();
var planID =
(Label)grdList.Rows[rowIndex].Cells[1].FindControl("lblPlanID");
EmpID.Text = tempTable.Rows[i]["Emp_ID"].ToString();
firstName.Text = tempTable.Rows[i]["First_Name"].ToString();
date = tempTable.Rows[i]["Created_Time"].ToString();
planID.Text = tempTable.Rows[i]["Plan_ID"].ToString();
rowIndex++;
}
}
}
}

Categories

Resources