Jump to content
Registration disabled at the moment Read more... ×
Freeeee

what wrong with this function?

Recommended Posts

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

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

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 by dummzeuch

Share this post


Link to post

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

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 by Remy Lebeau
  • Like 1

Share this post


Link to post

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
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

 

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×