生成所有excel单元格公式的平面列表

时间:2011-10-04 06:27:00

标签: c# excel excel-vba vba

我有一个用VBA和单元格公式编写的大型程序。我的任务是将其反向工程为C#winforms。我想一个开始,我需要在平面列表中看到所有的单元格公式。

现有的方法吗?提前谢谢!

编辑:只是为了分享,在回答者的帮助下,我设法提出了这个:

Excel formula browser lets you view precedents in a tree view.

5 个答案:

答案 0 :(得分:2)

在VBA中(可以轻松修改为vbscript)您可以使用高效的变量数组快速将所有工作表中的所有公式转储到平坦的txt文件(更改路径以适应)。 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

[更新部分 - 您可以使用SpecialCells在VBA中快速隔离公式。如果工作表上没有公式,则需要进行错误处理,请参阅下面的GetFormula

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

答案 1 :(得分:1)

以下是一些代码,用于获取工作表中包含公式的单元格列表。看起来很快。

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
}

答案 2 :(得分:0)

组合键ctrl +`(后退勾选)在查看值和公式之间切换,它不是平面列表,但它很有用。

答案 3 :(得分:0)

在brettdj的帮助下,我设法暂时进行四叉树搜索

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);
    }
}

答案 4 :(得分:0)

我找到了这个答案,并尝试使用@Jake的C#代码,但是发现它很慢。

这是一个更快(更完整)的版本:

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;
        }
    }
}