Reading multiple files with LINQ - 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)
{

Related

Trying to extract gridview cell content of a different form in a textbox using if conditions. Not working

This is a csv file, source for the gridview.
Child(5-12),400,800,1050,1450,2200
Adult(>12),550,1000,1500,2100,2700
Group of 5,3000,5000,8000,12500,25000
Group of 10,5000,8000,15000,22000,40000
I have stored the cell contents of the gridview(TicketRateView) in a list.
GlobalValues.UpdatedrateList = new List<Ticketpricerate>();
for (int i=0; i<TicketRateView.Rows.Count; i++)
{
Ticketpricerate rate = new Ticketpricerate();
rate.Ticket_Category = TicketRateView.Rows[i].Cells[0].Value.ToString();
rate.Rate_for_1hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[1].Value);
rate.Rate_for_2hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[2].Value);
rate.Rate_for_3hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[3].Value);
rate.Rate_for_4hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[4].Value);
rate.Rate_for_wholeday = Convert.ToInt32(TicketRateView.Rows[i].Cells[5].Value);
GlobalValues.UpdatedrateList.Add(rate);
}
In a different form, i have a textbox named staytime where i will get the visitors stay time in minutes. Based on that information, i want to show the cell value in another textbox pay_amount. Like if the visitors stay time is 1 hr, then show e.g 400$ from the cell.
and here is what i have tried, it doesnt show anything.
private void Pay_amount_Click(object sender, System.EventArgs e)
{
int timeofstay = Convert.ToInt32(visitorstaytime.Text);
foreach (Ticketpricerate rate in GlobalValues.UpdatedrateList)
{
if (timeofstay == 60)
{
pay_amount.Text = rate.Rate_for_1hr.ToString();
}
}
}
Seems you need to query against Ticket_Category and time of stay. For condensed version of your code, read data into your class then set to the DataGridView.
I used Child(5-12) but that needs to have logic to determine which category to select e.g. perhaps from a ComboBox.
ticketPriceRateList becomes GlobalValues.UpdatedrateList. Then the loading of the DatagridView is of course in a different place along with the code to get the rate.
var fileName = "SomeFile.txt";
int timeofstay = Convert.ToInt32(visitorstaytime.Text);
List<Ticketpricerate> ticketPriceRateList = (
from line in File.ReadAllLines(fileName)
where line.Length > 0
let Items = line.Split(',')
select new Ticketpricerate()
{
Ticket_Category = Items[0],
Rate_for_1hr = Convert.ToInt32(Items[1]),
Rate_for_2hr = Convert.ToInt32(Items[2]),
Rate_for_3hr = Convert.ToInt32(Items[3]),
Rate_for_4hr = Convert.ToInt32(Items[4]),
Rate_for_wholeday = Convert.ToInt32(Items[5]),
})
.ToList();
int price = 0;
if (timeofstay == 60)
{
price = ticketPriceRateList
.FirstOrDefault(x => x.Ticket_Category == "Child(5-12)")
.Rate_for_1hr;
} // more conditions
Console.WriteLine(price);

Writing a program in C# where depending on the Id (txtBxNumber) it will either update or create a new record in a text file and a Rich Text Box

