Smrf.NodeXL.ExcelTemplate.TaskAutomator.AutomateOneWorkbookIndirect C# (CSharp) Method

AutomateOneWorkbookIndirect() public static method

public static AutomateOneWorkbookIndirect ( String nodeXLWorkbookFilePath, String workbookSettings ) : void
nodeXLWorkbookFilePath String
workbookSettings String
return void
    AutomateOneWorkbookIndirect
    (
        String nodeXLWorkbookFilePath,
        String workbookSettings
    )
    {
        Debug.Assert( !String.IsNullOrEmpty(nodeXLWorkbookFilePath) );
        Debug.Assert( !String.IsNullOrEmpty(workbookSettings) );

        // Ideally, the Excel API would be used here to open the workbook
        // and run the AutomateOneWorkbook() method on it.  Two things
        // make that impossible:
        //
        //   1. When you open a workbook using
        //      Application.Workbooks.Open(), you get only a native Excel
        //      workbook, not an "extended" ThisWorkbook object.
        //
        //      Although a GetVstoObject() extension method is available to
        //      convert a native Excel workbook to an extended workbook,
        //      that method doesn't work on a native workbook opened via
        //      the Excel API -- it always returns null.
        //
        //      It might be possible to refactor AutomateOneWorkbook() to
        //      require only a native workbook.  However, problem 2 would
        //      still make things impossible...
        //
        //   2. If this method is being run from a modal dialog, which it
        //      is (see AutomateTasksDialog), then code in the workbook
        //      that needs to be automated doesn't run until the modal
        //      dialog closes.
        //      
        // The following code works around these problems.

        Microsoft.Office.Interop.Excel.Application oExcelApplication =
            null;

        ExcelApplicationKiller oExcelApplicationKiller = null;

        try
        {
            // Use a new Application object for each workbook.  If the same
            // Application object is reused, the memory used by each
            // workbook is never released and the machine will eventually
            // run out of memory.

            oExcelApplication =
                new Microsoft.Office.Interop.Excel.Application();

            if (oExcelApplication == null)
            {
                throw new Exception("Excel couldn't be opened.");
            }

            // ExcelApplicationKiller requires that the application be
            // visible.

            oExcelApplication.Visible = true;

            oExcelApplicationKiller = new ExcelApplicationKiller(
                oExcelApplication);

            // Store an "automate tasks on open" flag in the workbook,
            // indicating that task automation should be run on it the next
            // time it's opened.  This can be done via the Excel API.

            Microsoft.Office.Interop.Excel.Workbook oWorkbookToAutomate =
                ExcelUtil.OpenWorkbook(nodeXLWorkbookFilePath,
                oExcelApplication);

            PerWorkbookSettings oPerWorkbookSettings =
                new PerWorkbookSettings(oWorkbookToAutomate);

            oPerWorkbookSettings.WorkbookSettings = workbookSettings;
            oPerWorkbookSettings.AutomateTasksOnOpen = true;
            oWorkbookToAutomate.Save();
            oWorkbookToAutomate.Close(false, Missing.Value, Missing.Value);
            oExcelApplication.Quit();
        }
        catch (Exception oException)
        {
            ErrorUtil.OnException(oException);
            return;
        }
        finally
        {
            // Quitting the Excel application does not remove it from
            // memory.  Kill its process.

            oExcelApplicationKiller.KillExcelApplication();
            oExcelApplication = null;
            oExcelApplicationKiller = null;
        }

        try
        {
            // Now open the workbook in another instance of Excel, which
            // bypasses problem 2.  Code in the workbook's Ribbon will
            // detect the flag's presence, run task automation on it, close
            // the workbook, and close the other instance of Excel.

            OpenWorkbookToAutomate(nodeXLWorkbookFilePath, 60 * 60);
        }
        catch (Exception oException)
        {
            ErrorUtil.OnException(oException);
            return;
        }
    }

Usage Example

コード例 #1
0
        AggregateGraphMetricsInternal
        (
            AggregateGraphMetricsAsyncArgs oAggregateGraphMetricsAsyncArgs,
            BackgroundWorker oBackgroundWorker,
            DoWorkEventArgs oDoWorkEventArgs
        )
        {
            Debug.Assert(oAggregateGraphMetricsAsyncArgs != null);
            Debug.Assert(oBackgroundWorker != null);
            Debug.Assert(oDoWorkEventArgs != null);
            AssertValid();

            List <OverallMetricsInfo> oOverallMetricsInfos =
                new List <OverallMetricsInfo>();

            OverallMetricsReader oOverallMetricsReader =
                new OverallMetricsReader();

            foreach (String sFilePath in Directory.GetFiles(
                         oAggregateGraphMetricsAsyncArgs.SourceFolderPath, "*.xlsx"))
            {
                if (oBackgroundWorker.CancellationPending)
                {
                    oDoWorkEventArgs.Cancel = true;
                    return;
                }

                try
                {
                    if (!NodeXLWorkbookUtil.FileIsNodeXLWorkbook(sFilePath))
                    {
                        continue;
                    }
                }
                catch (IOException)
                {
                    // Skip any workbooks that are already open, or that have any
                    // other problems that prevent them from being opened.

                    continue;
                }

                oBackgroundWorker.ReportProgress(0,
                                                 String.Format(
                                                     "Reading \"{0}\"."
                                                     ,
                                                     Path.GetFileName(sFilePath)
                                                     ));

                OverallMetricsInfo oOverallMetricsInfo;

                for (Int32 iAttempt = 0; iAttempt < 2; iAttempt++)
                {
                    // Have overall metrics already been calculated for the
                    // workbook?

                    if (TryGetGraphMetricsForOneNodeXLWorkbook(sFilePath,
                                                               out oOverallMetricsInfo))
                    {
                        // Yes.

                        oOverallMetricsInfos.Add(oOverallMetricsInfo);
                        break;
                    }

                    if (iAttempt == 0)
                    {
                        // No.  Calculate them.

                        TaskAutomator.AutomateOneWorkbookIndirect(sFilePath,
                                                                  oAggregateGraphMetricsAsyncArgs.WorkbookSettings);
                    }
                }
            }

            if (oOverallMetricsInfos.Count > 0)
            {
                WriteOverallMetricsToNewWorkbook(
                    oAggregateGraphMetricsAsyncArgs.Workbook.Application,
                    oOverallMetricsInfos);
            }

            oBackgroundWorker.ReportProgress(0,
                                             String.Format(
                                                 "Done.  NodeXL workbooks aggregated: {0}."
                                                 ,
                                                 oOverallMetricsInfos.Count
                                                 ));
        }