// Copyright (c) 2017-today Informatikbüro Daniel Schick // Base class excel (writer not yet implemented but eventually..) using System; using System.Collections.Generic; using Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; using log4net; using System.Globalization; using System.Text.RegularExpressions; namespace ENI2.Excel { internal class ExcelBase : IDisposable { #region Fields internal enum CountryMode { NONE, DE, DK }; protected CountryMode _countryMode = CountryMode.DE; protected Workbooks _excelWorkbooks; protected Workbook _workBook; protected Application _excelApp; protected Dictionary _nameDict; protected ILog _log; #endregion Fields #region Construction public ExcelBase() { _log = LogManager.GetLogger(this.GetType().Name); this._excelApp = new Application(); this._excelApp.DisplayAlerts = false; this._excelWorkbooks = _excelApp.Workbooks; } #endregion Construction #region Properties internal CountryMode Mode { get { return _countryMode; } } internal Dictionary NameDict { get { return _nameDict; } } internal Sheets Worksheets { get { return _workBook.Worksheets; } } #endregion #region protected methods protected void InitNameFields() { _nameDict = new Dictionary(); int bookCnt = 0; foreach (Name name in _workBook.Names) { string theValue = name.Value; // Namensbezug: =SheetZelle. Leere Referenzen überspringen (kommt immer mal wieder vor!) string nameKey = name.Name; try { if (nameKey.Contains("!")) nameKey = nameKey.Substring(nameKey.IndexOf('!') + 1); } catch (Exception) { _log.DebugFormat("Strange name in Sheet: {0}", nameKey); continue; } if ((theValue != "=#REF!#REF!") && (theValue != "=#BEZUG!#BEZUG!")) { _nameDict[nameKey] = name; bookCnt++; } } _log.DebugFormat("{0} named ranges found at Workbook level", bookCnt); foreach (Worksheet ws in _workBook.Worksheets) { int wsCnt = 0; foreach (Name name in ws.Names) { string theValue = name.Value; // Namensbezug: =SheetZelle. Leere Referenzen überspringen (kommt immer mal wieder vor!) if (!_nameDict.ContainsKey(name.Name)) { if ((theValue != "=#REF!#REF!") && (theValue != "=#BEZUG!#BEZUG!")) { _nameDict[name.Name] = name; wsCnt++; } } } if (wsCnt > 0) _log.DebugFormat("{0} named ranges found in Worksheet {1}", wsCnt, ws.Name); } } private static double? ParseAnyDouble(string val) { double? result = null; if (double.TryParse(val, NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite, CultureInfo.InvariantCulture, out double tmpDouble)) result = tmpDouble; if (result == null) { if (double.TryParse(val, out tmpDouble)) // current language style (==GER, mit , statt .) result = tmpDouble; } return result; } internal double? ReadNumber(string lookup) { double? result = null; try { if (_nameDict.ContainsKey(lookup)) { var val = _nameDict[lookup].RefersToRange.Value; if (val is double) result = val; if ((val is string) && (val.Length > 0)) { result = ParseAnyDouble(val); if(result == null) { Match m = Regex.Match(val, "([0-9\\.\\,]+)([a-zA-Z]*)"); if (m.Success) { result = ParseAnyDouble(m.Groups[1].Value); } } } if ((result == null) && (val != null)) { double tmpDouble2 = val[1, 1]; result = tmpDouble2; } } } catch (Exception) { _log.WarnFormat("error reading number for lookup {0}", lookup); } return result; } internal void Colorize(string lookup, int color) { if(_nameDict.ContainsKey(lookup)) { var range = _nameDict[lookup].RefersToRange; Colorize(range, color); } } internal void Colorize(Range range, int color) { range.Interior.Color = color; range.Worksheet.Tab.Color = color; } #endregion #region public methods public void Save(string path) { this._workBook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); this._workBook.Saved = true; } #endregion #region Dispose public void Dispose() { try { if (this._workBook != null) { this._workBook.Close(0); _log.Debug("Close Worksheet"); Marshal.ReleaseComObject(this._workBook); } if (this._excelWorkbooks != null) { this._excelWorkbooks.Close(); _log.Debug("Close Workbooks"); Marshal.ReleaseComObject(this._excelWorkbooks); } if (this._excelApp != null) { _log.Debug("Quit Excel"); this._excelApp.Quit(); Marshal.ReleaseComObject(this._excelApp); } } catch(Exception ex) { _log.ErrorFormat("Exception disposing ExcelReader: {0}", ex.Message); } } #endregion } }