Autocomplete in a ComboBox Using Access 2017 - c#

I want to make Autocomplete in a ComboBox using Access 2017. So I used this code... But there are some errors, like:
"The name 'da' does not exist in the current context".
Please help me to fix this error.
private void Autocomplete()
{
string query;
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Neth1.accdb");
//opening connection
con.Open();
try
{
//initialize a new instance of sqlcommand
OleDbCommand cmd = new OleDbCommand();
//set a connection used by this instance of sqlcommand
cmd.Connection = con;
//set the sql statement to execute at the data source
cmd.CommandText = query;
OleDbDataAdapter da = new OleDbDataAdapter();
//set the sql statement or stored procedure to execute at the data source
da.SelectCommand = cmd;
//initialize a new instance of DataTable
DataTable dt = new DataTable();
//add or resfresh rows in the certain range in the datatable to match those in the data source.
da.Fill(dt);
foreach (DataRow r in dt.Rows)
{
//getting all rows in the specific field|Column
var rw = r.Field<string>("IMEI");
//Set the properties of a combobox to make it auto suggest.
comboBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
//adding all rows into the combobox
comboBox1.AutoCompleteCustomSource.Add(rw);
}
}
catch (Exception ex)
{
//catching error
MessageBox.Show(ex.Message);
}
//release all resources used by the component
da.Dispose();
//clossing connection
con.Close();
}

Your OleDbDataAdapter da = new OleDbDataAdapter(); is within try { } scope and
da.Dispose(); is outside of that scope, try to place this line within try { } scope or move OleDbDataAdapter da = new OleDbDataAdapter(); outside of try { }scope.

Your OleDbDataAdapter is declare inside the try block, it doesn't exist outside of it, hence the error you're seeing.
The query string presented here is empty.
When you deal with OleDb objects, it's common practice to make use
of using blocks, which take care of disposing the disposable objects you create.
What you rally don't want, is to set those controls properties inside a foreach loop.
It is also more efficient to fill the ComboBox AutoCompleteCustomSource using AddRage(), instead of adding objects one by one.
This is how I propose to edit your code:
// You can set these properties in the Form designer
comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
comboBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
// [...]
string query = "SELECT [Some Field] FROM [Some Table] WHERE [Some Condition]";
List<string> data = new List<string>();
try {
using (var con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|/Neth1.accdb"))
{
con.Open();
using (var cmd = new OleDbCommand(query, con))
using (var reader = cmd.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
data.Add((string)reader["IMEI"]);
}
}
}
}
}
catch {
// Notify, log, whatever fits
}
comboBox1.AutoCompleteCustomSource.Clear();
comboBox1.AutoCompleteCustomSource.AddRange(data.ToArray());
data.Clear();

Related

