Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Walk through date range in a variable for an array

Status
Not open for further replies.

txgeekgirl1

Programmer
Sep 10, 2009
85
US
I am trying to walk a date range using a For variable to compare to an array. I am getting a not numeric nesting error - it seems to be in the walk between the svcdate and createdate - FOR x = Casedata_.svcdate TO Casedata_.CreateDate. Any help is much appreciated.

Code:
IF Casedata_.CreateDate - Casedata_.SvcDate > 2 THEN
			LOCAL x, y
			STORE {} TO x
			STORE 0 TO y
			
			FOR x = Casedata_.svcdate TO Casedata_.CreateDate
			messagebox(DTOC(x))                          *------------------This coming up   /  /
				IF DOW(x,2) <> 6 OR DOW(x,2) <> 7 THEN
					FOR y = 1 TO 50
						IF x = holidayarray[y] THEN
							messagebox(str(lnNewDays))
							lnNewDays = lnNewdays - 1
							messagebox(str(lnNewDays))
						ENDIF
					NEXT y
				ENDIF
			NEXT x
		ENDIF
 
Not quite clear what you are doing here. What exactly are Casedata_.CreateDate and Casedata_.SvcDate? You refer to an array, but they look more like fields in a table. Is that correct? And if so, can you confirm that their data type is Date?

Also, what do you mean by "a not numeric nesting error"? I don't recognise that.

And it will help to know what the value of x is at the point of the error. Assuming it is a Date datatype, I can't see anything wrong with that line of code. And what's in the holidayarray array?

Are your message boxes present merely to help with your debugging? Are you aware that you could have 100 separate message boxes appearing just in your inner-most loop? If you want to monitor the value lnNewDays within the loop, better to use DEBUGOUT in conjuction with the Debugger.

Finally, you don't need to convert the data types for the MESSAGEBOX() function. MESSAGEBOX(x) and MESSAGEBOX(lnNewDays) will work fine, without the DTOC() or the STR().

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Dates in VFP can be EMPTY or NULL. " / / " represents an empty date, depends on your date format setting, it couls also be " . . ", no digits, but the datepart marks/separators.

So you have to handle NULL and EMPTY separately. ISNULL() and EMPTY() help about checking these values and NVL(something,alternativevalue) results in the alternative value if something is NULL, likewise EVL(something, alternativevalue) acts on empty values.

EMPTY() is a state also other types than dates and datetimes can have, 0 also is empty, empty strings and whitespace only strings also are EMPTY. The boolean false (.F.) is considered empty, but NULL is separate.

