I know the title is not appropriate,Im unable to put it in a single statement.,When the university results are published,the results of each student have to be retrieved individually,my task is to retrieve,a particular number of records,based on the textbox values in my aspx page(eg:1-10) and display them in an Excel sheet in a particular format(if you notice the university website,when a roll number is typed,for each student the results are displayed in a table format,with subject codes as first column,grades 2nd column,status as 3rd column,my task is to display them in an Excel sheet like:first row alone will be subject codes,remaining rows will display the grades of the particular number of students).I have created a webpage using asp.net-c#,im using xpath to retrieve the values from university website.I partially succeeded,still my output is not exact.I assumed that if the subject codes of the first record are alone displayed in the first row of the Excel sheet,then its easy to display the grades(2nd column)values of all the remaining numbers.
The code works fine,when the sequential numbers do not have arrear results,when there is an arrear result(which will not be orderedly displayed in the website,then the values are overwritten in the excel sheet,and finally extra subjects(arrear subject codes)are not displayed with their code in the 1st row(that is cause,the 1st roll number might have not had an arrear) now im unable to solve this issue,im having no idea how to retrieve the column values and correctly display,pls help.
//my code:
int rowno=2;
for(j=from;j
//retrieve the first column values of 1st roll number
var query = from table in doc.DocumentNode.SelectNodes("//table[2]").Cast<HtmlNode>()
from row in table.SelectNodes("tr[position()>2]").Cast<HtmlNode>()
from cell in row.SelectNodes("td[1]").Cast<HtmlNode>()
select new { CellText = cell.InnerText };
int cc = 1;
foreach (var cell in query)
{
int rwn = 1;
if (cc == 1)
{
myExcelWorksheet.get_Range("C" + rwn, misValue).Formula = cell.CellText;
}
if (cc == 2)
{
myExcelWorksheet.get_Range("D" + rwn, misValue).Formula = cell.CellText;
}
if (cc == 2)
{
myExcelWorksheet.get_Range("D" + rwn, misValue).Formula = cell.CellText;
}
if (cc == 3)
{
myExcelWorksheet.get_Range("E" + rwn, misValue).Formula = cell.CellText;
}
}
//retrieve the second column values of all roll number
var query1 = from table in doc.DocumentNode.SelectNodes("//table[2]").Cast<HtmlNode>()
from row in table.SelectNodes("tr[position()>2]").Cast<HtmlNode>()
from cell in row.SelectNodes("td[2]").Cast<HtmlNode>()
select new { CellText = cell.InnerText };
string ans = "";
int cc = 1;
foreach (var cell in query1)
{
if (cc == 1)
{
myExcelWorksheet.get_Range("C" + rowno, misValue).Formula = cell.CellText;
}
if (cc == 2)
{
myExcelWorksheet.get_Range("D" + rowno, misValue).Formula = cell.CellText;
}
if (cc == 3)
{
myExcelWorksheet.get_Range("E" + rowno, misValue).Formula = cell.CellText;
}}
Related
I am using MVC with C#, I am trying to import an excel sheet and validate those sheet and displays the excel data along with error message on one column in a table. If got any error my selection checkbox will not available, so the user cannot select and save the particular record. my page is actually working. What is my issue right now is, I wanna add Unique id validation. which means I have one Id column, where I don't want duplicate value. I added validation to check with my table and if found any same id, it returns an error message. but, if let say, user upload duplicate values on the excel sheet when they upload means, how to find out while uploading and how to prevent them from adding duplicate id records.
my sample coding below.
if (theFile != null && theFile.ContentLength > 0)
{
try
{
string[,] data = ExportUtil.GetData(theFile);
int rowValue = data.GetLength(0);
int colValue = data.GetLength(1);
Info _I;
ViewModel _VM;
for (int i = 0; i < rowValue; i++)
{
_VM= new ViewModel();
// _VM.Id = i;
_VM.Id = data[i, 0].ToString() != null ? data[i, 0].ToString() : "";
_VM.Description = data[i, 1].ToString() != null ? data[i, 1].ToString() : "";
if (string.IsNullOrWhiteSpace(_VM.Id))
{
_VM.Message = "Id cannot be empty" + System.Environment.NewLine;
}
_ID = TagInfo.Where(a => !string.IsNullOrEmpty(_VM.Id) && a.Id.ToUpper() == _VM.Id.ToUpper()).FirstOrDefault();
if (_ID != null)
{
_VM.Message += "Duplicate ID" + System.Environment.NewLine;
_ID =null;
}
if (string.IsNullOrEmpty(_VM.Description))
{
_VM.Message += "Description cannot be empty" + System.Environment.NewLine;
}
if (!string.IsNullOrEmpty(_VM.Message))
{
_VM.Message = string.Format("{0}{1}", "Row Number " + (i + 1) + " has " + Environment.NewLine, _VM.Message);
}
listvm.Add(_VM);
}
TempData["ID_DOWNLOAD"] = listvm;
}
}
_ID I declared with table name TableID _ID; above the try block. kindly help.
Add your unique ID to a list of int then find duplicate ids in that list by linq
var duplicateKeys = list.GroupBy(x => x)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
if duplicateKeys count is greater than 1 then you know there are some IDs duplicated.
How do I get the data of a specific row stored in a list box by clicking on the particular row ? So if i click on the row i can then access that particular row by index then store it to be used later on
int myMaxResultValue = (int)nud_MaxResults.Value;
int myMaxSuggestValue = (int)nud_MaxSuggestions.Value;
findResults = objBvSoapClient( txt_Search.Text, txt_LastId.Text, cb_SearchFor.Text, text_Country.Text, text_LanguagePreference.Text, myMaxResultValue, myMaxSuggestValue);
if (txt_Search.Text.Length <= 2)// if less than two letters are entered nothing is displayed on the list.
{
ls_Output.Items.Clear();// Clear LstBox
ls_Output.Items.Add(String.Format(allDetails, "ID", "Text", "Highlight", "Cursor", "Description", "Next"));
MessageBox.Show("Please enter more than 2 Chars!!");
}
else if (txt_Search.Text.Length >= 3)// if greater than or equal to 3 letters in the search box continue search.
{
// Get Results and store in given array.
foreach (var items in findResults)
{
//Loop through our collection of found results and change resulting value.
ls_Output.Items.Add(String.Format(allDetails, items.Id, items.Text.ToString(), items.Highlight, items.Cursor, items.Description, items.Next));
}
}
Then to retrieve the whole string i have placed this function within the indexChanged event,:
if (ls_Output.SelectedIndex != -1)
{
int itemAtPostion = ls_Output.SelectedIndex;
string nextStep = "Retrieve";
if (ls_Output.Items[itemAtPostion].ToString().Contains(nextStep))
{
string selItem = ls_Output.SelectedItem.ToString();
MessageBox.Show("You have selected the following address: " + selItem);
lst_Retreive.Text = ls_Output.SelectedItem.ToString();
}
}
You can either get the index of the item or the item itself.
To get the item you can use
string item = listBox.SelectedItem.ToString();
To get the index of the item you can use
int idx = listBox.SelectedIndex;
If your listbox supports multiselect you can use
var items = listBox.SelectedItems();
and
var idx = listBox.SelectedIndices;
I was looking at this in a completly different way, and i should have been thinking about DataTables. I wanted to only be clicking on individual cells and hence the reason I was getting the whole string back rather than individual feilds. Heres how i Solved it
DataTable ss = new DataTable();
ss.Columns.Add("ID");
ss.Columns.Add("Text");
ss.Columns.Add("Highlight");
ss.Columns.Add("Cursor");
ss.Columns.Add("Description");
ss.Columns.Add("Next");
DataRow row = ss.NewRow();
row["ID"] = findResults[0].Id;
row["Text"] = findResults[0].Text;
row["Highlight"] = findResults[0].Highlight;
row["Cursor"] = findResults[0].Cursor;
row["Description"] = findResults[0].Description;
row["Next"] = findResults[0].Next;
ss.Rows.Add(row);
foreach (DataRow Drow in ss.Rows)
{
int num = dataGridView1.Rows.Add();
dataGridView1.Rows[num].Cells[0].Value = Drow["id"].ToString();
dataGridView1.Rows[num].Cells[1].Value = Drow["Text"].ToString();
dataGridView1.Rows[num].Cells[2].Value = Drow["Highlight"].ToString();
dataGridView1.Rows[num].Cells[3].Value = Drow["Cursor"].ToString();
dataGridView1.Rows[num].Cells[4].Value = Drow["Description"].ToString();
dataGridView1.Rows[num].Cells[5].Value = Drow["Next"].ToString();
}
if (txt_Search.Text.Length <= 2)// if less than two letters are entered nothing is displayed on the list.
{
MessageBox.Show("Please enter more than 2 Chars!!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
findResults.Clear();
Had a look around and can't figure out how to do this.
I'm trying to query a datatable. I search the first column for the string value, and I need to return the integer that corresponds to it in the second column.
When I have that integer, I need to add 1 to the integer value and edit the row with the updated information.
public static string hashtag_counter(string message)
{
int hashcounter = 0;
DataTable hashtags = new DataTable();
DataRow row = new DataRow();
hashtags.Columns.Add("Hashtag", typeof(string));
hashtags.Columns.Add("Count", typeof(int));
string[] words = message.Split(' ');
foreach (string word in words)
{
if (word.StartsWith("#"))
{
if (hashtags.Columns.Contains(word))
{
DataRow[] selection = hashtags.Select("Hashtag == " + word);
}
}
else
{
row = hashtags.NewRow();
row["Hashtag"] = word;
row["Count"] = "1";
hashtags.Rows.Add(row);
}
I can't seem to find this anywhere, so any help would be appreciated
If I follow the requirements in your question, then your code should be like this.
.....
string[] words = message.Split(' ');
// Execute the loop ONLY for the required words (the ones that starts with #)
foreach (string word in words.Where(x => x.StartsWith("#")))
{
// Search if the table contains a row with the current word in the Hashtag column
DataRow[] selection = hashtags.Select("Hashtag = '" + word + "'");
if(selection.Length > 0)
{
// We have a row with that term. Increment the counter
// Notice that selection is an array of DataRows (albeit with just one element)
// so we need to select the first row [0], second column [1] for the value to update
int count = Convert.ToInt32(selection[0][1]) + 1;
selection[0][1] = count;
}
else
{
row = hashtags.NewRow();
row["Hashtag"] = word;
row["Count"] = "1";
hashtags.Rows.Add(row);
}
}
Notice that if you want to Select on a string field then your need to use quotes around the search term and you don't need to use == like in C#
I'm using LINQ to read and display result from 3 different csv files. The first file is CustomerInfo. Second is PackagePrice and third is HolidayTrans. I need to display result in the listbox based on startDate. My listBox only displays the first record. Here's my LINQ and for loop:
string[] myHolidayTransactionFile = File.ReadAllLines(#"c:\temp\HolidayTrans.csv");
//create an undefined variable myQuery1
//to read each line in the HolidayTrans file
var myQuery1 = from myline in myHolidayTransactionFile
let myField = myline.Split(',')
let id = myField[0]
let startDate = myField[1]
let numOfAdults = myField[2]
let numOfKids = myField[3]
where cid == id
orderby DateTime.Parse(startDate) descending
select new
{
cid,
startDate,
numOfAdults,
numOfKids
};
lstInfo.Items.Add(string.Format(formatLine, "Start Date", "End Date", "Adult Amt", "Kid Amt"));
foreach (var personRecord in myQuery1)
{
startTourDate = personRecord.startDate;
break;
}
//putting logic for getting break on a year every time before it changes
foreach (var personRecord in myQuery1)
{
//personRecord StartDate is equal to the Start tour Date which is selected
if (personRecord.startDate == startTourDate)
{
getNumofDaysTwinAdultPrSingleAdultPr(startTourDate, ref numOfDays, ref twoAdultPr, ref oneAdultPr);
//performing calculations for endate adult amt and kid amt
EndDate = Convert.ToDateTime(startTourDate).AddDays(numOfDays);
if (int.Parse(personRecord.numOfAdults) == 2)
{
adultAmt = twoAdultPr * 2;
}
if (int.Parse(personRecord.numOfAdults) == 1)
{
adultAmt = oneAdultPr;
}
if (int.Parse(personRecord.numOfKids) == 2)
{
kidsAmt = kidsPr * 2;
}
if (int.Parse(personRecord.numOfKids) == 1)
{
kidsAmt = kidsPr;
}
if (int.Parse(personRecord.numOfKids) == 0)
{
kidsAmt = 0;
}
// the subtotal is equal to subtotal + adultamt, it continues till the value stored in the starttourdate
//is same as that of ("transition .name") but as soon as start date changes this condition
//gets false and it get transfer to the else part
subtotalA = subtotalA + adultAmt;
subtotalK = subtotalK + kidsAmt;
//displaying output in a listbox
lstInfo.Items.Add(string.Format(formatLine1, startTourDate, EndDate, adultAmt, kidsAmt));
}
Please help. Thanks in advance
It might be because break; is the second command in your foreach statement. Therefore, only the first record is being printed because in your next foreach statement theres only one date that matches. You need to have only one foreach statement. In other words remove all this:
break;
}
//putting logic for getting break on a year every time before it changes
foreach (var personRecord in myQuery1)
{
So I have this datagridview that is linked to a Binding source that is binding to an underlying data table. The problem is I need to manual add rows to the datagridview.
This cannot be done while it is bound, so I have to work with the databinding.
If I add the rows to the underlying datatable, when the datatable is saved, the rows are duplicated, probably because the binding source somehow got a hold of a copy and inserted it also.
Adding it to the binding source is what I've been trying to do but it's not quite working.
Let me explain exactly what my setup is:
I have a database with two tables:
CashReceiptTable and CashReceiptItemsTable
CashReceiptItemsTable contains a FK to CashReceiptTable.
The form allows the users to add, and modify the two tables.
When the user enters a new cashreceipt, the cash receipt's id is -1, and the FK in cashReceiptitemstable is -1. When the database is saved, cashReceipt's id is updated, and I have to manually update cashreceiptitem's FK.
Here are the problems:
When I try to update the CashReceiptID (the FK) in more than one row in cashreceiteitems binding source, the first row is updated, and disappears (because it's filtered), and the other rows are removed, and I can no longer access them.
I have no idea why this is, I haven't updated the filter yet so they should still be there, but trying to access them throws RowNotInTableException.
I've managed a work around that copies the rows in the the binding source to an in memory array, deletes the first row in the binding source (all the other rows just vanish), update the row's FK and reinsert them into the binding source and save the table.
This works okay, but why do the rows disappear?
I also have one more slight problem. When the CashReceiptsTable is empty and I am adding a new row to it, if I add more than one row to the CashReceiptsItemTable it causes problems. When manually adding the items to the binding source, adding a new row pops to previous row off and pushes it onto the datatable. This hides it from my FK updating routine and it is lost, it also removes it from the DataGridView.
It only does that when I'm adding the first row to CashReceiptsTable. Why does it do this, and how can I fix it?
I'm posting my code that autopopulates it here:
private void autopopulate(decimal totalPayment) {
//remove old rows
for (int i = 0; i < tblCashReceiptsApplyToBindingSource.List.Count; i++) {
DataRowView viewRow = tblCashReceiptsApplyToBindingSource.List[i] as DataRowView;
RentalEaseDataSet.tblCashReceiptsApplyToRow row = viewRow.Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
if (row.CashReceiptsID == this.ReceiptID) {
tblCashReceiptsApplyToBindingSource.List.Remove(viewRow);
i--;
}
}
decimal payment = totalPayment;
//look for an exact amount
foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
decimal due = -1 * (Decimal)dueRow.Cells[Due.Index].Value;
if (due == payment) {
String charge = (String)dueRow.Cells[Description.Index].Value;
int chargeID = ManageCheckbooks.findTransactionID(charge);
tblCashReceiptsApplyToBindingSource.AddNew();
RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
row.CashReceiptsID = this.ReceiptID;
row.ApplyTo = chargeID;
row.Paid = payment; //convert to positive
payment = 0;
break;
}
}
//if the exact amount was found, payment will = 0, and this will do nothing, otherwise,
//divy out everything left over (which will be everything)
foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
String charge = (String)dueRow.Cells[Description.Index].Value;
decimal due = (Decimal)dueRow.Cells[Due.Index].Value;
if (due > 0 || payment <= 0) {
continue;
}
int chargeID = ManageCheckbooks.findTransactionID(charge);
payment += due; //due is negative, so this will subtract how much the user owes
tblCashReceiptsApplyToBindingSource.AddNew();
RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
row.CashReceiptsID = this.ReceiptID;
row.ApplyTo = chargeID;
if (payment >= 0) {
//payment is enough to cover this
row.Paid = due * -1; //convert to positive
} else {
//doesn't have enough money to conver this, can only cover partial, or none
row.Paid = (due - payment) * -1; //math:
//money remaining $50, current charge = $60
//payment = 50 + -60 = -10
//row["Paid"] = (-60 - -10) * -1
//row["Paid"] = (-60 + 10) * -1
//row["Paid"] = -50 * -1
//row["Paid"] = 50
}
if (payment <= 0) {
break; //don't conintue, no more money to distribute
}
}
isVirginRow = true;
}
And this is the function that saves it to the database:
protected override void saveToDatabase() {
tblCashReceiptsBindingSource.EndEdit();
isVirginRow = false;
RentalEaseDataSet.tblCashReceiptsRow[] rows = rentalEaseDataSet.tblCashReceipts.Select("ID < 0") as RentalEaseDataSet.tblCashReceiptsRow[];
int newID = -1;
if (rows.Count() > 0) {
tblCashReceiptsTableAdapter.Update(rows[0]);
newID = rows[0].ID;
}
tblCashReceiptsTableAdapter.Update(rentalEaseDataSet.tblCashReceipts);
//update table
/*foreach (RentalEaseDataSet.tblCashReceiptsApplyToRow row in rentalEaseDataSet.tblCashReceiptsApplyTo.Select("CashReceiptsID = -1")) {
row.CashReceiptsID = newID;
}*/
//update binding source
DataRowView[] applicationsOld = new DataRowView[tblCashReceiptsApplyToBindingSource.List.Count];
RentalEaseDataSet.tblCashReceiptsApplyToRow[] applicationsNew = new RentalEaseDataSet.tblCashReceiptsApplyToRow[tblCashReceiptsApplyToBindingSource.List.Count];
tblCashReceiptsApplyToBindingSource.List.CopyTo(applicationsOld, 0);
for (int i = 0; i < applicationsOld.Count(); i++) {
RentalEaseDataSet.tblCashReceiptsApplyToRow row = applicationsOld[i].Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
if (row.CashReceiptsID < 0) {
applicationsNew[i] = rentalEaseDataSet.tblCashReceiptsApplyTo.NewRow() as RentalEaseDataSet.tblCashReceiptsApplyToRow;
applicationsNew[i]["ID"] = row.ID;
applicationsNew[i]["CashReceiptsID"] = this.ReceiptID;
applicationsNew[i][2] = row[2];
applicationsNew[i][3] = row[3];
applicationsNew[i][4] = row[4];
//row.Delete();
}
}
for (int i = 0; i < applicationsOld.Count(); i++) {
try {
if ((int)applicationsOld[i].Row["ID"] < 0) {
applicationsOld[i].Row.Delete();
}
} catch (RowNotInTableException) {
break;
}
}
this.tblCashReceiptsApplyToBindingSource.Filter = "CashReceiptsID = " + this.ReceiptID;
foreach (DataRow newRow in applicationsNew) {
if (newRow == null) {
break;
}
tblCashReceiptsApplyToBindingSource.AddNew();
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[0] = newRow[0];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[1] = newRow[1];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[2] = newRow[2];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[3] = newRow[3];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[4] = newRow[4];
}
tblCashReceiptsApplyToBindingSource.EndEdit();
checkForBadRows();
tblCashReceiptsApplyToTableAdapter.Update(rentalEaseDataSet.tblCashReceiptsApplyTo);
tblCashReceiptsApplyToTableAdapter.Fill(rentalEaseDataSet.tblCashReceiptsApplyTo);
}
You might want to try adding rows to the DataGridView. Since you are binding to it, the DataGridView becomes your 'access point'.
I've got several applications that bind to DataGridView and for most circumstances when I add a row I do so through the DataGridView. It already has properties/methods/events that let you add with relative ease.
If you need some more information I can update.