:: Не фоксом единым
Убить Excel C шарп
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Только хотел кричать ура,
а приходится караул.
Смастерил до конца форму,
которая вызывает прорву процедур Оракл в кнопках.
Все параметризовал. Красота. В кнопке только имя процедуры и вариация ключа парамеров.
И Снова какая-то хрень с Excel
После успешной работы любой процедуры
показываю результат в гриде и
визуализую кнопку Вывод в Ексел
Она вызывает 2 функции
Первая формирует Ексел файл , сохраняет его и должна умереть
Потом вторая процедура имитирует shellexec на готовый файл
Результат такой- ексел открывается, все показывает, только крутится колесико,
ни на что нажать невозможно, ни даже закрыть ексел
Только диспетчером задач.
Пошел по шагам, и обнаружил, что после вызова первой функции до вызова
второй в диспетчере задач все еще виден Excel
Если его в это момент в диспетчере убить, то все срабатывает на ура во второй функции.
Она не виновата. Если ексел в диспечере не убить, он похоже находится в каком-то коматозном состоянии.
Вроде в конце первой функции приняты все меры, чтобы почистить все следы ексела
Вот код. Его основа взята в Интернет, только слегка допилина под нужное мне
private void CMDExls_Click(object sender, EventArgs e)
{
string lcfln = this.textBox1.Text + "\\мойхорошийфайл" + this.label2.Text + this.maskedTextBox1.Text + this.maskedTextBox2.Text + ".xlsx";

ExcelElements xls =new ExcelElements() ;
xls.fillxls(lcfln, this.dataGridView1.DataSource as DataTable);
xls = null;
this.runxls(lcfln);
}
}
public class ExcelElements
{


public void fillxls(string fln, DataTable dtt)
{
Excel.Application xlApp = new Excel.Application();
xlApp.Visible = false;

try
{
//добавляем книгу
xlApp.Workbooks.Add(Type.Missing);

//делаем временно неактивным документ
xlApp.Interactive = false;
xlApp.EnableEvents = false;
Excel.Workbook wb = xlApp.ActiveWorkbook;
//выбираем лист на котором будем работать (Лист 1)
Excel.Worksheet xlSheet = wb.Worksheets[1];

//Название листа
xlSheet.Name = "Данные";

//Выгрузка данных


int collInd = 0;
int rowInd = 0;
string data = "";

//называем колонки
Excel.Range xlSheetRange = xlSheet.Range[xlSheet.Cells[1, 1], xlSheet.Cells[1, 22]];
// Excel.Range oRng = ws.Range[/*get_Range(*/ws.Cells[i, j], ws.Cells[i1, j1]]/*)*/;

//делаем полужирный текст и перенос слов
xlSheetRange.WrapText = true;
xlSheetRange.Font.Bold = true;
for (int i = 0; i < dtt.Columns.Count; i++)
{
data = dtt.Columns.ColumnName.ToString();
xlSheet.Cells[1, i + 1] = data;

//выделяем первую строку

}

//заполняем строки
for (rowInd = 0; rowInd < dtt.Rows.Count; rowInd++)
{
for (collInd = 0; collInd < dtt.Columns.Count; collInd++)
{
data = dtt.Rows[rowInd].ItemArray[collInd].ToString();
xlSheet.Cells[rowInd + 2, collInd + 1] = data;
}
}

xlSheetRange.Columns.AutoFit();
xlSheetRange.Rows.AutoFit();
xlApp.ActiveWorkbook.SaveAs(fln);
xlApp.Visible = false;
releaseObject(xlSheet);
xlSheet = null;
// если не сделать предыдущую строку, в этом месте все еще виден объект типа excelsheet
//только нулевой
releaseObject(xlSheetRange);
xlSheetRange = null;
xlApp.ActiveWorkbook.Close();
releaseObject(wb);
wb = null;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{

xlApp.Quit();



releaseObject(xlApp);
xlApp = null;
// тут ексел все еще виден в диспетчере задач!
}
}




//Освобождаем ресуры (закрываем Excel)
void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show(ex.ToString(), "Ошибка!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
GC.Collect();
}
}




}



