Get first occurence of a char from a string - c#

First of all, I'd like to point out that the desired result is a char, not its position index (int).
I'm trying to give my users an option of choosing their desired date format and as such, I've created 2 comboBoxes: comboBox_DateFormatDivider where user chooses between dot, dash and a slash; and comboBox_DateFormat where user chooses date format. comboBox_DateFormat contains a List<string> as follows:
_dateFormatsList = new List<string>()
{
"d-M-yy (" + DateTime.Now.ToString("d-M-yy") + ")",
"dd-M-yy (" + DateTime.Now.ToString("dd-M-yy") + ")",
"d-MM-yy (" + DateTime.Now.ToString("d-MM-yy") + ")",
"dd-MM-yy (" + DateTime.Now.ToString("dd-MM-yy") + ")",
"d-M-yyyy (" + DateTime.Now.ToString("d-M-yyyy") + ")",
"dd-M-yyyy (" + DateTime.Now.ToString("dd-M-yyyy") + ")",
"d-MM-yyyy (" + DateTime.Now.ToString("d-MM-yyyy") + ")",
"dd-MM-yyyy (" + DateTime.Now.ToString("dd-MM-yyyy") + ")",
"yy-M-d (" + DateTime.Now.ToString("yy-M-d") + ")",
"yy-M-dd (" + DateTime.Now.ToString("yy-M-dd") + ")",
"yy-MM-d (" + DateTime.Now.ToString("yy-MM-d") + ")",
"yy-MM-dd (" + DateTime.Now.ToString("yy-MM-dd") + ")",
"yyyy-M-d (" + DateTime.Now.ToString("yyyy-M-d") + ")",
"yyyy-M-dd (" + DateTime.Now.ToString("yyyy-M-dd") + ")",
"yyyy-MM-d (" + DateTime.Now.ToString("yyyy-MM-d") + ")",
"yyyy-MM-dd (" + DateTime.Now.ToString("yyyy-MM-dd") + ")"
};
comboBox_DateFormat.DataSource = _dateFormatsList;
When user chooses different divider, it has to be reflected in the other comboBox, as such DateFormat is dependent on DateFormatDivider, so its contents have to be changed at runtime. And here's the code (and the question) for that:
private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < _dateFormatsList.Count; i++)
{
_dateFormatsList[i] = _dateFormatsList[i].Replace(_dateFormatsList[i].???.ToString(), comboBox_DateFormatDivider.SelectedText);
}
}
Chosen date format is later saved to database, so I guess I could also add another field where divider would be stored, but I'd prefer not to. As you can see, the code above contains ??? in it. So, the question is: how do I replace these question marks with code that will find me the divider it contains?

During those rare cases where you absolutely must do string searching, you can just do the following:
string[] separators = new string[] { "-", ".", "/" };
void DetectCurrentSeparator(string dbDateFormat)
{
for (int i = 0; i < separators.Length; i++)
{
if (dbDateFormat.IndexOf(separators[i]) >= 0)
{
// Assuming the above array corresponds with the order of the divider combobox
combobox_DateFormatDivider.SelectedIndex = i;
break;
}
}
}
Now this having been said, this method should only need to ever be used once during the life of your program - when the date format is first retrieved from the database. For the rest of the time, there is no reason to use any string searching at all for this. You already have the desired divider from your combo box, so instead of trying to figure out what the existing divider is, use a common temporary character and just replace that.
Initialize like so:
DateTime now = DateTime.Now;
_dateFormatsMasterList = new List<string>()
{
"d#M#yy (" + now.ToString("d#M#yy") + ")",
"dd#M#yy (" + now.ToString("dd#M#yy") + ")",
"d#MM#yy (" + now.ToString("d#MM#yy") + ")",
"dd#MM#yy (" + now.ToString("dd#MM#yy") + ")",
"d#M#yyyy (" + now.ToString("d#M#yyyy") + ")",
"dd#M#yyyy (" + now.ToString("dd#M#yyyy") + ")",
"d#MM#yyyy (" + now.ToString("d#MM#yyyy") + ")",
"dd#MM#yyyy (" + now.ToString("dd#MM#yyyy") + ")",
"yy#M#d (" + now.ToString("yy#M#d") + ")",
"yy#M#dd (" + now.ToString("yy#M#dd") + ")",
"yy#MM#d (" + now.ToString("yy#MM#d") + ")",
"yy#MM#dd (" + now.ToString("yy#MM#dd") + ")",
"yyyy#M#d (" + now.ToString("yyyy#M#d") + ")",
"yyyy#M#dd (" + now.ToString("yyyy#M#dd") + ")",
"yyyy#MM#d (" + now.ToString("yyyy#MM#d") + ")",
"yyyy#MM#dd (" + now.ToString("yyyy#MM#dd") + ")"
};
_dateFormatsList = new List<string>(_dateFormatsMasterList);
comboBox_DateFormat.DataSource = _dateFormatsList;
And your SelectionChanged event like so:
private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
for (int i = 0; i < _dateFormatsList.Count; i++)
{
_dateFormatsList[i] = _dateFormatsMasterList[i].Replace("#", comboBox_DateFormatDivider.SelectedText);
}
}

