private void AddToCache(ExcelReference reference, ExcelPrecedent newPrecedent) { List <ExcelPrecedent> cachedItems; if (!cache_.TryGetValue(reference, out cachedItems)) { cachedItems = new List <ExcelPrecedent>(); cache_[reference] = cachedItems; } cachedItems.Add(newPrecedent); }
// TODO Handle INDIRECT, etc. // TODO Static cache (string-ExcelFormula). // TODO Fix for R1C1 mode. // TODO Fix external references. private IEnumerable <ExcelPrecedent> GetPrecedents(ExcelReference reference) { List <ExcelPrecedent> items; if (cache_.TryGetValue(reference, out items)) { foreach (var item in items) { yield return(item); foreach (var p in GetPrecedents(item.Reference)) { yield return(p); } } } else { bool isFormula = (bool)XlCall.Excel(XlCall.xlfGetCell, 48, reference); if (isFormula) { string formula = (string)XlCall.Excel(XlCall.xlfGetCell, 6, reference); ExcelFormula excelFormula = new ExcelFormula(formula); foreach (var token in excelFormula) { if (token.Type == ExcelFormulaTokenType.Operand && token.Subtype == ExcelFormulaTokenSubtype.Range) { //if (isRCmode) //{ // var regex = new Regex( // @"^=(?:(?<Sheet>[^!]+)!)?(?:R((?<RAbs>\d+)|(?<RRel>\[-?\d+\]))C((?<CAbs>\d+)|(?<CRel>\[-?\d+\]))){1,2}$", // RegexOptions.Compiled | RegexOptions.IgnoreCase); // if (regex.IsMatch(formula)) // { // throw new NotSupportedException(); // } //} var range = token.Value; Match rangeMatch = rangeRegex_.Match(range); var col1 = ExcelAColumnToInt(rangeMatch.Groups["Col1"].Value) - 1; var row1 = Int32.Parse(rangeMatch.Groups["Row1"].Value) - 1; Group sheetGroup = rangeMatch.Groups["Sheet"]; var sheetName = sheetGroup.Success ? sheetGroup.Value : null; int col2 = col1; int row2 = row1; if (rangeMatch.Groups["Col2"].Success) { col2 = ExcelAColumnToInt(rangeMatch.Groups["Col2"].Value) - 1; row2 = Int32.Parse(rangeMatch.Groups["Row2"].Value) - 1; } for (int col = col1; col <= col2; col++) { for (int row = row1; row <= row2; row++) { ExcelReference precedantRef; if (sheetName == null) { precedantRef = new ExcelReference(row, row, col, col, reference.SheetId); } else { precedantRef = new ExcelReference(row, row, col, col, sheetName); } ExcelPrecedent newPrecedent = new ExcelPrecedent( precedantRef, excelFormula, formula, reference); AddToCache(reference, newPrecedent); yield return(newPrecedent); foreach (var nestedPrecedant in GetPrecedents(precedantRef)) { yield return(nestedPrecedant); } } } } } } } }