2013-01-09 14 views
6

Ich bin auf der Suche nach einem Makro, nennen wir es Macro01 von WorkSheet01 auf WorkSheet02.Ausführen eines Excel-Makros über C#: Ausführen eines Makros aus einer Arbeitsmappe auf einer anderen?

Mit Microsoft.Office.Interop.Excel Namespace Ich habe ein WorkSheet01 geöffnet.

public void Main_CodedStep() 
    { 
     // Object for missing (or optional) arguments. 
     object oMissing = System.Reflection.Missing.Value; 

     // Create an instance of Microsoft Excel 
     Excel.ApplicationClass oExcel = new Excel.ApplicationClass(); 

     // Make it visible 
     oExcel.Visible = true; 

     // Open Worksheet01.xlsm 
     Excel.Workbooks oBooks = oExcel.Workbooks; 
     Excel._Workbook oBook = null; 
     oBook = oBooks.Open("C:\\Users\\Admin\\Documents\\Worksheet01.xlsm", oMissing, oMissing, 
      oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, 
      oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); 
    } 

Ich verwende dann ein automatisiertes Skript, um einen Bericht zu ziehen. Dieser Bericht wird über die Download-Aufforderung von IE und nicht über das Interop geöffnet.

Das Problem kommt, wenn ich versuche, das Makro über C# zu laufen (habe ich wieder eine neue Excel.ApplicationClass(); nur so kompiliert, ich glaube, das ist eine meiner Fehltritte ist.)

public void FirstMacro_CodedStep() 
    { 
     // Create an instance of Microsoft Excel 
     Excel.ApplicationClass oExcel = new Excel.ApplicationClass(); 
     Console.WriteLine("ApplicationClass: " + oExcel); 

     // Run the macro, "First_Macro" 
     RunMacro(oExcel, new Object[]{"Worksheet01.xlsm!First_Macro"}); 

     //Garbage collection 
     GC.Collect(); 
    } 

    private void RunMacro(object oApp, object[] oRunArgs) 
    { 
     oApp.GetType().InvokeMember("Run", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, oApp, oRunArgs); 
    } 

Wenn Diese Methode führt das Makro aus Worksheet01 auf Worksheet01 statt Worksheet02 aus. Außerdem suchte er nach dem Arbeitsblatt in Meine Dokumente, also zog ich es um, um zu sehen, was passieren würde.

Recap:

  1. öffnen Worksheet01
  2. Via Scripting erhalten und öffnen Sie einen Bericht (Worksheet02) von MSIE
  3. Run Macro01 von Worksheet01 auf Worksheet02

Ressourcen:

http://support.microsoft.com/kb/306683

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.aspx

Für diejenigen, die versuchen möchte es diese zu Ihrem using-Direktiven hinzu:

using System.Reflection; 
using Microsoft.Office.Core; //Added to Project Settings' References from C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Office14 - "office" 
using Excel = Microsoft.Office.Interop.Excel; //Added to Project Settings' References from C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Office14 - "Microsoft.Office.Interop.Excel" 
+0

Bitte überprüfen Sie dieses http://stackoverflow.com/questions/27166341/run-microsoft-office-macro-using-c-sharp –

Antwort

5

ich eine Lösung gefunden, die Ich mag würde teilen. Zuerst entfernte ich das Bit, wo ich Worksheet01 geöffnet habe. Ich hatte dann mein automatisches Skript speichern die .CSV in Eigene Dateien. Ich benutzte dann den Code, den ich öffnen musste, um die heruntergeladene Datei zu öffnen. Das Wichtigste an dieser Stelle ist, dass sich Worksheet01 im Ordner Dokumente mit Worksheet02 befindet. Schließlich habe ich den Code verwendet, um das Makro aus Worksheet01 auszuführen, das auf Worksheet02 ausgeführt wird.

public void WebTest_CodedStep() 
    { 
     // Object for missing (or optional) arguments. 
     object oMissing = System.Reflection.Missing.Value; 

     // Create an instance of Microsoft Excel 
     Excel.ApplicationClass oExcel = new Excel.ApplicationClass(); 

     // Make it visible 
     oExcel.Visible = true; 

     // Define Workbooks 
     Excel.Workbooks oBooks = oExcel.Workbooks; 
     Excel._Workbook oBook = null; 

     // Get the file path 
     string path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
     path = path + "\\Worksheet02.csv"; 

     //Open the file, using the 'path' variable 
     oBook = oBooks.Open(path, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); 

     // Run the macro, "First_Macro" 
     RunMacro(oExcel, new Object[]{"Worksheet01.xlsm!First_Macro"}); 

     // Quit Excel and clean up. 
     oBook.Close(false, oMissing, oMissing); 
     System.Runtime.InteropServices.Marshal.ReleaseComObject (oBook); 
     oBook = null; 
     System.Runtime.InteropServices.Marshal.ReleaseComObject (oBooks); 
     oBooks = null; 
     oExcel.Quit(); 
     System.Runtime.InteropServices.Marshal.ReleaseComObject (oExcel); 
     oExcel = null; 

     //Garbage collection 
     GC.Collect(); 
    } 

    private void RunMacro(object oApp, object[] oRunArgs) 
    { 
     oApp.GetType().InvokeMember("Run", System.Reflection.BindingFlags.Default | System.Reflection.BindingFlags.InvokeMethod, null, oApp, oRunArgs); 
    } 
+1

RunMacro scheint nur zu funktionieren, wenn sich die Makrodatei im Ordner Dokumente des Benutzers befindet. Jeder Versuch, der Datei an anderer Stelle einen vollständigen Pfad zu geben, führt zu einer Fehlermeldung "das Makro wurde nicht gefunden oder Makros wurden deaktiviert". – waka

+0

Ja, ich habe mehrere Versuche gemacht und diese Methode Makro (mit InvokeMember) aufzurufen, hat nur funktioniert, wenn mein Makro phisisch im "Eigene Dateien" Ordner war. Es ist nicht möglich, einen anderen Speicherort anzugeben (mit einem an diesem Speicherort kopierten Makro). Ich habe auch mit Microsoft.Office.Interop.Excel.Application Klasse versucht, Run-Methode und es hat nur unter den gleichen Bedingungen funktioniert: Makro-Datei phisely in "Eigene Dateien" Ordner. – EAmez

0

Ich lief diese C# VSTO Code ein VBA-Makro aufrufen, das ist die Syntax ich benutze:

this.Application.Run("mymacro"); 

Edit:

Makros sind Arbeitsmappe breit, vielleicht müssen Sie Sheet2 das aktive Arbeitsblatt vor dem Ausführen des Makros, zum Beispiel machen:

foreach (Worksheet worksheet in workbook.Sheets.ComLinq<Worksheet>()) 
{ 
    if (worksheet.Name == "Sheet2") worksheet.Activate(); 
} 
+0

Sorry, ich nicht meine Namenskonventionen erkennen waren ein bisschen irreführend. Was ich Worksheet01 und Worksheet02 genannt habe, waren zwei verschiedene Dateien (eine ist eine xlsm und die andere eine csv). – kirbycope

Verwandte Themen