Programmatic Execution Excel Macro on Remote Machine from a website

℡╲_俬逩灬. 提交于 2019-12-09 23:54:09

问题


I have a website where users generate an Excel report using a macro, when I try to run it in my local machine it generates perfectly and runs the macro inside Excel. When I publish it into the server and at the same time I am logged in there (RDP open session) and try to run it from a browser outside that server it is also running as expected. The problem occurs when I am logged off in the server (RDP) then run it in a browser outside the server (ie from my machine) the macro does not run but creates my Excel.

This is the code that I am using

public class Report
    {
        protected Workbook Workbook { get; set; }
        protected Application Excel { get; set; }

        public void RunReport()
        {
            // Launch Excel on the server
            Excel = new Application
            {
                DisplayAlerts = false,
                ScreenUpdating = false,
                Visible = false
            };

            // Load the workbook template  
            Workbook = Excel.Workbooks.Open(@"D:\Book1.xlt");

            // Execute macros that generates the report, if any
            ExecuteMacros();

            Workbook.SaveAs(@"D:\Ray'sTesting.xls", XlFileFormat.xlExcel8);
            QuitExcel();

        }
        private void QuitExcel()
        {
            if (Workbook != null)
            {
                Workbook.Close(false);
                Marshal.ReleaseComObject(Workbook);
            }

            if (Excel != null)
            {
                Excel.Quit();
                Marshal.ReleaseComObject(Excel);
            }
        }        
        private void ExecuteMacros()
        {


            const string legacyModuleName = "Module1";
            const string legacyMacroName = "myMacro";

            bool legacyMacroExists = false;
            try
            {
                var legacyMacroModule = Workbook.VBProject.VBComponents.Item(legacyModuleName);
                if (legacyMacroModule != null)
                {
                    int legacyMacroStartLine = legacyMacroModule.CodeModule.ProcStartLine[legacyMacroName, Microsoft.Vbe.Interop.vbext_ProcKind.vbext_pk_Proc];
                    legacyMacroExists = legacyMacroStartLine > 0;
                }
            }
            catch (Exception)
            {
                legacyMacroExists = false;
            }

            if (!legacyMacroExists)
            {
                return;
            }

            // VBA code for the dynamic macro that calls the CI2 legacy macro
            var moduleCode = new StringBuilder();
            moduleCode.AppendLine("Public Sub LaunchLegacyMacro()");
            moduleCode.AppendLine(string.Format("{0}.{1}", legacyModuleName, legacyMacroName));
            moduleCode.AppendLine("End Sub");

            // Add the dynamic macro to the ThisWorkbook module
            var workbookMainModule = Workbook.VBProject.VBComponents.Item("ThisWorkbook");
            workbookMainModule.CodeModule.AddFromString(moduleCode.ToString());

            // Execute the dynamic macro
            Microsoft.VisualBasic.Interaction.CallByName(Workbook, "LaunchLegacyMacro", Microsoft.VisualBasic.CallType.Method, new object[] { });
        }
    }

回答1:


I got this working by editing the registry every time we run the excel macro by

private static void ModifyExcelSecuritySettings()
{
    // Make sure we have programmatic access to the project to run macros
    using (var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\14.0\Excel\Security", true))
    {
        if (key != null)
        {
            if ((int)key.GetValue("AccessVBOM", 0) != 1)
            {
                key.SetValue("AccessVBOM", 1);
            }
            key.Close();
        }
    }
}

So the code should look like this

public void RunReport()
{
    ModifyExcelSecuritySettings();

    // Launch Excel on the server
    Excel = new Application
    {
        DisplayAlerts = false,
        ScreenUpdating = false,
        Visible = false
    };

.....

I also created a blog post for the full solution which you can view here

http://anyrest.wordpress.com/2012/06/22/programmatic-execution-excel-macro-on-remote-machine-from-a-website/



来源:https://stackoverflow.com/questions/11149357/programmatic-execution-excel-macro-on-remote-machine-from-a-website

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!