Inserting selected items from a ListBox into MSSQL database with ADO.NET (c#)

I would like to know how to insert selected items from a ListBox into a MSSQL Database.
I am developing an ASP.NET web app and this is the problem:
I have a Listbox named lbxRuoli and items are loaded directly from the database:
SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", conn);
SqlDataReader dr = cmd.ExecuteReader();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
while (dr.Read())
{
li = new ListItem(dr["descrizione_Ruoli"].ToString(), dr["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
dr.Close();
cmd.Dispose();
Now it comes to write the INSERT for the selected items:
for (int i = 0; i < lbxRuoli.Items.Count; i++)
{
if (lbxRuoli.Items[i].Selected == true)
{
cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", conn);
cmd.Parameters.AddWithValue("#id", txtId.Text);
cmd.Parameters.AddWithValue("#idR", lbxRuoli.SelectedValue);
cmd.ExecuteNonQuery();
}
}
It happens that I only insert the same first selected item for the total numbers of the selected items.
It would be wonderful if someone can help me!
Thanks to every one in advance!
Connections need to be not only closed but disposed to release unmanaged objects. using blocks handle this even if there is an error.
Commands also need to be disposed. To accomplish this they should be declared local to the method where they are used. using blocks will close and dispose you database objects.
You don't want to hold a connection open while you update the user interface. Fill a DataTable, close the connection (the using block does it) and then fill the ListBox from the DataTable.
To insert the data create the connection, command and fill the parameters collection outside the loop. Only the values of the parameters change inside the loop
The code below demonstrates how to use the .Add method for parameters. I had to guess at the type and size of the parameters. Check your database and adjust the code accordingly making sure that the parameter values are compatible with the SqlDbType.
private string ConStr = "Your connection string";
private DataTable GetListData()
{
DataTable dt = new DataTable();
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("select descrizione_Ruoli, id_Ruoli from Ruoli", cn))
{
cn.Open();
dt.Load(cmd.ExecuteReader());
}
return dt;
}
private void FillListBox()
{
DataTable dt = GetListData();
ListItem li = new ListItem("- SELEZIONA -", "");
lbxRuoli.Items.Add(li);
foreach (DataRow row in dt.Rows)
{
li = new ListItem(row["descrizione_Ruoli"].ToString(), row["id_Ruoli"].ToString());
lbxRuoli.Items.Add(li);
}
}
private void InsertData()
{
using (SqlConnection cn = new SqlConnection(ConStr))
using (SqlCommand cmd = new SqlCommand("insert into [Utenti.Ruoli] (id_Utenti, id_Ruoli) values(#id, #idR)", cn))
{
cmd.Parameters.Add("#id", SqlDbType.VarChar, 20);
cmd.Parameters.Add("#idR", SqlDbType.VarChar, 20);
cn.Open();
foreach (ListItem li in lbxRuoli.Items)
{
if (li.Selected)
{
cmd.Parameters["#id"].Value = li.Text;
cmd.Parameters["idR"].Value = li.Value;
cmd.ExecuteNonQuery();
}
}
}
}

How to get data from SQL and write it in textbox?

I need a help.
I searched and I tried a lot but I am too bad to make it work on my project by myself.
This is code for button-Seek. I want to make Seek-button to fill textbox by respective data.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
var Conn = new SqlConnection();
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
var Cmd = new SqlCommand();
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = " + Number;
var DataAdapter = new SqlDataAdapter(Cmd);
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
}
}
And This is the data table.
This is what happens when I put 3 in the text box and press Seek-button.
So here, I want all text boxes to be filled by the data which I searched.
You will get only one row for the query right?
So give like that,
txtFirstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
txtLasttName.Text = DataSet.Tables[0].Rows[0]["LastName"].ToString();
Like this you need to assign the values to the respective text boxes.
There are three problem need to fix.
You forget to open the connection with DB,add Conn.Open(); before you excute sql command.
You need to add parameter to prevention SQL Injection
Please use using it will help you to use external resources to return the memory.
when the DataSet be filled you can get the data then fill in textbox
You can follow like this.
private void SeekClick(object sender, EventArgs e)
{
if (TBCusNumber.Text != "")
{
string Number = TBCusNumber.Text;
using (var Conn = new SqlConnection())
{
Conn.ConnectionString = ConfigurationManager.ConnectionStrings["WindowsFormsApp1.Properties.Settings.DataBase"].ConnectionString;
using (var Cmd = new SqlCommand())
{
Cmd.Connection = Conn;
Cmd.CommandText = "SELECT * FROM CustomerList WHERE CustomerNumber = #Number";
Cmd.Parameters.AddWithValue("#Number", Number);
//You miss to add Conn.Open()
Conn.Open();
using (var DataAdapter = new SqlDataAdapter(Cmd))
{
DataSet DataSet = new DataSet();
DataAdapter.Fill(DataSet, "CustomerList");
CusView.DataSource = DataSet;
CusView.DataMember = "CustomerList";
//when the DataSet be filled you can get the data then fill in textbox
txt_firstName.Text = DataSet.Tables[0].Rows[0]["FirstName"].ToString();
}
}
}
}
}

display data to listbox C#

Listbox does not show data. Verified data is in database and I am not getting an
error. Not sure where/what is wrong. Thanks in advance. My code is attached.
private void UpDateList()
{
// add data connection and fill data set.
SqlConnection conn = new SqlConnection(dataSource);
DataTable dt = new DataTable();
string sqlString = "select * from Suppliers";
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
try
{
cmd.Connection = conn;
conn.Open();
cmd.CommandText = sqlString;
da.Fill(ds);
conn.Close();
}
catch (SqlException ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
conn.Close();
}
foreach(DataRow dRow in ds.Tables[0].Rows)
{
ArrayList values = new ArrayList();
foreach(object value in dRow.ItemArray)
{
values.Add(value);
_Suppliers.Add(values);
}
}
lstSuppliers.DataSource = _Suppliers;
lstSuppliers.Update();
}
It's kinda pointless to enumerate one bindable data collection and transfer data into another bindable collection so it can be bound. Just have your list use the default view of the datatable that already holds the data (allows sorting, filtering etc)
E.g.
LstSuppliers.DataSource = ds.Tables[0].DefaultView;
LstSuppliers.DisplayMember = "column name goes here of what to show eg SupplierName";
LstSuppliers.ValueMember = "column whose value to use for lstSuppliers.SelectedValue e.g. supplierId";
And then for example, not required but an example possibility:
ds.Tables[0].DefaultView.Sort = "[SupplierName] ASC";

Fill ComboBox with Access DB data

I'm using Visual Studio 2010 and C# to create a windows form with a combobox that should contain employees initials. I have spent the last few days searching through every solution I can find and I still can not get my combobox to populate.
This is what I've got as of now:
public static void FillComboBox(string Query, System.Windows.Forms.ComboBox LoggedByBox)
{
using (var CONN = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Users\\Documents\\Service Request Application\\bin\\Debug\\servicereq1.mdb"))
{
CONN.Open();
DataTable dt = new DataTable();
try
{
OleDbCommand cmd = new OleDbCommand(Query, CONN);
OleDbDataReader myReader = cmd.ExecuteReader();
dt.Load(myReader);
}
catch (OleDbException e)
{
Console.WriteLine(e.ToString());
Console.ReadLine();
return;
}
LoggedByBox.DataSource = dt;
LoggedByBox.ValueMember = "ID";
LoggedByBox.DisplayMember = "Initials";
}
}
Then I call it when the form loads
private void Form1_Load(object sender, EventArgs e)
{
FillComboBox("select ID, Initials from [Fixers and Testers]", LoggedByBox);
}
When I run the program, the combobox is still blank. I'm positive that my column names and table names are correct. Any suggestions?
I finally got my ComboBox filled and I wanted to share what I changed for anyone else who stumbles across this question in their searches. After spending a bit more time searching through other questions and MSDN, I was able to come up with this.
private void LoadComboLogged()
{
AppDomain.CurrentDomain.SetData("DataDirectory",#"\\prod\ServiceRequests");
string strCon = #"Provider=Microsoft.Jet.OLEDB.4.0;DataSource=|DataDirectory|\servicereq1.mdb";
try
{
using (OleDbConnection conn = new OleDbConnection(strCon))
{
conn.Open();
string strSql = "SELECT Initials FROM [Fixers and Testers] WHERE [Status] ='C'";
OleDbDataAdapter adapter = new OleDbDataAdapter(new OleDbCommand(strSql, conn));
DataSet ds = new DataSet();
adapter.Fill(ds);
loggedByComboBox.DataSource = ds.Tables[0];
loggedByComboBox.DisplayMember = "Initials";
loggedByComboBox.ValueMember = "Initials";
}
}
catch (Exception ex)
{
}
}
I also found that I needed to call
LoadComboLogged();
when I initialized my form. Without that line, the ComboBox would only show a blank dropdown list. Hope this helps someone else who runs into this problem.
Passing control to static method causing this issue. Instead of passing control to the method make that method returns the table and within the load method load the control.
SqlConnection con = new SqlConnection("Data Source=RUSH-PC\\RUSH;Initial Catalog=Att;Integrated Security=True");
con.Open();
SqlDataAdapter da = new SqlDataAdapter("select name from userinfo", con);
DataTable dt = new DataTable();
da.Fill(dt);
DataRow dr;
dr = dt.NewRow();
dt.Rows.InsertAt(dr, 1);
comboBox1.DisplayMember = "name";
comboBox1.ValueMember = "name";
comboBox1.DataSource = dt;
con.Close();
This may help you...
Good luck...:-)
Another possible solution would be to query and return a list of strings. Perhaps it may be less efficient, but it's what I used in a recent project of mine. Here's an example that would reside in a method, possibly called GetInitialsFromDatabase():
using(var conn = new MySqlConnection(connectionString)
{
conn.Open();
using(MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT Initials FROM [Fixers and Testers] WHERE [Status] ='C'";
MySqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
// initials is a List<String> previously defined (Assuming strings)
initials.Add(String.Format("{0}", reader[0]));
}
}
conn.Close();
}
And then return the initials List, and then in your GUI you could say:
comboBox1.DataSource = returnedList;
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;

Programmatically Binding ComboBox(s) By Control Name

Let me preface this by saying I don't do very much winforms work so pardon my ignorance. Binding is slightly strange coming from ASP.
I'm trying loop over a series of combo boxes and bind them using a dictionary of control names and a corresponding stored procedure. Here is a simplified example of what I'm trying to do.
public Dictionary<string, string> GetDropDownSchema()
{
return new Dictionary<string, string> { {"ddClient", "guisp_SelectClientDropDown"}, {"ddType", "guisp_SelectTypeDropDown"}, {"ddCounty", "guisp_SelectCountyDropDown"}};
}
public void BindComboBoxes()
{
var ddSchem = GetDropDownSchema();
foreach (var dd in ddSchem) {
var dt = new DataTable();
using (var con = new SqlConnection(ConStr)) {
try {
var adapter = new SqlDataAdapter(dd.Value, con);
adapter.Fill(dt);
((ComboBox)Controls.Find(dd.Key, true)[0]).DataSource = dt;
((ComboBox)Controls.Find(dd.Key, true)[0]).DisplayMember = "DisplayText";
((ComboBox)Controls.Find(dd.Key, true)[0]).ValueMember = "ID";
}
catch //(Exception ex)
{
//Code is not throwing any exception, just doesn't work
}
}
}
I'm sure I'm missing something simple with this. I appreciate any help or suggestion on a more elegant way to go about this.
Thanks
I suppose that the guisp_XXXXXX are names of stored procedures. If this is the case then you cannot use them in that way to fill a datatable using a SqlDataAdapter.
Instead you need to build a SqlCommand, specify that its CommandType is StoredProcedure and assign that command to the SelectCommand property of the SqlDataAdapter
using (var con = new SqlConnection(ConStr))
{
try
{
con.Open();
var adapter = new SqlDataAdapter();
var cmd = new SqlCommand(dd.Value, con);
cmd.CommandType = CommandType.StoredProcedure;
adapter.SelectCommand = cmd;
adapter.Fill(dt);
......

Categories