Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, migel, Вы писали:
M>>Ссылочки на временные объекты освобождать не пробывал?
S>А сборщик мусора? Или всетаки не так он хорош? В таком случае можно поподробнее?
Он скорее всего даже и не вызывается
Вообще с COM interop нужно обращаться как написно в инструкции водолаза
Инструкция
1. Спустился под воду берегись акул — встретил ее по мордам ее!
2. Начав работу убедись в отсутствии акул — встретил ее по мордам ее!
3. Закручивая гайку убедись в отсутствии акул — встретил ее по мордам ее!
4...
ну и так далее
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, migel, Вы писали:
M>>Ссылочки на временные объекты освобождать не пробывал?
S>А сборщик мусора? Или всетаки не так он хорош? В таком случае можно поподробнее?
В общем случае все объекты, которые ты поюзал в Excel, нужно убивать после использования через System.Runtime.InteropServices.Marshal (range, worksheet, workbook, aplication). GC мало что сделает за тебя по очистке RCW-классов, возможно, ты в процесс работы не очищал занятую помять, вследствии чего и повалились ексепшны...
Вместо GC используй следующую конструкции:
// здесь создали ссылку на application
Excel.ApplicationClass excel = new Excel.ApplicationClass();
Excel.Workbook wb = excel.Workbooks.Add(1);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets.get_Item(1);
// поработали .......
// ..................
// выгружаем из памяти листif (System.Runtime.InteropServices.Marshal.IsComObject(ws))
{
while( System.Runtime.InteropServices.Marshal.ReleaseComObject(ws)>0){};
ws = null;
}
// выгружаем из памяти книгу
// wb.Close(false,null,null);if (System.Runtime.InteropServices.Marshal.IsComObject(wb))
{
while( System.Runtime.InteropServices.Marshal.ReleaseComObject(wb)>0){};
wb = null;
}
// выгружаем из памяти процесс
excel.Quit();
if (System.Runtime.InteropServices.Marshal.IsComObject(excel))
{
while( System.Runtime.InteropServices.Marshal.ReleaseComObject(excel)>0){};
excel = null;
}
GC.Collect();
GC.WaitForPendingFinalizers();
Помогите пожалуйста, уже не знаю что делать...
С помощью экселя(Microsoft.Office.Interop.Excel) создаю отчет. При создании копии шаблона листа
public void AddSheetCopy(int SourceIndex, int PasteAferIndex)
{
GetSheet(SourceIndex).Copy(Type.Missing, _excelApp.ActiveWorkbook.Sheets[PasteAferIndex]);
}
вылетает ошибка "Ошибка сервера" и все. Причем вылетает при создании 193-194 листа...
Раньше все было ок, сейчас стало глючить... В этот код не лазил... Перегруз машины не помогает...
Здравствуйте, DuШes, Вы писали:
DШ>Здравствуйте, Sheridan, Вы писали:
S>>Здравствуйте, migel, Вы писали:
M>>>Ссылочки на временные объекты освобождать не пробывал?
S>>А сборщик мусора? Или всетаки не так он хорош? В таком случае можно поподробнее?
DШ>В общем случае все объекты, которые ты поюзал в Excel, нужно убивать после использования через System.Runtime.InteropServices.Marshal (range, worksheet, workbook, aplication). GC мало что сделает за тебя по очистке RCW-классов, возможно, ты в процесс работы не очищал занятую помять, вследствии чего и повалились ексепшны...
Код переделал в
public void AddSheetCopy(int SourceIndex, int PasteAferIndex)
{
Worksheet sh = GetSheet(SourceIndex);
Worksheet csh = GetSheet(PasteAferIndex);
sh.Copy(Type.Missing, csh);
if (Marshal.IsComObject(sh)) while(Marshal.ReleaseComObject(sh)>0);
if (Marshal.IsComObject(csh)) while(Marshal.ReleaseComObject(csh)>0);
}
Потому как пишу собственную упрощенную обертку вокруг интеропа экселя.
Не помогает...
Кстати эксель после ошибки ведет себя более чем странно... На события в документе не реагирует совершенно (выделение, смена листа, итд), хотя главное меню реагирует на телодвижения мышой. И закрыть себя позволяет только через идиты, тоесть через снятие задачи... Что самое обидное — ведь работало же до обеда... А после обеда добавил еще пару строк в вывод и перебилдил.
[...]
Попробуй обновить Reference на typelib твоей версии Excel, опять таки проконтролируй список процессов, не осталось ли там незавершенных процессов с предыдущими сенсами работы...
Здравствуйте, DuШes, Вы писали:
DШ>Здравствуйте, Sheridan, Вы писали:
DШ>[...] DШ>Попробуй обновить Reference на typelib твоей версии Excel
Удалить — заново добавить Microsoft.Office.Interop.Excel reference в проекте? Делал. DШ>опять таки проконтролируй список процессов, не осталось ли там незавершенных процессов с предыдущими сенсами работы...
Ясное дело, слежу... Больше 3х не оставляю...
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, DuШes, Вы писали:
DШ>>Здравствуйте, Sheridan, Вы писали:
DШ>>[...] DШ>>Попробуй обновить Reference на typelib твоей версии Excel S>Удалить — заново добавить Microsoft.Office.Interop.Excel reference в проекте? Делал. DШ>>опять таки проконтролируй список процессов, не осталось ли там незавершенных процессов с предыдущими сенсами работы... S>Ясное дело, слежу... Больше 3х не оставляю...
Если есть вожможность, пришли код...сам всегода отчеты в excele лепил, ниразу не сталкивался с такой проблемой...
Здравствуйте, DuШes, Вы писали:
DШ>Здравствуйте, Sheridan, Вы писали:
DШ>[...] DШ>Попробуй обновить Reference на typelib твоей версии Excel, опять таки проконтролируй список процессов, не осталось ли там незавершенных процессов с предыдущими сенсами работы...
Дальше больше... Теперь эксель... мммать... просто вылетает гад. Причем в томже месте...
Вот что использую...
public void AddSheetCopy(string SourceCaption, int PasteAferIndex)
{
Worksheet sh = GetSheet(SourceCaption);
Worksheet csh = GetSheet(PasteAferIndex);
sh.Copy(Type.Missing, csh); // Здесь
FreeCOMObject(sh);
FreeCOMObject(csh);
}
private Worksheet GetSheet(string Caption)
{
return (Worksheet)_excelApp.Sheets.get_Item(Caption);
}
private void FreeCOMObject(object O)
{
if (Marshal.IsComObject(O))
while(Marshal.ReleaseComObject(O)>0);
}
Я уже вааабще не знаю куды беч... Помогите пожалуйста.
Здравствуйте, Sheridan, Вы писали:
S>Я уже вааабще не знаю куды беч... Помогите пожалуйста.
Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют...
Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...
-=RSDN@Home 1.1.4 beta 4 rev. 347=- [Pantera -==- — A new level]
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, Sheridan, Вы писали:
S>>Я уже вааабще не знаю куды беч... Помогите пожалуйста.
S>Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют... S>Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...
Тестовый проект прислать могеш?
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, migel, Вы писали: M>>Тестовый проект прислать могеш? S>Могу. Куда?
migel(dot)
geo
(dog)
yahoo
(dot)
com
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, Sheridan, Вы писали:
S>>Я уже вааабще не знаю куды беч... Помогите пожалуйста.
S>Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют... S>Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...
Ну прям не знаю %))
Если дело действительно в том, что ссылки на объекты Excel не были освобождены, то только вызов ReleaseComObject не сильно поможет. Дело в том, что сборщик мусора убирает мусор не сразу!!! Может помочь явный вызов "уборки": CG.Collect(). Если поможет — отпиши — самому интересно, можно сказать, что хобби у меня такое — собирать глюки Excel %))
Не судите строго и не кидайтесь тапками, после многих лет работы с виндоус и нескольких лет работы с .NET пришлось перейти к linux и вернуться к забытым с/с++.
Здравствуйте, Джафар-дракон, Вы писали:
ДД>Ну прям не знаю %)) ДД>Если дело действительно в том, что ссылки на объекты Excel не были освобождены, то только вызов ReleaseComObject не сильно поможет. Дело в том, что сборщик мусора убирает мусор не сразу!!! Может помочь явный вызов "уборки": CG.Collect().
Не помогает...
Здравствуйте, Sheridan, Вы писали:
S>Здравствуйте, Sheridan, Вы писали:
S>>Я уже вааабще не знаю куды беч... Помогите пожалуйста.
S>Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют... S>Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Sheridan, Вы писали:
S>>Здравствуйте, Sheridan, Вы писали:
S>>>Я уже вааабще не знаю куды беч... Помогите пожалуйста.
S>>Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют... S>>Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...
A>Посмотри http://www.rsdn.ru/Forum/Message.aspx?mid=1004160&only=1
. Если этот код заработает, используй его как отправную точку. У меня он работает превосходно.
Делал я релизкомобжект, пофигу...
У меня чуть по другому, я сейчас решил попробовать наоборот, кешировать это дело...
Вот например Worksheets.cs
using System;
using Microsoft.Office.Interop.Excel;
namespace Bng.Office.SimpleOffice
{
/// <summary>
/// Summary description for WorkSheets.
/// </summary>public class WorkSheets : WorkItems
{
private ApplicationClass _excelApp;
public WorkSheets(ApplicationClass ExcelApp)
{
_excelApp = ExcelApp;
}
public void Add(Worksheet Sheet)
{
Add(Sheet,Sheet.Index,Sheet.Name);
}
new public Worksheet this[int Index]
{
get
{
if (Exists(Index))
return (Worksheet)base[Index];
else
{
Worksheet sh = (Worksheet)_excelApp.Sheets.get_Item(Index);
Add(sh);
return sh;
}
}
}
public void CreateCopy(int SourceIndex, int DestinationIndex, bool PasteAfter)
{
if (PasteAfter)
this[SourceIndex].Copy(Type.Missing, this[DestinationIndex]); // Вылетает здесьelse
this[SourceIndex].Copy(this[DestinationIndex], Type.Missing);
MoveIndexes(DestinationIndex,1);
}
public string GetName(int Index)
{
return this[Index].Name;
}
public void SetName(int Index, string NewName)
{
this[Index].Name = NewName;
SetCaption(Index,NewName);
}
new public Worksheet this[string Caption]
{
get
{
if (Exists(Caption))
return (Worksheet)base[Caption];
else
{
Worksheet sh = (Worksheet)_excelApp.Sheets.get_Item(Caption);
Add(sh);
return sh;
}
}
}
}
}
... и один фиг не помогает, хотя теперь работает перед вылетом раза в 3 быстрее
Здравствуйте, Sheridan, Вы писали:
S>Делал я релизкомобжект, пофигу... S>У меня чуть по другому, я сейчас решил попробовать наоборот, кешировать это дело...
Вот пример, который копирует и потом удаляет лист 200 раз подряд (тебе вроде как это было нужно). У меня это все работает (примечательно, что без GC.Collect() ).
using System;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExcelTest
{
public class Copy
{
public static void Run()
{
Excel.ApplicationClass excel = new Excel.ApplicationClass();
excel.Visible = true;
// вытащить wb
Excel.Workbooks books = excel.Workbooks;
Excel.Workbook wb = books.Add (Type.Missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject (books);
// вытащить ws1 и ws2
Excel.Sheets sheets = wb.Worksheets;
Excel.Worksheet ws1 = (Excel.Worksheet)sheets.get_Item(1);
Excel.Worksheet ws2 = (Excel.Worksheet)sheets.get_Item(2);
System.Runtime.InteropServices.Marshal.ReleaseComObject (sheets);
// копирование и удаление 200 разfor (int i = 0; i < 200; i++)
{
ws1.Copy (Type.Missing, ws2);
Excel.Worksheet w = (Excel.Worksheet) ws2.Next;
w.Delete();
System.Runtime.InteropServices.Marshal.ReleaseComObject (w);
}
System.Runtime.InteropServices.Marshal.ReleaseComObject (ws2);
System.Runtime.InteropServices.Marshal.ReleaseComObject (ws1);
wb.Close (false, null, null);
System.Runtime.InteropServices.Marshal.ReleaseComObject (wb);
excel.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject (excel);
// GC.Collect();
// GC.WaitForPendingFinalizers();
}
}
}
Если это не то что тебе нужно, тогда сформулируй точнее задачу в части, касающейся Excel. У меня он работает просто как часы!
Здравствуйте, Andrbig, Вы писали: A>Вот пример, который копирует и потом удаляет лист 200 раз подряд (тебе вроде как это было нужно). У меня это все работает (примечательно, что без GC.Collect() ). A>Если это не то что тебе нужно, тогда сформулируй точнее задачу в части, касающейся Excel. У меня он работает просто как часы!
Мне нужно скопировать лист гдето более 350 раз. Удалять не нужно... Если хочеш я тебе зашлю исходники.
Здравствуйте, Andrbig, Вы писали:
A>Тебе надо создать книгу Excel с 350 листами? Думаю, этого он не понятнет. Лично у меня Excel рухнул на 336 странице.
Здравствуйте, Sheridan, Вы писали:
S>Млин, да ведь делал же! От он гад!
Боюсь что тут нет решения. Даже если открыть .xls с 335 страницами и добавить одну (т.е. 336-ю), то все падает. Кстати, из самого Excel добавляется без проблем! Спасибо M$...
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Sheridan, Вы писали:
S>>Млин, да ведь делал же! От он гад!
A>Боюсь что тут нет решения. Даже если открыть .xls с 335 страницами и добавить одну (т.е. 336-ю), то все падает. Кстати, из самого Excel добавляется без проблем! Спасибо M$...
Вот такой код на машине с 1 Gb нормально открывает все 800 закладок
Посему резюме :
Осовобождай все объекты!
Не забывай что все что возвращается методами екселевских объектов тоже есть COM объекты (коллекции тоже!!!!)
Кэшировать странички особой нужды нет. Если критична скорость то меняй архитектуру — вместо заполнения ячеек из программы делай в шаблоне макрос и заполняй ячейки с помощью его — резку снизиш затраты на маршаллинг.
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, migel, Вы писали:
M>>Вот такой код на машине с 1 Gb нормально открывает все 800 закладок
A>Дело не в добавлении нового, а в копировании листа. Если сможешь сделать 800 копий листа, приведи код.