IF Statement for day of the week - if-statement

I have a set of 7 checkboxes on my winForm that allow the user to select which days of the week they want assigned with the order being created. I am trying to create the IF Statement that implements these checkbox decisions correctly. I have tried many combination of If, IfElse, and Select statement but all to no avail.
If cbMon.Checked = True Then
.WriteString("Monday")
If cbTues.Checked = True Then
.WriteString("Tuesday")
If cbWed.Checked = True Then
.WriteString("Wednesday")
If cbThur.Checked = True Then
.WriteString("Thursday")
If cbFri.Checked = True Then
.WriteString("Friday")
If cbSat.Checked = True Then
.WriteString("Saturday")
If cbSun.Checked = True Then
.WriteString("Sunday")
End If
End If
End If
End If
End If
End If
End If
That what i have so far that works the best. The problem though is that if i check "Monday, Tuesday, and Thursday" on the winForm...Monday and Tuesday will show up, but Thursday gets skipped because it obviously breaks out of the if statement. Any guidance?

The problem is that you should not be nesting your if statements.
In your example, any portion of code will only hit if the day before it (all the way up to monday) is checked.
Simply flatten out the if statements, and do not nest them, like so :
If cbMon.Checked = True Then
.WriteString("Monday")
End If
If cbTue.Checked = True Then
.WriteString("Tuesday")
End If
...etc...
If you want the users to select only ONE option, perhaps a dropdown or radio button list is more suitable rather than checkboxes.

do not use nesting
just simple if loop is needed here
Initialise an array
if monday
add monday to array
if tuesday checked
add tuesday to array
.
.
.
if sunday checked
add sunday to array
get the string by append all values in array with ','

Yes your problem is that you are nesting your if statements, which is why Thursday gets skipped because Wednesday proved to be false.
What you need to do is run a for loop that will go through each check box and check whether its checked value is true.

Related

Two conditions in Google Sheets Function

I have a question on using two functions with an if statement in Google Sheets as one complete function. Both variables have to be true, otherwise it returns false. I need one function to check the date 20 months back from today. If said cell is less than today's date 20 months back it's true, naturally. However, for the complete function to return true it also searches for another text value in another cell and has to be an exact match. Both conditions have to be true (the date and the exact match) for the function to be true. So if the date in the cell is less than today's date 20 months back and the text value in the other cell is an exact match, function is true.
Problem is that it seems like the date function does not seem to apply.
=IF(D2<DATE(YEAR(TODAY()),MONTH(TODAY())-20,DAY(TODAY())),AND(REGEXMATCH(M2,"text")),TRUE,FALSE)
You current formula is not set up correctly (nor logically). Given only what you've shown here, this should work:
=IF(AND( D2<DATE(YEAR(TODAY()),MONTH(TODAY())-20,DAY(TODAY())), REGEXMATCH(M2,"text") ),TRUE,FALSE)
Notice that the AND( ) contains both conditions here, whereas your original formula had it only around the second condition.
However, a shorter version of this would be as follows:
=AND( D2<DATE(YEAR(TODAY()),MONTH(TODAY())-20,DAY(TODAY())), REGEXMATCH(M2,"text") )
... since the result of a properly functioning AND( ) is always TRUE or FALSE anyway.
It looks like you're supplying 4 arguments to the IF statement:
=IF(DATECHECK,AND(TEXTCHECK),TRUE,FALSE)
The IF statement expects 3 arguments instead. 1) the condition, 2) the value if true, and 3) the value if false. You can combine your two conditions using an AND statement like this:
AND(DATECHECK,TEXTCHECK)
The final formula would then be:
=IF(AND(D2<DATE(YEAR(TODAY()),MONTH(TODAY())-20,DAY(TODAY())), REGEXMATCH(M2,"text")),TRUE,FALSE)

Pandas - If cell is blank, turn a pd.timedelta[ns64] cell to a string '--'

