For some reason, my code doesn't seem to reach the last few lines.
I've added the stop point and the return point in the code.
I don't see anything wrong with the data source I use on that row whenever I check it out in debug.
The code seems to set the value there and jumps back to the top of the foreach loop.
foreach (DataGridViewRow row in dataGridView1.Rows) {
//We check if the user has already filled in some info
return point if (row.Cells[7].Value != null && row.Cells[6].Value != null && !askedTheUser)
{
//trigger for message if you want to replace them
Message m = new Message("There is already info present in the category and or size dropdown. Would you like to overwrite this?", "Overwrite", "YESNO");
if (m.Awnser) {
overwrite = true;
}
askedTheUser = true;
}
DataGridViewComboBoxCell cat = (DataGridViewComboBoxCell)row.Cells[6];
string toMatch = row.Cells[3].Value.ToString();
//Now we will start matching
//First we try to match with the package ( if that is filled in )
if (row.Cells[5].Value != null && (string)row.Cells[5].Value != "") {
toMatch = row.Cells[5].Value.ToString();
matchWithPackage = true;
}
Regex re = new Regex(#"([a-zA-Z]+)(\d+)");
Match result = re.Match(toMatch);
string alphaPart = result.Groups[1].Value;
string numberPart = result.Groups[2].Value;
Datagridview dgv = new Datagridview();
if (numberPart.Length < 4) {
numberPart = numberPart.PadLeft(4, '0');
}
#if DEBUG
Console.WriteLine(numberPart);
#endif
//Matching the category
if (CHIP != null && CHIP.Contains(alphaPart))
{
cat.Value = "CHIP";
}
else if (SOJ != null && SOJ.Contains(alphaPart))
{
cat.Value = "SOJ";
}
else if (PLCC != null && PLCC.Contains(alphaPart))
{
cat.Value = "PLCC";
}
else if (QFP != null && QFP.Contains(alphaPart))
{
cat.Value = "QFP";
}
else if (SOP != null && SOP.Contains(alphaPart))
{
cat.Value = "SOP";
}
else {
if (cat.Value != "") {
cat.Value = "";
}
cat.FlatStyle = FlatStyle.Flat;
cat.Style.BackColor = Color.DarkRed;
continue;
}
//Setting the matched color
cat.FlatStyle = FlatStyle.Flat;
cat.Style.BackColor = Color.SpringGreen;
//Adding the dropdownlist to the size cb
(row.Cells[7] as DataGridViewComboBoxCell).DataSource = dgv.AddSeconderyCombobox(dataGridView1, row.Cells[6].Value.ToString());
if (!matchWithPackage) {
continue;
}
//Matching the size
Stop Point List<string> sizeList = (List<string>)(row.Cells[7] as DataGridViewComboBoxCell).DataSource;
Doesn't reach this and beyond List<string> matchedList = sizeList.FindAll(stringToCheck => stringToCheck.Contains(numberPart));
if (matchedList.Count > 0) {
(row.Cells[7] as DataGridViewComboBoxCell).DataSource = matchedList;
}
}
So i fixt my own problem and i'm going to awnser my own question i case somebody comes across a similar problem.
if (sizeList != null) {
List<string> matchedList = sizeList.FindAll(stringToCheck => stringToCheck.Contains(numberPart));
if (matchedList.Count > 0)
{
(row.Cells[7] as DataGridViewComboBoxCell).DataSource = matchedList;
}
}
After adding the few last lines in an extra check that needed to be done I noticed that the code was being executed, but the matchedlist.count was always 0.
So what was happening is that the code after that was redundant as the matchList was 0 and the debugger just skipped jumping to these lines ( a bit confusing if you ask me ).
Related
I have a datatable which fetches some records. So there is one column name as UPDATED_STATUS. In that column either Pre Hoto or Post Hoto value will come.
So what I want is, Either any one of those values should be their in that column then only the it should move ahead otherwise it should prompt alert as
Either Pre Hoto or Post Hoto can be their
Below is sample image for reference
Below is the code for getting the datatable with the UPDATED_STATUS column
if (strFlag == "")
{
dtStatus = GET_STATUS_FROM_SAPID_FOR_HOTO(dtExcelRows.Rows[i]["Current SAPID"].ToString());
if (dtStatus == null && dtStatus.Rows.Count < 0)
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
}
else
{
dtExcelRows.Rows[i]["UPDATED_STATUS"] = dtStatus.Rows[0][1].ToString();
dtExcelRows.AcceptChanges();
}
}
Your current check (if (dtStatus == null && dtStatus.Rows.Count < 0)) is wrong:
when dtStatus is null, you continue checking dtStatus.Rows, which throws a nullref exception (you just found out that it was null);
Rows.Count is never less than zero.
Try if (dtStatus == null || dtStatus.Rows.Count == 0) to check whether there is no status at all (it is null) or no status rows (count is zero). The || will prevent checking for dtStatus.Rows when it was found that dtStatus is null.
&& means that both sides must be true at the same time.
|| means that at least of the sides must be true (both true is also fine).
Both don't evaluate the second test when the first already decided the outcome (false && whatever is always false, true || whatever is always true)
Are you looking for like this !
foreach (DataRow row in dtStatus.Rows)
{
if (string.IsNullOrEmpty(Convert.ToString(row["UPDATED_STATUS"])) ||
(Convert.ToString(row["UPDATED_STATUS"]).ToLower() != "pre hoto" &&
Convert.ToString(row["UPDATED_STATUS"]).ToLower() != "post hoto"))
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
break;
}
else { }
}
I have got a way to get this done.. Here I go
if (strFlag == "")
{
dtStatus = GET_STATUS_FROM_SAPID_FOR_HOTO(dtExcelRows.Rows[i]["Current SAPID"].ToString());
if (dtStatus == null && dtStatus.Rows.Count < 0)
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
}
else
{
dtExcelRows.Rows[i]["UPDATED_STATUS"] = dtStatus.Rows[0][1].ToString();
dtExcelRows.AcceptChanges();
}
}
}
DataTable dtGetHotoPre = null;
var rows = dtExcelRows.AsEnumerable().Where(x => x.Field<string>("UPDATED_STATUS") == "PRE HOTO");
if (rows.Any())
{
dtGetHotoPre = rows.CopyToDataTable();
}
DataTable dtGetHotoPost = null;
var rowsPost = dtExcelRows.AsEnumerable().Where(x => x.Field<string>("UPDATED_STATUS") == "POST HOTO");
if (rowsPost.Any())
{
dtGetHotoPost = rowsPost.CopyToDataTable();
}
string strFlagStatus = "";
if (dtGetHotoPre != null)
{
if (dtGetHotoPost != null)
{
strFlagStatus = "No Process";
}
else
{
strFlagStatus = "Process";
grdDvHoto.DataSource = dtGetHotoPost;
}
}
else
{
if (dtGetHotoPost != null)
{
strFlagStatus = "Process";
grdDvHoto.DataSource = dtGetHotoPre;
}
else
{
strFlagStatus = "No Process";
}
}
// if(dtGetHotoPre != null && dtGetHotoPost != null)
if (strFlagStatus == "No Process")
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('The sites contains both Pre and Post Hoto Status, so it cannot be uploaded');", true);
}
else
{
// will move ahead.
grdDvHoto.DataBind();
}
I have group of conditions like
foreach
{
Condition a
condition b
}
So I am validating the values based on conditions.I am facing the problem: for example I have list of items like {1,2,3,4}. So I have a condition like if item 1 is fail then item 2,3,4 should be fail.
if item 2 is fail then item 3,4 should be fail and so on.
I am trying in below code.
foreach (SagaData item in lstPrm)
{
PriceDetail prevPrice = null;
PriceDetail currentPrice = null;
PriceDetail nextPrice = null;
bool bHasError = false;
int iPriceMasterId = 0;
int iPriceTypeId = 0;
string sMprCurrencyType = null;
string sPublisherCurrencyType = null;
int? iExpirationCalendarId = 0;
string sPRMMessage = string.Empty;
//a) If Change Indicator = C or A and Price = 0.00: Cannot change price value to zero.
if ((item.ChangeIndicator == 'C' || item.ChangeIndicator == 'A') && item.PostingPrice == 0)
{
bHasError = true;
sPRMMessage = "FAILURECannot change price value to zero";
}
//b) If Change Indicator = D and Price > 0.00: Invalid deactivation.
if ((item.ChangeIndicator == 'D') && (item.PostingPrice > 0) && (!bHasError))
{
bHasError = true;
sPRMMessage = "FAILUREInvalid deactivation";
}
so i have if condition a fail for item 1 then how should i keep maintain the error for next iteration.
Thanks for the help. if you want more info plz let me know.
You can go through your Collection with a simple for loop and use an ErrorArray:
bool[] bHasError = new bool[lstPrm.Count];
for (int i = 0; i < lstPrm.Count; i++)
{
...
bHasError[i] = true;
...
}
or you can define bHasError BEFORE the foreach if one error is enough for you to consider.
I have a class in my app that is not transforming my XML data as expected.
XML Data
Below is an excerpt of the XML. The file size can be between 2 GB and 3 GB, and the data is a representation of Mutual Funds. Each Fund usually has managers associated with it, but it's possible that there are none listed. A Fund in the data can have multiple ManagerDetail nodes or can have no ManagerDetail nodes. Each manager can have multiple CollegeEducation nodes or no CollegeEducation nodes.
<MutualFund>
<ManagerList>
<ManagerDetail>
<ManagerRole>M</ManagerRole>
<ManagerId>7394</ManagerId>
<ManagerTenure>3.67</ManagerTenure>
<StartDate>2011-09-30</StartDate>
<OwnershipLevel>6</OwnershipLevel>
<GivenName>Stephen</GivenName>
<MiddleName>M.</MiddleName>
<FamilyName>Kane</FamilyName>
<Gender>M</Gender>
<Certifications>
<CertificationName>CFA</CertificationName>
</Certifications>
<CollegeEducations>
<CollegeEducation>
<School>University of Chicago</School>
<Year>1990</Year>
<Degree>M.B.A.</Degree>
</CollegeEducation>
<CollegeEducation>
<School>University of California - Berkeley</School>
<Year>1985</Year>
<Degree>B.S.</Degree>
<Major>Business</Major>
</CollegeEducation>
</CollegeEducations>
</ManagerDetail>
</ManagerList>
</MutualFund>
C# Class
I've created a class that is called within a BackgroundWorker instance in another form. This class places the above data into the following table:
public static DataTable dtManagersEducation = new DataTable();
dtManagersEducation.Columns.Add("ManagerId");
dtManagersEducation.Columns.Add("Institution");
dtManagersEducation.Columns.Add("DegreeType");
dtManagersEducation.Columns.Add("Emphasis");
dtManagersEducation.Columns.Add("Year");
The method that places the XML data is set up like this. Basically, I have certain points where DataRows are created and completed, and certain XML data is to be placed into the available row as the data is read.
public static void Read(MainForm mf, XmlReader xml)
{
mainForm = mf;
xmlReader = xml;
while (xmlReader.Read() && mainForm.continueProcess)
{
if (xmlReader.Name == "CollegeEducation")
{
if (nodeIsElement())
{
drManagersEducation = dtManagersEducation.NewRow();
drManagersEducation["ManagerId"] = currentManager.morningstarManagerId;
}
else if (nodeIsEndElement())
{
dtManagersEducation.Rows.Add(drManagersEducation);
drManagersEducation = null;
}
}
else if (xmlReader.Name == "School")
{
if (nodeIsElement() && drManagersEducation != null)
{
string value = xmlReader.ReadElementContentAsString();
drManagersEducation["Institution"] = value;
}
}
else if (xmlReader.Name == "Year")
{
if (nodeIsElement() && drManagersEducation != null)
{
string value = xmlReader.ReadElementContentAsString();
drManagersEducation["Year"] = value;
}
}
else if (xmlReader.Name == "Degree")
{
if (nodeIsElement() && drManagersEducation != null)
{
string value = xmlReader.ReadElementContentAsString();
drManagersEducation["DegreeType"] = value;
}
}
else if (xmlReader.Name == "Major")
{
if (nodeIsElement() && drManagersEducation != null)
{
string value = xmlReader.ReadElementContentAsString();
drManagersEducation["Emphasis"] = value;
}
}
}
}
private static bool nodeIsElement()
{
return xmlReader.NodeType == XmlNodeType.Element;
}
private static bool nodeIsEndElement()
{
return xmlReader.NodeType == XmlNodeType.EndElement;
}
The result ends up with no data in the Emphasis or Year columns, which as you can see above, there are instances (plenty) that have data in these fields.
ManagerId Institution DegreeType Emphasis Year
5807 Yale University M.S.
9336 Yale University
7227 Yale University M.S.
Would you all happen to have some insight into what is going on?
Thanks
Edit: Answer
My sample XML data listed above has indented spaces, but the actual data that I was running through the XmlReader did not. As dbc has shown below, adding a variable bool readNext fixed my issues. As I understand it, if readNext is set to false when ReadElementContentAsString() is called, the XmlReader will not call Read() since my while loop condition now contains (!readNext || xmlReader.Read()). This prevents the two methods ReadElementContentAsString() and Read() to be called right after another, and thus, it will not skip over data.
Thanks to dbc!
The problem you are seeing is that the method XmlReader.ReadElementContentAsString moves the reader past the end element tag. If you then do xmlReader.Read() unconditionally right afterwards, the node immediately after the end element tag will be skipped. In the XML shown in your question, the node immediately after your end element tags is whitespace, so the bug isn't reproducible with your question. But if I strip the indentation (and hopefully your 2+GB XML file has no indentation), the bug becomes reproducible.
Also, in your question, I don't see where you actually read the <ManagerId>7394</ManagerId> tag. Instead you just take it from currentManager.morningstarManagerId (an undefined global variable). I reckon that's a typo in your question, and in your actual code you read this somewhere.
Here's a version of your method that fixes these problems and can be compiled and tested standalone:
public static DataTable Read(XmlReader xmlReader, Func<bool> continueProcess)
{
DataTable dtManagersEducation = new DataTable();
dtManagersEducation.TableName = "ManagersEducation";
dtManagersEducation.Columns.Add("ManagerId");
dtManagersEducation.Columns.Add("Institution");
dtManagersEducation.Columns.Add("DegreeType");
dtManagersEducation.Columns.Add("Emphasis");
dtManagersEducation.Columns.Add("Year");
bool inManagerDetail = false;
string managerId = null;
DataRow drManagersEducation = null;
bool readNext = true;
while ((!readNext || xmlReader.Read()) && continueProcess())
{
readNext = true;
if (xmlReader.NodeType == XmlNodeType.Element)
{
if (!xmlReader.IsEmptyElement)
{
if (xmlReader.Name == "ManagerDetail")
{
inManagerDetail = true;
}
else if (xmlReader.Name == "ManagerId")
{
var value = xmlReader.ReadElementContentAsString();
readNext = false;
if (inManagerDetail)
managerId = value;
}
else if (xmlReader.Name == "School")
{
var value = xmlReader.ReadElementContentAsString();
readNext = false;
if (drManagersEducation != null)
drManagersEducation["Institution"] = value;
}
else if (xmlReader.Name == "Year")
{
var value = xmlReader.ReadElementContentAsString();
readNext = false;
if (drManagersEducation != null)
drManagersEducation["Year"] = value;
}
else if (xmlReader.Name == "Degree")
{
var value = xmlReader.ReadElementContentAsString();
readNext = false;
if (drManagersEducation != null)
drManagersEducation["DegreeType"] = value;
}
else if (xmlReader.Name == "Major")
{
var value = xmlReader.ReadElementContentAsString();
readNext = false;
if (drManagersEducation != null)
drManagersEducation["Emphasis"] = value;
}
else if (xmlReader.Name == "CollegeEducation")
{
if (managerId != null)
{
drManagersEducation = dtManagersEducation.NewRow();
drManagersEducation["ManagerId"] = managerId;
}
}
}
}
else if (xmlReader.NodeType == XmlNodeType.EndElement)
{
if (xmlReader.Name == "ManagerDetail")
{
inManagerDetail = false;
managerId = null;
}
else if (xmlReader.Name == "CollegeEducation")
{
if (drManagersEducation != null)
dtManagersEducation.Rows.Add(drManagersEducation);
drManagersEducation = null;
}
}
}
return dtManagersEducation;
}
The code below contains a foreach loop that loops through a list of string collection which contains XML. While enumerating through the collection, it reads the question and answer elements and adds them to the list collection. I need to ensure that no repeated question is added to the list collection.
The code below questionnaire.QuestionAnswers.Add(fataQuestionsAnswers) adds the elements to the list collection. The problem that I am facing is that the repeated questions are getting added to the list. I tried to put the following condition that is:
if (questionnaire.QuestionAnswers.Find(a => a.Question != fataQuestionsAnswers.Question) == null)
but that doesn't seem to work.
var fataQuestionnaireData = DbAccess.GetFatcaQuestionnaire(contactId);
if (fataQuestionnaireData != null)
{
var questionnaire = new FatcaQuestionnaire();
foreach (var fatcaQuestionnaire in fataQuestionnaireData)
{
//var QData = GetObjectFromStream<FatcaQuestionnaire>fataQuestionnaireData);
//FatcaQuestionnaire.Deserialize(fataQuestionnaireData);
XDocument doc = XDocument.Parse(fatcaQuestionnaire.ToString(CultureInfo.InvariantCulture));
// w.WriteLine("The value of doc" + doc);
doc.Descendants("QuestionAnswer").ToList().ForEach(questionAnswer =>
{
var fataQuestionsAnswers = new QuestionAnswers();
{
//var questionAnswer = qa.Element("QuestionAnswer");
var questionElement = questionAnswer.Element("Question");
if (questionElement != null )
fataQuestionsAnswers.Question = questionElement.Value;
//if (questionElement != null)
// w.WriteLine("The value of questionElement" + questionElement.Value);
var answerElement = questionAnswer.Element("Answer");
if (answerElement != null)
fataQuestionsAnswers.Answer = answerElement.Value;
//if (answerElement != null)
// w.WriteLine("The value of answerElement" + answerElement.Value);
var sqa = questionAnswer.Element("SubQuestionAnswer");
if (sqa != null)
{
var subQuestionElement = sqa.Element("Question");
if (subQuestionElement != null)
fataQuestionsAnswers.SubQuestionAnswer.Question = subQuestionElement.Value;
//if (subQuestionElement != null)
// w.WriteLine("The value of answerElement" + subQuestionElement.Value);
var subAnswerElement = sqa.Element("Answer");
if (subAnswerElement != null)
fataQuestionsAnswers.SubQuestionAnswer.Answer = subAnswerElement.Value;
//if (subQuestionElement != null)
// w.WriteLine("The value of answerElement" + subQuestionElement.Value);
}
if (questionnaire.QuestionAnswers.Find(a => a.Question != fataQuestionsAnswers.Question) == null)
questionnaire.QuestionAnswers.Add(fataQuestionsAnswers);
//fatcaQuestionsList.Add(fataQuestionsAnswers);
}
fatca.Questionnaire.Add(fataQuestionsAnswers);
});
}
}
You have your condition wrong, you are looking for questionanswers where the question does not match, you should be looking where they do match and checking that the result is null. (switch the != with ==)
It should be
if (questionnaire.QuestionAnswers.Find(a => a.Question == fataQuestionsAnswers.Question) == null)
However I would change it to Any() as it is a bit nearer and easier to read, it returns a true if one of the items in your list matches the condition that you specify.
if(!questionnaire.QuestionAnswers.Any(a => a.Question == fataQuestionAnswers.Question)) {
questionnaire.QuestionAnswers.Add(fataQuestionsAnswers);
}
Use Any instead
if(!questionnaire.QuestionAnswers.Any(a => a.Question == fataQuestionsAnswers.Question))
{
questionnaire.QuestionAnswers.Add(fataQuestionsAnswers);
}
Is it possible there's trailing spaces / casing differences?
if(!questionnaire.QuestionAnswers.Any(a => a.Question.Trim().Equals(fataQuestionsAnswers.Question.Trim(), StringComparison.OrdinalIgnoreCase)))
{
questionnaire.QuestionAnswers.Add(fataQuestionsAnswers);
}
So what my problem is and i have looked on the internet for this but really cannot find out how to do it.
I want to use my combo box which is populated with items from a notepad. i want the combo box to search through the notepad when an items from the combo box is selected and when it gets a match i want it to return the line number(ID).
This is what i thought would work, but it doesn't full work.
int items = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt").Count();
string line;
int thisnum;
if (cboItemPick.SelectedIndex != -1)
{
if (cboItemPick.SelectedItem != null)
{
for (int i = 0; i <items;)
{
items = i;
line = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt").ElementAt(items);
if (line == cboItemPick.Text)
{
MessageBox.Show("Boom");
break;
}
else
{
i++;
}
}
}
}
First of all, your code will have very bad performances. Please refer to this reviewed example:
if( cboItemPick.SelectedItem != null) {
var filepath = #"C:\Users\PC\Documents\File\IDs.txt";
var lines = File.ReadLines(filepath);
var keyword = cboItemPIck.SelectedItem as String;
for(var i = 0; i < lines.length; i++) {
var line = lines[i];
if( string.Compare(line, keyword) == 0) {
// Good, you have a match!
MessageBox.Show(string.Format("Item found at line: {0}", i));
break;
}
}
}
I hope this can help you.
You can try this:
var lines = File.ReadLines(#"C:\Users\PC\Documents\File\IDs.txt");
var result = lines.Select((i, index) => new { Value = i, Index = index }).ToList();
//Check if cboItemPick.SelectedItem is valid and set it to comboboxValue
var lineNumber = result.First(i => i.Value == comboboxValue).Select(i => i.Index);