Remove repeated values from dataGridViewComboBoxColumn - sql

I use DataGridViewComboBoxColumn to make a ComboBox in DataGridView but my ComboBox isn't good enough. I need my ComboBox to not have repeated values on it. This is an example:
Apple
Blackberry
Chrome
Apple
I want to remove the values that appear more than one time. How can I do that?
This is my code:
OleDbConnection conn = new OleDbConnection();
OleDbCommand cmd = new OleDbCommand();
Dataset data = new Dataset();
OleDbDataAdapter adapter = new OleDbDataAdapter();
string path = "Data Source = "+".\\"+"test.accdb";
string conStr = "Provider = Microsoft.ACE.OleDb.12.0;"+#path;
conn.Open();
string sql = "SELECT * FROM Table1;"
cmd = new OleDbCommand(sql,conn);
adapter = new OleDbDataAdapter(cmd);
data = new Dataset();
adapter.Fill(data,"Table1");
DataGridViewComboBoxColumn testcolumn = new DataGridViewComboBoxColumn();
testcolumn.Name = "test na ja";
testcolumn.Datasource = data.table[0];
testcolumn.ValueMember = "Remedy";
testcolumn.DisplayMember = "Remedy";
dataGridview1.Columns.Add(testcolumn);
conn.Close()

change the SELECT statement to return distinct values of remedy:
string sql = "SELECT DISTINCT remedy FROM Table1;"
and if you want it ordered:
string sql = "SELECT DISTINCT remedy FROM Table1 ORDER BY remedy ASC;"
or
string sql = "SELECT DISTINCT remedy FROM Table1 ORDER BY remedy DESC;"

As well as applying the distinct statement to your SQL it is possible to apply a distinct to the original DataTable when creating a second table as shown below (with a unit test and helper classes included that I used to prototype this).
I've added a comment below to highlight the line where the distinct is applied - what you use is the .ToTable() method which takes the Boolean parameter Distinct to specify only return distinct rows.
[TestMethod]
public void CreateDistinctDataTable()
{
DataTable originalTable = CreateDataTable();
AddDataToTable("Fred", "Bloggs", originalTable);
AddDataToTable("Fred", "Bloggs", originalTable);
AddDataToTable("John", "Doe", originalTable);
// This is the key line of code where we use the .ToTable() method
DataTable distinctTable = originalTable.DefaultView.ToTable( /*distinct*/ true);
// The original table has two rows with firstname of Fred
Assert.AreEqual(2, originalTable.Select("firstname = 'Fred'").Length);
// The new table only has one row with firstname of Fred
Assert.AreEqual(1, distinctTable.Select("firstname = 'Fred'").Length);
}
private DataTable CreateDataTable()
{
DataTable myDataTable = new DataTable();
DataColumn myDataColumn;
myDataColumn = new DataColumn();
myDataColumn.DataType = Type.GetType("System.String");
myDataColumn.ColumnName = "firstname";
myDataTable.Columns.Add(myDataColumn);
myDataColumn = new DataColumn();
myDataColumn.DataType = Type.GetType("System.String");
myDataColumn.ColumnName = "lastname";
myDataTable.Columns.Add(myDataColumn);
return myDataTable;
}
private void AddDataToTable(string firstname, string lastname, DataTable myTable)
{
DataRow row = myTable.NewRow();
row["firstname"] = firstname;
row["lastname"] = lastname;
myTable.Rows.Add(row);
}
One additional thought is I would suggest not selecting * from your table in the SQL statement. This can have performance implications down the track if more columns are added (particularly things like blobs) and could also mean you get columns that break the distinct nature of your query.

Related

Taking one value from a table