Your code does make use of an empty date in the line STORE {} To x, x is set to the empty date, because a) {} are delimiters for literal date/datetime values and b) {} is the empty date (in contrast a sample date would be {^1999-12-31}. If the first use of a variable is an assignment, like X first is set in the for loop, you don't have to store any initial value. If your first assignment is a concatenation, for examplle s = s + '...', then s needs to be a string type, or you can't use + operator with another string, but you declare a variable with the LOCAL command and thus your STORE lines are merely making clear what type these variables x and y are and should be. It would also be ok to use the usual name convention to make that statement via prefix l for local an d for date or i for integer or n for number or other single letters, like used for field types (all the vartype letters are expained in TYPE(), VARTYPE(), maybe even CREATE TABLE and CREATE CURSOR.

Bye, Olaf.
 
Thanks guys - I got it....ask Google enough in a number of different ways :)

Code:
IF Casedata_.CreateDate - Casedata_.SvcDate > 2 THEN
			LOCAL x, y
			STORE casedata_.svcdate TO x
			STORE 0 TO y
			
			DO WHILE x <= Casedata_.CreateDate
			messagebox(DTOC(x))
				IF DOW(x,2) <> 6 OR DOW(x,2) <> 7 THEN
					FOR y = 1 TO 50
						IF x = holidayarray[y] THEN
							IF BETWEEN(x,Casedata_.SvcDate,Casedata_.CreateDate) = .T. THEN
								messagebox(str(lnNewDays))
								lnNewDays = lnNewdays - 1
								messagebox(str(lnNewDays))
							ENDIF
						ENDIF
					NEXT y
				ENDIF
			x = x + 1
			ENDDO
		ENDIF
 
Removed the THENs?
Declared the holidayarray[] or maybe initialised it with some values?
What the heck is lnNewDays?

Could be anything Mike.


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Sorry not the THENs, I just ran the help for IF...ENDIF, never used the optional THEN myself.


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Mike said:
Got what? What was the cause of the error? How did you fix it?

Mike

Instead of :
Code:
STORE {} TO x

FOR x = Casedata_.svcdate TO Casedata_.CreateDate

I used a DO WHILE

Code:
STORE casedata_.svcdate TO x

DO WHILE x <= Casedata_.CreateDate
 
GriffMG - THEN can or cannot be used - I write in several languages and use just to be consistent.

The array is declared and lnNewDays is also declared higher up in code as it is used throughout the function.

Thanks for your input

 
There is the explanation!

You have tried to initiate a For Next loop using a date as the controlling variable - that is not allowed.

You would need to run it as a numeric for a For Next to work - Do While is different, it's just looking for a .t. / .f. expression.


Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Ah, that even didn't occur to me, but makes sense. For loop counters need to be numeric, not any type supporting to be ordered by qualifies as counter variable type.

Bye, Olaf.

 
it can be done with a For...Next

Code:
for I = 0 to m.LaterDate - m.EarlierDate
  m.ThisDate = m.EarlierDate+i
  && code here
next

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Overall, you're subtractging holidays from a date range, aren't you?

If you had holidays in a table in the field dDate, it's simple to get the count of holidays in that range:

Code:
SELECT COUNT(*) as nCountHolidays FROM holidays Where holidays.dDate BETWEEN Casedata_.svcdate AND Casedata_.CreateDate

That count then has to be subtracted from the date difference and that's it.

Bye, Olaf.

 
I did an ARRAY for holiday dates from 11/24/2016 - 01/01/2024 and threw it in the bottom of the function that takes out weekends.
 
Well, I haven't seen good approaches to populate arrays in code in VFP, lots of assignments, though many holidays are static and some are having a formula. I'd put them in a table, maybe even including weekend days, though they are clear in a simple iteration via DOW, as you do, a table indexed on the date column can give you several answers fastest, as you rather only iterate some dates instead of all dates of the range.

Bye, Olaf.
 
Olaf - you are right - it was brut force populated because we don't do some holidays and get extra days for others.

Hopefully the people we are tracking lag time for and their supervisors straighten up and get their notes in the system in under 2 days like they are supposed to.

Code:
*look for holidays
		DIMENSION holidayarray[53]
		
		holidayarray[1] = {11/24/2016}
		holidayarray[2] = {11/25/2016}
		holidayarray[3] = {12/23/2016}
		holidayarray[4] = {12/26/2016}
		holidayarray[5] = {01/02/2017}
		holidayarray[6] = {05/29/2017}
		holidayarray[7] = {07/04/2017}
		holidayarray[8] = {09/04/2017}
		holidayarray[9] = {11/23/2017}
		holidayarray[10] = {11/24/2017}
		holidayarray[11] = {12/25/2017}
		holidayarray[12] = {12/26/2017}
		holidayarray[13] = {01/01/2018}
		holidayarray[14] = {05/28/2018}
		holidayarray[15] = {07/04/2018}
		holidayarray[16] = {09/03/2018}
		holidayarray[17] = {11/22/2018}
		holidayarray[18] = {11/23/2018}
		holidayarray[19] = {12/24/2018}
		holidayarray[20] = {12/25/2018}
		holidayarray[21] = {01/01/2019}
		holidayarray[22] = {05/27/2019}
		holidayarray[23] = {07/04/2019}
		holidayarray[24] = {09/02/2019}
		holidayarray[25] = {11/28/2019}
		holidayarray[26] = {11/29/2019}
		holidayarray[27] = {12/24/2019}
		holidayarray[28] = {12/25/2019}
		holidayarray[29] = {01/01/2020}
		holidayarray[30] = {05/25/2020}
		holidayarray[31] = {07/03/2020}
		holidayarray[32] = {09/07/2020}
		holidayarray[33] = {11/26/2020}
		holidayarray[34] = {11/27/2020}
		holidayarray[35] = {12/24/2020}
		holidayarray[36] = {12/25/2020}
		holidayarray[37] = {01/01/2021}
		holidayarray[38] = {05/31/2021}
		holidayarray[39] = {07/05/2021}
		holidayarray[40] = {09/06/2021}
		holidayarray[41] = {11/25/2021}
		holidayarray[42] = {11/26/2021}
		holidayarray[43] = {12/23/2021}
		holidayarray[44] = {12/24/2021}
		holidayarray[45] = {12/31/2021}
		holidayarray[46] = {05/30/2022}
		holidayarray[47] = {07/04/2022}
		holidayarray[48] = {09/05/2022}
		holidayarray[49] = {11/24/2022}
		holidayarray[50] = {11/25/2022}
		holidayarray[51] = {12/23/2022}
		holidayarray[52] = {12/26/2022}
		holidayarray[53] = {01/02/2023}
 
I would use a table, either embedded in the .exe or in a table of binary tables and written to disk on request

Then you can ADD to it when there are other 'breaks' shutdowns for maintenance that sort of thing

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
That would work in a private company - this is for gov't. We get no breaks and have no down time. I even had an Exec Director during a tornado tell me to do what I would have done before computers. I turned to my boss and said "She does know that what I do didn't exist before computers, right?"

When that table expires I will no longer be there to be responsible for changes or maintenance.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top