Assuming that number of dividers in the Date format are finite, I will do the following:
List<string> dividers = new List<string>{".","/","-"}
private void comboBox_DateFormatDivider_SelectedIndexChanged(object sender, EventArgs e)
{
string currentSeparator = string.Empty;
foreach(var s in dividers)
{
string pattern = #".*(?:\" + s + ").*";
if(Regex.IsMatch(_dateFormatsList[0],pattern))
{
currentSeparator = s;
break;
}
}
for (int i = 0; i < _dateFormatsList.Count; i++)
{
_dateFormatsList[i] = _dateFormatsList[i].Replace(currentSeparator, comboBox_DateFormatDivider.SelectedText);
}
}
Edit 1:
Explanation about regular expression:
Following are details:
".*(?:\.).*",
.* means anything which means 0 or more occurrence, of any character,
?: refers to pattern search matching starts and it expects the character being passed (here "."), (which is escaped, to avoid special treatment of special characters like ., *, ? etc) to be searched in all the data an it will return true on first occurrence or else false.
Edit 2:
To provide an example of the potential of Regular expressions, in the _dateFormatsList, you have multiple date formats, but all the solutions, just pick one value to figure out operator, what about the other values, what if there's data corruption and more than one separators exist, following code will take care of lot of such issues and can further be made strict by changing the pattern:
string pattern = #"^(?!\.\/)[\d]{1,4}[\-][\d]{1,2}[\-][\d]{1,4}$";
It represent all the date formats which contains separator - but not . or /, also there's a digit (\d) repetition, before a separator -, this pattern needs to be applied using Linq All operator as follows:
bool result = _dateFormatsList.All(data => Regex.IsMatch(data,pattern));
This is just to depict, the power of Regular expressions, which no other solution can help achieve, I think most people find Regex complex due to lack of understanding regarding pattern creation

first of all, i'd like to go with Abion47's advice to use a variable to store date and use it in the list.
and then you can do this
char x = _dateFormatsList[0][1];
for (int i = 0; i < _dateFormatsList.Count; i++)
{
_dateFormatsList[i] = _dateFormatsList[i].Replace(x, comboBox_DateFormatDivider.SelectedItem.ToString()[0]);
}

Related

Is there any way to filter C# DataView like this?

I am writing some code for filtering data in BindingSource in c#.
In DataTable, I have one column and data is something like this,
coding is very good
I want to filter data from string after every empty space like my example,
var ss = "coding is ery";
var s = ss.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var filter = ColumnName + " like \'%" + s[0] + "%\' ";
for (int i = 1; i < s.Length; i++)
{
filter = filter + "AND " + ColumnName + " like \'%" + s[i] + "%\' ";
}
BindingSource.Filter = filter;
The problem here is that I will get all the data (coding is very good). I don't want to get the data when word is not starting with the correct letter. Example,
coding is ery.
I want to be like
"coding very is" or "is very coding".
I want correct starting letters but position of word doesn't matter.
Does anybody have an idea how to do that?
You need to check it this way:
var filter = "(" + columnName
+ " like \'" + s[0] + "%\' " // first word
+ " OR like \'% " + s[0] + "%\' )"; //in a sentence
for (int i = 1; i < s.Length; i++)
{
filter += "AND " + "(" + columnName
+ " like \'" + s[i] + "%\' " // first word
+ " OR like \'% " + s[i] + "%\' )"; //in a sentence
}