sorry if this has been asked before but I everything I found has not helped.
I'm looking to set a value from a table to the text property of a label. This is what I have so far:
In a separate class with the connection string "conn" -
(SQL Region)
Public Const SELECT_1 As String = "SELECT TOP 1 * FROM [TableTimes]
WHERE [timeID] = #PKey"
(Methods Region)
Public Shared Function returnOneRow(PrimaryKey As Integer) As TableTimes
Dim returnRow As New TableTimes(0)
Dim conn As New SqlConnection
conn.connectionstring = Conn.getConnectionString
Dim command As New SqlCommand
command.connection = conn
command.CommandType = CommandType.Text
command.CommandText = SQL.SELECT_1
command.Parameters.AddWithValue("#PKey", PrimaryKey)
Try
conn.Open()
Dim dR As IDataReader = command.ExecuteReader
If dR.Read() Then
returnRow.timeID = PK
If Not IsDBNull(dR(Fields.linkID)) Then returnRow.linkID = dR(Fields.linkID)
If Not IsDBNull(dR(Fields.dateTime)) Then returnRow.dateTime = dR(Fields.dateTime)
End If
Catch ex As Exception
Console.WriteLine(Err.Description)
End Try
Return returnRow
End Function
And then back in the main form I am trying to set the dateTime to a label based on what primary key (timeID) I enter as a parameter. This is the closest I can think of:
label.Text = (Tables.TableTimes.returnOneRow(1).dateTime).ToString
I know the output should be "2016-02-04 10:00:00" for the row with the timeID of 1 based on my table data, but instead it returns "0001-01-01 12:00:00" no matter what parameter I enter.
I would prefer to not change my method or sql statement and just change how I call the function in the main form if that's possible.
Thank you!

How to use SQL parameters with NpgsqlDataAdapter?

Is it possible to use parameters together with NpgsqlDataAdapter, as I can do with NpgsqlCommand:
string sql = "SELECT * FROM tbl_student WHERE name = #val";
NpgsqlCommand command = new NpgsqlCommand(sql, conn);
command.Parameters.AddWithValue("#val", name);
I have this code, which displays the information about the students i a gridview:
string sql = "SELECT * FROM tbl_student WHERE studentname = '" + name + "'";
DataSet ds = new DataSet();
DataTable dt = new DataTable();
NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);
ds.Reset();
da.Fill(ds); // filling DataSet with result from NpgsqlDataAdapter
dt = ds.Tables[0]; // select select first column
GridView1.DataSource = dt; //connect grid to DataTable
GridView1.DataBind();
My question is: can I somehow use parameters (as in the example above) instead of using '" + name + "' in the SQL?
I have learned always to use parameters, is it also necessary when using NpgsqlDataAdapter?
Thank you.
I used to have the same question and this is what I came up with:
string sql = "SELECT * FROM tbl_student WHERE studentname = #param";
NpgsqlCommand command = new NpgsqlCommand(sql,conn);
command.Parameters.Add("#param", textBox_studentname.Text); //add the parameter into the sql command
DataTable dt = new DataTable();
//load the DataReader object of the command to the DataTable
dt.Load(NpgsqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection));
GridView1.DataSource = dt;
You could read this and this.

Linking two DataGridViews

I have two Grid controls in VB.Net Winform application connected to Oracle Database. The first one shows a table 1 with fields (among others) ID and TaskName. The second one shows a linked table with fields (among others) Task. In the logic of the application the two tables are linked (Table 1, Field ID) <----> (Table 2, Field Task).
I would like, when selecting a row in the first DataGridView, have only the linked row in the second GridView but I can't make it work.
Here is my code attempt :
Dim SQLQuery As String = "SELECT * FROM SCHEME.ARCH_TASKS"
Conn = New OracleConnection(ConnectionString)
Command = New OracleCommand(SQLQuery, Conn)
DataAdapter = New OracleDataAdapter(Command)
DataSet = New DataSet()
DataTable1 = New DataTable
DataSet.Tables.Add(DataTable1)
DataAdapter.Fill(DataTable1)
DataGridView.DataSource = DataTable1.DefaultView
GridControl1.DataSource = DataTable1.DefaultView
SQLQuery = "SELECT * FROM SCHEME.ARCH_LINK_ROLE_TASK"
Command = New OracleCommand(SQLQuery, Conn)
DataAdapter = New OracleDataAdapter(Command)
DataTable2 = New DataTable
DataSet.Tables.Add(DataTable2)
DataAdapter.Fill(DataTable2)
GridControl2.DataSource = DataTable2
DataSet.Relations.Add(DataTable1.Columns("ID"), DataTable2.Columns("TASK"))
Here is the result
http://img11.hostingpics.net/pics/4713062013102413h1253.png
As you can see, I added manually a relationship between the two data tables but it doesn't really do what i'm looking for. It simply adds a subline in the first grid control.
http://img11.hostingpics.net/pics/7508382013102413h1309.png
I tried to apply what PeterG suggested but I still can't make it work.
Dim SQLQuery As String = "SELECT * FROM SCHEME.ARCH_TASKS"
Command = New OracleCommand(SQLQuery, Conn)
DataAdapter = New OracleDataAdapter(Command)
DataSet.Tables.Add(DataTable1)
DataAdapter.Fill(DataTable1)
SQLQuery = "SELECT * FROM SCHEME.ARCH_LINK_ROLE_TASK"
Command = New OracleCommand(SQLQuery, Conn)
DataAdapter = New OracleDataAdapter(Command)
DataSet.Tables.Add(DataTable2)
DataAdapter.Fill(DataTable2)
DataSet.Relations.Add(DataTable1.Columns("ID"), DataTable2.Columns("TASK"))
BindingSource1.DataSource = DataSet
GridControl1.DataSource = BindingSource1.DataSource
GridControl1.DataMember = "Table1"
BindingSource2.DataSource = BindingSource1.DataSource
GridControl2.DataSource = BindingSource2.DataSource
GridControl2.DataMember = "Table2"
Am I missing something ?
Thank you.

