【问题标题】:Excel Formula & MetadataExcel 公式和元数据
【发布时间】:2012-05-02 18:54:50
【问题描述】:

有没有办法提取各种excel公式的底层元数据。我正在使用 excel 公式在 C# 中构建这个框架,并且有兴趣了解每个公式的输入参数、它们的数据类型和返回类型。这将帮助我根据所提供的元数据构建一个向导屏幕。

提前感谢您的帮助。

【问题讨论】:

  • 对不起,我认为这不可能。您可以尝试解析在线文档或本地帮助文件,但这并不容易。
  • 我找到了带有工作表功能的urloffice.microsoft.com/client/…
  • + 1 到两个 :) 好问题和好建议。 but it ain't going to be easy@ja72:很简单:)

标签: c# excel vba


【解决方案1】:

根据@ja72 的建议,从他提到的链接中解析数据非常容易。我不太擅长 C#,所以这里有一个 vb.net 代码,您可以将其转换为 C#

话虽如此,您可以通过多种方式从 C# 中查看此问题

方式 1

在运行时导航到 URL 并使用以下代码解析值。

缺点

1) 你必须有互联网连接

2) 这个过程很慢

方式 2

创建一个单独的程序以导航到 URL 并使用以下代码解析值。 使用以下代码生成文本文件或 csv 文件的输出并将文件嵌入到您的资源中,以便您可以随时使用它

我会建议 WAY 2,但最终决定权在你。 :)

代码

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        TextBox1.Clear()
        GetFormulas()
        MessageBox.Show ("Done!")
    End Sub

    Sub GetFormulas()
        Dim wc As New Net.WebClient
        '~~> first get links
        Dim mainPage As String = wc.DownloadString("http://office.microsoft.com/client/helppreview.aspx?AssetId=HV805551279990&lcid=1033&NS=EXCEL.DEV&Version=12&pid=CH080555125")
        Dim doc As mshtml.IHTMLDocument2 = New mshtml.HTMLDocument
        doc.write (mainPage)
        doc.close()
        Dim table As mshtml.IHTMLElement = DirectCast(doc.getElementById("vstable"), mshtml.IHTMLElement2).getElementsByTagName("table")(0)
        Dim links As mshtml.IHTMLElementCollection = table.getElementsByTagName("A")
        For Each link In links
            Dim childPage As String = wc.DownloadString(link.getAttribute("href"))
            Dim doc2 As mshtml.IHTMLDocument2 = New mshtml.HTMLDocument
            doc2.write (childPage)
            doc2.close()
            Dim div2 As mshtml.IHTMLElement2 = doc2.getElementById("m_article")
            For Each elem As mshtml.IHTMLElement In div2.getElementsByTagName("P")
                If elem.getAttribute("className") = "signature" Then
                    Dim formulaString As String = elem.innerText
                    TextBox1.AppendText (link.innerText & vbTab & formulaString & vbCrLf)
                End If
            Next
        Next
    End Sub
End Class

快照

注意:以上只是关于如何抓取 ja72 给出的上述链接的示例。如果您打算使用任何其他链接,则必须相应地更改代码。另请注意,上述链接中提到的公式适用于 Excel 2007 及更高版本。对于 Excel 2003,您将不得不进入另一个链接。我没有在上面的示例中包含STOP 按钮,因此一旦程序开始运行,它在完成之前无法停止。我相信您可以再添加一个按钮来终止提取。

【讨论】:

  • + 1 做得很好。让我想起了这个帖子stackoverflow.com/questions/8798260/…你真的很喜欢报废哈哈
  • @PradeepKumar: LOL No :) 只是我觉得这个问题很有趣......
  • +1 感谢您填补我的建议中的空白。解析 html 不是我的生计,我很高兴社区能够迎接挑战并提供我无法回答的答案。
【解决方案2】:

感谢@SiddharthRout。下面是 Sid 贴出的代码的 C# 转换

在使用 C# 时,您确实需要处理大量的转换和转换。但这就是 C# 的工作方式:P

using System;
using System.Windows.Forms;

Namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Clear();
            GetFormulas();
            MessageBox.Show("Done!");
        }

        public void GetFormulas()
        {
            mshtml.HTMLDocument doc = NewHtmlDoc("http://office.microsoft.com/client/helppreview.aspx?AssetId=HV805551279990&lcid=1033&NS=EXCEL.DEV&Version=12&pid=CH080555125");
            mshtml.IHTMLElement2 table = (mshtml.IHTMLElement2)(mshtml.IHTMLElement2)((mshtml.IHTMLElement2)doc.getElementById("vstable")).getElementsByTagName("table").item(null, 0);
            mshtml.IHTMLElementCollection links = table.getElementsByTagName("A");
            foreach (mshtml.IHTMLElement link in links)
            {
                mshtml.HTMLDocument doc2 = NewHtmlDoc(link.getAttribute("href",0).ToString());
                mshtml.IHTMLElement div2 = doc2.getElementById("m_article");
                foreach (mshtml.IHTMLElement elem in ((mshtml.IHTMLElement2)div2).getElementsByTagName("P"))
                {
                    if (elem.getAttribute("className",0) != null && elem.getAttribute("className",0).ToString() == "signature")
                    {
                        string formulaString = elem.innerText;
                        textBox1.AppendText(link.innerText + "\t\t" + formulaString + "\n");
                    }
                }
            }
        }

        private mshtml.HTMLDocument NewHtmlDoc(string url)
        {
            System.Net.WebClient wc = new System.Net.WebClient();
            string page = wc.DownloadString(url);
            mshtml.IHTMLDocument2 doc = (mshtml.IHTMLDocument2)(new mshtml.HTMLDocument());
            doc.write(page);
            doc.close();
            return (mshtml.HTMLDocument)doc;
        }

    }
}

【讨论】:

  • + 1 :) 猜猜我需要用 C# 做更多的实验但是第二个想法......不! :)
  • 顺便说一句,我添加了一个停止按钮 ;) 您可能想要包含它? ;) siddharthrout.wordpress.com/2012/05/02/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多