Execute array values in query c# - c#

I'm busy with a task program and then I came on to a problem!
Here is my code:
int id = 1;
List<Button> _bListGroups = new List<Button>();
MySqlCommand mcCommandUserID = new MySqlCommand("SELECT * FROM pakket WHERE gebruikersid=#id", _msConnection);
mcCommandUserID.Parameters.AddWithValue("#id", id);
MySqlDataReader msReader = mcCommandUserID.ExecuteReader();
DataTable dtGetUserid = new DataTable();
dtGetUserid.Load(msReader);
string[] nummer = new string[10];
int i = 0;
foreach (DataRow row in dtGetUserid.Rows)
{
nummer[i] = row["groepsid"].ToString();
i++;
}
MySqlCommand msCommandGetGroup = new MySqlCommand("SELECT * FROM groep WHERE id=#id",_msConnection);
msCommandGetGroup.Parameters.AddWithValue("#id", nummer[i]);
MySqlDataReader msGetGroup = msCommandGetGroup.ExecuteReader();
DataTable dtGetGroup = new DataTable();
dtGetGroup.Load(msGetGroup);
int mtop = 10;
int mleft = 15;
int count = 1;
foreach (DataRow dr in dtGetGroup.Rows)
{
Button temp = new Button();
temp.Name = "bt" + dr["id"];
temp.Text = (string)dr["groepsnaam"];
temp.Width = 125;
temp.Height = 125;
temp.Left = mleft;
temp.Top = mtop;
mleft += 127;
if (count == 2)
{
mtop += 125;
mleft = 15;
count = 0;
}
count++;
_bListGroups.Add(temp);
}
return _bListGroups.ToArray();
When i give my array a specific number(like nummer[1]) i get one button back but if I use the variable i, it doesn't give me any buttons. I already tried to debug it but I couldn't solve it.

Note that you are increasing i in the end of every iteration. So in the end i is greater than the last assigned index by 1. Therefore you need i-1:
msCommandGetGroup.Parameters.AddWithValue("#id", nummer[i-1]);
Also you might want to have some prechecks here for edge cases, say when there is no rows in dtGetUserid.Rows.

You've failed to reset your counter.
the variable i is at this stage:
msCommandGetGroup.Parameters.AddWithValue("#id", nummer[i]);
set to an array index which you havent allocated with any values.

Related

Pagination c# aspx help using listview

protected void showproduct()
{
int pagecount = 0;
int currentpage = 0;
if (Request.QueryString["page"] != null)
{
currentpage = Int32.Parse(Request.QueryString["page"]);
}
Response.Write("</br>"+currentpage);
MySqlConnection dbcon = new MySqlConnection("Server=localhost; Database=ip; Uid=root; Password=root;");
MySqlCommand dbcmd = new MySqlCommand();
dbcon.Open();
dbcmd.Connection = dbcon;
for (int q = 0; q <= currentpage; q++)
{
if (currentpage >2 )
{
pagecount = q * 3;
}else if(currentpage==2){
pagecount = 3;
}
}
dbcmd.CommandText = "select * from product where id >" + pagecount + " order by id asc limit 3";
//dbcmd.CommandText = "select * from product limit "+ pagecount +",3";
MySqlDataAdapter adapter = new MySqlDataAdapter(dbcmd.CommandText, dbcon);
DataTable t = new DataTable();
adapter.Fill(t);
ListView1.DataSource = t;
ListView1.DataBind();
}
http://prntscr.com/d83mgh
In page 2 I can view
http://prntscr.com/d83msj
When clicked on page 3 nothing is shown
I have like 9 data in my source
I am assuming that the items in the db have continuous ids without holes.
Then you can calculate the first id to be shown using the index of the selected page and the number of items to be shown per page like this:
const int itemsPerPage = 3; // number of items per page to be shown
const int minId = 1; // id of first record in db
// page selected by user in ui
int selectedPage;
if (Request.QueryString["page"] != null) {
// first page has index 0 to simplify the calculation
selectedPage = Int32.Parse(Request.QueryString["page"]) - 1;
}
// id of first record to be shown
int minIdToBeShown = minId + itemsPerPage * selectedPage;
// fetch records including the first record to be shown on the page
dbcmd.CommandText = "select * from product where id >=" + minIdToBeShown
+ " order by id asc limit " + itemsPerPage;

