VBA
EPPlus supports Creating, Reading and Writing VBA. Execution/Interpretation of VBA code is not supported. Remember that the package must be saved with the extension xlsm.
A VBA project is created by the CreateVBAProject() method of the ExcelWorkbook class. This enables you to write VBA code to the project as shown in Sample 8.2-C# or Sample 8.2-VB.
private static void VBASample1(DirectoryInfo outputDir)
{
ExcelPackage pck = new ExcelPackage();
//Add a worksheet.
var ws=pck.Workbook.Worksheets.Add("VBA Sample");
ws.Drawings.AddShape("VBASampleRect", eShapeStyle.RoundRect);
//Create a vba project
pck.Workbook.CreateVBAProject();
//Now add some code to update the text of the shape...
var sb = new StringBuilder();
sb.AppendLine("Private Sub Workbook_Open()");
sb.AppendLine(" [VBA Sample].Shapes(\"VBASampleRect\").TextEffect.Text = \"This text is set from VBA!\"");
sb.AppendLine("End Sub");
pck.Workbook.CodeModule.Code = sb.ToString();
//And Save as xlsm
pck.SaveAs(new FileInfo(outputDir.FullName + @"\sample15-1.xlsm"));
}
Private Shared Sub VBASample1(outputDir As DirectoryInfo)
Dim pck As New ExcelPackage()
'Add a worksheet.
Dim ws = pck.Workbook.Worksheets.Add("VBA Sample")
ws.Drawings.AddShape("VBASampleRect", eShapeStyle.RoundRect)
'Create a vba project
pck.Workbook.CreateVBAProject()
'Now add some code to update the text of the shape...
Dim sb As New StringBuilder()
sb.AppendLine("Private Sub Workbook_Open()")
sb.AppendLine(" [VBA Sample].Shapes(""VBASampleRect"").TextEffect.Text = ""This text is set from VBA!""")
sb.AppendLine("End Sub")
pck.Workbook.CodeModule.Code = sb.ToString()
'And Save as xlsm
pck.SaveAs(New FileInfo(outputDir.FullName & "\sample15-1.xlsm"))
End Sub
Add a code module¶
Here is an example where we add a code module with a method that adds a BubbleChart with VBA to an existing VBA project in the workbook.
var sb = new StringBuilder();
sb.AppendLine("Public Sub CreateBubbleChart()");
sb.AppendLine("Dim co As ChartObject");
sb.AppendLine("Set co = Inventory.ChartObjects.Add(10, 100, 400, 200)");
sb.AppendLine("co.Chart.SetSourceData Source:=Range(\"'Inventory'!$B$1:$E$5\")");
sb.AppendLine("co.Chart.ChartType = xlBubble3DEffect 'Add a bubblechart");
sb.AppendLine("End Sub");
//Create a new module and set the code
var module = pck.Workbook.VbaProject.Modules.AddModule("MyBubbleChartModule");
module.Code = sb.ToString();
Dim sb As New StringBuilder()
sb.AppendLine("Public Sub CreateBubbleChart()")
sb.AppendLine("Dim co As ChartObject")
sb.AppendLine("Set co = Inventory.ChartObjects.Add(10, 100, 400, 200)")
sb.AppendLine("co.Chart.SetSourceData Source:=Range(""'Inventory'!$B$1:$E$5"")")
sb.AppendLine("co.Chart.ChartType = xlBubble3DEffect 'Add a bubblechart")
sb.AppendLine("End Sub")
'Create a new module and set the code
Dim [module] = pck.Workbook.VbaProject.Modules.AddModule("MyBubbleChartModule")
[module].Code = sb.ToString()
Sign your VBA code¶
You can also sign your VBA code with a code signing certificate, see below. When you set the VbaProject.Signature.Certificate property, the digital signature will be created when the workbook is saved.
Dim store As New X509Store(StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly)
For Each cert In store.Certificates
If cert.HasPrivateKey AndAlso cert.NotBefore <= DateTime.Today AndAlso cert.NotAfter >= DateTime.Today Then
pck.Workbook.VbaProject.Signature.Certificate = cert
Exit For
End If
Next
From version 6.1, EPPlus also supports the Agile and V3 types of code signing. You can also change the hash algorithm used for each version.
In the code below, we sign the workbook with a certificate stored in a pfx file. We create the v3 signature only and change the hash algorithem to SHA256:
var cert = new X509Certificate2(FileUtil.GetRootDirectory() + "\\21-VBA\\SampleCertificate.pfx", "EPPlus");
using (var p = new ExcelPackage(FileUtil.GetFileInfo("21.3-CreateABattleShipsGameVba.xlsm")))
{
var signature = p.Workbook.VbaProject.Signature;
signature.Certificate = cert;
//Only create the v3 signature on save.
signature.LegacySignature.CreateSignatureOnSave = false;
signature.AgileSignature.CreateSignatureOnSave = false;
signature.V3Signature.CreateSignatureOnSave = true;
//You can also set the hash algorithm for each signature version.
//The Excel and EPPlus default is MD5 for the legacy signature and SHA1 for the Agile and V3 signature.
//We want to change it to SHA256 to get better and more modern hash algorithm.
signature.V3Signature.HashAlgorithm = VbaSignatureHashAlgorithm.SHA256;
}
Dim cert = New X509Certificate2(FileUtil.GetRootDirectory() & "\21-VBA\SampleCertificate.pfx", "EPPlus")
Using p As New ExcelPackage(FileUtil.GetFileInfo("21.3-CreateABattleShipsGameVba.xlsm"))
Dim signature = p.Workbook.VbaProject.Signature
signature.Certificate = cert
'Only create the v3 signature on save.
signature.LegacySignature.CreateSignatureOnSave = False
signature.AgileSignature.CreateSignatureOnSave = False
signature.V3Signature.CreateSignatureOnSave = True
'You can also set the hash algorithm for each signature version.
'The Excel and EPPlus default is MD5 for the legacy signature and SHA1 for the Agile and V3 signature.
'We want to change it to SHA256 to get better and more modern hash algorithm.
signature.V3Signature.HashAlgorithm = VbaSignatureHashAlgorithm.SHA256
End Using
See also¶
We have made a