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?
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.
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