How to get both dynamic numericupdown and textbox values in c# windows forms

I have a code where TextBox and NumericUpDown tools are generated dynamically through a foreach loop. Now, I want to be able to get both values in which with each iteration, both their values would be added to the same row in the database. I have the code for getting the NumericUpDown values and I was wondering how can I implement getting the TextBox values too.
Code for generating the dynamic NumericUpDown and TextBox
t = temp.Split(';'); // e.g. t = Arial;32
int pointX = 70;
int pointY = 80;
int pointA = 300;
int pointB = 80;
for (int i = 0; i < N; i++)
{
foreach (object o in t)
{
TextBox a = new TextBox();
a.Text = o.ToString();
a.Location = new Point(pointX, pointY);
a.Size = new System.Drawing.Size(150, 25);
panel.Controls.Add(a);
panel.Show();
pointY += 30;
NumericUpDown note = new NumericUpDown();
note.Name = "Note" + i.ToString();
note.Location = new Point(pointA, pointB);
note.Size = new System.Drawing.Size(40, 25);
note.Maximum = new decimal(new int[] { 10, 0, 0, 0 });
panel.Controls.Add(note);
pointB += 30;
}
}
Code for getting dynamic NumericUpDown values on button click (the database code works)
foreach (NumericUpDown ctlNumeric in panel.Controls.OfType<NumericUpDown>())
{
var value = ctlNumeric.Value;
int number = Decimal.ToInt32(value);
sample_save = "INSERT INTO forthesis (testVal) VALUES ('" + number + "');";
MySqlConnection myConn = new MySqlConnection(connectionString);
MySqlCommand myCommand = new MySqlCommand(sample_save, myConn);
MySqlDataAdapter da = new MySqlDataAdapter(myCommand);
MySqlDataReader myReader;
myConn.Open();
myReader = myCommand.ExecuteReader();
myConn.Close();
MessageBox.Show(number.ToString());
}
Sample output, each row would be inserted in the database
How can I get the values in the TextBox(es) too? Your help will be much appreciated. Thank you so much!!!
Maybe you could use a string - TextBox dictionary to save the matching paired text box like this :
Dictionary<string, TextBox> textboxes = new Dictionary<string, TextBox>();
for (int i = 0; i < N; i++)
{
foreach (object o in t)
{
TextBox a = new TextBox();
.....
NumericUpDown note = new NumericUpDown();
note.Name = "Note" + i.ToString();
......
textboxes.Add(note.Name, a);
}
}
foreach (NumericUpDown ctlNumeric in panel.Controls.OfType<NumericUpDown>())
{
var value = ctlNumeric.Value;
int number = Decimal.ToInt32(value);
TextBox tb = textboxes[ctrlNumeric.Name];
String text = tb.Text;
.........
}
If you are removing the TextBoxs & NumericUpDowns - then you will need to clear the Dictionary as well - otherwise it will retain references to them & they will not be cleaned up by the Garbage Collector.

Display pictures with their name from database in winforms?

