I am trying to list multiple companies in a combobox. These companies populate from database table tbl_companies. Combobox value should be id of table(Which is primary key of the table). Text should be the name of company.
Like id=1 and name = "XYZ".
Code is
string connStr = "My Connection string";
SqlConnection conn = new SqlConnection(connStr);
string strQuery = "SELECT * FROM tbl_Companies ORDER BY id ASC";
SqlCommand cmd = new SqlCommand(strQuery, conn);
conn.Open();
SqlDataReader companyRead = cmd.ExecuteReader();
if (companyRead.HasRows)
{
while (companyRead.Read())
{
int cId = (Convert.ToInt16(companyRead["id"].ToString()));
cmbCompany.Items.Insert(cId, companyRead["name"].ToString());
}
}
conn.Close();
When I am executing the code, getting the following error.
System.ArgumentOutOfRangeException: 'InvalidArgument=Value of '1' is not valid for 'index'.
Parameter name: index'
For reference, I am also sharing the [enter image description here]screenshot of code with error1
I need guidance, how to fix the problem.
Your error is in the Item.Insert method where the first parameter should be the position in the already existing items collection where you want to insert the new value and not the Item's value.
Instead of using this manual loop you could simply set the combo datasource to a DataTable and set the DisplayMember and ValueMember properties
string connStr = "My Connection string";
using(SqlConnection conn = new SqlConnection(connStr))
{
string strQuery = "SELECT * FROM tbl_Companies ORDER BY id ASC";
SqlCommand cmd = new SqlCommand(strQuery, conn);
conn.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader())
cmbCompany.DisplayMember = "name";
cmbCompany.ValueMember = "id";
cmbCompany.DataSource = dt;
}
Consider also that once you set the Datasource property in this way you shouldn't manually insert new items, instead you add elements to the underlying DataTable and refresh the combo datasource binding
You are inserting at a specific index, and when the list is empty at the start, an index of '1' is considered out of range.
Try:
cmbCompany.Items.Add(companyRead["name"].ToString());
instead.
Related
I have a Combobox in my form. This Combobox is populated with values from a table(Faculty) in the database.
I need to set the SelectedValue of this Combobox based on the record in another table(student). Both tables are in the same database.
I tried to set SelectedValue using the value getting from student table
cmbfaculty.SelectedValue = table.Rows[0][1].ToString();
but it didn't work.
So far I was only able to populate the Combobox ,
// --- populate faculty cmb ---
MySqlCommand cmdCmb = new MySqlCommand("SELECT facultyname FROM faculty;", db.getConnection());
db.openConnection(); // open connection
using (var reader = cmdCmb.ExecuteReader())
{
while (reader.Read())
{
cmbfaculty.Items.Add(reader.GetString("facultyname"));
}
}
but unable to set SelectedValue.
string sQuery = "SELECT indexno,faculty FROM student WHERE indexno ='"+selected+"'";
MySqlCommand cmd = new MySqlCommand(sQuery, db.getConnection());
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
DataTable table = new DataTable();
adapter.Fill(table);
txtindex.Text = table.Rows[0][0].ToString();
cmbfaculty.SelectedValue = table.Rows[0][1].ToString();
Hoping to fix the issue.
EDIT:
Able to do that by finding the item that exactly matches the specified
string ComboBox.FindStringExact Method,
cmbfaculty.SelectedValue = table.Rows[0][1].ToString();
needed to be replaced with
cmbfaculty.SelectedIndex = cmbfaculty.FindStringExact(table.Rows[0][1].ToString()) ;
Are there any other ways to archieve this.
Able to do that by finding the item that exactly matches the specified string ComboBox.FindStringExact Method,
cmbfaculty.SelectedValue = table.Rows[0][1].ToString();
needed to be replaced with
cmbfaculty.SelectedIndex = cmbfaculty.FindStringExact(table.Rows[0][1].ToString()) ;
I created a Windows Forms application in C# and my database in Visual Studio. I want to know how, if it's possible, to sort one of the columns in the table by clicking a button? Or how can I sort this column automatically without using a button?
I've tried to implement this sort in the code below, but it doesn't work :(
private c void button5_Click(object sender, EventArgs e)
{
SqlConnection sqlConnection = new SqlConnection("Here is my connecting string");
SqlCommand myCommand = new SqlCommand("SELECT * FROM [Information] ORDER BY (Перевозчик)", sqlConnection);
sqlConnection.Open();
myCommand.ExecuteNonQuery();
}
As found here: https://www.w3schools.com/sql/sql_orderby.asp
Sine we don't know what you want to oder we can only guess here.
But with the query you could try:
SELECT column1, column2, ...
FROM table_name
ORDER BY column1, column2, ... ASC
In your case:
"SELECT * FROM [Information] ORDER BY (Перевозчик) ASC"
Best would be to use the visual query builder where you can query against your database. When you are happy with your result you can at least be sure that the query is correct.
How you can do that is explained here:
https://www.c-sharpcorner.com/article/connect-to-a-database-from-visual-studio/
Since the sqlconnection and the sqlcommand is disposable you should consider putting it in a using tag, like in this example.
https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand?view=netframework-4.8
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(
queryString, connection);
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
}
}
There is 2 way for sort data
1) sorting just data and fill into grid:
DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
DataTable dt2 = new DataTable(); // temp data table
DataRow[] dra = dt1.Select("", "ID DESC");
if (dra.Length > 0)
dt2 = dra.CopyToDataTable();
datagridview1.DataSource = dt2;
2) sort default view that is like of sort with grid column header:
DataGridView datagridview1 = new DataGridView(); // for show data
DataTable dt1 = new DataTable(); // have data
dt1.DefaultView.Sort = "ID DESC";
datagridview1.DataSource = dt1;
I found this solution here:
Sorting rows in a data table
For a listbox you could give this a shot
ArrayList q = new ArrayList();
foreach (object o in listBox4.Items)
q.Add(o);
}
q.Sort();
listBox5.Items.Clear();
foreach(object o in q){
listBox5.Items.Add(o);
}
I found this solution here:
Sorting a list of items in a list box
You need to do ExecuteDatareader then process the result coming from this call. ExecuteNonQuery cannot be used to retrieve data.
I am coding win form app, which checks on startup right of the currently logged user. I had these right saved in MS SQL server in the table. When importing data to Datatable, there is no problem. But when I want to read value, there is message "cannot find column xy".
SqlDataAdapter sdaRights = new SqlDataAdapter("SELECT * FROM rights WHERE [user]='" + System.Security.Principal.WindowsIdentity.GetCurrent().Name + "'", conn);
DataTable dtRights = new DataTable(); //this is creating a virtual table
sdaRights.Fill(dtRights);
Object cellValue = dt.Rows[0][1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
I would like, that program would save the value from SQL to int.
You are assuming that you have rows being returned, would be my first guess. You should loop through your DataTable instead of simply trying to access element 0 in it.
DataTable dtRights = new DataTable();
sdaRights.Fill(dtRights);
foreach(DataRow row in dtRights.Rows) {
Object cellValue = row[1];
int value = Convert.ToInt32(cellValue);
MessageBox.Show(value.ToString());
}
using (SqlConnection con = new SqlConnection("your connection string"))
{
using (SqlCommand cmd = new SqlCommand("SELECT [column_you_want] FROM [rights] WHERE [user] = #user"))
{
cmd.Parameters.AddWithValue("#user", System.Security.Principal.WindowsIdentity.GetCurrent().Name);
con.Open();
int right = Convert.ToInt32(cmd.ExecuteScalar());
}
}
I have been working on a personal project for the company I work for to control stock levels in order to practice my c#.
I want my application to search through tblJuiceStock, find a matching FlavourID to what the user is inputting and update the stock of that record through an UPDATE SET query.
public void InsertJuiceStockWithCheck()
{
using (OleDbConnection conn = new OleDbConnection())
{
conn.ConnectionString = ConnectionString;
conn.Open();
string tblJuiceStockCheck = "SELECT FlavourID, Quantity FROM tblJuiceStock";
OleDbCommand cmdCheck = new OleDbCommand(tblJuiceStockCheck, conn);
OleDbDataAdapter daCheck = new OleDbDataAdapter(cmdCheck);
DataTable dtCheck = new DataTable();
daCheck.Fill(dtCheck);
foreach (DataRow row in dtCheck.Rows)
{
if ((int)row["FlavourID"] == fID)
{
int currentQty = (int)row["Quantity"];
int updatedQty = currentQty + qty;
string tblJuiceStockExisting = #"UPDATE tblJuiceStock
SET Quantity = #newquantity
WHERE FlavourID = #flavourID";
OleDbCommand cmdJuiceStockExisting = new OleDbCommand(tblJuiceStockExisting, conn);
cmdJuiceStockExisting.Parameters.AddWithValue("#flavourID", fID);
cmdJuiceStockExisting.Parameters.AddWithValue("#newquantity", updatedQty);
cmdJuiceStockExisting.ExecuteNonQuery();
matchFound = true;
break;
}
}
if (!matchFound)
{
string tblJuiceStockNew = "INSERT INTO tblJuiceStock (FlavourID, Quantity, MinStockPOS) VALUES (#fID, #quantity, #minstock)";
OleDbCommand cmdJuiceStockNew = new OleDbCommand(tblJuiceStockNew, conn);
cmdJuiceStockNew.Parameters.AddWithValue("#fID", fID);
cmdJuiceStockNew.Parameters.AddWithValue("#quantity", qty);
cmdJuiceStockNew.Parameters.AddWithValue("#minstock", amt);
cmdJuiceStockNew.ExecuteNonQuery();
}
}
}
Please note: this query works fine in Access when I replace parameters with the same values. Also, using breakpoints I identified that the parameters have the correct values set to them, the variables assigned to them are obtained within another method, all methods are called in the submit button event.
However, the Quantity value in TblJuiceStock remains the same.
My tblJuiceStock table
After some time of messing about the answer was simple.
OLEDB does work with named parameters but you have to declare them, if you don't declare them they use the parameters positioning to match them up.
My problem was that in my query string I had #newquantity first and #flavourID second, whereas when adding my parameters I added #flavourID first and #newquantity second.
The following coding doesn't update my table. But rows variable value is 1 after updating.
I cannot understand what is the cause behind this. Please help.
SqlConnection connection1 = new SqlConnection(connectionString);
connection1.Open();
var wktbl = new DataTable();
var cmd = new SqlCommand("SELECT * FROM Test", connection1);
var da1 = new SqlDataAdapter(cmd);
var b = new SqlCommandBuilder(da1);
da1.Fill(wktbl);
wktbl.Rows[0][2] = "5";
da1.UpdateCommand = b.GetUpdateCommand(true);
int rows = da1.Update(wktbl);
Check this page out. It shows the example below of doing an update with the dataadapter.
The following examples demonstrate how to perform updates to modified rows by explicitly setting the UpdateCommand of a DataAdapter and calling its Update method. Notice that the parameter specified in the WHERE clause of the UPDATE statement is set to use the Original value of the SourceColumn. This is important, because the Current value may have been modified and may not match the value in the data source. The Original value is the value that was used to populate the DataTable from the data source.
private static void AdapterUpdate(string connectionString)
{
using (SqlConnection connection =
new SqlConnection(connectionString))
{
SqlDataAdapter dataAdpater = new SqlDataAdapter(
"SELECT CategoryID, CategoryName FROM Categories",
connection);
dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE Categories SET CategoryName = #CategoryName " +
"WHERE CategoryID = #CategoryID", connection);
dataAdpater.UpdateCommand.Parameters.Add(
"#CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
"#CategoryID", SqlDbType.Int);
parameter.SourceColumn = "CategoryID";
parameter.SourceVersion = DataRowVersion.Original;
DataTable categoryTable = new DataTable();
dataAdpater.Fill(categoryTable);
DataRow categoryRow = categoryTable.Rows[0];
categoryRow["CategoryName"] = "New Beverages";
dataAdpater.Update(categoryTable);
Console.WriteLine("Rows after update.");
foreach (DataRow row in categoryTable.Rows)
{
{
Console.WriteLine("{0}: {1}", row[0], row[1]);
}
}
}
}
I found the problem. It's because connectionString has |DataDirectory|.
The MDF file location is different when running the application.