The following code is used to save data from an SQL table to excel. The problem is, it does not save table headers if the table is empty.
worksheet4 = workbook.Sheets[4];
worksheet4.Name = "Adjs ";
SQL.DataTable dtAG = new SQL.DataTable();
using (SqlConnection cn1 = new SqlConnection(conStr))
{
using (SqlDataAdapter da4 = new SqlDataAdapter(query4.ToString(), cn1))
{
da4.Fill(dtAG);
}
}
DataColumnCollection dcCollection4 = dtAG.Columns;
for (int i = 1; i < dtAG.Rows.Count + 1; i++)
{
for (int j = 1; j < dtAG.Columns.Count + 1; j++)
{
if (i == 1)
worksheet4.Cells[i, j] = dcCollection4[j - 1].ToString();
else
worksheet4.Cells[i, j] = dtAG.Rows[i - 1][j - 1].ToString();
}
}
Any help would be appreciated.
You could add the columns before you it start filling out the data:
int a = 1;
foreach(DataColumn dc in dtAG.Columns)
{
worksheet4.Cells[1, a] = dc.ColumnName;
a++;
}
and then just start from the next row:
for (int i = 2; i < dtAG.Rows.Count + 1; i++)
{
for (int j = 1; j < dtAG.Columns.Count + 1; j++)
{
worksheet4.Cells[i, j] = dtAG.Rows[i - 1][j - 1].ToString();
}
}
You can set the header values like this: ws.Cells[1, 1].Value = "example";
[i, j] has to be [i+1,j] if not, you over write your headings.
Related
I have Created Checkboxes like this:
but now i want to be able to check all the Checkboxes in one Row after giving the Row number
private void button4_Click(object sender, EventArgs e)
{
CheckBox[,] c = new CheckBox[10, 5];
for (i = 1; i < c.GetLength(0); i++)
{
for ( j = 1; j < c.GetLength(1); j++)
{
c[i, j] = new CheckBox();
c[i, j].Location = new Point(i * 50, j * 50);
c[i, j].AutoSize = true;
c[i, j].Name = i + "-" + j.ToString();
c[i, j].Text = i + "-" + j.ToString();
this.Controls.Add(c[i, j]);
}
}
You already use name:
for (i = 1; i < c.GetLength(0); i++)
{
for ( j = 1; j < c.GetLength(1); j++)
{
...
c[i, j].Name = i + "-" + j.ToString();
this.Controls.Add(c[i, j]);
}
}
So you could create a method to search against that:
private CheckBox Find(int row, int col)
{
foreach(var control in this.Controls)
{
if (control is CheckBox && control.Name == $"{row}-{col}")
return control as CheckBox;
}
}
So then just loop the rows and/or columns you want. This should check every even row:
for(var i = 1; i <= rowCount; i++)
{
if (i % 2 == 0)
{
for(var j = 1; i <= colCount; i++)
{
var checkBox = Find(i, j);
if (checkBox != null)
checkBox.Checked = true;
}
}
}
It's not the most efficient as each Find call is essentially looping over the controls so you'd be iterating multiple times but should work for a reasonable grid.
A shorter solution would use a jagged array instead, but with 2D array you can do the following:
You should change your check box array initialisation to this:
for (int i = 0; i < c.GetLength(0); i++)
{
for (int j = 0; j < c.GetLength(1); j++)
{
c[i, j] = new CheckBox
{
Location = new Point(i * 50, j * 50),
AutoSize = true,
Name = i + "-" + j.ToString(),
Text = i + "-" + j.ToString()
};
Controls.Add(c[i, j]);
}
}
If you still want their location to not be the upper left corner you can add 1 to the index like this:
Location = new Point((i + 1) * 50, (j + 1) * 50)
Than you can later obtain a row like this:
private CheckBox[] GetCheckBoxsByRow(int row, CheckBox[,] checkboxs)
{
CheckBox[] selectedRowCheckboxs = new CheckBox[checkboxs.GetLength(0)];
for (int x = 0; x < checkboxs.GetLength(0); x++)
{
selectedRowCheckboxs[x] = checkboxs[x, row - 1];
}
return selectedRowCheckboxs;
}
Example usage:
var firstRow = GetCheckBoxsByRow(1, c);
I am implementing the NEH algorithm following this slide and video:
http://mams.rmit.edu.au/b5oatq61pmjl.pdf
https://www.youtube.com/watch?v=TcBzEyCQBxw
My problem during the test is the variable Sorted_list got changed which cause different results from what I expect:
This the portion where I have the problem but I couldn't know what it changes it(I used breakpoints and watch variable window):
for (int i = 0; i < kmsList.Count; i++)
{
for (int j = 0; j < kmsList[i].Length - 1; j++)
{
/*
*
* HERE Sorted_list GET MODIFIED UNEXPECTEDLY
*/
if (i == 0 && j == 0)
kmsList[0][0] = Sorted_list[0][0];
else if (i == 0)
kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
else if (j == 0)
kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
}
}
Complete implementation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FINAL_NEH
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("entre the nmbr of jobs : ");
string row = Console.ReadLine();
Console.WriteLine("entre the nmbr of machines : ");
string column = Console.ReadLine();
int job = int.Parse(row.ToString());
int machine = int.Parse(column.ToString());
List<int[]> list = new List<int[]>();
// read the nmbrs and put it in list-----------------------------------------------------
for (int i = 0; i < job; i++)
{
list.Add(new int[machine + 1]);
for (int j = 0; j < machine; j++)
{
list[i][j] = int.Parse(Console.ReadLine());
}
list[i][list[i].Length - 1] = int.Parse((i + 1).ToString()); //Last Elemnt Is Job Number-
}
// show the list----------------------------------------------------------------------------
for (int i = 0; i < job; i++)
{
for (int j = 0; j < machine + 1; j++)
{
Console.Write("\t" + "[" + list[i][j] + "]");
}
Console.WriteLine();
}
// sort the list------------------------------------------------------------------------------
for (int i = 0; i < list.Count; i++)
{
for (int j = i + 1; j < list.Count; j++)
{
int sumI = 0, sumJ = 0;
for (int a = 0; a < list[i].Length - 1; a++)
{
sumI += list[i][a];
}
for (int a = 0; a < list[j].Length - 1; a++)
{
sumJ += list[j][a];
}
if (sumI < sumJ)
{
int[] temp = new int[int.Parse(job.ToString())];
temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
}
Console.Write("\n\n-----------------after sorting ------------------------------------\n\n");
// shaw the list after sorting------------------------------------------
for (int i = 0; i < job; i++)
{
for (int j = 0; j < machine + 1; j++)
{
Console.Write("\t" + "[" + list[i][j] + "]");
}
Console.WriteLine();
}
// clculate the maxpane of the first 2 jobs---------------------------------------
List<int[]> initMaxpane = new List<int[]>();
initMaxpane.Add((int[])list[0].Clone());
initMaxpane.Add((int[])list[1].Clone());
// calculer maxspan of first jobs..............................................
for (int i = 0; i < initMaxpane.Count; i++)
{
for (int j = 0; j < initMaxpane[i].Length - 1; j++)
{
if (j == 0 && i == 0)
initMaxpane[0][0] = list[i][j];
else if (i == 0)
initMaxpane[0][j] = (int)(initMaxpane[0][j - 1] + list[0][j]);
else if (j == 0)
initMaxpane[i][0] = (int)(initMaxpane[i - 1][0] + list[i][0]);
}
}
for (int i = 1; i < initMaxpane.Count; i++)
{
for (int j = 1; j < initMaxpane[i].Length - 1; j++)
{
if ((initMaxpane[i][j - 1] > initMaxpane[i - 1][j]))
initMaxpane[i][j] = (int)(initMaxpane[i][j - 1] + list[i][j]);
else
initMaxpane[i][j] = (int)(initMaxpane[i - 1][j] + list[i][j]);
}
}
int Cmax = initMaxpane[initMaxpane.Count - 1][initMaxpane[initMaxpane.Count - 1].Length - 2];
Console.WriteLine("\n\n-------the maxpane offirst jobs----------");
for (int i = 0; i < initMaxpane.Count; i++)
{
for (int j = 0; j < initMaxpane[i].Length; j++)
{
Console.Write("\t" + "[" + initMaxpane[i][j] + "]");
}
Console.WriteLine();
}
List<int[]> initMaxpane2 = new List<int[]>();
initMaxpane2.Add(list.ElementAt(1));
initMaxpane2.Add(list.ElementAt(0));
// calculer maxspan of first jobs reverse..............................................
for (int i = 0; i < initMaxpane2.Count; i++)
{
for (int j = 0; j < initMaxpane2[i].Length - 1; j++)
{
if (j == 0 && i == 0)
initMaxpane2[0][0] = list[i][j];
else if (i == 0)
initMaxpane2[0][j] = (int)(initMaxpane2[0][j - 1] + list[0][j]);
else if (j == 0)
initMaxpane2[i][0] = (int)(initMaxpane2[i - 1][0] + list[i][0]);
}
}
for (int i = 1; i < initMaxpane2.Count; i++)
{
for (int j = 1; j < initMaxpane2[i].Length - 1; j++)
{
if ((initMaxpane2[i][j - 1] > initMaxpane2[i - 1][j]))
initMaxpane2[i][j] = (int)(initMaxpane2[i][j - 1] + list[i][j]);
else
initMaxpane2[i][j] = (int)(initMaxpane2[i - 1][j] + list[i][j]);
}
}
int Cmax2 = initMaxpane2[initMaxpane2.Count - 1][initMaxpane2[initMaxpane2.Count - 1].Length - 2];
Console.WriteLine("\n\n-------the maxpane of first jobs (reverse)----------");
for (int i = 0; i < initMaxpane2.Count; i++)
{
for (int j = 0; j < initMaxpane2[i].Length; j++)
{
Console.Write("\t" + "[" + initMaxpane2[i][j] + "]");
}
Console.WriteLine();
}
List<int[]> MaxpaneList = new List<int[]>();
if (Cmax > Cmax2)
{
MaxpaneList.Add((int[])list[1].Clone());
MaxpaneList.Add((int[])list[0].Clone());
}
else
{
MaxpaneList.Add((int[])list[0].Clone());
MaxpaneList.Add((int[])list[1].Clone());
}
List<int[]> bestSequenceList = null;
List<int[]> kmsList = null;
List<int[]> Sorted_list = list.ToList();
int bestCma = 0;
//int maxspan = 0;
for (int jo = 2; jo < job; jo++)
{
for (int ins = 0; ins <= MaxpaneList.Count; ins++)
{
MaxpaneList.Insert(ins, list[jo]);
kmsList = MaxpaneList.ToList();
int Cma = 0;
for (int i = 0; i < kmsList.Count; i++)
{
for (int j = 0; j < kmsList[i].Length - 1; j++)
{
/*
*
* HERE Sorted_list GET MODIFIED UNEXPECTEDLY
*/
if (i == 0 && j == 0)
kmsList[0][0] = Sorted_list[0][0];
else if (i == 0)
kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
else if (j == 0)
kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
}
}
for (int i = 1; i < kmsList.Count; i++)
{
for (int j = 1; j < kmsList[i].Length - 1; j++)
{
if ((kmsList[i][j - 1] > kmsList[i - 1][j]))
kmsList[i][j] = kmsList[i][j - 1] + Sorted_list[i][j];
else
kmsList[i][j] = kmsList[i - 1][j] + Sorted_list[i][j];
}
}
Cma = kmsList[kmsList.Count - 1][kmsList[kmsList.Count - 1].Length - 2];
Console.WriteLine("\n\n\n------- the maxpane sequence ----------");
for (int i = 0; i < MaxpaneList.Count; i++)
{
for (int j = 0; j < MaxpaneList[i].Length; j++)
{
Console.Write("\t" + "[" + MaxpaneList[i][j] + "]");
}
Console.WriteLine();
}
Console.WriteLine("MAX : " + Cma + "\n\n\n");
if (ins == 0)
{
bestCma = Cma;
}
if (jo == 2 && ins == 0)
{
bestSequenceList = MaxpaneList.ToList();
bestCma = Cma;
}
else
{
if (bestCma > Cma)
{
bestSequenceList = MaxpaneList.ToList();
bestCma = Cma;
}
}
MaxpaneList.RemoveAt(ins);
}
MaxpaneList = bestSequenceList.ToList();
}
Console.ReadLine();
}
}
}
The issue lies in the following code (snippet):
List<int[]> Sorted_list = list.ToList();
ToList will create a new list, but because in this case int[] is a reference type then the new list will contain references to the same arrays as the original list.
Updating a value (of an array) referenced in the new list will also affect the equivalent value in the original list.
kmsList[0][0] = Sorted_list[0][0];
The solution is to create a real copy of 'list' and its items (in this case int[]):
List<int[]> Sorted_list = list.ConvertAll(myArray => (int[])myArray.Clone());
This piece of code clones all arrays within the list to a new variable Sorted_list.
A useful link that explains the difference between value and reference types is: https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx
Reference Types
A reference type contains a pointer to another memory location that holds the data.
Reference types include the following:
String
All arrays, even if their elements are value types Class
types, such as Form
Delegates
When you create a List<> (or any other container) from another container (as you do when you call list.ToList()) you do not create copies of all of the elements in the container. You create new references to the items in the list that you're copying. In CS parlance it's a shallow copy and not a deep copy.
So, if you do this:
int[] ia = new[] {0, 1, 2, 3, 4};
int[] ib = new[] {5, 6, 7, 8, 9};
List<int[]> la = new List<int[]>() { ia, ib };
List<int[]> lb = la.ToList();
Both lists refer to the same two arrays, and if you change one array like this:
la[1][4] = 10;
Then lb[1][4] will also be 10 because the two lists each contain the same arrays. Copying the list does not copy the elements in the list.
I have a console application that retrieves data from a web service. It will write the response on an excel file. My logic is fine with one data row, but if it is more than one, it's need writing on the excel file properly.
int i = 0;
int j = 0;
int k = 0;
foreach (var response in responseList)
{
dt = response;
for (i = 0; i <= dt.Rows.Count - 1; i++)
{
for (j = 0; j <= dt.Columns.Count - 1; j++)
{
xlWorkSheet.Cells[i + 1, j + 1] = dt.Rows[i].ItemArray[j].ToString();
}
}
}
My problem with this code is that the excel rows that are being written are always the same.
Example: first response has 20 rows, second response has 10 rows. But after the loop, my excel only generated 20 rows. Seems like not all the data are not being written. Any ideas why?
EDIT
I tried the code below but still no luck.
int jOffset = 0;
int iOffset = 0;
foreach (var response in responseList)
{
dt = response;
for (i = 0; i <= dt.Rows.Count - 1; i++)
{
for (j = 0; j <= dt.Columns.Count - 1; j++)
{
xlWorkSheet.Cells[i + iOffset + 1, j + jOffset + 1] = dt.Rows[i].ItemArray[j].ToString();
}
}
jOffset++;
iOffset++;
}
try this...
class YourClass
{
//rowOffset as field
int rowOffset = 0;
void YourMethod()
{
//... your other codes here
int i = 0;
int j = 0;
int k = 0;
dt = response;
for (i = 0; i <= dt.Rows.Count - 1; i++)
{
for (j = 0; j <= dt.Columns.Count - 1; j++)
{
xlWorkSheet.Cells[i + iOffset + 1, j + 1] = dt.Rows[i].ItemArray[j].ToString();
}
}
rowOffset += i; //the last 'i' (row) recorded will now be added to your row offset
//...
}
}
Basically, you only need a rowOffset and you should store it as a field to retain its value. Then, every after you finish one loop through the response, you add the last i (row #) to the rowOffset which will be the offset for succeeding loops.
EDIT: correction on rowOffset+=i
//export header
for (i = 1; i <= this.datagridview1.Columns.Count; i++)
{
ExcelSheet.Cells[3, i] = this.datagridview1.Columns[i - 1].HeaderText;
}
//export data
for (i = 1; i <= this.datagridview1.RowCount; i++)
{
for (j = 1; j <= datagridview1.Columns.Count; j++)
{
ExcelSheet.Cells[i + 3, j] = datagridview1.Rows[i - 1].Cells[j - 1].Value;
}
}
This is exporting all data from datagridview but I don't want to export "Date " column and "checkbox" column
Showing like this
You can use an additional counter for columns to get the proper output (not just empty columns). Also, you can move the logics of "skipping" columns to a function.
int columnsCount = 0;
//export header
for (i = 1; i <= this.datagridview1.Columns.Count; i++)
{
if (SkipColumn(this.datagridview1.Columns[i - 1]))
continue;
columnsCount++;
ExcelSheet.Cells[3, columnsCount] = this.datagridview1.Columns[columnsCount - 1].HeaderText;
}
//export data
for (i = 1; i <= this.datagridview1.RowCount; i++)
{
columnsCount = 0;
for (j = 1; j <= datagridview1.Columns.Count; j++)
{
if (SkipColumn(this.datagridview1.Columns[i - 1]))
continue;
columnsCount++;
ExcelSheet.Cells[i + 3, columnsCount] = datagridview1.Rows[i - 1].Cells[columnsCount - 1].Value;
}
}
// ...
private bool SkipColumn(DataGridViewColumn column)
{
return column.GetType() == typeof(DataGridViewCheckBoxColumn)
|| column.Name == "Date";
}
You can add any logics to SkipColumn. Add any validations, conditions there using DataGridViewColumn properties.
Read about DataGridViewColumn properties at MSDN.
dgvEmployeeTimeSheet.DataSource = OCommonFunctions.SelectData("sp_GP_EmployeeTimeSheetDetailSelectForXLS", "#fromdate", dtpFromDate.Value.ToString("MM/dd/yyyy"), "#todate", dtpTODate.Value.ToString("MM/dd/yyyy"), "#companyid", cmbCompany.SelectedValue.ToString());
data from the above procedure is to be taken in to
for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
for (j = 0; j <= ds.Tables[0].Columns.Count - 1; j++)
{
data = ds.Tables[0].Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 1, j + 1] = data;
}
}
how do I do it?