Example #1
0
        public override ValueEval Evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg0, ValueEval arg1)
        {
            double s0;
            String s1;
            try
            {
                s0 = TextFunction.EvaluateDoubleArg(arg0, srcRowIndex, srcColumnIndex);
                s1 = TextFunction.EvaluateStringArg(arg1, srcRowIndex, srcColumnIndex);
            }
            catch (EvaluationException e)
            {
                return e.GetErrorEval();
            }
            if (Regex.Match(s1, "[y|m|M|d|s|h]+").Success)
            {
                //may be datetime string
                ValueEval result = TryParseDateTime(s0, s1);
                if (result != ErrorEval.VALUE_INVALID)
                    return result;
            }
            //The regular expression needs ^ and $. 
            if (Regex.Match(s1, @"^[\d,\#,\.,\$,\,]+$").Success)
            {
                //TODO: simulate DecimalFormat class in java.
                FormatBase formatter = new DecimalFormat(s1);
                return new StringEval(formatter.Format(s0));
            }
            else if (s1.IndexOf("/", StringComparison.Ordinal) == s1.LastIndexOf("/", StringComparison.Ordinal) && s1.IndexOf("/", StringComparison.Ordinal) >= 0 && !s1.Contains("-"))
            {
                double wholePart = Math.Floor(s0);
                double decPart = s0 - wholePart;
                if (wholePart * decPart == 0)
                {
                    return new StringEval("0");
                }
                String[] parts = s1.Split(' ');
                String[] fractParts;
                if (parts.Length == 2)
                {
                    fractParts = parts[1].Split('/');
                }
                else
                {
                    fractParts = s1.Split('/');
                }

                if (fractParts.Length == 2)
                {
                    double minVal = 1.0;
                    double currDenom = Math.Pow(10, fractParts[1].Length) - 1d;
                    double currNeum = 0;
                    for (int i = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i > 0; i--)
                    {
                        for (int i2 = (int)(Math.Pow(10, fractParts[1].Length) - 1d); i2 > 0; i2--)
                        {
                            if (minVal >= Math.Abs((double)i2 / (double)i - decPart))
                            {
                                currDenom = i;
                                currNeum = i2;
                                minVal = Math.Abs((double)i2 / (double)i - decPart);
                            }
                        }
                    }
                    FormatBase neumFormatter = new DecimalFormat(fractParts[0]);
                    FormatBase denomFormatter = new DecimalFormat(fractParts[1]);
                    if (parts.Length == 2)
                    {
                        FormatBase wholeFormatter = new DecimalFormat(parts[0]);
                        String result = wholeFormatter.Format(wholePart) + " " + neumFormatter.Format(currNeum) + "/" + denomFormatter.Format(currDenom);
                        return new StringEval(result);
                    }
                    else
                    {
                        String result = neumFormatter.Format(currNeum + (currDenom * wholePart)) + "/" + denomFormatter.Format(currDenom);
                        return new StringEval(result);
                    }
                }
                else
                {
                    return ErrorEval.VALUE_INVALID;
                }
            }
            else
            {
                return TryParseDateTime(s0, s1);
            }
        }
            /// <summary>
            /// Formats a number or date cell, be that a real number, or the
            /// answer to a formula
            /// </summary>
            /// <param name="cell">The cell.</param>
            /// <param name="value">The value.</param>
            /// <returns></returns>
            private String FormatNumberDateCell(CellValueRecordInterface cell, double value)
            {
                // Get the built in format, if there is one
                int formatIndex = ft.GetFormatIndex(cell);
                String formatString = ft.GetFormatString(cell);

                if (formatString == null)
                {
                    return value.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    // Is it a date?
                    if (Zephyr.Utils.NPOI.SS.UserModel.DateUtil.IsADateFormat(formatIndex, formatString) &&
                            Zephyr.Utils.NPOI.SS.UserModel.DateUtil.IsValidExcelDate(value))
                    {
                        // Java wants M not m for month
                        formatString = formatString.Replace('m', 'M');
                        // Change \- into -, if it's there
                        formatString = formatString.Replace("\\\\-", "-");

                        // Format as a date
                        DateTime d = Zephyr.Utils.NPOI.SS.UserModel.DateUtil.GetJavaDate(value, false);
                        SimpleDateFormat df = new SimpleDateFormat(formatString);
                        return df.Format(d);
                    }
                    else
                    {
                        if (formatString == "General")
                        {
                            // Some sort of wierd default
                            return value.ToString(CultureInfo.InvariantCulture);
                        }

                        // Format as a number
                        DecimalFormat df = new DecimalFormat(formatString);
                        return df.Format(value);
                    }
                }
            }