[i]Исправлено 1 раз(а). Последнее : boba, 01.04.19 15:43
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не устану повторять.
Igor Korolyov
А вообще "работать с эксель" - тупиковый путь.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Игорь.
Вы наверное правы на все 100.
Просто я так устроен, что если сам
не докопаюсь до причины,
остановиться не могу.
Обнаружил десятки постов с описанием проблемы
и ее возможным решением. Есть ответ даже в msdn , на который ссылаются многие ответы,
заключающейся в
цикле while (System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)!=0);
и System.Runtime.InteropServices.Marshal.FinalReleaseComObject(obj)
Взял оба совета и оба не работают!Даже зациклил второй совет
FinalReleaseComObject -не помогает.
Excel сидит в диспетчере и все. Запустить просмотр файла excel
после этого нельзя-висит рюмка, никакие пункты меню и выход не доступны.
Есть замечательный совет с кодом убить процесс excel и он действительно работает.
Только этот совет не честный. У человека в этот момент могут быть просто открыты
другие документы excel к работающей форме не имеющие никакого отношения.
Может там правка была. И что все закрываем оптом?
Получается, что эта штука просто не работает, не доделана.
Даже решение с мсдн толком не проверили.
Вообще большое число разочарований.
Вот ругают фоксовый грид, а он поля чар и ньюмерик правильно
выравнивает слева и с права, а dataview это нужно кодом объяснять.
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
boba
Получается, что эта штука просто не работает, не доделана.
Даже решение с мсдн толком не проверили.
Именно так. Потому и совет - не связываться с этим если не припёрли к стенке.
boba
а dataview это нужно кодом объяснять.
Он вообще слишком тупой, ещё и медленный, особенно если заниматься его "раскрасками". Зато бесплатный


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Есть купленный Express
Пока руки не дошли.
Ексел вчера вечером все-таки
убили.
Вроде танца с бубнами
куча ньюансов.
Нельзя освобождение писать в отдельном методе releaseobject ,
а нужно прямо в методе работы с Ексел.
Блок очистки мусора 2 раза и тоже там же.(collect waitfor что то такое)
На всякий случай sendmessage хэндлу окна ексела ( чтобы убить rcp)
Упаси бог сидеть при этом в дебагере раньше блока убития , все опять не будет работать.
Теперь я спокоен, и могу работать с нормальной библиотекой работы
с ексел, которую тут используют, а про это забыть.
Осадок конечно остался, почему в Фоксе такой проблемы нет,
(написал excel.quit, excel=null sys(1104))
а тут какую-то глупость не доделали.
Если бы только я один был, кто на это нарвался,
а так сотни постов на эту тему,
причем большинству никакие рецепты не помогли, кроме убить процесс
Ексела.
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
Александр Жевелев

Сообщений: 2723
Откуда: Новосибирск
Дата регистрации: 09.10.2003
Посмотри в сторону EPPlus в части формирования файла.Excel использую только для отображения готового файла ( Process.Start(tfile);)
Ratings: 0 negative/0 positive
Re: Убить Excel C шарп
boba
Автор

Сообщений: 6269
Откуда: Медвежьи озера-
Дата регистрации: 26.03.2001
Я так и сделал с самого начала
1 формируется ексел, закрывается
2 эмуляция shellexec указанным классом.
Если 2 не делать, а оставить ексел видимым
для просмотра пользователю, придется еще писать часть
обработки события ексела на закрытие.
Это не слишком просто, потому как пользователь
может минимизировать ексел документ, и пойти гулять
по другим пунктам задачи. При этом метод работы с ексел останется не законченным.
У нас человек с таким способом мучается, ексел часто подвисает.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 13 (Гостей: 13)

© 2000-2024 Fox Club 
Яндекс.Метрика