如何使用新的CodeModule从模板复制ExcelWorkSheet

时间:2014-11-20 16:38:16

标签: c# epplus

我在复制ExcelWorkSheet和复制的表单的相应CodeModule时遇到问题。让我解释一下:

情境: 我有一个带有宏的excel文件(.xlsm),我使用这个excel文件作为模板来创建另一个excel文件(数据将被复制到新文件中)。

所以,首先我从数据库中获取一些数据并打开excel模板(.xlsm)文件。

在某个时刻,某些条目需要位于不同的工作表中,这就是' WorkSheets.Add()'进来了。

 var newSheet = workbook.Worksheets.Add("someName", templateSheet);

复制模板表(包含我想要复制的VBA'代码)后,我遇到了问题。

似乎' CodeModule'新创建的工作表的大小等于模板中的名称和引用。

那是;所有属性值都相同,并且:workbook.VbaProject.Modules仅包含模板文件的初始代码模块,而不包含新newSheet的新代码模块。

更糟糕的是,如果我想像这样绑定一个新的CodeModule

workbook.VbaProject.Modules.AddModule("test");
newSheet.CodeModule.Name = "test";

newSheet.CodeModuletemplateSheet.CodeModule都设置为null(实际上Nothing,因为我使用的是VB.Net)。

所以问题是:这是一个错误还是我在这里做错了什么?甚至更好:你能指导完成这种情况的方式吗?

2 个答案:

答案 0 :(得分:4)

这似乎是一个错误。我在epplus项目的问题中心创建了一个问题。它已被标记为resolved

https://epplus.codeplex.com/workitem/15095

我还没有测试过新版本。完成后我会给出更新。

<强>更新 在最新的消息来源中,这个问题已得到解决。

答案 1 :(得分:3)

我认为你正在做点什么。我看到了同样的事情 - 使用EPP 3.1。 xlsm文件格式中的整个vba事物是不同的,因为它们不是基于XML的,它们是包含编译文件的bin文件。所以,根据我所看到的,这是EPPlus的一个缺陷,值得提交给他们。这是他们可以直接进入他们的解决方案的单元测试(这就是我在使用EPP时所做的事情):

[TestMethod]
public void VBAWorksheetCopyTest()
{
    var sb = new StringBuilder();
    sb.AppendLine("Private Sub Test()");
    sb.AppendLine("    Range(\"G10\").Value = \"TEST\"");
    sb.AppendLine("End Sub");

    var existingFile = new FileInfo(@"c:\temp\temp1.xlsm");
    if (existingFile.Exists)
        existingFile.Delete();

    using (var package = new ExcelPackage(existingFile))
    {
        var workbook = package.Workbook;
        workbook.CreateVBAProject();

        var worksheet = workbook.Worksheets.Add("templateSheet");

        //Module saved in the workSHEET
        worksheet.CodeModule.Code = sb.ToString();
        worksheet.CodeModule.Name = "templateSheet";

        worksheet.Cells["A1"].Value = "Col1";
        worksheet.Cells["A2"].Value = "sdf";
        worksheet.Cells["A3"].Value = "wer";

        package.Save();
    }

    //Open temp1.xlsm and copy the sheet
    using (var package = new ExcelPackage(existingFile))
    {
        var workbook = package.Workbook;
        var templateSheet = workbook.Worksheets["templateSheet"];
        var someName = workbook.Worksheets.Add("someName", templateSheet);

        //VBA code does seem to copy but dose NOT match what is seen in excel
        Assert.IsTrue(templateSheet.CodeModule.Code.Length > 0);
        Assert.IsTrue(someName.CodeModule.Code.Length > 0);

        package.Save();
    }

    //Open temp1 and try to name the modules
    using (var package = new ExcelPackage(existingFile))
    {
        var workbook = package.Workbook;
        var templateSheet = workbook.Worksheets["templateSheet"];
        var someName = workbook.Worksheets["someName"];

        //Give it a name otherwise Excel autonames it 'newsheet1'
        someName.CodeModule.Name = "someName"; //BUT will cause both CodeModule objects to go null

        //These will now fail becuase codemodule is now null for both
        Assert.IsTrue(templateSheet.CodeModule.Code.Length > 0);
        Assert.IsTrue(someName.CodeModule.Code.Length > 0);
    }
}

enter image description here