2014-04-01 9 views
7

Używam ClosedXML do generowania arkuszy kalkulacyjnych z C# (asp.net-mvc) i działa świetnie. Mam jedno dodatkowe wymaganie, więc chciałem uzyskać informacje zwrotne na temat tego, w jaki sposób mogę to osiągnąć.Jak mogę osadzić kod VBA w arkuszu kalkulacyjnym utworzonym przy użyciu ClosedXML?

Chcę zapisać jako skoroszyt z włączonym makrem, a kiedy po prostu nadaję mu rozszerzenie "xlsm", to nie wydaje się, aby otworzyć (w przeciwieństwie do xlsx). Tu jest mój kodu:

public ActionResult ExportExcel() 
{ 
    MemoryStream stream = nModel.GenerateSS(); 
    return File(stream, @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "MySS.xlsx"); 
} 

ale gdy próbuję to zrobić:

public ActionResult ExportExcel() 
{ 
    MemoryStream stream = nModel.GenerateSS(); 
    return File(stream, @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", "MySS.xlsm"); 
} 

Excel narzeka podczas próby otwarcia.

Następnie, zakładając, że mogę zrobić # 1, muszę mieć możliwość wzięcia trochę VBA (zakładając tylko funkcję zakodowaną na sztywno) i wstawienia tego do modułu lub skoroszytu, więc gdy ktoś otworzy arkusz kalkulacyjny i kliknie na Makra , mogą uruchamiać makra. Z google'a to nie jest obsługiwane przez ClosedXML, więc byłem ciekawy, czy ktoś ma jakieś alternatywne sposoby, aby to osiągnąć?

+1

To może lub nie może pomóc, ja zazwyczaj nie pracują bezpośrednio z ClosedXML, ale raczej użyć EPPlus zrobić ciężkiego unoszenie dla mnie ... Udokumentowali przykłady dodawania makra do arkusza - http://epplus.codeplex.com/ –

Odpowiedz

10

Jedynym sposobem, jaki znam na wstawienie kodu do projektu VBA, jest użycie Office.Interop.Excel wraz z Microsoft.Vbe.Interop (nie jestem pewien co do ClosedXML i innych stron trzecich ...ale mimo to chciałem podzielić się)

Ale skoro pytasz o alternatywę, to w jaki sposób chciałbym to zrobić;

Creating a workbook and inserting a macro to it using C#


Trzeba allow programmatic access to VBA Project w programie Excel.

  • (Excel) Plik -> Opcje -> Centrum zaufania -> Ustawienia Centrum zaufania -> Ustawienia Macro -> Zaufanie Dostęp do VBA Projektu Object Model

enter image description here

W swoim C# rozwiązanie dodać Odsyłacze COM do

  • Microsoft Visual Basic for Applications rozciągliwość 5,3

  • Microsoft Excel Biblioteka 14.0 Object

dodawania za pomocą dyrektyw do swojego kodu C# za akt

using Microsoft.Office.Interop.Excel; 
using System.Reflection; 
using Microsoft.Vbe.Interop; 
using System.Runtime.InteropServices; 

Teraz wykonaj kod i komentarze

Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
xlApp.Visible = true; 
Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); 

VBProject vbProj = wb.VBProject; // access to VBAProject 
VBComponent vbComp = vbProj.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule); // adding a standard coding module 
vbComp.CodeModule.DeleteLines(1, vbComp.CodeModule.CountOfLines); //emptying it 

// this is VBA code to add to the coding module 
string code = "Public Sub HelloWorld() \n" + 
       " MsgBox \"hello world!\" \n" + 
       "End Sub"; 

// code should be added to the module now 
vbComp.CodeModule.AddFromString(code); 

// location to which you want to save the workbook - desktop in this case 
string fullPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\macroWorkbook.xlsm"; 

// run the macro 
xlApp.Run("HelloWorld"); 

// save as macro enabled workbook 
wb.SaveAs(Filename: fullPath, FileFormat: XlFileFormat.xlOpenXMLWorkbookMacroEnabled); 
xlApp.Quit(); 

W powyższym kodzie;

tworzysz aplikację Excel dla hosta, dodajesz skoroszyt. Uzyskaj dostęp do modułu obiektu projektu VBA, dodaj nowy standardowy moduł kodu do projektu VBA, napisz makro VBA do tego modułu. Application.Run("HelloWorld") po prostu wywołuje makro - uwaga, możesz skomentować tę sekcję, jeśli nie chcesz, aby okno wyskakujące. Następnie na koniec zapisuje się skoroszyt jako Skoroszyt roboczy do lokalizacji określonej w zmiennej fullPath.

PS. Uwaga Nie dodałem żadnej obsługi błędów.

uzyskać dodatkowe wskazówki na temat C# i VBA zobaczyć this blog nadzieję, że to pomaga :)

1
return File(stream, @"application/vnd.ms-excel.sheet.macroEnabled.12", "MySS.xlsm"); 

Według tego link, typ MIME dla Office Excel 2007 z obsługą makr skoroszytu (.xlms) jest

application/vnd.ms-excel.sheet.macroEnabled.12.

Czy widziałeś post this posta w projekcie codeplex ClosedXml dotyczący obsługi makr.

+0

dzięki. . jakiś pomysł, w jaki sposób mogę wprowadzić kod VBA do arkusza kalkulacyjnego? – leora

+0

Wystarczy spojrzeć na dokumenty na stronie http://closedxml.codeplex.com/documentation, które nie wspominają o makrach. Jeśli jesteś martwy, korzystając z ClosedXML, to musisz to zrobić w trudny sposób poprzez ręczne wprowadzenie vba do strumienia plików przy użyciu specyfikacji dla formatu pliku xls. –

+0

Dodano kolejny post podobny do twojego na codeplex. –

2

ClosedXML aktualnie nie obsługuje bezpośredniego pisania VBA.

Jednak można ręcznie dodać plik .bin zawierający wstępnie zdefiniowane makra/funkcje VBA do istniejącego arkusza kalkulacyjnego .XLSX programowo. Najpierw zapisz wszystkie swoje makra VBA i zapisz plik jako plik .XLSM. Wyodrębnij zawartość do folderu, a otrzymasz plik vbaProject.bin zawierający cały twój kod. Aby projekt VBA do prawidłowego obciążenia, workbook.xml wymaga następujące dodatki:

<Default Extension="bin" ContentType="application/vnd.ms-office.vbaProject"/> 
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.ms-excel.sheet.macroEnabled.main+xml"/> 

vbaProject.bin będą musiały być umieszczone w folderze „xl” folderu, a skoroszyt będzie wymagać kryptonim GUID i alias (domyślnie "Księga pracy"). Wszystkie arkusze będą również wymagać nazwy kodowej (pasującej do nazwy arkusza), aby wywołania w makrach rzeczywiście działały podczas odwoływania się do nazwanych arkuszy.

John McNamara stworzył proof-of-concept pracuje w Perl, które warto sprawdzić tutaj: http://blogs.perl.org/users/john_mcnamara/2012/12/adding-macros-to-excelwriterxlsx.html

Skanowanie nad zespołem w IlSpy, to powinno być dość proste do wdrożenia w ClosedXML, dlatego jeśli masz Sukces tutaj byłby dobry, aby popchnąć swój wkład do głównego projektu.

Powiązane problemy