Generate a flat list of all excel cell formulas

前端 未结 5 1064
离开以前
离开以前 2021-01-06 14:10

I have a massive program written with VBA and cell formulas. I am tasked to reverse engineer it into C# winforms. I figured for a start, I need to see all the cell formulas

相关标签:
5条回答
  • 2021-01-06 14:32

    I found this answer, and tried to use the C# code by @Jake, but discovered it was slow.

    Here is a faster (and complete) version:

    using System;
    using System.Text;
    using Microsoft.Office.Interop.Excel;
    
    namespace ExportExcelFormulas
    {
        static class ExcelAccess
        {
            public static void ExportFormulasSimple(string filePath)
            {
                var app = new Application();
                var workbook = app.Workbooks.Open(filePath);
                var sCount = workbook.Sheets.Count;
    
                var sb = new StringBuilder();
    
                for (int s = 1; s <= sCount; s++)
                {
                    var sheet = workbook.Sheets[s];
                    var range = sheet.UsedRange;
                    var f = range.Formula;
    
                    var cCount = range.Columns.Count;
                    var rCount = range.Rows.Count;
    
                    for (int r = 1; r <= rCount; r++)
                    {
                        for (int c = 1; c <= cCount; c++)
                        {
                            var id = ColumnIndexToColumnLetter(c) + "" + r + ": ";
                            var val = f[r, c];
    
                            if (!string.IsNullOrEmpty(val))
                            {
                                sb.AppendLine(id + val);
                                Console.WriteLine(id + val);
                            }
    
                        }
                    }
    
                }
    
                var text = sb.ToString();
            }
    
            // Based on https://www.add-in-express.com/creating-addins-blog/2013/11/13/convert-excel-column-number-to-name/
            public static string ColumnIndexToColumnLetter(int i)
            {
                var l = "";
                var mod = 0;
    
                while (i > 0)
                {
                    mod = (i - 1) % 26;
                    l = (char)(65 + mod) + l;
                    i = (int)((i - mod) / 26);
                }
    
                return l;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-06 14:34

    in VBA (easily modifiable to vbscript) you could quickly dump all formulae in all sheets to a flat txt file (change your path to suit) with an efficient variant array. code sourced from my article here

    Const sFilePath = "C:\test\myfile.txt"    
    
    Sub CreateTxt_Output()
        Dim ws As Worksheet
        Dim rng1 As Range
        Dim X
        Dim lRow As Long
        Dim lCol As Long
        Dim strTmp As String
        Dim lFnum As Long
    
        lFnum = FreeFile
        Open sFilePath For Output As lFnum
    
        For Each ws In ActiveWorkbook.Worksheets
        Print #lFnum, "*****" & ws.Name & "*****"
            'test that sheet has been used
            Set rng1 = ws.UsedRange
            If Not rng1 Is Nothing Then
                'only multi-cell ranges can be written to a 2D array
                If rng1.Cells.Count > 1 Then
                    X = ws.UsedRange.Formula
                    For lRow = 1 To UBound(X, 1)
                        For lCol = 1 To UBound(X, 2)
                            'write each line to txt file
                            Print #lFnum, X(lRow, lCol)
                        Next lCol
                    Next lRow
                Else
                    Print #lFnum, rng1.Formula
                End If
            End If
        Next ws
    
        Close lFnum
        MsgBox "Done!", vbOKOnly
    End Sub
    

    [Updated section - you can isolate formulae quickly in VBA by using SpecialCells. Error Handling is needed in case there are no formulae on a sheet, see GetFormula below

    Sub GetFormula()
        Dim ws As Worksheet
        Dim rng1 As Range
        Dim rng2 As Range
        For Each ws In ActiveWorkbook.Sheets
        Set rng1 = Nothing
            On Error Resume Next
            Set rng1 = ws.Cells.SpecialCells(xlCellTypeFormulas)
            On Error GoTo 0
            If Not rng1 Is Nothing Then
                For Each rng2 In rng1.Areas
                'dump cells here
                Next rng2
            End If
        Next ws
    End Sub
    
    0 讨论(0)
  • 2021-01-06 14:48

    Here is some code that I used to get a list of cells on a worksheet with formulas in them. It seems pretty fast.

    try
    {
        Excel.Worksheet excelWorksheet = workbook.ActiveSheet as Excel.Worksheet;
        Excel.Range formulaCell = excelWorksheet.Cells.SpecialCells(
            Excel.XlCellType.xlCellTypeFormulas, Type.Missing);
    
        Excel.Range cell;
        foreach (var fc in formulaCell)
        {
            cell = fc as Excel.Range;
            string s1 = cell.Formula as string;
            int c = cell.Column;
            int r = cell.Row;
    
            // Gives formula text and location of formula.
        }
    }
    catch (Exception)
    {
        ; // Throws an exception if there are no results.
          // Probably should ignore that exception only
    }
    
    0 讨论(0)
  • 2021-01-06 14:49

    The key combination ctrl+` (back tick) toggles between viewing values and formulas, it is not a flat list, but it is useful.

    0 讨论(0)
  • 2021-01-06 14:49

    With help from brettdj, I managed to whip up a quad tree search at the moment

    private static void FindFormula(Excel excel, TextWriter writer, int rowstart, int rowend, int colstart, int colend)
    {
        // Select the range
        excel.Range(rowstart, rowend, colstart, colend);
    
        // Check whether this range has formulas
        if (!excel.RangeHasFormula())
            return;
    
        // Check if we only have a single cell
        if (excel.RangeCellCount() == 1)
        {
            Console.WriteLine(excel.CellFormula(rowstart, colstart));
            return;
        }
    
        int r1, r2, r3, r4;
        int c1, c2, c3, c4;
    
        r1 = rowstart;
        r2 = rowstart + (rowend - rowstart + 1) / 2 - 1;
        r3 = r2 + 1;
        r4 = rowend;
    
        if (colstart == colend)
        {
            c1 = c2 = c3 = c4 = colstart;
    
            FindFormula(excel, writer, r1, r2, c1, c2);
            FindFormula(excel, writer, r3, r4, c1, c2);
        }
        else
        {
            c1 = colstart;
            c2 = colstart + (colend - colstart + 1) / 2 - 1;
            c3 = c2 + 1;
            c4 = colend;
    
            FindFormula(excel, writer, r1, r2, c1, c2);
            FindFormula(excel, writer, r1, r2, c3, c4);
            FindFormula(excel, writer, r3, r4, c1, c2);
            FindFormula(excel, writer, r3, r4, c3, c4);
        }
    }
    
    0 讨论(0)
提交回复
热议问题