I'm trying to write a custom query generator for a small database that I'm making, but the comma that should appear in between all the entries to the string aren't appearing only the one at the end is.
private void BTN_advancedSearch_Click(object sender, EventArgs e)
{
// Creates the variable part of the custom query
string customwhereclause = "";
if (CHK_enableGameName.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Game.GameName LIKE '%" + TXT_addGame.Text + "%'";
}
if (CHK_enableGenreName.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Genre.GenreID =" + genreID + "";
}
if (CHK_enableConsoleName.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Console.ConsoleID =" + consoleID + "";
}
if (CHK_enablePlayers.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Game.Players >=" + NUD_players.Value + "";
}
if (CHK_enableDisc.Checked == true)
{
if (CHK_discOwned.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Game.Disc ='" + "yes" + "'";
}
else
{
Connectqry(customwhereclause);
customwhereclause += "Game.Disc ='" + "no" + "'";
}
}
if (CHK_enableCompleted.Checked == true)
{
if (CHK_completed.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause += "Game.Completed ='" + "yes" + "'";
}
else
{
Connectqry(customwhereclause);
customwhereclause += "Game.Completed ='" + "no" + "'";
}
}
//varible query code being passed back to search form.
frm_search.Cstmqry = customwhereclause;
//close the form and reopen the other one.
this.Close();
frm_search.Show();
}
private void Connectqry(string s)
{
if (s == "")
{
Console.WriteLine("the query is blank");
}
else
{
s = s + " , ";
Console.WriteLine(s);
}
}
the output is currently this:
the query is blank
Game.GameName LIKE '%name%' ,
Game.GameName LIKE '%name%'Genre.GenreID =0 ,
Game.GameName LIKE '%name%'Genre.GenreID =0Console.ConsoleID =0 ,
Game.GameName LIKE '%name%'Genre.GenreID =0Console.ConsoleID =0Game.Players >=1 ,
Game.GameName LIKE '%name%'Genre.GenreID =0Console.ConsoleID =0Game.Players >=1Game.Disc ='no' ,
I'm not sure why it's removing the commas that be in between the string.
You should add the code:
if (!string.IsNullOrEmpty(customwhereclause))
{
customwhereclause += " AND ";
}
customwhereclause += // Your condition
in all your conditions. It'll add an AND operator everywhere it's necessary.
Even better:
private static string computeCondition(string current, string newCondition)
{
if (!string.IsNullOrEmpty(current))
{
current += " AND ";
}
return current + newCondition;
}
private void BTN_advancedSearch_Click(object sender, EventArgs e)
{
// Creates the variable part of the custom query
string customwhereclause = "";
if (CHK_enableGameName.Checked == true)
{
Connectqry(customwhereclause);
customwhereclause = computeCondition(customwhereclause, "Game.GameName LIKE '%" + TXT_addGame.Text + "%'");
}
...
To avoid too big code dup
Or even better:
private void BTN_advancedSearch_Click(object sender, EventArgs e)
{
// Creates the variable part of the custom query
List<string> whereClausesList = new List<string>();
if (CHK_enableGameName.Checked == true)
{
Connectqry(customwhereclause);
whereClausesList.Add("Game.GameName LIKE '%" + TXT_addGame.Text + "%'");
}
...
string.Join(" AND ", whereClausesList);
as suggested by Rob
Your code is not working because string is immuteable. When you do string concatenation like s = s + " , "; this is not updating the object that s references. It's creating a new string and assigning the reference to s. And because you don't pass s as a ref you are only updating a local copy of the reference and not the original. The correct way to fix that is to return the new string and assign it.
private string Connectqry(string s)
{
if (s == "")
{
Console.WriteLine("the query is blank");
}
else
{
s = s + " , ";
Console.WriteLine(s);
}
return s;
}
and use it like
customwhereclause = Connectqry(customwhereclause);
As other's have mentioned you probably want to use "AND" instead of commas, and using string.Join or StringBuilder would likely be more efficient, but string being immutable and string concatenation creating a new string is why your current code doesn't do what you expect.
Related
I have a listbox in which my selected products are stored like this ...
'Product name'.padright(30) 'price' 'quantity'
listBox1.Items.Add(details.Name.PadRight(30) + details.Price.ToString() + " " + 1 );
but when I read price of a product it selects price and quantity
string currentPriceString = foundItem.Replace(details.Name.PadRight(30), "");
string quantityString = foundItem.Replace(details.Name.PadRight(33), "");
I only want price in currentPriceString and quantity in quantityString
here is complete code of this method
private void ProductButton_Click(object sender, EventArgs e)
{
Button ProductButton = sender as Button;
DataAccess dataAccess = new DataAccess();
int ProductID = Convert.ToInt32(ProductButton.Tag);
Details details = dataAccess.ReadProductDetails(ProductID);
decimal price = details.Price;
string foundItem = CheckProductInListBox(details.Name);
if (!String.IsNullOrEmpty(foundItem))
{
string currentPriceString = foundItem.Replace(details.Name.PadRight(30), "");
decimal currentPriceValue;
string quantityString = foundItem.Replace(details.Name.PadRight(33), "");
int quantiy;
MessageBox.Show(currentPriceString);
if (Decimal.TryParse(currentPriceString, out currentPriceValue))
{
quantiy = Convert.ToInt16(quantityString);
currentPriceValue += price;
quantiy++;
string newItem = details.Name.PadRight(30) + currentPriceValue.ToString() + quantiy.ToString();
int index = listBox1.Items.IndexOf(foundItem);
listBox1.Items[index] = newItem;
}
else
{
MessageBox.Show("Error");
}
}
else
{
listBox1.Items.Add(details.Name.PadRight(30) + details.Price.ToString() + " " + 1 );
}
}
private string CheckProductInListBox(string name)
{
foreach (string item in listBox1.Items)
{
if (item.Contains(name))
{
return item;
}
}
return String.Empty;
}
On replacing (foundItem.Replace(details.Name.PadRight(33), "");), you are just removing the name part from the string, so the price and quantity will be there for sure.
You should can try this code,
// suppose your found text is like this,
//foundItem = "AMIT".PadRight(30) + "200" + " " + "1";
You can get price and quantity separately like below:
string currentPriceQuantityString = foundItem.Replace(details.Name.PadRight(30), "");
//currentPriceQuantityString => "200 1"
string[] strArray = currentPriceQuantityString.Split();
string currentPriceString = strArray[0]; //currentPriceString => "200"
string quantityString = strArray[1]; //quantityString => "1"
Side note:
I guess your line:
listBox1.Items.Add(details.Name.PadRight(30) + details.Price.ToString() + " " + 1 );
..should be:
listBox1.Items.Add(details.Name.PadRight(30) + details.Price.ToString() + " " + "1" );
I need to copy multiple lines from text file(cisco config file): based on the below condition
if the line starts with interface copy from interface until '! '
my file is like :
!
access-list 1>
!
interface 1
ip address xx.xx.xx.xx
!
interface 2
ip address xx.xx.xx.xx
!
route 1
!
I try the below code :
var lines = File.ReadAllLines("C:\\My File2.txt");
foreach (var line1 in lines){
string firstWord = line1.Split(' ').First();
if ((firstWord == "access-list") && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (firstWord == "nat")
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
else if (firstWord == "interface")
{
var result = lines.Substring(line1.LastIndexOf('!') + 1);
TextBox3.Text = TextBox3.Text + "\r\n" + result;
}
but I get only one line as output
In case you want to keep your algorithm, this will work for you.
var lines = File.ReadAllLines("C:\\My File2.txt");
int i;
for (i = 0; i<lines.Length;i++)
{
var line1 = lines[i];
if (line1 == "!" || line1 == " ") continue;
if (line1.StartsWith("access-list")) && (!line1.Contains("remark ")))
{
TextBox1.Text = TextBox1.Text + "\r\n" + line1;
}
else if (line1.StartsWith("nat"))
{
TextBox2.Text = TextBox2.Text + "\r\n" + line1;
}
if (line1.StartsWith("interface"))
{
var str = line1;
while (!Equals(lines[i + 1], "!"))
{
str += lines[i + 1];
i++;
}
TextBox3.Text = TextBox3.Text + "\r\n" + str;
}
}
As per the file structure shown by you interface and ip address are on different lines. So you won't get it in same iteration of for loop. When you find that firstWord == "interface" you will need to set a flag that will tell you that next line is ip address and in next iteration check if that flag is true parse the current line as ip address and process it the way you want.
You should use "File.ReadAllText" instead of "File.ReadAllLines". "File.ReadAllText" returns a string with the complete text file text. After that, you can use the "String.Split" method to generate a string array.
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
Each index of "seperatedStrings" contains what you want.
UPDATE: Here is a code snippet, that can help:
var lines = File.ReadAllText("C:\\My File2.txt");
var seperatedStrings = lines.Split('!');
foreach (var oneString in seperatedStrings)
{
if (oneString.Contains("access-list"))
{
Console.WriteLine("Access-List: " + oneString);
}else if (oneString.Contains("nat"))
{
Console.WriteLine("Nat: " + oneString);
}else if (oneString.Contains("interface"))
{
Console.WriteLine("Interface: " + oneString);
}
}
This is the output of my code snippet:
I have a system which inserts some recopies into a table. The thing is when I click the update button repeatedly it insert duplicate records into my database. Please help me to fix it.
Note: When I try to use the data in the table, these duplicate data does crash the program.
private void button1_Click(object sender, EventArgs e)
{
(sender as Button).Enabled = false;
string ItemCode;
string ItemDesc;
string ItID;
string InItID;
decimal EntQty;
string EntUOM;
decimal TQty;
string NewRec;
bool Prt;
TQty = 0;
foreach (DataRow RowVal in dataSetMaster.ITEM_LINE)//
{
ItemCode = RowVal["InITCode"].ToString();
ItemDesc = RowVal["InITDesc"].ToString();
ItID = RowVal["ItemID"].ToString();
InItID = RowVal["Ingredient_ItemID"].ToString();
EntQty = Convert.ToDecimal(RowVal["Entry_Qty"].ToString());
TQty = Convert.ToDecimal(RowVal["T_Qty"].ToString());
NewRec = RowVal["NewRec"].ToString();
EntUOM = RowVal["Entry_UOM"].ToString();
Prt = Convert.ToBoolean(RowVal["Print"].ToString());
// MessageBox.Show("Items in the grid " + ItemCode + " == " + ItemDesc+" /"+Convert.ToString(EntQty)+" / "+Convert.ToString(TQty));
string ComdTextItemCode;
string ComdTextItemCodeInsert;
string Itcode;
Itcode = TextBoxCode.Text.Trim();
string X1;
X1 = "TEST";
sqlConnection1.Open();
if (NewRec == "True")
{
Guid newGuid;
Guid newGuid2;
if (Guid.TryParseExact(ItID, "D", out newGuid))
{
Console.WriteLine("Converted {0} to a Guid", ItID);
}
else
{
Console.WriteLine("Unable to convert {0} to a Guid",
ItID);
}
if (Guid.TryParseExact(InItID, "D", out newGuid2))
{
Console.WriteLine("Converted {0} to a Guid", InItID);
}
else
{
Console.WriteLine("Unable to convert {0} to a Guid",
InItID);
}
// MessageBox.Show("Test");
Guid ItmID = newGuid;
Guid IngItmID = newGuid2;
Guid GuItem_LineID = Guid.NewGuid();
//INSERT INTO ITEM_LINE (Item_LineID,ItemID,Ingredient_ItemID,Entry_Qty,Entry_UOM) VALUES (convert(uniqueidentifier, #Item_LineID),convert(uniqueidentifier, #ItemID),convert(uniqueidentifier, #Ingredient_ItemID),#Entry_Qty,#Entry_UOM)
ComdTextItemCodeInsert = "INSERT INTO ITEM_LINE (Item_LineID,ItemID,Ingredient_ItemID,Entry_Qty,Entry_UOM,[Print],T_Qty)" +
"VALUES (convert(uniqueidentifier, #Item_LineID),convert(uniqueidentifier, #ItemID),convert(uniqueidentifier, #Ingredient_ItemID),#Entry_Qty,#Entry_UOM,#Print,#T_Qty)";
sqlInsertItemDtl.CommandText = ComdTextItemCodeInsert;
sqlInsertItemDtl.Parameters["#Item_LineID"].Value = GuItem_LineID;
sqlInsertItemDtl.Parameters["#ItemID"].Value = ItmID; // roleID;
sqlInsertItemDtl.Parameters["#Ingredient_ItemID"].Value = IngItmID;
sqlInsertItemDtl.Parameters["#Entry_Qty"].Value = EntQty;
sqlInsertItemDtl.Parameters["#Entry_UOM"].Value = EntUOM;
sqlInsertItemDtl.Parameters["#Print"].Value = Prt;
sqlInsertItemDtl.Parameters["#T_Qty"].Value = TQty;
sqlDADetail.InsertCommand.ExecuteNonQuery();
}
else
{
ComdTextItemCode = "UPDATE ITEM_LINE SET ITEM_LINE.T_Qty=" + #TQty +",ITEM_LINE.[Print]='"+ #Prt +
"' WHERE ITEM_LINE.ItemID=convert(uniqueidentifier,'" + ItID + "') AND ITEM_LINE.Ingredient_ItemID=convert(uniqueidentifier,'" + InItID + "')";
sqlUpdateDtl.CommandText = ComdTextItemCode;
sqlDADetail.UpdateCommand.ExecuteNonQuery();
}
sqlConnection1.Close();
}
MessageBox.Show("Material Master updated.");
}
I'm working on an app that extracts content from a game page (example), displays it to the user in a textbox and if the user wishes to do so, he/she can save it as a .txt file or .xsl (excel spreadsheet format).
But the main problem I'm facing right now is that you have to manually change the code to "extract" data about another in-game unit.
If you open the link you'll see that I'm currently extracting the "Weapons", "Used", "Survived" and "Casualties" from the Defender side (as for now), but only 1 type of unit (more like only 1 row of that table) is being "extracted", I'm looking for a way to search "tr[1]/td[2]/span[1]" through "tr[45]/td[2]/span[1]" (even if the example page only goes until tr[16]), or maybe a way to automate it to search until it finds no data (nothing) then it would stop.
Sorry for any text mistakes, I'm not a native speaker
private void btnStart_Click(object sender, RoutedEventArgs e)
{
HtmlDocument brPage = new HtmlWeb().Load("http://us.desert-operations.com/world2/battleReport.php?code=f8d77b1328c8ce09ec398a78505fc465");
HtmlNodeCollection nodes = brPage.DocumentNode.SelectNodes("/html[1]/body[1]/div[1]/div[1]/div[3]/div[1]/div[1]/div[1]/div[2]/table[2]");
string result = "";
List<brContentSaver> ContentList = new List<brContentSaver>();
foreach (var item in nodes)
{
brContentSaver cL = new brContentSaver();
/* Here comes the junk handler, replaces all junk for nothing, essentially deleting it
I wish I knew a way to do this efficiently */
cL.Weapons = item.SelectSingleNode("tr[16]/td[1]").InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
cL.Used = item.SelectSingleNode("tr[16]/td[2]/span[1]").InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
cL.Survived = item.SelectSingleNode("tr[16]/td[3]").InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
if (cL.Survived == "0")
{
cL.Casualties = cL.Used;
} else
{
/* int Casualties = int.Parse(cL.Casualties);
* int Used = int.Parse(cL.Used);
* int Survived = int.Parse(cL.Survived);
* Casualties = Used - Survived; */
cL.Casualties = item.SelectSingleNode("tr[16]/td[4]").InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
}
ContentList.Add(cL);
}
foreach (var item in ContentList)
{
result += item.Weapons + " " + item.Used + " " + item.Survived + " " + item.Casualties + Environment.NewLine;
}
brContent.Text = result;
}
Sorry if this sounds silly, but I'm new to programming, especially in C#.
Edit 1: I noticed that "if (cL.Survived == "0")", I was just testing stuff some stuff way earlier and I forgot to change it, but hey, it works
Edit 2: If you are wondering I'm also using this:
public class brContentSaver
{
public string Weapons
{
get;
set;
}
public string Used
{
get;
set;
}
public string Survived
{
get;
set;
}
public string Casualties
{
get;
set;
}
}
I don't have much time to write this but hope it will help if you still need. I find Linq is more handy:
private static void Run()
{
HtmlDocument brPage = new HtmlWeb().Load("http://us.desert-operations.com/world2/battleReport.php?code=f8d77b1328c8ce09ec398a78505fc465");
var nodes = brPage.DocumentNode.Descendants("table").Where(_ => _.Attributes["class"] != null && _.Attributes["class"].Value != null && _.Attributes["class"].Value.Contains("battleReport"));
string result = "";
List<brContentSaver> ContentList = new List<brContentSaver>();
foreach (var item in nodes)
{
if (item.Descendants("th").Any(_ => _.InnerText.Equals("Weapons")))
{
//get all tr nodes except first one (header)
var trNodes = item.Descendants("tr").Skip(1);
foreach (var node in trNodes)
{
brContentSaver cL = new brContentSaver();
var tds = node.Descendants("td").ToArray();
/* Here comes the junk handler, replaces all junk for nothing, essentially deleting it
I wish I knew a way to do this efficiently */
cL.Weapons = tds[0].InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
cL.Used = tds[1].Descendants("span").FirstOrDefault()?.InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
if (string.IsNullOrEmpty(cL.Used))
{
cL.Used = tds[1].InnerText;
}
cL.Survived = tds[2].Descendants("span").FirstOrDefault()?.InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
if (string.IsNullOrEmpty(cL.Survived))
{
cL.Casualties = cL.Used;
}
else
{
/* int Casualties = int.Parse(cL.Casualties);
* int Used = int.Parse(cL.Used);
* int Survived = int.Parse(cL.Survived);
* Casualties = Used - Survived; */
cL.Casualties = tds[3].Descendants("span").FirstOrDefault()?.InnerText
.Replace(" * ", " ")
.Replace("  ; *  ;", " ");
if (string.IsNullOrEmpty(cL.Casualties))
{
cL.Casualties = tds[3].InnerText;
}
}
ContentList.Add(cL);
}
}
}
foreach (var item in ContentList)
{
result += item.Weapons + " " + item.Used + " " + item.Survived + " " + item.Casualties + Environment.NewLine;
}
var text = result;
}
I want to use textbox and checkboxlist to search data in gridview using asp.net c#. Using textbox can search the data. But for checkboxlist only can search the data when check only one checkbox. If check more than one checkbox, can't search the data. thanks a lot for helping.
the code:
c# code
protected void btnSearch_Click(object sender, EventArgs e)
{
if (cblDay.SelectedIndex != -1)
{
foreach (ListItem val in cblDay.Items)
{
if (val.Selected == true)
{
RptRateData.Day += val.Value + "";
}
}
}
RptRateData.RateAmount = txtRate.Text.Trim();
BindGrid();
}
code for class:
public string RateAmount { get; set; }
public string Day { get; set; }
internal DataSet GetRptRateSet()
{
DataSet tmpDS = new DataSet();
try
{
string strSQL = #"SELECT ComplexRateInfo.ComplexRateId,
ComplexRateDetailInfo.Day,
ComplexRateInfo.RateAmount
FROM ComplexRateInfo
LEFT JOIN ComplexRateDetailInfo ON ComplexRateInfo.ComplexRateId = ComplexRateDetailInfo.ComplexRateId ";
string whereSQL = " WHERE";
string orderBySQL = " order by Day ;";
int filterCount = 0; //to keep track of needed filter that are going to be used by the sql string
string[] sIndex = new string[2]; //to keep track of scalar variable needed by the sql, four string of sIndex because maximum filter available is 4
int indexCount = 0; //count to access sIndex members
//filter with or without day
if (_ds.Day != null && _ds.Day != "")
{
if (filterCount > 0) //query need additional filter
whereSQL = whereSQL + " AND ComplexRateDetailInfo.Day LIKE '{" + filterCount + "}'";
else //if this is the first filter
whereSQL = whereSQL + " ComplexRateDetailInfo.Day LIKE '{" + filterCount + "}'";
filterCount++;
sIndex[indexCount] = _ds.Day;
indexCount++;
}
//filter with or without rate amount
if (_ds.RateAmount != null && _ds.RateAmount != "")
{
if (filterCount > 0) //query need additional filter
whereSQL = whereSQL + " AND ComplexRateInfo.RateAmount LIKE '{" + filterCount + "}'";
else //if this is the first filter
whereSQL = whereSQL + " ComplexRateInfo.RateAmount LIKE '{" + filterCount + "}'";
filterCount++;
sIndex[indexCount] = _ds.RateAmount;
indexCount++;
}
//build complete query with no filter at all
if (filterCount == 0)
{
strSQL = strSQL + orderBySQL;
tmpDS = Db.GetDataSet(string.Format(strSQL));
}
//build complete query with 1 or more filter
else
{
strSQL = strSQL + whereSQL + orderBySQL;
tmpDS = Db.GetDataSet(string.Format(strSQL, sIndex));
}
}
catch (Exception ex)
{
throw ex;
}
return tmpDS;
}
There are two mistakes in your code.
Assigning values to RptRateData.Day from CheckBoxList.
Description: You assign selected values to object without using any separator. So For example if you have selected 1, 2, 4 days then as per your code, value of RptRateData.Day will be 124. Instead of that, it should be separated with comma as shown below:
var selectedDays = string.Empty;
foreach (ListItem val in cblDay.Items)
{
if (val.Selected == true)
{
selectedDays += "'" + val.Value + "',";
}
}
RptRateData.Day = selectedDays.TrimEnd(new char[] { ',' });
Now come to the second point which is in your SQL query which you make dynamically.
Description: In this query in WHERE clause you use Like operator for ComplexRateDetailInfo.Day. This will not work anymore. Instead of that you should use IN operator.
Note: Are you sure that your Like operator is working with curly braces ('{' and '}') and without '%' symbol ?