Case Statement bug?
RB Enterprise 10.03, Delphi 2006
Negative values in a case statement are giving me an AccessViolation, e.g.
if Pms_Project['PMS_PROJECT-Proj Rep Milestones'] <> null then
begin
i:= Pms_Project['PMS_PROJECT-Proj Rep Milestones'];
case i of
-100..0: milestonesLabel.font.color := clGreen;
1..4: milestonesLabel.font.color := clAmber;
5..100: begin
milestonesLabel.font.color := clRed;
end;
end;
end
else
milestonesLabel.text := '';
if I lose the -100 then all is fine. Moreover, if I declare a variable or
constant first and assign -100 then I get the following error snip (as
trapped by madExcept). Any ideas?
Paul
date/time : 2006-07-19, 23:54:41, 328ms
computer name : MAINCOMPUTER
user name : Administrator
operating system : Windows XP Service Pack 2 build 2600
system language : English
system up time : 5 days 11 hours
program up time : 1 minute 13 seconds
processors : 4x Intel(R) Xeon(TM) CPU 2.66GHz
physical memory : 1642/2048 MB (free/total)
free disk space : (C:) 12.15 GB (E:) 25.17 GB
display mode : 1280x1024, 32 bit
process id : $914
allocated memory : 47.89 MB
executable : SAPS_MS.exe
exec. date/time : 2006-07-19 22:31
version : 1.0.0.16
madExcept version : 2.7i
exception class : EListError
exception message : List index out of bounds (-1).
Main ($1658):
00451499 SAPS_MS.exe Classes TList.Get
006d2737 SAPS_MS.exe raStatem TraCaseStatement.GetValueForIndex
006d2e1f SAPS_MS.exe raStatem TraCaseStatement.ReadCaseCondition
006d2a51 SAPS_MS.exe raStatem TraCaseStatement.Build
006cd286 SAPS_MS.exe raClass TraProgram.ReadStatement
Negative values in a case statement are giving me an AccessViolation, e.g.
if Pms_Project['PMS_PROJECT-Proj Rep Milestones'] <> null then
begin
i:= Pms_Project['PMS_PROJECT-Proj Rep Milestones'];
case i of
-100..0: milestonesLabel.font.color := clGreen;
1..4: milestonesLabel.font.color := clAmber;
5..100: begin
milestonesLabel.font.color := clRed;
end;
end;
end
else
milestonesLabel.text := '';
if I lose the -100 then all is fine. Moreover, if I declare a variable or
constant first and assign -100 then I get the following error snip (as
trapped by madExcept). Any ideas?
Paul
date/time : 2006-07-19, 23:54:41, 328ms
computer name : MAINCOMPUTER
user name : Administrator
operating system : Windows XP Service Pack 2 build 2600
system language : English
system up time : 5 days 11 hours
program up time : 1 minute 13 seconds
processors : 4x Intel(R) Xeon(TM) CPU 2.66GHz
physical memory : 1642/2048 MB (free/total)
free disk space : (C:) 12.15 GB (E:) 25.17 GB
display mode : 1280x1024, 32 bit
process id : $914
allocated memory : 47.89 MB
executable : SAPS_MS.exe
exec. date/time : 2006-07-19 22:31
version : 1.0.0.16
madExcept version : 2.7i
exception class : EListError
exception message : List index out of bounds (-1).
Main ($1658):
00451499 SAPS_MS.exe Classes TList.Get
006d2737 SAPS_MS.exe raStatem TraCaseStatement.GetValueForIndex
006d2e1f SAPS_MS.exe raStatem TraCaseStatement.ReadCaseCondition
006d2a51 SAPS_MS.exe raStatem TraCaseStatement.Build
006cd286 SAPS_MS.exe raClass TraProgram.ReadStatement
This discussion has been closed.
Comments
- here is a tech tip about checking for null values, I think that might be
causing the AV
- I tried creating a case statement with a negative value and it worked
properly in my testing here
----------------------------------------------
Tech Tip: RAP: Checking for Null Data values
----------------------------------------------
The DataPipeline.FieldObjects[] array property provides access to the
TppField objects. TppField has an IsNull boolean property.
The notation is DataPipeline.FieldObjects['FieldName'].IsNull
example:
if Customer.FieldObjects['Addr1'].IsNull then
ShowMessage('field value is null');
--
Tech Support mailto:support@digital-metaphors.com
Digital Metaphors http://www.digital-metaphors.com
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
an AV. Moreover, if I change the literals (-9999 and 9999) to constants I
get "Index Out of Bounds error (-1)" in the code editor or maybe the 3rd or
4th use of the constant is not recognised by the compiler:
const
circle = 'n';
square = 'g';
upTriangle = '5';
downTriangle = '6';
clAmber = 6730751;
begin
{always test for null first otherwise if null we get an A/V}
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Stat Funding'].isnull
then
begin
case Pms_Project['PMS_PROJECT-Proj Stat Funding'] of
0:
begin
financeLabel.text := square;
financeLabel.font.color := clLime;
end;
1:
begin
financeLabel.text := upTriangle;
financeLabel.font.color := clAmber;
end;
2:
begin
financeLabel.text := upTriangle;
financeLabel.font.color := clRed;
end;
3:
begin
financeLabel.text := downTriangle;
financeLabel.font.color := clAmber;
end;
4:
begin
financeLabel.text := downTriangle;
financeLabel.font.color := clRed;
end;
end;
end
else
financeLabel.text := '';
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Rep Claims'].isnull then
begin
claimsLabel.text :=circle ;
case Pms_Project['PMS_PROJECT-Proj Rep Claims']of
-9999..0: claimsLabel.font.color := clGreen;
1..4: claimsLabel.font.color := clAmber;
5..9999: claimsLabel.font.color := clRed;
end;
end
else
claimsLabel.text := '';
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Rep Human'].isnull then
begin
humanLabel.text :=circle ;
case Pms_Project['PMS_PROJECT-Proj Rep Human'] of
-9999..0: humanLabel.font.color := clGreen;
1..4: humanLabel.font.color := clAmber;
5..9999: humanLabel.font.color := clRed;
end;
end
else
humanLabel.text := '';
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Rep Other'].isnull then
begin
otherLabel.text :=circle ;
case Pms_Project['PMS_PROJECT-Proj Rep Other'] of
-9999..0: otherLabel.font.color := clGreen;
1..4: otherLabel.font.color := clAmber;
5..9999: otherLabel.font.color := clRed;
end;
end
else
otherLabel.text := '';
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Rep Milestones'].isnull
then
begin
milestonesLabel.text :=circle ;
case Pms_Project['PMS_PROJECT-Proj Rep Milestones'] of
-9999..0: milestonesLabel.font.color := clGreen;
1..4: milestonesLabel.font.color := clAmber;
5..9999: milestonesLabel.font.color := clRed;
end;
end
else
milestonesLabel.text := '';
if not Pms_Project.fieldobjects['PMS_PROJECT-Proj Stat Outputs'].isnull
then
begin
case Pms_Project['PMS_PROJECT-Proj Stat Outputs'] of
0:
begin
OutputsLabel.text := square;
OutputsLabel.font.color := clLime;
end;
1:
begin
OutputsLabel.text := upTriangle;
OutputsLabel.font.color := clAmber;
end;
2:
begin
OutputsLabel.text := upTriangle;
OutputsLabel.font.color := clRed;
end;
3:
begin
OutputsLabel.text := downTriangle;
OutputsLabel.font.color := clAmber;
end;
4:
begin
OutputsLabel.text := downTriangle;
OutputsLabel.font.color := clRed;
end;
end;
end
else
OutputsLabel.text := '';
end;
example below is much more complex.
- I would modify that code so that when not null the
{Pms_Project['PMS_PROJECT-Proj Stat Funding'] value is placed into a local
variable. Then use the local variable in the case statement. Same for the
other case statements in that code. I notice in those there is no check for
IsNull, perhaps add that.
- Try creating some RAP global procedures/functions that each contain
logical parts of that code. Then you can call the functions. This will break
things up and you can put some showmessage calls in between each.
- once you encounter an AV, I would exit the application, otherwise you can
encounter other errors that are caused by the AV corrupting the memory.
Hopefully doing the above will either solve the problem or at least help to
narrow things to down to a small section of code that enables you to create
a simple test case that we can run here.
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
fact I only removed it to clarify the code before posting it up. But lets
face it, nothing I write in my RAP code should create an AV unless I am
doing anything that affects memory allocation. So something must be going on
in the implementation of CASE in RAP that is fouling up. I'm not in a
desperate situation because if I code around it with the
HighNumberForNegatives constant kludge it all works fine (you'll see how I
do use a local variable to get the field value in this one, but I was doing
that in the other routine that fails too):
const
circle = 'n';
square = 'g';
upTriangle = '5';
downTriangle = '6';
clAmber = 6730751;
HighNumberForNegatives = 999999;
var
i: integer;
begin
{always test for null first otherwise if null we get an A/V}
if Pms_Project['PMS_PROJECT-Proj Stat Funding'] <> null then
begin
i := Pms_Project['PMS_PROJECT-Proj Stat Funding'];
case i of
0:
begin
financeLabel.text := square;
financeLabel.font.color := clLime;
end;
1:
begin
financeLabel.text := upTriangle;
financeLabel.font.color := clAmber;
end;
2:
begin
financeLabel.text := upTriangle;
financeLabel.font.color := clRed;
end;
3:
begin
financeLabel.text := downTriangle;
financeLabel.font.color := clAmber;
end;
4:
begin
financeLabel.text := downTriangle;
financeLabel.font.color := clRed;
end;
end;
end
else
financeLabel.text := '';
if Pms_Project['PMS_PROJECT-Proj Rep Claims'] <> null then
begin
claimsLabel.text :=circle ;
i := Pms_Project['PMS_PROJECT-Proj Rep Claims'];
if i <= 0 then
i := HighNumberForNegatives;
case i of
1..4: claimsLabel.font.color := clAmber;
5..999998:
begin
claimsLabel.font.color := clRed;
end;
HighNumberForNegatives: claimsLabel.font.color := clGreen;
end;
end
else
claimsLabel.text := '';
if Pms_Project['PMS_PROJECT-Proj Rep Human'] <> null then
begin
humanLabel.text :=circle ;
i := Pms_Project['PMS_PROJECT-Proj Rep Human'];
if i <= 0 then
i := HighNumberForNegatives;
case i of
1..4: humanLabel.font.color := clAmber;
5..999998:
begin
humanLabel.font.color := clRed;
end;
HighNumberForNegatives: humanLabel.font.color := clGreen;
end;
end
else
humanLabel.text := '';
if Pms_Project['PMS_PROJECT-Proj Rep Other'] <> null then
begin
otherLabel.text :=circle ;
i := Pms_Project['PMS_PROJECT-Proj Rep Other'];
if i <= 0 then
i := HighNumberForNegatives;
case i of
1..4: otherLabel.font.color := clAmber;
5..999998:
begin
otherLabel.font.color := clRed;
end;
HighNumberForNegatives: otherLabel.font.color := clGreen;
end;
end
else
otherLabel.text := '';
if Pms_Project['PMS_PROJECT-Proj Rep Milestones'] <> null then
begin
milestonesLabel.text :=circle ;
i := Pms_Project['PMS_PROJECT-Proj Rep Milestones'];
if i <= 0 then
i := HighNumberForNegatives;
case i of
1..4: milestonesLabel.font.color := clAmber;
5..999998:
begin
milestonesLabel.font.color := clRed;
end;
HighNumberForNegatives: milestonesLabel.font.color := clGreen;
end;
end
else
milestonesLabel.text := '';
if Pms_Project['PMS_PROJECT-Proj Stat Outputs'] <> null then
begin
i := Pms_Project['PMS_PROJECT-Proj Stat Outputs'];
case i of
0:
begin
OutputsLabel.text := square;
OutputsLabel.font.color := clLime;
end;
1:
begin
OutputsLabel.text := upTriangle;
OutputsLabel.font.color := clAmber;
end;
2:
begin
OutputsLabel.text := upTriangle;
OutputsLabel.font.color := clRed;
end;
3:
begin
OutputsLabel.text := downTriangle;
OutputsLabel.font.color := clAmber;
end;
4:
begin
OutputsLabel.text := downTriangle;
OutputsLabel.font.color := clRed;
end;
end;
end
else
OutputsLabel.text := '';
end;
please create a simple test case using the DBDemos data and email to
support@digital-metaphors.com in zip format. We can run it here and examine
it in the debugger.
--
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com