how to copy ExcelWorkSheet from template with new CodeModule

北战南征 提交于 2019-12-01 21:39:36

问题


I am having an issue with copying a ExcelWorkSheet and the corresponding CodeModule of the copied sheet. Let me explain:

Scenario: I have an excel file with macro's (.xlsm) and I use this excel file as a template to create an other excel file (data will be copied into the new file).

So, first I fetch some data from a database and open the excel template (.xlsm) file.

At a certain point, some entries need to be in different worksheets, this is where the 'WorkSheets.Add()' comes in.

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

After copying the template sheet (which contains 'VBA' code that I want to duplicate as well), I am experiencing problems.

It seems that the 'CodeModule' of the newly created sheet equals the one from the template by name AND by reference.

That is; all the property values are the same and: workbook.VbaProject.Modules contains only the initial code modules of the template file and not a new one for the new newSheet.

Even worse, if I want to bind a new CodeModule like this:

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

both the newSheet.CodeModule and templateSheet.CodeModule are set to null (well Nothing actually, since I am using VB.Net).

So the question: is this a bug or am I doing something wrong here? And even better: can you guide the way to accomplish this scenario?


回答1:


It seems to be a bug. I have created an issue in the issue center of the epplus project. It has been marked as resolved

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

I haven't tested the new version yet. I'll give an update when that's done.

Update In the latest sources this issue is resolved.




回答2:


I think you are onto something. I see the same thing - using EPP 3.1. The whole vba thing in the xlsm file format are different since they are not XML-based, they are bin files containing complied files. So, based on what I saw, it is a flaw in EPPlus and worth submitting to them. Here is a unit test they can drop right into their Solution (that is what I do when I am messing around with 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);
    }
}



来源:https://stackoverflow.com/questions/27044854/how-to-copy-excelworksheet-from-template-with-new-codemodule

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!