我在复制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.CodeModule
和templateSheet.CodeModule
都设置为null
(实际上Nothing
,因为我使用的是VB.Net)。
所以问题是:这是一个错误还是我在这里做错了什么?甚至更好:你能指导完成这种情况的方式吗?
答案 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);
}
}