dataGridView1.DataSource = null;
using (SqlConnection myDatabaseConnection = new SqlConnection(myConnectionString.ConnectionString))
{
myDatabaseConnection.Open();
using (SqlCommand mySqlCommand = new SqlCommand("Select Name, Picture from Employee ", myDatabaseConnection))
{
DataSet ds = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(mySqlCommand);
adapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
}
}
Instead of using datagridview, How I can display the picture with their Name in the panel or other control from the database something like this format http://static.neatorama.com/images/2008-04/yearbook-project-robot-johnny.gif in win form?
For example I have 7 records in the database, the form will display 7 panels with picture and label. And when I click or select a panel it will dipslay more information such as Address, Contacts, Etc in a textBox. If the records in the database is too many to fit in the form there will be a vertical or horizontal scroll bar.
I suggest you to create the objects you need dynamically. You can use "Location" to position your object.
Example :
int cptx = 0;
int cpty = 0;
for(int i=0; i<ds.Tables[0].Rows.Count;i++)
{
PictureBox currentpic = new PictureBox();
Label currentlabel = new Label();
currentpic.Size = new Size(20,20);
currentlabel.Size = new Size(20,20);
currentpic.BorderStyle = BorderStyle.FixedSingle;
currentlabel.Text = "te";
if(cptx >= 4)
{
cptx = 0;
cpty ++;
}
currentpic.Location= new Point((cptx*25),(cpty*50));
currentlabel.Location = new Point((cptx*25),(cpty*50)+25);
This.Controls.Add(currentpic);
cptx ++;
}
This code should do this :
EDIT : I suggest you to take a look at the "User control", the user control allow you to create you own control. So, the picture and the label will be inside a single control. The advantage to use the user control is the control you will create will be totally reusable for your other windows and/or programs.
Form has only one panel (pnlGrid) and panel's AutoScroll property setted as true;
DataTable dtImage = new DataTable();
dtImage.Columns.Add("Path");
dtImage.Columns.Add("Name");
dtImage.Rows.Add(new object[] { "ImagePath", "ImageText" });
dtImage.Rows.Add(new object[] { "ImagePath", "ImageText" });
dtImage.Rows.Add(new object[] { "ImagePath", "ImageText" });
CreateImageGrid(dtImage);
and method;
private void CreateImageGrid(DataTable dtDataSource)
{
int colCount = 5;
int rowCount = 0;
int imgWidth = 100;
int imgHeight = 100;
int imgPadding = 10;
int lblPadding = 5;
int ind = -1;
PictureBox pic = null;
Label lbl = null;
if (dtDataSource.Rows.Count > colCount)
{
rowCount = Convert.ToInt32(dtDataSource.Rows.Count / colCount);
if (Convert.ToInt32(dtDataSource.Rows.Count % colCount) > 0)
{
rowCount++;
}
}
else
{
rowCount = 1;
}
for (int j = 0; j < rowCount; j++)
{
for (int i = 0; i < colCount && dtDataSource.Rows.Count > ((j * colCount) + i); i++)
{
ind = (j * colCount) + i;
pic = new PictureBox();
pic.Image = Image.FromFile(dtDataSource.Rows[ind]["Path"].ToString());
pnlGrid.Controls.Add(pic);
pic.Width = imgWidth;
pic.Height = imgHeight;
pic.Top = (j * (imgHeight + imgPadding)) + imgPadding;
pic.Left = (i * (imgWidth + imgPadding)) + imgPadding;
lbl = new Label();
lbl.Text = dtDataSource.Rows[ind]["Name"].ToString();
pnlGrid.Controls.Add(lbl);
lbl.Left = pic.Left;
lbl.Top = pic.Top + pic.Height + lblPadding;
}
}
}
Note: Text lengths may cause problems, you should define some rules.

Add only a percentage of rows to DataTable

