From 18e4705687b17f7fc94c733d869e8eed878431b0 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Mon, 5 Mar 2012 12:11:13 +0000 Subject: [PATCH] bugzilla 52818 - Added implementation for RANK() git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1297021 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../poi/ss/formula/eval/FunctionEval.java | 1 + .../apache/poi/ss/formula/functions/Rank.java | 129 ++++++++++++++++++ .../poi/ss/formula/functions/TestRank.java | 68 +++++++++ test-data/spreadsheet/FormulaEvalTestData.xls | Bin 167936 -> 167424 bytes test-data/spreadsheet/rank.xls | Bin 0 -> 28160 bytes 6 files changed, 199 insertions(+) create mode 100644 src/java/org/apache/poi/ss/formula/functions/Rank.java create mode 100644 src/testcases/org/apache/poi/ss/formula/functions/TestRank.java create mode 100644 test-data/spreadsheet/rank.xls diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 64508fdb80..df242e6444 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 52818 - Added implementation for RANK() 52682 - allow setting text with trailing carriage return in HSLF 52244 - use correct text attributes when presentation has multiple TxMasterStyleAtoms of the same type support setting background color of sheet tab in XSSF diff --git a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java index 65ca0f89ac..fb4f8d7252 100644 --- a/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java +++ b/src/java/org/apache/poi/ss/formula/eval/FunctionEval.java @@ -171,6 +171,7 @@ public final class FunctionEval { retval[212] = NumericFunction.ROUNDUP; retval[213] = NumericFunction.ROUNDDOWN; + retval[216] = new Rank(); retval[219] = new Address(); //Aniket Banerjee retval[220] = new Days360(); retval[221] = new Today(); diff --git a/src/java/org/apache/poi/ss/formula/functions/Rank.java b/src/java/org/apache/poi/ss/formula/functions/Rank.java new file mode 100644 index 0000000000..c6ff86068d --- /dev/null +++ b/src/java/org/apache/poi/ss/formula/functions/Rank.java @@ -0,0 +1,129 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.apache.poi.ss.formula.functions; + +import org.apache.poi.ss.formula.eval.AreaEval; +import org.apache.poi.ss.formula.eval.ErrorEval; +import org.apache.poi.ss.formula.eval.EvaluationException; +import org.apache.poi.ss.formula.eval.NumberEval; +import org.apache.poi.ss.formula.eval.OperandResolver; +import org.apache.poi.ss.formula.eval.RefEval; +import org.apache.poi.ss.formula.eval.ValueEval; + + +/** + * Returns the rank of a number in a list of numbers. The rank of a number is its size relative to other values in a list. + + * Syntax: + * RANK(number,ref,order) + * Number is the number whose rank you want to find. + * Ref is an array of, or a reference to, a list of numbers. Nonnumeric values in ref are ignored. + * Order is a number specifying how to rank number. + + * If order is 0 (zero) or omitted, Microsoft Excel ranks number as if ref were a list sorted in descending order. + * If order is any nonzero value, Microsoft Excel ranks number as if ref were a list sorted in ascending order. + * + * @author Rubin Wang + */ +public class Rank extends Var2or3ArgFunction { + + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1) { + + AreaEval aeRange; + double result; + try { + ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); + result = OperandResolver.coerceValueToDouble(ve); + if (Double.isNaN(result) || Double.isInfinite(result)) { + throw new EvaluationException(ErrorEval.NUM_ERROR); + } + aeRange = convertRangeArg(arg1); + } catch (EvaluationException e) { + return e.getErrorEval(); + } + return eval(srcRowIndex, srcColumnIndex, result, aeRange, true); + } + + public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1, ValueEval arg2) { + + AreaEval aeRange; + double result; + boolean order=false; + try { + ValueEval ve = OperandResolver.getSingleValue(arg0, srcRowIndex, srcColumnIndex); + result = OperandResolver.coerceValueToDouble(ve); + if (Double.isNaN(result) || Double.isInfinite(result)) { + throw new EvaluationException(ErrorEval.NUM_ERROR); + } + aeRange = convertRangeArg(arg1); + + ve = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex); + int order_value = OperandResolver.coerceValueToInt(ve); + if(order_value==0){ + order=true; + }else if(order_value==1){ + order=false; + }else throw new EvaluationException(ErrorEval.NUM_ERROR); + + } catch (EvaluationException e) { + return e.getErrorEval(); + } + return eval(srcRowIndex, srcColumnIndex, result, aeRange, order); + } + + private static ValueEval eval(int srcRowIndex, int srcColumnIndex, double arg0, AreaEval aeRange, boolean descending_order) { + + int rank = 1; + int height=aeRange.getHeight(); + int width= aeRange.getWidth(); + for (int r=0; rarg0 || !descending_order && valuerR)}9WEQjv4I^a#~F*Z==fajUog;b@vuj zb87w9YVK|b2WOa?=c%;|)qJeetrjV%I+jLFR7Is!LvhrPP7ouT`3NT>e)=c1Ve~%O z2HF7oiBqI<#U;=srcY4`b#`X5!e2>ocC}M(jAF>HQElVz#wnmrD;MwE#dFR^k9!!S z@wc0ta}IRrRfKY=?869DhPl}L4OH@bD3@`!wc6WE=&jS}QQ5bfPM7|w!7|slBDbWw zZgC3o!eGC(MG*ZSgnYCQMO-E$c_~wU118;ByWL(3!MnD)ga51B+I;WS)~>i3M~r^% zXLPpz4FCDtI)l9L=&?hs^;X(^1DLnc;U5rpr;J_mo&27*82i7_{2ODyq&wRlw)cC7 zJqLe=-_sZK3t&FVb)SGB-=4Ocy}gC2aP3(OqcX{F3G-8q`i)@z%5}ehpnx99^Hf08 z8i*aI_7bS{_YVjPx?LO5yEaIf>OX?@Q`#UCd|RdjWWOE_A#%o;m-43n2;a~i8Q9Yq z-Wd*i6xV=I7N#_M2Ly%p)Sk!oqK;cOM95l8Lx4f6RECuJ_JYf4e5QTtTw{B}!C=xP^b`#>*69}{l*e9$GPYk)jg`iJ`|mxmZF(J}El z&B@RIpxig2T*adf92{#eKkmT4J8(|iy{g;+2Rg;u%f$}taG*Xxr0bT(P$H=B<5cuv277A+Hq}bte&7$l;ZuoLz`>saUIPxem#6`|Y&-BX zpnDi;C z;5kHv@Qqz_u>Nm@h`gUD56-a__&U&cF41^6$$H>Hpsoa#!zb1P_W^GLqu>+Or9@kR z-vT4x6V+uX1Fr%-;1ebDpaXaTsDV$+EQbzYH}E=jZ^w z4@_7H zpf`M?yoTs;;Ki9Bba0CFTB17Oi@?jklsckH_{Q77AAmFJiPpe3z5p8G3uO)H6nF{f z3|~lVB&q@K1zrI9D?hBL_1X}U|Hxl-)2in>JHM7Q?Ri&a`O3lO#Ff~M?L;S^N7r3& zn>R5b?_k2O5PkG1T=1{h#W#t*`VpH=!{|o?qo>^&b@?zl(~r>;k&GS~%xK?GM!_Q( zS>hS}X(S^}G9$f-QQAaCgQhWhu!NDZn$d3-GupM9k>7)i);+=|(6!Bs+_y1m-O1?j zT~P2mqZbaMlUErP9Ah-)ETjA1XVm;9BlaDmG8?1AdQP)EISuu-l&qSr3x^Xpn@B#Z z5WWofk(-I&Yiilq^5U9CzF;Zc{pUunQW%8U&(tr4N-3fFml8ja3&B@uneyl_3lmn- z3^?+uXsIJ77_o|0lQY?6TxccDRBJs@>#EkGUh#ckNZMk`g^pLr2Q@}o((4!GXx)$I z(jK(7>x!mkHLfzQCp}s&x2$@gjd?c_1zhinCdtO!fbF^NY398M?tMJf&c+mh{l-I9 zRXX>KgN^M1_M__?RO!v<9Bk|wust4)RHbhz!KMK_?XhH4y8Jzdw3}or>mR?tmMg6r zK0!Wz<1XYLo1R5}Xj2FBYULdAahvxd|MTV=w!$)F%TzBc|FchfGVSFH7M*hBnK4>= z55)J+jMoN&u#DTaSKR5b(ved_r1wc_|yJ-kQ+K=K2pug)co-d_^0JS$3odI z><}DP$yW0QnOn9UN@v;=va`#F)3y6SSO&e6FBL910#%mZ9a)EhWmxC48c#EA!o15V zoda(%TRwShKTfks`>|-`M~?MJeo5w=-uU!DH{%Gw-t;bwp?_ef8@Q29(tTLdLjKl) z6Uo>}%9vBKVTsHw51e{N?dPp7&T1@Qo!u`5o;*JgRo&-@%fh$sO1a<*Yo&2dUX+D5 zE`Bd-x-QAWrq7^UzZ&BuJGf;*T>ATVn!D}PI@ge*6MMtS5jtyoQ zlJ(Dn+4e}SK7xJ_>vF)+iG4Y2FwJA00^{^IkkED;d8 zO@({6u`#T__0er?i>KL{Y#1vZ<_YKU!V8cgK=kDm-Gw*fF1(p{;my7aulP0(Q{(7( zu4GzYc$O{InDsOmhG;0wZW?)|;^nE)+I%Pj;iW5D#u%qAmo5{(0BR^?wYOx4Ll$jq zesX1XQq}-j*Df3wOqw2X-7WEJ6QsDdkGNTtXT9Y0x7;F1Rj;$l8+xhlE$(zn+^CA{ z?-cKCjRE2uXK5VTF!6=j*-k&gdIM>Dskh6^U|Xc+u>L(rzd}(c*{8`XRZiA$HNQ4N zI&oC0%#Ep-1#FHYt?b2_m&Y38sBV`EhH`&)BbvoBscXYFIcJL%Cg$dTO)9lyi zyZx-{+XK(CUrX+>x7k>@eES7E_X695oh}YvX3#Faxy)t(@~*HH!1^n!5b)s@hBJZi z`G}eDE(+KA*#?O(Kf=CP`4JnUa{PNZXFg&wUVQcu%K{9)$_mh<`6|=+1J~YUoqAUD zVmcqnS)HioJQ}bC;8aKT@+XdR9u$f*5?!7k^R5Y6yh}Z(Qm3N^yNLB4oEtGJ;il)Y zfD}DXL?AHhyk#Kp#oFT?EMpQlR7gD0;T~eM9^H}kB|Z0XLc25WvM9c>Ly!kYfU}PE z;ARg^!8D8Yl@MNw6%#|l_@L02GRZSd8v|bpg|}(+*yz}P=mnIss1M_T9z|ODDrImN zP_EW3VZ4U96bEuzJ&=>jAf;s04(qN6zSmuYaA=(|oKNEVZ|~u>FBw%&STo|dpQ~C` zJdTgob4{0Zhl!^%{it!As!}1-V4ar1H*2Mg`0GSIl>;YC;zz~)NBFPWC-bHJhDI!( z%$MtMZlxk|b249{!;6a+h-En-aR{aN#LXO@Zj|1K!>sB`IJBy$6!39cS)pv`AG}@qP2xC}U%{6f3b=7&`e)uF5+5U|3b`ds(k6>CcWeVQ|xYEok zHa3Ka<@wyl)u3)$oT|sU36al3=gL-$wL*uhPb8NmkR?c}K1W#=)p8HIIZE=2nCKC_ zGh~fjhOZ4%^~kOoL|g$6cE^ViMLVi@ia7;5$7`Y#cRYw5B==It#s;mtBorSO@GxT% zjigwbPe~L{qdKzy}JiwOns)pUz_#?DzP8yPd%!+l%-igMCG9w)UC4 zSr>&a&xvI-;lqh4c~g=ZcJ3^`LSH0Fji@W&{Wdnt7h`7sXVw<~yVlO>J4ydxw zx26BpZp;7OZY%z)-Bvof^*voGWZ1Mh!`Wr}Sj)saReYEjSjUq@QVn0%UJWNG#~Lpd z%c`;Rn?P2In;`W&Kz3`z@`Zf4>weIMyA)N-RRHgT_E zxJV}tya&C2K1fE;{z!ppoKPbU{2E{9b0a6ai_#_@9n7VHKY6rjl+lUO0`4n**TnmI z^bHZ4x-;zIbYgduooMLJ4U`+F0~SiO0DteGmGj+EX_DCm#!;l#kX}bRh9vpjz~e|K zklsW(iF69-G?J`;OX9}T^U$PF3-$DrtOAlnRrj)lF&(Ok3U_Q9&_X69{%&j#vA_TJ(=w%w%1ksF5&$i zetE(DU#)Ae${G0B4`DB7mp=VzPld!v7~QH4Gm!a_hLsPpCN1F}Of(m8Bi?#x_N~y5 z%hyQ=*B}o^6Q^6FmP(?rWt?abWL#(nWL#+|*W$Kh7}t@zIEq~nWPpgx=F)4rWJ8uYQ4 zd7W0DS2eGxei7BrZ;mLeEN!BS^5XogtV!vV8JAd`SC~IMHX}E8z=K|E^CIHBTN@+t z%i4}cO-V&uHhC~T?Jdus7XAYM zu;=U*pXp@?X~k`bd7_EM9eu4q?wc?ZXS(0sW9s+$+5RTOP!nznUTZ9>tXhOiy{3g_ z_4Nz0$t5sVUzED2iWbqD8Lbgbw2;cWSap3D>-Uyx{6*J4L`65AjcVgcw@ z{go9J&16d3S(rNDKt)$eGqt5mxqVgwVq zl|0*wNmrdfI)Y4C2i)oPO<1|rxSv$dEV#3D95R^WtYQyDU{m;+J-b7S4U@NwT&};k zbzd32N1@Ih&1JnB;IZ&}V(TL8TI5;!u)J-MvRGl ztGK^P59vjx^`d9lX)h_?D7P9OEj$$C_vgtP75ZycNYhC$LkI&^PmNsOl1(?I6*SdX zSIlb$n>&G{`bR|^#)No*v$eX^_LY_*(w;)OesO(D@qJ1OeM*VYrTH4)qw+67)CItk z1?7B%_=TCr-zSZNt4U*ElgmSnk;tjiV(H{@ufxF$l3MUM0<66t*Hhzbuvc~2d09Aj z@m%Qhl34g;X!MwS1m+@cK(L@T97FPbSsJs`lSDA4c(T;oHWe z&FY*iYA&y@sgU|NI&?_=4z+aH!IN$xp8`8La;ZP}?03VypB?P=$|tmkGA`YVHRTgf zpFXA-3$&oAv^FBEs-|L*Jv7ug3Nk#1FWPuSxoSlI{P|V$R3nx-IJK-8_`t-4NsKXLTu>X+N7^*7^kB{cJ8B%2~Yf7!PogYlczD z*yzWa)rMmATE6C)2RLj01#e~tM9VL@nY}2!1?V~42~Mu90Ma#Yf&w9!eUO{0_T3Hv&H5WppNO|0|OGu>B56`abTO@Rvz^a{%S1V+c^L z=x&_9AL7%U<i=kH@U4^}y4G=AJcz7^`NJFy-hP<>574@2 aJ)h3nAHyl{3|cP~9dSIzdh9Vij{P4pT#pq1 delta 8917 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 diff --git a/test-data/spreadsheet/rank.xls b/test-data/spreadsheet/rank.xls new file mode 100644 index 0000000000000000000000000000000000000000..4d2521af4b57c7566e088c3f95524869127efb1f GIT binary patch literal 28160 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 BaJc{g literal 0 HcmV?d00001 -- 2.39.5