Отключенный контекст Excel Com Object

У меня многопоточное приложение. Одним из свойств приложения является отчетность.

Пользователь может ежедневно получать данные за год

Я извлекаю базу данных, получаю результаты в список. Затем используйте Excel (как объект com).

Открывается Excel и начинают добавляться значения ячеек из списка.

Пока эти процессы идут внезапно получаю такое сообщение:

Ошибка

Вот мой код для отчетов Excel:

private void RNReportDensityStatistics(List<object[]> _PlateBasedDensityStaticticsList)
        {
            try
            {
                RNTakeReportButton.Enabled = false;
                RNExcelApp = new RNExcel.Application();
                RNExcelApp.Visible = false;
                RNWorkBook = RNExcelApp.Workbooks.Add();
                RNWorkSheet = (RNExcel.Worksheet)RNExcelApp.ActiveSheet;
                RNExcelApp.DisplayAlerts = false;

                RNProgressBar.Visible = true;
                RNProgressBar.Minimum = 0;
                RNProgressBar.Maximum = _PlateBasedDensityStaticticsList.Count;
                RNProgressBar.Value = 0;
                RNProgressBar.Step = 1;

                RNExcelApp.Range["A2"].Value = GetGUIItemString(GUIItemIndex.RNReportDensityStatisticsAutoParkPlate);
                RNExcelApp.Range["B2"].Value = GetGUIItemString(GUIItemIndex.RNReportDensityStatisticsAutoParkEntryTime);
                RNExcelApp.Range["C2"].Value = GetGUIItemString(GUIItemIndex.RNReportDensityStatisticsAutoParkExitTime);
                RNExcelApp.Range["D2"].Value = GetGUIItemString(GUIItemIndex.RNReportDensityStatisticsAutoParkCameraIP);
                RNExcelApp.Range["E2"].Value = GetGUIItemString(GUIItemIndex.RNReportDensityStatisticsAutoParkSpaceNo);

                RNWorkSheet.Columns[1].AutoFit();
                RNWorkSheet.Columns[2].AutoFit();
                RNWorkSheet.Columns[3].AutoFit();
                RNWorkSheet.Columns[4].AutoFit();
                RNWorkSheet.Columns[5].AutoFit();

                var row = 2;
                foreach (var DensityStatistics in _PlateBasedDensityStaticticsList)
                {
                    row++;
                    RNWorkSheet.Cells[row, "A"] = DensityStatistics[4];
                    RNWorkSheet.Cells[row, "B"] = ConvertEpochToDateTime(Convert.ToUInt64(DensityStatistics[2]));
                    RNWorkSheet.Cells[row, "C"] = ConvertEpochToDateTime(Convert.ToUInt64(DensityStatistics[3]));
                    RNWorkSheet.Cells[row, "D"] = DensityStatistics[0];
                    RNWorkSheet.Cells[row, "E"] = DensityStatistics[1];                    
                    RNProgressBar.PerformStep();
                }

                RNWorkSheet.Columns[1].AutoFit();
                RNWorkSheet.Columns[2].AutoFit();
                RNWorkSheet.Columns[3].AutoFit();
                RNWorkSheet.Columns[4].AutoFit();
                RNWorkSheet.Columns[5].AutoFit();

                string RNExcelReportPath = RNExcelReportPathStartingAdress
                    + GetGUIItemString(GUIItemIndex.RNReportPathNameAsPlate)
                    + RNPlateSearchTextBox.Text + " "
                    + GetGUIItemString(GUIItemIndex.RNReportPathNameAsDensity)
                                      + ".xlsx";
                RNWorkBook.SaveAs(RNExcelReportPath, 
                                  misValue,
                                  RNExcelPassword, 
                                  misValue, 
                                  misValue,
                                  misValue, 
                                  RNExcel.XlSaveAsAccessMode.xlExclusive,
                                  misValue, 
                                  misValue, 
                                  misValue, 
                                  misValue, 
                                  misValue);

                RNWorkBook.Close(true, misValue, misValue);
                RNExcelApp.Application.Quit();
                RNExcelApp.Quit();

                RNReleaseObject(RNWorkSheet);
                RNReleaseObject(RNWorkBook);
                RNReleaseObject(RNExcelApp);

                RNTakeReportButton.Enabled = true;
                AddLog(LogIndex.RNReportDensityStatisticsSuc, RNExcelReportPath, string.Empty, string.Empty);

            }
            catch (Exception ex)
            {
                RNReleaseObject(RNWorkSheet);
                RNReleaseObject(RNWorkBook);
                RNReleaseObject(RNExcelApp);
                AddException(ex.ToString());
                RNTakeReportButton.Enabled = true;
                AddLog(LogIndex.RNReportDensityStatisticsFail, string.Empty, string.Empty, string.Empty);
            }
            finally
            {
                RNReleaseObject(RNWorkSheet);
                RNReleaseObject(RNWorkBook);
                RNReleaseObject(RNExcelApp);
                RNTakeReportButton.Enabled = true;

                RNProgressBar.Value = _PlateBasedDensityStaticticsList.Count;
                RNProgressBar.Update();
            }
        }

        private void RNReleaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);

                if (System.Runtime.InteropServices.Marshal.AreComObjectsAvailableForCleanup())
                {
                    System.Runtime.InteropServices.Marshal.CleanupUnusedObjectsInCurrentContext();
                }

                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                AddTrace("Unable to release the Object ");
                AddException(ex.ToString());
            }
            finally
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }

person Birol Capa    schedule 26.02.2013    source источник
comment
спасибо, Питер, я новичок в этом вопросе, поэтому я допустил ошибки, когда пытался поделиться своим кодом, большое спасибо   -  person Birol Capa    schedule 27.02.2013


Ответы (1)


Нет необходимости использовать COM-объект для создания отчетов. Я решил свою проблему, не используя объект com для использования excel для отчетов.

Существуют различные инструменты для создания отчетов и использования Excel для этого.

  1. Open XML SDK: http://www.microsoft.com/en-us/download/details.aspx?id=5124

Документация http://msdn.microsoft.com/en-us/library/bb491088(v=office.14).aspx

  1. Если синтаксис Open XML SDK для вас сложен, вы можете использовать: http://spreadsheetlight.com/

Документация очень хорошая, и Винсент (http://spreadsheetlight.com/about/) действительно полезен для ваших вопросов. .

  1. Если вашему приложению не требуются какие-либо диаграммы, вы можете использовать: http://closedxml.codeplex.com/

И электронная таблица, и закрытый XML основаны на Open XML SDK, и, исходя из моего опыта, у меня нет проблем с отключенным контекстом.

Если вам нужно защитить файлы Excel, вы можете использовать: http://dotnetzip.codeplex.com/. заархивированный файл xlsx, защищенный паролем.

Как следствие, вам не нужно использовать COM-объект, службы взаимодействия и Excel.Exe на вашем компьютере.

Я желаю, чтобы предложения были полезными, и спасибо всем, кто разработал SpreadSheetLight, Closed XML и Open XML.

person Birol Capa    schedule 07.03.2013