I have been working on a python project to automate some reports my team was designing by hand. I am running into a bit of an stubborn problem I can't figure out what I'm doing.
Essentially, the area I am stuck on has 4 separate data columns which I have made generic version of below.
Start Time | Finish Time | Not Usable Reason | Start to Finish
12:36 15:36 3:00
16:35 19:45 Production Defect 3:10
19:55 QA Failure
Not Usable Reason has at a high level two options. Blank OR text describing the issue. As well, depending on the issue, a finish time may not have been recorded due to some QA issue which was noticed before it was finished resulting in a Not Usable Reason which does not allow a start to finish to be calculated.
Essentially, what I am trying to do is IF there is a Not Usable Reason, in that row in the Start to Finish column, put a "--" into that field.
The code that I used to attempt this:
processor_df['Start to Finish'] = processor_df['Finish Time'] - processor_df['Start Time']
processor_df['Start to Finish'] = processor_df['Start to Finish'].astype(str)
processor_df['Start to Finish'] = processor_df.loc[pd.isnull(processor_df['Not Usable Reason']) == False, 'Start to Finish'] == '--'
processor_df['Start to Finish'] = pd.to_timedelta(processor_df['Start to Finish'])
This represents just a fraction of the code relating specifically to the small portion performing the calculation, then attempting to modify the start to finish column appropriately.
As well, I go from timedelta -> str -> timedelta due to an error I received when I didn't change it to a string:
ValueError: only leading negative signs are allowed
The issue is my desired output would be:
Start Time | Finish Time | Not Usable Reason | Start to Finish
12:36 15:36 3:00
16:35 19:45 Production Defect --
19:55 QA Failure --
but the above code produces it as:
Start Time | Finish Time | Not Usable Reason | Start to Finish
12:36 15:36
16:35 19:45 Production Defect False
19:55 QA Failure False
What is the best way to use a check if a condition exists and if it does replace it. The above has worked when I used it purely for strings but my condition was not checking if it as blank, but if it matched a specific value.
Thank you for your help with this, and if its a stupidly simple mistake, I thank you twice as hard for helping a novice out.
Best,
Andy
This line is where I think the problem lies:
processor_df['Start to Finish'] = processor_df.loc[pd.isnull(processor_df['Not Usable Reason']) == False, 'Start to Finish'] == '--'
You are basically overwriting the Start to Finish column with a boolean array. Your last expression in the line of code is == which returns a boolean array of all False values because of course the string '--' is not in any of the cells of that column.
The following line should do the trick instead:
processor_df.loc[processor_df['Not Usable Reason'].notnull() , 'Start to Finish'] = '--'
We use .loc, which I would in general recommend to start using out of habit for indexing rather than just square brackets, to get the rows where we have a 'Not Usable Reason' and the column 'Start to Finish' and we assign (using =, the assignment operator) the string '--' to these cells.

How to add regex matches to list in VB.net

