Re[9]: Дополнение...
От: Sheridan Россия  
Дата: 03.03.05 08:48
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Здравствуйте, Sheridan, Вы писали:


S>>Здравствуйте, Sheridan, Вы писали:


S>>>Я уже вааабще не знаю куды беч... Помогите пожалуйста.


S>>Короче я так понял тут настолько крутые программеры, что такие мелочи их не интересуют...

S>>Народ, ну хоть какие идеи, а? Я уже че тока не перепробывал...

A>Посмотри http://www.rsdn.ru/Forum/Message.aspx?mid=1004160&only=1
Автор: Andrbig
Дата: 26.01.05
. Если этот код заработает, используй его как отправную точку. У меня он работает превосходно.

Делал я релизкомобжект, пофигу...
У меня чуть по другому, я сейчас решил попробовать наоборот, кешировать это дело...
Вот например 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 быстрее
-=RSDN@Home 1.1.4 beta 4 rev. 347=- [Craig Armstrong — Inhaler]
Matrix has you...
Re[10]: Дополнение...
От: Andrbig  
Дата: 03.03.05 12:15
Оценка:
Здравствуйте, 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. У меня он работает просто как часы!
Re[11]: Дополнение...
От: Sheridan Россия  
Дата: 03.03.05 12:22
Оценка:
Здравствуйте, Andrbig, Вы писали:
A>Вот пример, который копирует и потом удаляет лист 200 раз подряд (тебе вроде как это было нужно). У меня это все работает (примечательно, что без GC.Collect() ).
A>Если это не то что тебе нужно, тогда сформулируй точнее задачу в части, касающейся Excel. У меня он работает просто как часы!
Мне нужно скопировать лист гдето более 350 раз. Удалять не нужно... Если хочеш я тебе зашлю исходники.
-=RSDN@Home 1.1.4 beta 4 rev. 347=- [silent]
Matrix has you...
Re[12]: Дополнение...
От: Andrbig  
Дата: 03.03.05 12:49
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Мне нужно скопировать лист гдето более 350 раз. Удалять не нужно... Если хочеш я тебе зашлю исходники.


Тебе надо создать книгу Excel с 350 листами? Думаю, этого он не понятнет. Лично у меня Excel рухнул на 336 странице.
Re[13]: Дополнение...
От: Sheridan Россия  
Дата: 03.03.05 13:35
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Тебе надо создать книгу Excel с 350 листами? Думаю, этого он не понятнет. Лично у меня Excel рухнул на 336 странице.


Млин, да ведь делал же! От он гад!
-=RSDN@Home 1.1.4 beta 4 rev. 347=- [silent]
Matrix has you...
Re[14]: Дополнение...
От: Andrbig  
Дата: 03.03.05 15:30
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Млин, да ведь делал же! От он гад!


Боюсь что тут нет решения. Даже если открыть .xls с 335 страницами и добавить одну (т.е. 336-ю), то все падает. Кстати, из самого Excel добавляется без проблем! Спасибо M$...
Re[15]: Дополнение...
От: migel  
Дата: 04.03.05 08:26
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Здравствуйте, Sheridan, Вы писали:


S>>Млин, да ведь делал же! От он гад!


A>Боюсь что тут нет решения. Даже если открыть .xls с 335 страницами и добавить одну (т.е. 336-ю), то все падает. Кстати, из самого Excel добавляется без проблем! Спасибо M$...

Вот такой код на машине с 1 Gb нормально открывает все 800 закладок
        public void CreateSheets()
        {
            Sheets shs = null;
            try
            {
                shs = _excelApp.Worksheets;
                object wsh = null;

                int failCount = 0;
                Exception failEx = null;
                for (int i = 0; i < 800; i++)
                {
                    try
                    {
                        wsh = shs.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                    }
                    catch (Exception e)
                    {
                        failEx = e;
                        failCount = i;
                        break;
                    }
                    finally
                    {
                        FreeCOMObject(wsh);
                    }
                }
                if (failCount != 0)
                    System.Diagnostics.Debugger.Break();
                else
                    _excelApp.Visible = true;
            }
            finally
            {
                FreeCOMObject(shs);
            }
        }


Посему резюме :
Осовобождай все объекты!
Не забывай что все что возвращается методами екселевских объектов тоже есть COM объекты (коллекции тоже!!!!)
Кэшировать странички особой нужды нет. Если критична скорость то меняй архитектуру — вместо заполнения ячеек из программы делай в шаблоне макрос и заполняй ячейки с помощью его — резку снизиш затраты на маршаллинг.
... << RSDN@Home 1.1.4 beta 4 rev. 324>>
Re[16]: Дополнение...
От: Andrbig  
Дата: 04.03.05 09:23
Оценка:
Здравствуйте, migel, Вы писали:

M>Вот такой код на машине с 1 Gb нормально открывает все 800 закладок


Дело не в добавлении нового, а в копировании листа. Если сможешь сделать 800 копий листа, приведи код.
Re[17]: Дополнение...
От: migel  
Дата: 04.03.05 09:45
Оценка:
Здравствуйте, Andrbig, Вы писали:

A>Здравствуйте, migel, Вы писали:


M>>Вот такой код на машине с 1 Gb нормально открывает все 800 закладок


A>Дело не в добавлении нового, а в копировании листа. Если сможешь сделать 800 копий листа, приведи код.

    for (int i = 0; i < 800; i++)
    {
        try
        {
            wshCopy = shs[1];
            ((Worksheet)wshCopy).Copy(Type.Missing, wshCopy);
        }
        catch (Exception e)
        {
            failEx = e;
            failCount = i;
            break;
        }
        finally
        {
            FreeCOMObject(wshCopy);
        }
    }


Сам Excel упал на 490 закладке
Так что программа не при чем — видать слишком сложные странички получаються
... << RSDN@Home 1.1.4 beta 4 rev. 324>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.