Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.10.2016, 21:00   #1
player95
 
Регистрация: 16.10.2016
Сообщений: 9
По умолчанию Выгрузка Excel из процессов - C#

Доброго времени суток всем! Заранее прошу прощения если тема создана не в том разделе.
Итак, есть код, который из Excel передает все данные на форму в dataGridView1. Естественно после работы с Эксель нужно выгрузить все его барахло для того чтобы он не висел в процессах.
Весь код:
Код:
private void button3_Click(object sender, EventArgs e)
        {
            test();
           
        }
        public void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
            }
            finally
            {
                GC.Collect();
            }
        }
        public void test()
        {
            dsTest dSet = new dsTest();
            Excel.Application ExcelApp = new Excel.Application();
            Excel.Worksheet ExcelWorkSheet;
            Excel.Workbook ExcelWorkBook;
            Excel.Range ExcelRange;
 
            var workbooks = ExcelApp.Workbooks;
            ExcelWorkBook = workbooks.Open(@"D:\\Эксель.xlsm", 0, false);
            ExcelWorkSheet = ExcelWorkBook.ActiveSheet;
            ExcelRange = ExcelWorkSheet.UsedRange;
 
            for (int Rnum = 2; Rnum <= ExcelRange.Rows.Count - 2; Rnum++)
            {
                DataRow dr = dSet.DataTable1.NewRow();
                for (int Cnum = 1; Cnum <= ExcelRange.Columns.Count; Cnum++)
                {
                    if ((ExcelRange.Cells[Rnum, Cnum] as Excel.Range).Value2 != null)
                    {
                        dr[Cnum - 1] =
            (ExcelRange.Cells[Rnum, Cnum] as Excel.Range).Value2.ToString();
                    }
                }
                dSet.DataTable1.Rows.Add(dr);
                dSet.DataTable1.AcceptChanges();
            }
 
            dataGridView1.DataSource = dSet.DataTable1;
            dataGridView1.Visible = true;
            ExcelWorkBook.Close(true, null, null);
            ExcelApp.Quit();
            releaseObject(ExcelApp);
            releaseObject(workbooks);
            releaseObject(ExcelWorkBook);
            releaseObject(ExcelWorkSheet);
            releaseObject(ExcelRange);
        }
Проблема заключается вот в этой строке:
Код:
ExcelWorkBook = workbooks.Open(@"D:\\Эксель.xlsm", 0, false);
Понадобилось путь к файлу засунуть в отдельную переменную. Записал:
Код:
string fullPath = "D:\\Эксель.xlsm";
И после того как я вместо пути прописываю fullpath у меня Excel остается висеть в процессах. Если вернуть все как было, то есть путь напрямую, то все корректно работает. В чем тут может быть проблема?
player95 вне форума Ответить с цитированием
Старый 16.10.2016, 21:33   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

если нужен только 2007+ формат (xlsx, наверно xlsm тоже), то проще взять библиотеку основанную на OpenXML API, например ClosedXML https://closedxml.codeplex.com
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 16.10.2016, 21:45   #3
player95
 
Регистрация: 16.10.2016
Сообщений: 9
По умолчанию

Уже слишком много на Interop написано. Это ведт только часть кода) Замена библиотеки точно не вариант. Мне в идеале надо получить вот это вот:
Код:
ExcelWorkBook = workbooks.Open(Application.StartupPath + "\\Эксель.xlsm", 0, false);
То есть файлик должен находится всегда рядом с приложением. Я в общем то так и пробовал, и в переменную записывал. Но вот процесс перестал выгружаться. В упор не понимаю как так если я по сути заменил только название.
player95 вне форума Ответить с цитированием
Старый 16.10.2016, 22:01   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от player95 Посмотреть сообщение
Уже слишком много на Interop написано. Это ведт только часть кода) Замена библиотеки точно не вариант.
так с ней проще писать + производительность возрастет в 100500 раз и не будет нужно наличие офиса