Pivotgrid prefilter settings

i want to change devexpress pivotgrid prefilter with code. I am using linqtosql method for bind data in c# MVC.
PivotGridPartialview.cshtml
settings.Fields.Add(field =>
{
field.Area = PivotArea.RowArea;
field.FieldName = "DefTarih";
field.Caption = "Tarih";
field.SortOrder = PivotSortOrder.Descending;
field.ValueFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
field.ValueFormat.FormatString = "dd/MM/yyyy";
field.AreaIndex = 0;
});
var Tarih1 = System.DateTime.Parse("01." + System.DateTime.Today.Month.ToString() + "." + System.DateTime.Today.Year.ToString());
var Tarih2 = System.DateTime.Parse(System.DateTime.DaysInMonth(System.DateTime.Today.Year, System.DateTime.Today.Month).ToString() +
"." + System.DateTime.Today.Month.ToString() + "." + System.DateTime.Today.Year.ToString());
settings.Prefilter.CriteriaString = "[DefTarih] between ('" + Tarih1 + "','" + Tarih2 + "')";
Controller
public ActionResult PivotGridPartial()
{
var model = db.USDRapors;
return PartialView("_PivotGridPartial", model);
}
When pivotgrid loaded with this code i see prefilter bottom of pivotgrid correctly. But datas not effected with prefilter. When changed start date in prefilter, prefilter works otherwise not works.
Which method can use for changing prefilter in code and work at opening page?
The problem is between operator. If i change the code below this message, its working.
settings.Prefilter.CriteriaString = "[DefTarih] ='" + Tarih1 + "'"
It's strange tried other operators and all of other operators not working. Also below this code not working.
settings.Prefilter.CriteriaString = "DefTarih => '" + Tarih1 + "' And [DefTarih] =<'"
+ Tarih2 + "'"
Try this if data is numeric:
settings.Prefilter.CriteriaString = "DefTarih => " + Tarih1 + " And [DefTarih] =< " + Tarih2
you are using "between" and "=<" which are comparing operators, and these not able to compare or find value between two Strings value.

Writing data to SQL and dumping it into Excel