I am having a Regex and I want the matches to be added to my previous List. The list (called "Items") has already some entries. (It got the entries from a listbox1 and added is now a datasource of the listbox1)
This is my source:
Dim Items As List(Of String)
<some other code here>
For Each Bam As Match In Treffer
If hashtagz = False Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = True Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = False Then
Items.Add(Bam.Groups(1).ToString)
Console.WriteLine(Bam.Groups(1).ToString)
End If
Next
The last part is important (the last if loop with hashtagz = true and Firsthashtags = False)
I also added the console.writeline to see what is going on. In the console, I get all the new scraped and correct information. In the Items list however, I just get a duplicate of what has been already stored in there instead of adding and updating my list with the new regex matches.
edit Additional information: The whole if condition is in a timer, so it runs again and again. At first it will add entries to a listbox. Then (now important!) it will do the Items.Add(Bam.Groups(1).ToString). It seems to add the new entries the FIRST time THAT part of the code gets executed, but after it is being run trhough again trhough a timer, it will just add the previous entries again and again
Dim Items As New List(Of String)
Dim hashtagz As Boolean
Dim FirstHashtags As Boolean
' Other code here
For Each Bam As Match In Treffer
Select Case True
Case Not hashtagz
ListBox1.Items.Add(Bam.Groups(1).ToString)
Case FirstHashtags
ListBox1.Items.Add(Bam.Groups(1).ToString)
Case Items.Contains(Bam.Groups(1).ToString)
' Already Exists
Case Else
Items.Add(Bam.Groups(1).ToString)
Console.WriteLine(Bam.Groups(1).ToString)
End Select
Next
After using more than 7 hours today (and a few hours yesterday, I am a newbie in VB) of testing, going through my code and building in some outputs to see where the problem is...
My concept is correct, there are no logical errors in the flow of my programm, as one can see from the console.writeline(Bam.Groups(1).ToString . I tested everything and ended up putting in a richtextbox and its like this now
For Each Bam As Match In Treffer
If hashtagz = False Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = True Then
ListBox1.Items.Add(Bam.Groups(1).ToString)
ElseIf hashtagz = True And FirstHashtags = False Then
Items.Add(Bam.Groups(1).ToString)
RichTextBox1.Text = RichTextBox1.Text + Bam.Groups(1).ToString & vbNewLine
End If
Next
The adding procedure seems to be looking correct with the richtextbox, but when I want to add to the Items list, it just gives out the duplicates of the previous entries instead of adding to it. The .add seems to work only the FIRST time running through that line of code, after the second time it just gives out the duplicate of the entries.
I am still trying to figure out WHY that is and I will trying to understand the posts above. Maybe someone else has also an explanation, jsut in case the others were wrong
Edit I have been experimenting still with all this, I have a function that grabs the last entry of my item list and prints out a part of it. When I do that, the print seems correct and updated. So it seems like the list IS actually being updated somehow since the "getting a part of the latest entry of list" is working and always updated. But when I want to show or save the content of the item list, that's when I get the duplicates and the updated and newest entries are not being shown!
Alright guys, I am back again after testing.
The code I posted above was correct. The real reason behind the mistake was in a few other parts of the code, which resulted in partially duplicated output of the entries of the list etc.
I lost track of the variables and the procedures my program was doing. Any hints or tips for me on how to keep track of the code on what it does and having everything in mind or how to properly structure code etc. so that I won't get lost again and again in the code?
This case can be closed, sorry for the inconvenience.

IF Statement with Network days

I'm trying to write a formula using an IF and Networkdays function. I basically want this formula to look in column J3 and see if there is a date. If there is a date the it should return the number of work days between the completion date and the discovery date.
If J3 (completion date) is blank, which means it hasn't benn completed, then I just want it to return blank
Try something like this:
=IF(J3 = "", "", NETWORKDAYS(A3, J3))
You already had 50% of the formula.
The IF statement will check whether or not J3 is blank (i.e. ""). If that is true, it will return a blank value. If it's false meaning that there is something in there, it will return your formula.
Let me know if that works.
Here is the formula that I use:
=IF(NETWORKDAYS($G7,$H7)>0, NETWORKDAYS($G7,$H7),"-")

PL/SQL optimize searching a date in varchar

I have a table, that contains date field (let it be date s_date) and description field (varchar2(n) desc). What I need is to write a script (or a single query, if possible), that will parse the desc field and if it contains a valid oracle date, then it will cut this date and update the s_date, if it is null.
But there are one more condition - there are must be exactly one occurence of a date in the desc. If there are 0 or >1 - nothing should be updated.
By the time I came up with this pretty ugly solution using regular expressions:
----------------------------------------------
create or replace function to_date_single( p_date_str in varchar2 )
return date
is
l_date date;
pRegEx varchar(150);
pResStr varchar(150);
begin
pRegEx := '((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d)((.|\n|\t|\s)*((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d))?';
pResStr := regexp_substr(p_date_str, pRegEx);
if not (length(pResStr) = 10)
then return null;
end if;
l_date := to_date(pResStr, 'dd.mm.yyyy');
return l_date;
exception
when others then return null;
end to_date_single;
----------------------------------------------
update myTable t
set t.s_date = to_date_single(t.desc)
where t.s_date is null;
----------------------------------------------
But it's working extremely slow (more than a second for each record and i need to update about 30000 records). Is it possible to optimize the function somehow? Maybe it is the way to do the thing without regexp? Any other ideas?
Any advice is appreciated :)
EDIT:
OK, maybe it'll be useful for someone. The following regular expression performs check for valid date (DD.MM.YYYY) taking into account the number of days in a month, including the check for leap year:
(((0[1-9]|[12]\d|3[01])\.(0[13578]|1[02])\.((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\.(0[13456789]|1[012])\.((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\.02\.((19|[2-9]\d)\d{2}))|(29\.02\.((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))
I used it with the query, suggested by #David (see accepted answer), but I've tried select instead of update (so it's 1 regexp less per row, because we don't do regexp_substr) just for "benchmarking" purpose.
Numbers probably won't tell much here, cause it all depends on hardware, software and specific DB design, but it took about 2 minutes to select 36K records for me. Update will be slower, but I think It'll still be a reasonable time.
I would refactor it along the lines of a single update query.
Use two regexp_instr() calls in the where clause to find rows for which a first occurrence of the match occurs and a second occurrence does not, and regexp_substr() to pull the matching characters for the update.
update my_table
set my_date = to_date(regexp_subtr(desc,...),...)
where regexp_instr(desc,pattern,1,1) > 0 and
regexp_instr(desc,pattern,1,2) = 0
You might get even better performance with:
update my_table
set my_date = to_date(regexp_subtr(desc,...),...)
where case regexp_instr(desc,pattern,1,1)
when 0 then 'N'
else case regexp_instr(desc,pattern,1,2)
when 0 then 'Y'
else 'N'
end
end = 'Y'
... as it only evaluates the second regexp if the first is non-zero. The first query might also do that but the optimiser might choose to evaluate the second predicate first because it is an equality condition, under the assumption that it's more selective.
Or reordering the Case expression might be better -- it's a trade-off that's difficult to judge and probably very dependent on the data.
I think there's no way to improve this task. Actually, in order to achieve what you want it should get even slower.
Your regular expression matches text like 31.02.2013, 31.04.2013 outside the range of the month. If you put year in the game,
it gets even worse. 29.02.2012 is valid, but 29.02.2013 is not.
That's why you have to test if the result is a valid date.
Since there isn't a full regular expression for that, you would have to do it by PLSQL really.
In your to_date_single function you return null when a invalid date is found.
But that doesn't mean there won't be other valid dates forward on the text.
So you have to keep trying until you either find two valid dates or hit the end of the text:
create or replace function fn_to_date(p_date_str in varchar2) return date is
l_date date;
pRegEx varchar(150);
pResStr varchar(150);
vn_findings number;
vn_loop number;
begin
vn_findings := 0;
vn_loop := 1;
pRegEx := '((0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)\d\d)';
loop
pResStr := regexp_substr(p_date_str, pRegEx, 1, vn_loop);
if pResStr is null then exit; end if;
begin
l_date := to_date(pResStr, 'dd.mm.yyyy');
vn_findings := vn_findings + 1;
-- your crazy requirement :)
if vn_findings = 2 then
return null;
end if;
exception when others then
null;
end;
-- you have to keep trying :)
vn_loop := vn_loop + 1;
end loop;
return l_date;
end;
Some tests:
select fn_to_date('xxxx29.02.2012xxxxx') c1 --ok
, fn_to_date('xxxx29.02.2012xxx29.02.2013xxx') c2 --ok, 2nd is invalid
, fn_to_date('xxxx29.02.2012xxx29.02.2016xxx') c2 --null, both are valid
from dual
As you are going to have to do try and error anyway one idea would be to use a simpler regular expression.
Something like \d\d[.]\d\d[.]\d\d\d\d would suffice. That would depend on your data, of course.
Using #David's idea you could filter the ammount of rows to apply your to_date_single function (because it's slow),
but regular expressions alone won't do what you want:
update my_table
set my_date = fn_to_date( )
where regexp_instr(desc,patern,1,1) > 0