So i'm making a program to Audit some of our workers randomly. And i'm trying to make a program to scan our Access DB and pull a percentage of orders. But i want to randomly select the orders, i dont want just the top 5% or something.
static DataTable RandomSelect(double errPercentage,string User)
{
OleDbConnection conn = new OleDbConnection(strAccessConn);
string query = "SELECT ControlNumber FROM Log WHERE User ='" + User + "' AND Log.EndStatus in ('Needs Review', 'Check Search', 'Vision Delivery', 'CA Review', '1TSI To Be Delivered');";
OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn);
DataTable dt = new DataTable();
DataTable dtRandomRows = new DataTable();
try
{
adapter.Fill(dt);
//dtRandomRows = dt.Clone();
Random rDom = new Random();
int i = 0;
for (int ctr = 1; ctr <= dt.Rows.Count; ctr++)
{
i = rDom.Next(1, dt.Rows.Count);
//dtRandomRows.Rows.Add(dt.Rows[i]);
dtRandomRows.ImportRow(dt.Rows[i]);
}
dtRandomRows.AcceptChanges();
}
catch (OleDbException ex)
{
}
return dtRandomRows;
}
The code above works, but it randomly selects rows from the entire table of the ControlNumbers (orders) and puts them all into dtRandomRows. However, i just want this to select the 'errPercentage' or rows randomly...any thoughts?
Random rand = new Random();
// Mark every row as not selected yet.
int[] nonSelectedRows = new int[dt.Rows.Count];
for(int i = 0; i < dt.Rows.Count; i++)
nonSelectedRows[i] = 1;
int numSelected = 0;
int numLeft = dt.Rows.Count;
int targetNum = dt.Rows.Count * errPercentage;
while(numSelected < targetNum)
{
for (int row = 0; row < dt.Rows.Count; row++)
{
// Each record has a 1/numleft chance of getting selected.
boolean isSelected = rand.Next(numLeft) == 0;
// Check to make sure it hasn't already been selected.
if(isSelected && nonSelectedRows[row] > 0)
{
dtRandomRows.ImportRow(dt.Rows[row]);
nonSelectedRows[row] = -1; // Mark this row as selected.
numSelected++;
numLeft--;
}
// We've already found enough to match our targetNum.
if(numSelected >= targetNum)
break;
}
}

indexing Array out of Range Exception