My C# application is significantly slower than I would like. The program accesses an Excel sheet and loops through each row on a sheet / does the following:
Collects variables from that row
Creates an SQL query based off those variables
Executes that query
then a reader goes out and puts it in its proper column on that same row.
*Note, each row has 6 different SQL queries/ final numbers that are calculated and input into the sheet, the code below is just showing the first 2 for brevity's sake. The sheet has around 300 rows, so the program is executing 300 * 6= 1,800 SQL queries each time its run. For each one of those 1,800 numbers, the program is accessing the sheet and inputting it into the sheet.
Instead of doing the excelWorksheet.get_Range and inputting the number into the Excel sheet for each number, one at a time, would it be faster to store each number into an array and then go back later and mass dump all of the numbers into the sheet, once all of the queries have been executed and the array is full?
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = "Data Source=WRDXPVSEPIRPT00;DATABASE=Epicor905;Workstation ID=SMEBPPL204TN;Trusted_Connection=true";
try
{
//initiate the connection
conn.Open();
}
catch(SqlException ex)
{
throw new ApplicationException(string.Format("You're not connected to the database, please close the program, re-connect to the network, and try again."), ex);
}
progressBar1.Value = 60;
statusLabel.Text = "Retrieving account balances from database...";
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//iterate through each row and pull information
for (int i = 2; i < lastUsedRow + 1; i++)
{
//string iString = Convert.ToString(i);
statusLabel.Text = "Retrieving balances for " + i + " of " + lastUsedRow + " accounts...";
//declare excel sheet range variables
var CompanyVar = excelWorksheet.get_Range("A" + i, "A" + i).Text;
var FiscalYear = excelWorksheet.get_Range("B" + i, "B" + i).Text;
var FiscalPeriod = excelWorksheet.get_Range("C" + i, "C" + i).Text;
var segValue1 = excelWorksheet.get_Range("F" + i, "F" + i).Text;
var segValue2 = excelWorksheet.get_Range("G" + i, "G" + i).Text;
var segValue3 = excelWorksheet.get_Range("H" + i, "H" + i).Text;
int FiscalYearHelper = Convert.ToInt32(FiscalYear);
var FiscalYearPYY = FiscalYearHelper - 1;
//begin filling in CY YTD column
string SQLCode = "SELECT SUM(DebitAmount-CreditAmount) as BalanceAmt FROM GLJrnDtl WITH (NOLOCK) WHERE" +
" FiscalPeriod between 1 AND " + FiscalPeriod + "AND Company =" + "'" + CompanyVar + "'" +
"AND FiscalYear =" + "'" + FiscalYear + "'" + "AND SegValue1 LIKE " + "'" + segValue1 + "'" +
"AND SegValue2 LIKE " + "'" + segValue2 + "'" + "AND SegValue3 LIKE " + "'" + segValue3 + "'";
SqlCommand command = new SqlCommand(SQLCode, conn);
// Create new SqlDataReader object and read data from the command.
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string cyAct = reader["BalanceAmt"].ToString();
if (cyAct == "")
{
goto CYM;
//cyAct = "0.00";
}
var cyAct1 = (float)Convert.ToDouble(cyAct);
int one = Convert.ToInt32(excelWorksheet.get_Range("E" + i, "E" + i).Text);
double cyAct2 = (cyAct1 * one);
string cyAct3 = cyAct2.ToString("0.##");
excelWorksheet.get_Range("I" + i, "I" + i).Value = cyAct3;
}
}
//end filling in column
//begin filling in CY Month column
CYM:
string SQLCodeMonth = "SELECT SUM(DebitAmount-CreditAmount) as BalanceAmt FROM GLJrnDtl WITH (NOLOCK) WHERE" +
" FiscalPeriod = " + FiscalPeriod + "AND Company =" + "'" + CompanyVar + "'" +
"AND FiscalYear =" + "'" + FiscalYear + "'" + "AND SegValue1 LIKE " + "'" + segValue1 + "'" +
"AND SegValue2 LIKE " + "'" + segValue2 + "'" + "AND SegValue3 LIKE " + "'" + segValue3 + "'";
SqlCommand commandMonth = new SqlCommand(SQLCodeMonth, conn);
// Create new SqlDataReader object and read data from the command.
using (SqlDataReader reader = commandMonth.ExecuteReader())
{
while (reader.Read())
{
string cyAct = reader["BalanceAmt"].ToString();
if (cyAct == "")
{
goto APY;
//cyAct = "0.00";
}
var cyAct1 = (float)Convert.ToDouble(cyAct);
int one = Convert.ToInt32(excelWorksheet.get_Range("E" + i, "E" + i).Text);
double cyAct2 = (cyAct1 * one);
string cyAct3 = cyAct2.ToString("0.##");
excelWorksheet.get_Range("J" + i, "J" + i).Value = cyAct3;
}
}
//end filling in column
//begin filling in Act PY month column
THIS IS NOT A FULL ANSWER, there is not enough space to write this as a comment, do not mark this as an answer its a comment.
Please try to use objects (instances of classes or structs) it will make your programming more efficient and easy to maintain.
for example:
private void UseObjects()
{
List<ExcelObjects> ListOfvarsForQuery = new List<ExcelObjects>();
for (int i = 2; i < lastUsedRow + 1; i++)
{
ExcelObjects obj = new ExcelObjects();
obj.CompanyVar = ws.Cells[i, 1];
obj.FiscalYear = ws.Cells[i, 2];
obj.FiscalPeriod = ws.Cells[i, 3];
obj.segValue1 = ws.Cells[i, 4];
obj.segValue2 = ws.Cells[i, 5];
obj.segValue3 = ws.Cells[i, 6];
ListOfvarsForQuery.Add(obj);
}
string SQLCode = // use the list of ExcelObjects and write a better query.
}
}
struct ExcelObjects
{
public string CompanyVar;
public string FiscalYear;
public string FiscalPeriod;
public string segValue1;
public string segValue2;
public string segValue3;
}
Instead of looping through each row and running a SQL query for each row, I found that it is faster to outer join the table I speak of in my question with another SQL table that has the account balances on it. I'm doing all of it within memory because I've been coding for 3 weeks and I don't have time to learn how to create a temp table in SQL server yet.