Fill Datatable with list member, if it matches a SQL select

I have a list of numbers and names. I would like to search through a database and find if the number matches my sql select. if it does I need to fill it to the datatable along with the name. Then foreach row in the datatable write that to another list. I'm having trouble filling the name to the datatable as well because I'm not using it in the SQl select as a parameter.
DataTable dt = new DataTable();
try {
using (SqlConnection conn = getconnection()) {
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandTimeout = 5000;
string select = #"SELECT NBR
FROM People
where ID in (15,17) and NBR=Nbr and ACCEPTED=0";
foreach (Fields f in Members) {
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#Nbr", f.nbr);
cmd.CommandText = select;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
//if f.nbr matches sql select fill it to datatable how can I fill dt with f.name as well?
adapt.Fill(dt);
}
}
foreach (DataRow row in dt.Rows) {
Fields f1 = new Fields();
f1.nbr= Convert.ToInt64(row["NBR"]);
// f1.name=Convert.ToString(row["Name"]????
Not.Add(f1);
}
use
string select = #"SELECT NBR, Name
FROM People
where ID in (15,17) and NBR=#Nbr and ACCEPTED=0";

Connect to Excel spreadsheet using OleDbConnection , sort by column number

I am connecting to an Excel spreadsheet via OleDbConnection .
How do I order by ColumnNumber ? I'd like to do something like :
SELECT * FROM [Sheet1$] ORDERBY ColumnNumber
where ColumnNumber is a number like 1 or 2 ?
Any ideas ?
Note: the file I'm trying to open has no headers.
private String BuildConnectionStringXLS()
{
String fileName = GetFileName();
Dictionary<string, string> props = new Dictionary<string, string>();
props["Provider"] = "Microsoft.Jet.OLEDB.4.0";
props["Data Source"] = fileName;
props["Extended Properties"] = "\"Excel 8.0;HDR=No;IMEX=1\"";
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> prop in props)
{
sb.Append(prop.Key);
sb.Append('=');
sb.Append(prop.Value);
sb.Append(';');
}
return sb.ToString();
}
public DataTable GetFullTable(int columnToOrderBy)
{
String fileName = GetFileName();
DataTable resultDataTable = new DataTable();
String connectionString = BuildConnectionString();
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [Sheet1$] ORDERBY ColumnNumber", conn);
da.Fill(resultDataTable);
conn.Close();
return resultDataTable;
}
I find it surprising that you are calling [sheet1$] directly without referring to any linked server.
Here are 2 approaches that are possible:
Using Linked Server
First create a linked server to access excel data as below:
(I am assuming you have already have either JET or ACE provider for excel)
exec sp_addLinkedServer #server='ExcelLnkdServr',
#srvproduct='ACE 12.0',
#provider='Microsoft.ACE.OLEDB.12.0',
#datasrc='\\sysdev\loadExcel.xlsx',
#provstr='Excel 12.0;HDR=Yes';
/* If the above creation is successful, you can see a listing when use SP_LINKEDSERVERS in SSMS. Now you can query the sheet using order by as below: */
select * from ExcelLnkdServr...[Sheet1$]
order by 1 asc, 2 desc
Using Adhoc Queries
You can OPENROWSET, OPENDATASOURCE or OPENQUERY as shown below: (Second option doesnt need any linked server creation )
select * from openquery(ExcelLnkdServr, 'SELECT * FROM [Sheet1$] order by 1 asc, 3 desc')
SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0;Database=\\sysdev\loadExcel.xlsx;HDR=Yes','Select * from [Sheet1$] order by 1 asc')