Freeeee 1 Posted Sunday at 01:54 PM function DaysInMonth ( Mo, Yr : LongInt): LongInt; begin case Mo of 1,3,5,7,8,10,12:DaysInMonth := 31; 4,6, 9,11:DaysInMonth := 30; 2: If (Yr mod 4 = 0) and (yr mod 400 = 0) and (yr mod 100 > 0) then DaysInMonth := 29; else DaysInMonth := 28; end; end; It's based on the Gregorian calendar's rules for Leap Year. And YES I KNOW that Delphi has Date Routines that are better than anything I can write so, please spare me that critique. I want to know why the compiler rejects this with 4 errors in one Unit but accepts in a different Unit. . Share this post Link to post
GPRSNerd 12 Posted Sunday at 02:20 PM Superfluous semicolon in line DaysInMonth := 29; Share this post Link to post
Freeeee 1 Posted Sunday at 04:20 PM Thanks for replying. That was a good catch. I think i put that semicolon in trying to correct the errors My bad. Sorry. taking it out didn't change any of the four errors which start at the function label on line 415 interesting I can't cut and paste errors so I'm going to copy them E2023 Function needs result type at line 415 (415:10) E2029 Declaration expected but '(' found at line 415 (415:22) E2003 Undeclared identifier: 'Mo" at line 417 (417:11) E2993 Undeclared identifier: DaysInMonth at line 418(418:22) the function heading should be the identifier and I was under the impression that the arguments passed are placeholders for the real arguments as long as they are of the same type. LongInt in this case. I didn't use VAr in front of them because they shouldn't be modified. This worked fine in a Unit where the full routine of which this is a part was tested., aside for a label a memo box and two buttons it was the only code the test program. So I'm trying to determine why it works in one simple unit but not this one. Share this post Link to post
dummzeuch 1669 Posted Sunday at 05:01 PM (edited) Move the code to an empty unit and try to compile that one. If it still does not compile post the full code of that new unit here. I think the problem is not in the code you have shown us but somewhere before that. Edited Sunday at 05:02 PM by dummzeuch Share this post Link to post
Freeeee 1 Posted Sunday at 07:21 PM I tried the test Unit but It recompiled without errors. and it would be the empty unit you described. one memo, 1 label 2 buttons. button 1 converts the date in the memo and moves the answer (which is days since year zero) into the label. Button two converts the days back into yyyy mm dd form and moves that back into the memo. If you used "/" as a separator there;s no change, If you used space, comma, period or letters as separators they're changed to "/" so you know it worked. ie you got back the same date. I got the idea from Microsoft. There year zero date is 01/01/1980. mine is 01/01/0000 . good in a long integer (and a 5 digit year) until 31,999/12/31. I think your right about something else going on that's confusing the compiler. The Unit it's in is quite large Over 500 lines. and there's till more code to write to get to a working program. I think what I'm going to have to do is fix the other typos and errors first and just leave this code alone hoping that eventually the compiler will accept them. I'll just comment then out to continue testing. thank for you help. Share this post Link to post
Remy Lebeau 1641 Posted Sunday at 08:05 PM (edited) FYI, the SysUtils unit has an IsLeapYear() function, and a MonthDays[] array, eg: uses ..., SysUtils; function DaysInMonth(Mo, Yr : Word): Word; begin Result := MonthDays[IsLeapYear(Yr), Mo]; end; Alternatively, the DateUtils unit has its own DaysInAMonth() function, eg: uses ..., DateUtils; function DaysInMonth(Mo, Yr : Word): Word; begin Result := DateUtils.DaysInAMonth(Yr, Mo); end; No need to reinvent the wheel here... Edited Sunday at 08:10 PM by Remy Lebeau 1 Share this post Link to post
Freeeee 1 Posted Sunday at 08:48 PM thank you Remy the errors are E2023 Function needs result type at line 415 (415:10) there - is - a" : LongInt; " after the closing paren E2029 Declaration expected but '(' found at line 415 (415:22) that's the opening paren for Mo, yr: LongInt E2003 Undeclared identifier: 'Mo" at line 417 (417:11) Mo was declared in the input args E2993 Undeclared identifier: DaysInMonth at line 418(418:22) ??? It's the name of the function. I already admitted that Delphi has better date routines. and I wrote this routine in turbo pascal before Delphi. That's beside the point. I want to know WHY the compiler accepts the routine without error in at least two other UNITS earlier but NOT THIS ONE? the above errors don't mention 'duplicate function ; or anything that indicate that's true. they are all about the way it's written. Is there some major flaw in the code above the routine that confuses the compiler so badly it starts flagging errors where there are none?? By the way, Why would I need to qualify a variable on a form when it's the ONLY form in the program? example ( ABCycle.Visible ) is a E2003 - but if I put in ( Form5.ABCycle.Visible ) in the code it's accepted. And Form5 IS the only form in this particular program Same program as the DaysInMonth problem Share this post Link to post
Remy Lebeau 1641 Posted Sunday at 11:28 PM 2 hours ago, Freeeee said: thank you Remy the errors are E2023 Function needs result type at line 415 (415:10) there - is - a" : LongInt; " after the closing paren E2029 Declaration expected but '(' found at line 415 (415:22) that's the opening paren for Mo, yr: LongInt E2003 Undeclared identifier: 'Mo" at line 417 (417:11) Mo was declared in the input args E2993 Undeclared identifier: DaysInMonth at line 418(418:22) ??? It's the name of the function. Since we can't see the rest of your code, we can't help you with these errors. The sole function you have shown only had one mistake in it. So clearly these other errors are caused by other problems (likely other syntax mistakes) higher up in your code that we can't see. 2 hours ago, Freeeee said: I want to know WHY the compiler accepts the routine without error in at least two other UNITS earlier but NOT THIS ONE? Because clearly THIS unit has other mistakes in it that are breaking its compilation. 2 hours ago, Freeeee said: Is there some major flaw in the code above the routine that confuses the compiler so badly it starts flagging errors where there are none?? Obviously yes, but what that flaw could be specifically is anybody guess without seeing the rest of the code in question. 2 hours ago, Freeeee said: By the way, Why would I need to qualify a variable on a form when it's the ONLY form in the program? example ( ABCycle.Visible ) is a E2003 - but if I put in ( Form5.ABCycle.Visible ) in the code it's accepted. That behavior happens when the failing code is NOT inside a non-static method of the TForm5 class, thus requires an explicit object reference to reach the ABCycle member. 2 hours ago, Freeeee said: And Form5 IS the only form in this particular program It doesn't matter if you have 1 Form or 100. You need a valid TForm5 object reference in order to access its ABCycle member. Inside of a method of the TForm5 class, that reference can be the implicit 'Self' pointer. But code outside of TForm5's methods will need an explicit pointer to the Form5 object. 2 hours ago, Freeeee said: Same program as the DaysInMonth problem That behavior would happen if DaysInMonth() is a non-static method of the TForm5 class, and thus must be called on a valid Form5 object reference, but the calling code does not have such a reference without qualifying it. Share this post Link to post
Freeeee 1 Posted Monday at 01:10 AM Is there some reason for using Non-Static as opposed to Active or Dynamic when talking about classes? What I'm understanding is any Procedure code generated from the Tform by some action (like a mouse clik) is in the TForm class. so as long as you do ALL of your coding inside one of those procedures you don't have to qualify back to the TForm. But if you call something like a WriteRecord procedure that was NOT generated by an action in./of/on the form you do have to qualify because you;ve gone outsife of the scope of the TForm class. or are the nuances ?? like hierarchy rules. Is it "You know when your outside of the class scope when you have to qualify". or is there an easier way? Share this post Link to post
Doug Rudd 2 Posted Monday at 02:32 AM May have same function name in one of the uses files in your 500 line unit? Share this post Link to post
Remy Lebeau 1641 Posted Monday at 06:20 AM (edited) 5 hours ago, Freeeee said: Is there some reason for using Non-Static as opposed to Active or Dynamic when talking about classes? There's no such thing as an "active" class method. Non-static, dynamic, virtual methods - these all have a hidden implicit Self pointer to the object instance they are called on. Quote What I'm understanding is any Procedure code generated from the Tform by some action (like a mouse clik) is in the TForm class. so as long as you do ALL of your coding inside one of those procedures you don't have to qualify back to the TForm. Yes, because they will all be using the Self pointer. For example procedure TForm5.FormClick(Sender: TObject); begin ABCycle.Visible := True; end; Is really this: procedure TForm5.FormClick(Sender: TObject); begin Self.ABCycle.Visible := True; end; Quote But if you call something like a WriteRecord procedure that was NOT generated by an action in./of/on the form you do have to qualify because you;ve gone outsife of the scope of the TForm class. If such a procedure is trying to access members of the Form of object, then yes. Quote or are the nuances ?? like hierarchy rules. Is it "You know when your outside of the class scope when you have to qualify". or is there an easier way? I suggest you brush up on your fundamentals. For instance: https://docwiki.embarcadero.com/RADStudio/en/Procedures_and_Functions_Index https://docwiki.embarcadero.com/RADStudio/en/Classes_and_Objects_Index https://docwiki.embarcadero.com/RADStudio/en/Methods_(Delphi) Edited Monday at 06:24 AM by Remy Lebeau 1 Share this post Link to post
Die Holländer 90 Posted Monday at 12:09 PM I didn't know that you can use a case statement where the numbers used are not in order.. 1,3,5,7,8,10,12:DaysInMonth := 31; And in the next line you use 4,6,9 and 11 while the line before ends with 12.. 4,6, 9,11:DaysInMonth := 30; What if you replace all the old Pascal style return vars DaysInMonth into Result like: 1,3,5,7,8,10,12:Result := 31; Share this post Link to post
Freeeee 1 Posted Monday at 12:30 PM Hi the function worked perfectly in Turbo Pascal when I first wrote it. then you used the name of the function to return the value. and Yes I could use Result rather than function name. but the question was why is the compiler finding these errors (that are not errors). Why did this function Pass in 2 other Units but not this one. Share this post Link to post
Uwe Raabe 2168 Posted Monday at 12:42 PM 10 minutes ago, Freeeee said: but the question was why is the compiler finding these errors (that are not errors). As mentioned elsewhere, you need to show more code that is before the function. The function code is correct, it is something before it that makes the compiler unhappy. 1 Share this post Link to post
Die Holländer 90 Posted Monday at 12:52 PM 18 minutes ago, Freeeee said: Why did this function Pass in 2 other Units but not this one. Because as Remy suggested these 2 other units don't have DateUtils or SysUtils in the uses? But if you change the "DaysInMonth:=" into "Result:=" does that work ? Share this post Link to post
Brian Evans 129 Posted Monday at 01:16 PM Messed up structure elements can lead to odd errors in others parts of the code. It may look like a block of code is part of a function but due to messed up structure elements it actually isn't. Your first error indicates you are still probably still inside a begin/end code block - the same error is produced by the code below in a simple button click procedure TForm1.Button1Click(Sender: TObject); begin function AddTwo(a,b:integer):integer; end; Share this post Link to post
Freeeee 1 Posted Monday at 01:20 PM (edited) thanks Remy agrees that I've screwed up something higher up in the code so the compiler is confused. I'm still 're-' Learning. 🙂 Edited Monday at 01:22 PM by Freeeee Added relearning Share this post Link to post
Pat Foley 54 Posted Monday at 01:31 PM 18 hours ago, Freeeee said: I got the idea from Microsoft. There year zero date is 01/01/1980. mine is 01/01/0000 . good in a long integer (and a 5 digit year) until 31,999/12/31. mmm, I run win 11 are you still using DOS. procedure TForm16.Button4Click(Sender: TObject); var SL: TStrings; // F1 click bait begin SL := memo1.Lines; for var aDate in [0, 1,2,3, 30000-2*365-32-17 , 30000, 40000, 50000, 100000] do begin SL.Add(DateToStr(aDate)); end; end; Share this post Link to post
Freeeee 1 Posted Monday at 01:35 PM Yes, I am running MSDos, AND Window XP And Window 10 and my game machine is a Win 11. Emulators are great, if you can remember which system your in. but I don't like side kick at all. Share this post Link to post
Brandon Staggs 386 Posted Monday at 06:15 PM Seriously, show the whole unit. 2 Share this post Link to post
Brian Evans 129 Posted Monday at 07:02 PM Putting the function definition inside a Begin / End code block produces the multiple errors posted. So the unit has an open code block where the function definition currently is. 1 Share this post Link to post
Freeeee 1 Posted yesterday at 02:38 AM code was from ? 2000,. Worked then. There wasn't a reserved word "Result" so you used the function name at the end of the code set equal to whatever variable you were using to get the results. Function doSomething: Integer; var X : integer begin X := code to do something; doSomething := X; end. 1 Share this post Link to post
David Heffernan 2460 Posted 21 hours ago 3 hours ago, Freeeee said: code was from ? 2000,. Worked then. There wasn't a reserved word "Result" so you used the function name at the end of the code set equal to whatever variable you were using to get the results. Function doSomething: Integer; var X : integer begin X := code to do something; doSomething := X; end. What are you expecting anyone to do with this? 2 Share this post Link to post
Remy Lebeau 1641 Posted 20 hours ago 4 hours ago, Freeeee said: code was from ? 2000,. Worked then. There wasn't a reserved word "Result" so you used the function name at the end of the code set equal to whatever variable you were using to get the results. The Result variable (enabled by default via the {$EXTENDEDSYNTAX ON} / {$X+} directive) has been available for a very very long time, much earlier than 2000. But even so, assigning values to the function's name is still an allowed option, too. 2 Share this post Link to post
Sherlock 685 Posted 18 hours ago Just to clear and sum up: The error is in the 414 lines of code above this totally fine function. So, until one of the following two things happens, this will turn in to a merry game of guessing: 1) You provide us with the top 414 lines of code 2) You let your IDE format the code and discover formatting is "out of whack" beginning somewhere above line 415, and home in on the problem yourself In any case, I do hope you will provide us with the solution to this riveting riddle. Share this post Link to post