Visual studio C# Oracle database sort Date

I am not able to find what's wrong with the following code. There is a form on which the selected start date and finish date , as well as a button transition to a new form where DataGridView populated the database , it is necessary to conclusions regarding the selected date , but that he does not want to issue ORA- 00933.No "where" all is well.
void renewOtchet()
{
dgvOtchet.Rows.Clear();
OracleCommand ocm = Oracle.DBConneciton.CreateCommand();
ocm.CommandText = "select num, date_start, date_finish, " +
"trim(name_video), price_video, " +
"trim(fam_client), " +
"trim(kind_zal) from video.allData" +
"where date_start >= ('"+ date1 + "', 'DD.MM.YYYY' ) and date_finish <= ('" + date2+ "', 'DD.MM.YYYY') ";
string[] str = new string[7];
OracleDataReader ord = ocm.ExecuteReader();
while (ord.Read())
{
for (int i = 0; i < 7; i++)
{
str[i] = ord[i].ToString();
if (i == 1 || i == 2)
{
str[i] = str[i].Remove(10);
}
}
dgvOtchet.Rows.Add(str);
}
ord.Dispose();
ord.Close();
}
You can try this.
"select num, date_start, date_finish, " +
"trim(name_video), price_video, " + "trim(fam_client), " +
"trim(kind_zal) from video.allData " +
"where date_start >= TO_DATE('"+ date1 + "', 'DD.MM.YYYY' )
and date_finish <= TO_DATE('" + date2+ "','DD.MM.YYYY') ";
string[] str = new string[7];

Incorrect syntax near '10'

SqlConnection con = new SqlConnection(str);
int ID;
ID = Int32.Parse(Combo_Stu.SelectedValue.ToString());
double a = double.Parse(Txt_Ins.Text);
string date = dtp_Stu.Value.ToString();
SqlCommand sqlcmd1 = new SqlCommand("INSERT INTO Instalment_Billing(ID,Pay_Date, Fees) VALUES (" + ID + "," + **date** + "," + a + ")", con);
con.Open();
sqlcmd1.ExecuteNonQuery();
Incorrect syntax near '10'
I am getting this error in date
guess pls help me
The problem is probably that your date is unquoted, but the real solution to this problem is to use a parameterized query.
Whenever you get an error in a line like:
SqlCommand sqlcmd1 = new SqlCommand("INSERT INTO Instalment_Billing(" +
"ID,Pay_Date, Fees) VALUES (" + ID + "," + date + "," + a + ")", con);
you should immediately insert some code to print it out and check whether it's valid SQL:
Console.WriteLine ("INSERT INTO Instalment_Billing(" +
"ID,Pay_Date, Fees) VALUES (" + ID + "," + date + "," + a + ")");
or:
System.Windows.Forms.MessageBox.Show("INSERT INTO Instalment_Billing" +
"(ID,Pay_Date, Fees) VALUES (" + ID + "," + date + "," + a + ")");
This should show you exactly where your problem lies. Most likely insertions of dates should use strings of the format 'yyyy.mm.dd' or something similar so you should, at a bare minimum:
quote the date string (... + ",'" + date + "'," + ...).
ensure that its format is okay (I'm not sure what ToString() will give you off the top of my head but I would think, given that you posted this today and it's not the tenth month or tenth day of the month, that it's probably something like yy-mm-dd and the unquoted 10 from 2010 is causing you grief).

Categories

Resources