Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/FormulaParsing/CalculateExtentions.cs @ 15888

Last change on this file since 15888 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 8.4 KB
Line 
1/*******************************************************************************
2 * You may amend and distribute as you like, but don't remove this header!
3 *
4 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
5 * See http://www.codeplex.com/EPPlus for details.
6 *
7 * Copyright (C) 2011  Jan Källman
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
17 * See the GNU Lesser General Public License for more details.
18 *
19 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
20 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
21 *
22 * All code and executables are provided "as is" with no warranty either express or implied.
23 * The author accepts no liability for any damage or loss of business that this product may cause.
24 *
25 * Code change notes:
26 *
27 * Author             Change            Date
28 * ******************************************************************************
29 * Jan Källman                      Added                       2012-03-04 
30 *******************************************************************************/
31
32using System.Threading;
33using OfficeOpenXml.FormulaParsing.LexicalAnalysis;
34using System;
35using System.Collections.Generic;
36using System.Linq;
37using System.Text;
38using OfficeOpenXml.FormulaParsing;
39using OfficeOpenXml.FormulaParsing.Exceptions;
40namespace OfficeOpenXml
41{
42    public static class CalculationExtension
43    {
44        public static void Calculate(this ExcelWorkbook workbook)
45        {
46            Calculate(workbook, new ExcelCalculationOption(){AllowCirculareReferences=false});
47        }
48        public static void Calculate(this ExcelWorkbook workbook, ExcelCalculationOption options)
49        {
50            Init(workbook);
51
52            var dc = DependencyChainFactory.Create(workbook, options);
53            workbook.FormulaParser.InitNewCalc();
54            if (workbook.FormulaParser.Logger != null)
55            {
56                var msg = string.Format("Starting... number of cells to parse: {0}", dc.list.Count);
57                workbook.FormulaParser.Logger.Log(msg);
58            }
59
60            //TODO: Remove when tests are done. Outputs the dc to a text file.
61            //var fileDc = new System.IO.StreamWriter("c:\\temp\\dc.txt");
62                       
63            //for (int i = 0; i < dc.list.Count; i++)
64            //{
65            //    fileDc.WriteLine(i.ToString() + "," + dc.list[i].Column.ToString() + "," + dc.list[i].Row.ToString() + "," + (dc.list[i].ws==null ? "" : dc.list[i].ws.Name) + "," + dc.list[i].Formula);
66            //}
67            //fileDc.Close();
68            //fileDc = new System.IO.StreamWriter("c:\\temp\\dcorder.txt");
69            //for (int i = 0; i < dc.CalcOrder.Count; i++)
70            //{
71            //    fileDc.WriteLine(dc.CalcOrder[i].ToString());
72            //}
73            //fileDc.Close();
74            //fileDc = null;
75
76            //TODO: Add calculation here
77
78            CalcChain(workbook, workbook.FormulaParser, dc);
79
80            //workbook._isCalculated = true;
81        }
82        public static void Calculate(this ExcelWorksheet worksheet)
83        {
84            Calculate(worksheet, new ExcelCalculationOption());
85        }
86        public static void Calculate(this ExcelWorksheet worksheet, ExcelCalculationOption options)
87        {
88            Init(worksheet.Workbook);
89            //worksheet.Workbook._formulaParser = null; TODO:Cant reset. Don't work with userdefined or overrided worksheet functions           
90            var dc = DependencyChainFactory.Create(worksheet, options);
91            var parser = worksheet.Workbook.FormulaParser;
92            parser.InitNewCalc();
93            if (parser.Logger != null)
94            {
95                var msg = string.Format("Starting... number of cells to parse: {0}", dc.list.Count);
96                parser.Logger.Log(msg);
97            }
98            CalcChain(worksheet.Workbook, parser, dc);
99        }
100        public static void Calculate(this ExcelRangeBase range)
101        {
102            Calculate(range, new ExcelCalculationOption());
103        }
104        public static void Calculate(this ExcelRangeBase range, ExcelCalculationOption options)
105        {
106            Init(range._workbook);
107            var parser = range._workbook.FormulaParser;
108            parser.InitNewCalc();
109            var dc = DependencyChainFactory.Create(range, options);
110            CalcChain(range._workbook, parser, dc);
111        }
112        public static object Calculate(this ExcelWorksheet worksheet, string Formula)
113        {
114            return Calculate(worksheet, Formula, new ExcelCalculationOption());
115        }
116        public static object Calculate(this ExcelWorksheet worksheet, string Formula, ExcelCalculationOption options)
117        {
118            try
119            {
120                worksheet.CheckSheetType();
121                if(string.IsNullOrEmpty(Formula.Trim())) return null;
122                Init(worksheet.Workbook);
123                var parser = worksheet.Workbook.FormulaParser;
124                parser.InitNewCalc();
125                if (Formula[0] == '=') Formula = Formula.Substring(1); //Remove any starting equal sign
126                var dc = DependencyChainFactory.Create(worksheet, Formula, options);
127                var f = dc.list[0];
128                dc.CalcOrder.RemoveAt(dc.CalcOrder.Count - 1);
129
130                CalcChain(worksheet.Workbook, parser, dc);
131
132                return parser.ParseCell(f.Tokens, worksheet.Name, -1, -1);
133            }
134            catch (Exception ex)
135            {
136                return new ExcelErrorValueException(ex.Message, ExcelErrorValue.Create(eErrorType.Value));
137            }
138        }
139        private static void CalcChain(ExcelWorkbook wb, FormulaParser parser, DependencyChain dc)
140        {
141            var debug = parser.Logger != null;
142            foreach (var ix in dc.CalcOrder)
143            {
144                var item = dc.list[ix];
145                try
146                {
147                    var ws = wb.Worksheets.GetBySheetID(item.SheetID);
148                    var v = parser.ParseCell(item.Tokens, ws == null ? "" : ws.Name, item.Row, item.Column);
149                    SetValue(wb, item, v);
150                    if (debug)
151                    {
152                        parser.Logger.LogCellCounted();
153                    }
154                    Thread.Sleep(0);
155                }
156                catch (FormatException fe)
157                {
158                    throw (fe);
159                }
160                catch (Exception e)
161                {
162                    var error = ExcelErrorValue.Parse(ExcelErrorValue.Values.Value);
163                    SetValue(wb, item, error);
164                }
165            }
166        }
167        private static void Init(ExcelWorkbook workbook)
168        {
169            workbook._formulaTokens = new CellStore<List<Token>>();;
170            foreach (var ws in workbook.Worksheets)
171            {
172                if (!(ws is ExcelChartsheet))
173                {
174                    if (ws._formulaTokens != null)
175                    {
176                        ws._formulaTokens.Dispose();
177                    }
178                    ws._formulaTokens = new CellStore<List<Token>>();
179                }
180            }
181        }
182
183        private static void SetValue(ExcelWorkbook workbook, FormulaCell item, object v)
184        {
185            if (item.Column == 0)
186            {
187                if (item.SheetID <= 0)
188                {
189                    workbook.Names[item.Row].NameValue = v;
190                }
191                else
192                {
193                    var sh = workbook.Worksheets.GetBySheetID(item.SheetID);
194                    sh.Names[item.Row].NameValue = v;
195                }
196            }
197            else
198            {
199                var sheet = workbook.Worksheets.GetBySheetID(item.SheetID);
200                sheet._values.SetValue(item.Row, item.Column, v);
201            }
202        }
203    }
204}
Note: See TracBrowser for help on using the repository browser.