fileName = txtBxFileNamePath.Text;
if (File.Exists(fileName))
{
if (txtBxDate.Text != null && txtBxNumber.Text != null && txtBxUnit.Text != null && txtBxUnitPrice.Text != null && txtBxShipTo.Text != null
&& txtBxOrdered.Text != null && richTxBxDesc.Text != null)
{
try
{
int higherThanZero = Int32.Parse(txtBxNumber.Text);
if (higherThanZero > 0)
{
using (StreamReader reader = File.OpenText(fileName))
{
string[] lines = File.ReadAllLines(fileName);
for (int i = 0; i < lines.Length - 1; i++)
{
string firstNum = lines[i].Substring(0, 2);
if (firstNum == txtBxNumber.Text)
{
string record = "hello ";
lines[i].Replace(lines[i], record);
}
else
{
int orderNum = Int32.Parse(txtBxOrdered.Text);
int unitPriceNum = Int32.Parse(txtBxUnitPrice.Text);
double tax = .13;
int taxInt = (int)tax;
int amount = orderNum * unitPriceNum;
string amountStr = amount.ToString();
int amountTotal = amount * taxInt;
string amountTotalStr = amountTotal.ToString();
amountList.Add(amountStr);
amountTotalList.Add(amountTotalStr);
string record = amountTotalStr.PadRight(30) + amountStr.PadRight(30);
richTxtBxRecord.Text += record + "\n";
using (StreamWriter write = new StreamWriter(fileName, true))
{
write.WriteLine(record + "\n");
write.Close();
}
}
}
}
}
else
{
richTxtBxError.Text += "Textbox Number must contain a digit higher than 0 ";
}
}
catch
{
richTxtBxError.Text += "Please make sure number text box is a digit";
}
}
else
{
richTxtBxError.Text += "please make sure that no text boxes are empty";
}
}
else
{
richTxtBxError.Text += "Please select a file that already exists";
}
I am having an issue where once i get past the try-catch statement "please make sure number is a digit, no code executes. I am trying to obtain the first few characters in a text file and match it with the users input. If the input is the same as what is already inserted in the text file, i update the whole record. If there is no match (non existent number) i write in a brand new record.
I can't quite follow your logic, but I tried. You should be able to take this code and do what you want (whatever it is).
I started by declaring some class level variables.
private DateTime _dateValue;
private int _numberValue;
private decimal _unitPrice;
private int _numberOrdered;
Then, since you have so many preconditions and so many text boxes, I factored out the validation and setting of these variables. It makes the logic (whatever it supposed to be) much easier to follow:
private bool ValidateUserEntry()
{
bool isError = false;
if (!File.Exists(txtBxFileNamePath.Text))
{
AddError("File Name must exist");
isError = true;
}
if (txtBxDate.Text == string.Empty || !DateTime.TryParse(txtBxDate.Text, out var _dateValue))
{
AddError("The date must be a valid date");
isError = true;
}
if (txtBxNumber.Text == string.Empty || !int.TryParse(txtBxNumber.Text, out _numberValue) ||
_numberValue <= 0)
{
AddError("You must enter a number greater than 0 for [Number]");
isError = true;
}
if (txtBxUnitPrice.Text == string.Empty || !decimal.TryParse(txtBxUnitPrice.Text, out _unitPrice) ||
_unitPrice <= 0.0m)
{
AddError("The unit price must be a positive decimal number");
isError = true;
}
if (txtBxShipTo.Text == string.Empty)
{
AddError("A ship to address is required");
isError = true;
}
if (txtBxOrdered.Text == string.Empty || !int.TryParse(txtBxOrdered.Text, out _numberOrdered) ||
_numberOrdered <= 0)
{
AddError("The Number ordered must be a number greater than 0");
isError = true;
}
if (richTxBxDesc.Text == string.Empty)
{
AddError("A description is required");
isError = true;
}
return !isError;
}
I also added two utility functions for managing the error list:
private void ClearError()
{
richTxtBxError.Text = string.Empty;
}
private void AddError(string errorMessage)
{
richTxtBxError.Text += (errorMessage + Environment.NewLine);
richTxtBxError.SelectionStart = richTxtBxError.Text.Length;
richTxtBxError.SelectionLength = 0;
}
Now comes the real code. Near as I can tell, you want to scan a text file. If the number in the first few character positions matches a number in your input, then you change the line to some constant text. Otherwise, you want to do a calculation and put the results of the calculation on the line of text.
My input file looks like this:
1 First
2 Second
3 Third
12 Twelth
13 Thirteenth
34 Thirty-fourth
and the code that I run looks like what's below. The logic makes no sense, but it was what I could discern from your code. Instead of trying to do things on the fly to a file (which never really turns out well unless you are really careful), I gather the output into a List<string>. Once I have all the output, I put it in a text box control and overwrite the file.
ClearError();
//check pre-conditions
if (!ValidateUserEntry())
{
return;
}
string[] lines;
using (StreamReader reader = File.OpenText(txtBxFileNamePath.Text))
{
lines = File.ReadAllLines(txtBxFileNamePath.Text);
}
List<string> newLines = new List<string>();
for (var lineIndex = 0; lineIndex < lines.Length; ++lineIndex)
{
var line = lines[lineIndex];
if (line.Length > 2 && int.TryParse(line.Substring(0, 2), out var linePrefixNumber) &&
linePrefixNumber == _numberValue)
{
newLines.Add("Bingo, hit the right record");
}
else
{
decimal tax = .13m;
var amount = _numberOrdered * _unitPrice;
var amountTotal = amount * (1m + tax);
//amountList.Add(amount.TosString());
//amountTotalList.Add(amountTotal.ToString());
var newRecord = $"{amountTotal,30:C}{amount,30:C}";
newLines.Add(newRecord); //every record but one will be the same, but, such is life
}
}
//at this point, the newLines list has what I want
//put it in the text box
richTxtBxRecord.Text = string.Join(Environment.NewLine, newLines);
//and write it out
using (StreamWriter write = new StreamWriter(txtBxFileNamePath.Text, append:false))
{
write.Write(richTxtBxRecord.Text);
write.Flush();
}
With inputs that look like:
Number: 12
Number Ordered: 3
Unit Price: 1.23
The output (oddly enough - but it's what I could figure from your code) looks like:
$4.17 $3.69
$4.17 $3.69
$4.17 $3.69
Bingo, hit the right record
$4.17 $3.69
$4.17 $3.69
You can see that the input line that had the 12 at the start gets switched for bingo. The rest get the same information. I'm sure that's not what you want. But, with this code, you should be able to get something that you'd like.
Also note that I treat all the currency values as decimal (not int or double). For the life of me, I have no idea what you were trying to do with the taxInt variable (it will always be zero the way you have coded it). Instead, I did a rational tax calculation.
All of the code below the catch block is inside an else block, so I wouldn't expect it to execute. If you want something to execute after the catch, remove it from the else block.

How do i get the data stored in a list box by clicking on the particular row?

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();

Summing up rows with the same row ID

I have a project and I am trying to sum up rows of the same ID together.
Like for example:
ID Quantity
1 5
1 7
2 10
2 18
1 8
So when I press a button, quantity under ID 1 will give me 20 and for ID 2, I will get 28.
But I faced an error specifying that "Object reference is not set to an instance of an object". Below are my codes:
id = int.Parse(row.Cells[0].Value.ToString());
This is the code that shows the error msg:
int id = 0;
int qty = 0;
List<QuantityPerID> qtyList = new List<QuantityPerID>();
QuantityPerID qtyObj;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
id = int.Parse(row.Cells[0].Value.ToString());
qty = int.Parse(row.Cells[1].Value.ToString());
qtyObj = new QuantityPerID();
bool ifexists = false;
if (qtyList != null && qtyList.Count() > 0)
{
if (qtyList.Where(q => q.ID == id).Count() > 0)
{
ifexists = true;
}
}
if (ifexists)
{
qtyObj = qtyList.Where(q => q.ID == id).First();
qtyObj.Quantity += qty;
}
else
{
qtyObj.ID = id;
qtyObj.Quantity = qty;
qtyList.Add(qtyObj);
}
}
I would like to ask also is there any other easier method to achieve the same results?
Are you sure that Cells[0] and Cells[1] are not empty? You are calling the ToString on it's Values. Check if the Value is null before the call to ToString
if( null != row.Cells[0].Value )
{
id = int.Parse(row.Cells[0].Value.ToString());
}
if(null != row.Cells[1].Value)
{
qty = int.Parse(row.Cells[1].Value.ToString());
}
Do you see an empty line at the end of the rows? Does the DataGridView.AllowUserToAddRows property set to true?
If so, then this is the issue. You are also reading the values of the empty line.
Instead of the foreach, you can do it with a for loop
// notice the Count - 1.
for(var index = 0; index < dataGridView1.Rows.Count - 1; ++index)
{
// your code here
}
Split this definition
id = int.Parse(row.Cells[0].Value.ToString());
into multiple parts to see what is generating your NullReferenceException (and possibly the Qty one too).
Or, at runtime, you could check the Cells' values using IntelliSense (if you hover above "Cells", or "row" it will show you their contents".

xpath retrieval using asp.net c#

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;
}}

Categories

Resources