Current filter:
                                You should refresh the page.
                                  • Hi,

                                     TcxPivotGridCrossCellSummary.CalculateSummaryVariation under some circumstances lets  math/variant exceptions raise just to immediately catch and handle them by simply assigning "null" to the variable being calculated. 

                                      This happens only in one of the two nested procedures contained in this method: the other explicitly tests the divisor for being not null and not zero before attempting to perform the division.. and this is far more "debugger-friendly": the application does not continuosly break into the debugger every time a zero (or null) divisor is found.

                                    You would please fix the CalculateRelation nested procedure in order to behave like the other one? You would just need to change this:

                                      procedure CalculateRelation;
                                      ....
                                      begin
                                        ....
                                        try

                                            ....

                                             FSummaryVariation := AValue / AOwnerValue *  100; // <<<<<<<
                                        except
                                          on EMathError do FSummaryVariation := Null;
                                          on EDivByZero do FSummaryVariation := Null;
                                          on EVariantError do FSummaryVariation := Null;
                                        else
                                          raise;
                                        end;
                                      end;

                                    to this:

                                      procedure CalculateRelation;
                                      ....
                                      begin
                                        ....
                                        try

                                            ....

                                            if VarIsNull(AOwnerValue) or (VarIsNumericEx(AOwnerValue) and (AOwnerValue=0)) then  // <<<<<<<
                                              FSummaryVariation := null     // <<<<<<<
                                             else                                           // <<<<<<<                         
                                              FSummaryVariation := AValue / AOwnerValue *  100;  // <<<<<<<
                                        except
                                          on EMathError do FSummaryVariation := Null;
                                          on EDivByZero do FSummaryVariation := Null;
                                          on EVariantError do FSummaryVariation := Null;
                                        else
                                          raise;
                                        end;
                                      end;

                                    thank you.


                                Show all comments
                                • Carlo Sirna 10.07.2014

                                  Another cause of continuos exceptions (that get immediately caught and handled for returning NULL, but annoy the programmer running the program in the debugger) is in this method:

                                  function TcxPivotGridField.GetGroupValue(ARecordIndex: Integer): Variant;:

                                  that tries to convert the value Values[ARecordIndex] (using the proper conversion imposed by AGroupInterval) without testing for nullness and then uses a try/except to have the function return null if some error has been raised

                                  99,9% of the exceptions could be avoided by explicitly testing for the nullness of  Values[ARecordIndex], by simply adding this line of code right at the beginning of the method:

                                  function TcxPivotGridField.GetGroupValue(ARecordIndex: Integer): Variant;
                                   ....
                                  begin
                                   Result := Values[ARecordIndex];
                                   if vartype(Result) in [varEmpty,varNull] then   exit (null);  <<----- just add THIS LINE

                                • Carlo Sirna 10.07.2014

                                  Here is another one: (I am not a wizard discovering these things in a couple of seconds: these are fixes I have been manually applying for the last years every time I get an updated version of the devexpress sources. I just decided that maybe it would be better to let you know about them (more to come.. I'll send you a comment for each of them. the problem is always the same: the code relies on exceptions for handling things that are not "exceptional" at all and may happen continuosly, forcing the programmer to disable the "stop on exception" feature even for exceptions that usually are proper bugs:

                                   function TcxPivotGridMapsInfo.CheckNativeValue(AProperties: TcxCustomEditProperties;
                                     APivotField: TcxPivotGridField; const AValue: Variant): Variant;
                                   begin
                                  // --- this avoids exceptions when AValue is null                          
                                  if vartype(AValue) in [varempty, varnull] then begin
                                     result := null;
                                     exit;
                                  end;
                                  //---

                                • Carlo Sirna 10.07.2014

                                  here is another one:

                                  function TcxGridCustomExport.CheckNativeValue(AProperties: TcxCustomEditProperties;
                                   AItem: TcxCustomGridTableItem; const AValue: Variant): Variant;
                                  begin
                                   // --- this avoids exceptions when AValue is null  
                                   if vartype(AValue) in [varempty, varnull] then begin
                                      result := null;
                                      exit;
                                   end;
                                   // ----

                                • Paulo (DevExpress Support) 10.07.2014
                                  Hello Carlo,

                                  Would you please provide us with a small sample project so we can precisely replicate your scenario on our side?
                                • Carlo Sirna 10.08.2014

                                  Actually, I'd rather not waste half a day in writing toy applications to reproduce a problem that is clearly visible by simply  looking at the code: all the pieces of code I pointed out are making divisions or variant conversions on data that is taken from the grid without testing for null or zero values before taking the action.
                                  These pieces of code do return null (or assign null to the variable being calculated) whenever a variant or edivbyzero happens,.
                                  The modifications i am suggesting are identical to the same modifications you ALREADY did apply to other parts of code that had the very same problem (just look at the other local procedure i am referring in my first post: you already fixed that one. Versions ago it had the same problem)
                                  This is the problem:
                                  1) since calculations are  done on data coming from a DB it is perfecly normal that some cell may contain null or zero,  so here we have code that relies on exceptions to handle things that normally happen.  And they may happen VERY often, depending on the data. The fix i am proposing does not change the behavior of the procedures: it just lets them carry out  the very same results without raising exceptions for things that are not exceptional (i did not remove the exception block: i just handled separately  the null and zero cases
                                  2) exception handling is slow. And it becomes a hundreds of times slower if you are including in your application an exception logging mechanism like Eurekalog,  madexcept or,  in my case, jcldebug: these tools do perform a complete stack trace every time an exception to be tracked is raised...  And surely a division by zero is something that can't be ignored - generally speaking - . Actually i have my application send me a bug report every time a Edivbyzero or a variant conversion error happens (even for handled exceptions: i simply don't want them to be rised,  since I consider it a very bad programming practice to let such things happen just to "fix" them in the exception block,  but i don't want to start a religion war on this) . If i don't apply the above fixes I get actually mailbombed by such bugreports. Just let me point out that my application is very big,  uses a lot of third party components but the only one raising Edivbyzero exceptions is expresspivotgrid
                                  3) actually is very annoying to have the application stop in the debugger just because the programmer preferred to let exceptions happen instead of testing for zero or null. And surely i don't want to disable this debugger feature just because i have just one component that has been written this way.
                                  4) as I already said i noticed that you already did fix many other parts of this component by doing exacly what i am suggesting. The list of fixes i have to apply on earlier versions once was much longer. What i can guess is that some other developer,  in your team, got annoyed by the debugger continuously stopping the execution of the program and fixed the lines of code that were causing his annoyance while trying to hunt some other bug.
                                  5) i am sure that the lines of code i identified do actually (not just in theory) raise such exceptions because, as i said,  i got bugreport-bombed by my customers (such bugreports are sent transparently, even if the application handles the exceptions),  but it is not that easy for me to reproduce the data they are working on when this happens... What is sure is that i keep a log of all exceptions that - generally speaking - should never be raised,  and having a component that raises them on purpose (and this is the ONLY component doing it)  is slowing down the calculations done by the component itself
                                  6) since my fixe does not change at all the behavior of the component and lets it raise less exceptions...  Is there any good reason for not applying it?

                                  Thank you

                                • Paulo (DevExpress Support) 10.08.2014
                                  We are working on your request, but it can take us some time to research and discuss it with developers. I will get back to you once we have any results or need additional information. Thank you for your patience.
                                • Paulo (DevExpress Support) 10.21.2014

                                  We have examined our code and see that your suggestion has merits. The code may reduce the number of exceptions when processing Null values. We will possibly implement similar code with future versions of our controls. However, other exceptions (unrelated to Nulls) will be raised in any way.

                                0 Solutions

                                Creation Date Importance Sort by