я когда-то делал как-то так без всяких FinalReleaseComObject и все закрывалось и не висело.
Код:
        public void CreateAndOpenDocument(string outputFilePath, string templateFilePath)
        {
            File.Copy(templateFilePath, outputFilePath);

            _excelApp = new Excel.Application();

            _excelApp.Visible = true;

            var workbooks = _excelApp.Workbooks;

            _workbook = workbooks.Open(outputFilePath,
                0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",
                true, false, 0, true, false, false);

            var workheets = _workbook.Worksheets;

            try
            {
                _mainWorksheet = (Excel.Worksheet)workheets.Item["..."];
            }
            catch (Exception ex)
            {
                throw new Exception(....);
            }
        }

        public void Stop()
        {
            try
            {
                _workbook.Save();
            }
            catch (Exception)
            { }

            if (_workbook != null)
            {
                _workbook.Close(false, Missing.Value, Missing.Value);

                _workbook = null;
                _mainWorksheet = null;
            }

            if (_excelApp != null)
            {
                _excelApp.Quit();

                _excelApp = null;
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
у вас releaseObject неправильный вроде, смысл в таком obj = null? ExcelApp и т.п. так и останется не null же, только локальная переменная станет null.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 16.10.2016 в 22:04.
Alex11223 вне форума Ответить с цитированием
Старый 16.10.2016, 22:06   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

там сложная вещь на самом деле.
надо освобождать каждую переменную из пространства имен интеропа.
причем часто =null не помогает.

поищите на проторах интернета AutoReleaseComObject класс.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 16.10.2016, 22:13   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
надо освобождать каждую переменную из пространства имен интеропа.
не совсем каждую обязательно наверно.
тут у меня Range не освобождается и это не мешало.
Код:
        private void WriteData(.... data)
        {
            int startCol = ...;

            int row = ...;

            var values = new object[1, 4]
            {
                { data...., data....., data....., data..... }
            };

            var range = (Excel.Range) _mainWorksheet.Range[_mainWorksheet.Cells[row, startCol], _mainWorksheet.Cells[row, startCol + 3]];

            range.Value = values;
        }
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 16.10.2016, 22:13   #7
player95
 
Регистрация: 16.10.2016
Сообщений: 9
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
так с ней проще писать + производительность возрастет в 100500 раз и не будет нужно наличие офиса
Не отрицаю, но в данном случае переходить на нее уже не вариант. В следующий раз если буду работать с Excel, то уже буду смотреть в сторону OpenXML.
Присваивание null переменным тоже работает, но сути вопроса не меняет. Если я в методе Open указываю просто путь кавычках напрямую, все корректно работает, а если прописываю переменную или прописываю вот так: Application.StartupPath + "\\Эксель.xlsm", то процесс остается висеть.

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
там сложная вещь на самом деле.
надо освобождать каждую переменную из пространства имен интеропа.
причем часто =null не помогает.

поищите на проторах интернета AutoReleaseComObject класс.
Ну у меня в общем т в releaseobject оно и есть.

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
не совсем каждую обязательно наверно.
тут у меня Range не освобождается и это не мешало.
У меня все коректно работает если освобождаю каждую использованную.

Последний раз редактировалось Alex11223; 16.10.2016 в 22:17.
player95 вне форума Ответить с цитированием
Старый 16.10.2016, 22:16   #8
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Так я ж говорю, releaseObject неправильный скорее всего.

Про путь не знаю, видимо так сложились звезды компилятора.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 16.10.2016, 22:20   #9
player95
 
Регистрация: 16.10.2016
Сообщений: 9
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Так я ж говорю, releaseObject неправильный скорее всего.

Про путь не знаю, видимо так сложились звезды компилятора.
releaseObject нормальный. Я пробегался по нему отладчиком, все хорошо работает. Вот звезды компилятора эти, это да(
player95 вне форума Ответить с цитированием
Старый 16.10.2016, 22:24   #10
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

И что увидели в отладчике? Неужели ExcelApp в test стал null?
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выгрузка из MySQL в Excel (некорректный файл Excel) Maxx PHP 4 16.09.2015 00:07
Выгрузка в Excel city32 Общие вопросы Delphi 2 18.10.2012 15:58
Выгрузка dll из всех процессов Anton911 Win Api 3 01.08.2012 14:50
Выгрузка из БД в Excel fenetka Microsoft Office Excel 6 20.10.2011 09:06
Выгрузка данных из БД в Excel Rougez Microsoft Office Excel 3 17.06.2011 13:06