I try to save the SQL Results in a array and return it back. but i'm getting an exception: array out of range error.
here is my code:
public BookingUpdate[] getBookingUpdates(string token)
{
String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
SqlConnection connection = new SqlConnection(GetConnectionString());
BookingUpdate[] bookingupdate = new BookingUpdate[1];
connection.Open();
try
{
SqlCommand cmd = new SqlCommand(command, connection);
SqlDataReader rdr = null;
int count = 0;
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
DataTable dt = new DataTable();
dt.Load(rdr);
count = dt.Rows.Count;
for (int c = 0; c < count; c++)
{
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"]; // <---- Error is here
bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
bookingupdate[c].newStart = (DateTime)rdr["VON"];
bookingupdate[c].newStart = (DateTime)rdr["BIS"];
bookingupdate[c].newSubject = rdr["THEMA"].ToString();
bookingupdate[c].newlocation = rdr["BEZEICHNUNG"].ToString();
if (rdr["STORNO"].ToString() != null)
{
bookingupdate[c].deleted = true;
}
else
{
bookingupdate[c].deleted = false;
}
}
}
}
catch (Exception ex)
{
log.Error(ex.Message + "\n\rStackTrace:\n\r" + ex.StackTrace);
}
finally
{
connection.Close();
}
return bookingupdate;
}
What am i missing?
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"];
you are creating an Array of length c, which means it has the Indexes 0 to (c-1) - and then you are out of bounds, when trying to store at Position c.
You appear to be creating and allocating memory for an array with
bookingupdate = new BookingUpdate[c];
but not actually creating instances of BookingUpdate. When you attempt to set properties on your array element there is no actual BookingUpdate to update - there is only a holder for one.
I'd suggest changing your code to something along the lines of:
...
bookingupdate = new BookingUpdate[count]; // allocates space for the number of BookingUpdates to be created
for (int c = 0; c < count; c++)
{
bookingupdate[c] = new BookingUpdate(); // create a new instance of BookingUpdate and assign it the array
bookingupdate[c].bookingID = (long)rdr["ID"];
...
I hope that this helps!
Imho i would simplify your way to construct that array with Linq:
BookingUpdate[] bookingupdate = dt.AsEnumerable()
.Select(r => new BookingUpdate{
bookingID = r.Field<long>("ID"),
fullUserName = r.Field<string>("VERANSTALTER"),
newStart = r.Field<DateTime>("Von"),
newEnd = r.Field<DateTime>("Bis"), // here was another bug in your originalcode
newSubject = r.Field<string>("THEMA"),
newlocation = r.Field<string>("BEZEICHNUNG"),
deleted = r.Field<string>("STORNO") != null
})
.ToArray();
On this way you will not have problems with arrays that are out of bounds.
You accessing the n'th element of an n-Elements array which is out of range, you need to access the n - 1 element.
bookingupdate = new BookingUpdate[c]; // You create an array of 5 elements for example
bookingupdate[c].bookingID = (long)rdr["ID"]; // Here you access the 5th elements but there are only 4
the problem is related with the size of the array;
for (int c = 0; c < count; c++)
{
bookingupdate = new BookingUpdate[c];
bookingupdate[c].bookingID = (long)rdr["ID"];
in the previous code, you are creating an array (bookingupdate ) of size 0 at first; then you are trying to insert an item. Even if you somehow manage to skip first one, it will again fail. Just update these lines to the following;
bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
{
bookingupdate[c].bookingID = (long)rdr["ID"];
for (int c = 0; c < count; c++)
{
bookingupdate = new BookingUpdate[c];
Error is at first iteration of this for loop where c is zero. ie, you are trying to create a array of length zero. bookingupdate = new BookingUpdate[0];
You have initialized an array but not the class itself before calling it. Also your initialization is wrong
count = dt.Rows.Count;
bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
{
bu = new BookingUpdate();
bu.bookingID = (long)rdr["ID"]; // <---- Error is here
bu.fullUserName = rdr["VERANSTALTER"].ToString();
bu.newStart = (DateTime)rdr["VON"];
bu.newStart = (DateTime)rdr["BIS"];
bu.newSubject = rdr["THEMA"].ToString();
bu.newlocation = rdr["BEZEICHNUNG"].ToString();
if (rdr["STORNO"].ToString() != null)
{
bu.deleted = true;
}
else
{
bu.deleted = false;
}
bookingupdate[c] = bu;
}
Arrays has zero based index.
When you create bookingupdate = new BookingUpdate[c]; your last index would c-1.
You can't access BookingUpdate[c] because it is not exist.
Let's say c = 4, that means we definedan array with 4 elements which they are;
BookingUpdate[0]
BookingUpdate[1]
BookingUpdate[2]
BookingUpdate[3]
BookingUpdate[c] would equal BookingUpdate[4] which there is no such an index.
From MSDN page;
Arrays are zero indexed: an array with n elements is indexed from 0 to
n-1.
Use this code
public BookingUpdate[] getBookingUpdates(string token)
{
String command = "SELECT b.ID,b.VERANSTALTER, rr.VON ,rr.BIS, b.THEMA, b.STORNO, ra.BEZEICHNUNG from BUCHUNG b JOIN RESERVIERUNGRAUM rr on rr.BUCHUNG_ID = b.ID JOIN RAUM ra on ra.ID = rr.RAUM_ID WHERE b.UPDATE_DATE BETWEEN DATEADD (DAY , -20 , getdate()) AND getdate() AND b.BOOKVERNR = 0";
BookingUpdate[] bookingupdate;
SqlConnection connection = new SqlConnection(GetConnectionString());
connection.Open();
try
{
SqlCommand cmd = new SqlCommand(command, connection);
SqlDataReader rdr = null;
int count = 0;
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
DataTable dt = new DataTable();
dt.Load(rdr);
count = dt.Rows.Count;
bookingupdate = new BookingUpdate[count];
for (int c = 0; c < count; c++)
{
bookingupdate[c].bookingID = (long)rdr["ID"]; // <---- Error is here
bookingupdate[c].fullUserName = rdr["VERANSTALTER"].ToString();
bookingupdate[c].newStart = (DateTime)rdr["VON"];
bookingupdate[c].newStart = (DateTime)rdr["BIS"];
bookingupdate[c].newSubject = rdr["THEMA"].ToString();
bookingupdate[c].newlocation = rdr["BEZEICHNUNG"].ToString();
if (rdr["STORNO"].ToString() != null)
{
bookingupdate[c].deleted = true;
}
else
{
bookingupdate[c].deleted = false;
}
}
}
}
catch (Exception ex)
{
log.Error(ex.Message + "\n\rStackTrace:\n\r" + ex.StackTrace);
}
finally
{
connection.Close();
}
return bookingupdate;
}

Categories