[COM] Выгрузка данных в MS Excel файл через COM

rid2000

Выгрузка может длиться пару минут.
Проблема заключается в следующем:
Создаю экземпляр Excel.Application и начинаю работать с ним.
Если параллельно пользователь откроет какой-нибудь Excel-файл (Например, двойным щелчком по файлу
то при открытии юзается мой экземпляр (т.е. открытие происходит через мной созданный экземпляр).
В следствии чего падает вся выгрузка.
Если пользователь создаст свой экземпляр (Например, через меню Пуск) и будет работать с каким-нибудь
фалом, то все нормально.
Кто-нибудь сталкивался с этим?
Есть какие-нибудь варианты борьбы с этим или другие подходы к этому? (Например, запретить юзать мной созданный экземпляр)
ЗЫ:
Программа пишеться на Java. C COM работаю через JACOB 1.10.pre4
Но тут язык , как бы, не причем.
Дельфисты говорят, что тоже с таким сталкивались.

Andbar

Есть такое. Точнее, у меня было веселее обычно: если до того, пока я не освобожу интерфейс, открыть файл, то он не показывается, т.к. экзель спрятан.
Вот только у меня передача данных (табличка с различиными данными размером ~80*32) проходит в течении не более 5 секунд. При этом на экран выводится окошко прогресса. Вероятность того, что кому-то прийдет в голову запускать какой-то файл довольно мала.
Кстати, попробуй передавать данные через буффер обмена - это в разы быстрее, хоть и не очень красиво.

gopnik1994

эксель как-нть заблокируй
повесь на него эвенты, блокирующие открытие левых файлов
еще у Application есть свойство Interactive или что-то в этом роде.
Его полежно поставить в False на время импорта.
или попробуй покопать в сторону параметров, с которыми эксель запускается при клику по файлу и можно ли добавить туда ключик заставляющий всегда создавать новый экзепляр, но это не совсем правильно

9173306234

MSOWC.dll
попробуй это
В ответ на:
COM curSheet;
COM excel = new COM("OWC.Spreadsheet");
COM range;
COM interior;
ComVariant ret;
Str valueCell;
curSheet = excel.ActiveSheet;
// Пишем в ячейку:
range = curSheet.range(‘A1’);
range.value(‘Test-test-test’);
// Играем с цветом:
interior = range.interior;
interior.color(‘Green’); // перевод номера цвета в название – отдельная история.
// Рамка, выравнивание, ширина колонки – аналогично )
// Экспорт в Excel:
excel.export(_fileName, _visible); // _filename – думаю понятно, _visible – показывать рез-т в Excel-е или все сделать вслепую.
// Загрузка в curSheet файла типа txt с разделителями типа tab:
excel.LoadText(_fileName,num2char(9false, '\\042' );
// Параметры: (File As String, [Delimiters As String], [ConsecutiveDelimAsOne As Boolean = False], [TextQualifier As String = "\042"]) – это описание из VBA
// Читаем из ячейки:
ret = range.text;
valueCell = ret.bStr;
.

только перепиши на Java

gopnik1994

и вообще нельзя данные через COM выгружать - это тормоз великий.
для этого есть ADO/ODBC, DDE в конце концов.
а саоме правильное - вызвать макрос и передать ему все данные в XML - пусть сам все разложит как ему больше нравится.

rid2000

Я передаю данные через COM размером 5000 строк.
Пробовал с буфером 24 х 5000 - нормально. Одна такая порция занимает 5 секунд.
Передача через COM состовляет доли секунды. А вот передача данных от сервера - клиенту и преобразование их в VARIANT - занимают основное время.

rid2000

Поставил я Interactive значение false.
И проэксперементировал:
- запустил экспорт 116000 строк в "3.xls"
- открыл "1.xls" с рабочего стола
Excel открыл "1.xls". но заблокировал его, т.е. рабоать с ним нельзя, и даже закрыть.
Вот картинка:

На скрине видно, что он отобразил на таскбаре и "3.xls".
Одно радует - есть програсс: моя програмка хоть не валиться .
Будем дальше эксперементировать.

Andbar

попробуй регулярно прятать экзель, дабы бороться с наглым пользователем. То, что экзель так работает (юзая один объект под всё это можно было бы заметить и на работе обычного пользовательского интерфейса.
И всё-таки интересно, какие же объёмы данных передаются? ведь через буффер обмена передача будет осуществляться на пару порядков быстрее.

laki

а что сторонню либину взять низя?
POI работает тоже через ком

psm-home

POI работает тоже через ком

Неправда. POI это pure Java решение. Нет там никакого COM.

serg05

если у всех юзеров стоит 2003-й ексель можешь генерить готовый xml 2003-го екселевского формата

laki

если у всех юзеров стоит 2003-й ексель можешь генерить готовый xml 2003-го екселевского формата

эквивалентно самоубийству .
проще уж через COM.

psm-home

эквивалентно самоубийству

Почему?
Смотря что делать нужно. Если задачу можно свести к заполнению шаблонов, заранее подготовленных в самом Excel, то ничего страшного там не будет.

Selena

А ты как обращаешся к файлу при экспорте?
Если Excel.Application.Workbooks("3.xls").WorkSheets(1).Cells(1,1).Value = 1, то "перепутывания" файлов быть не должно.
А если Excel.Application.Workbooks(1).WorkSheets(1).Cells(1,1).Value = 1 или Excel.Application.ActiveWorkbook.WorkSheets(1).Cells(1,1).Value = 1, то может произойти как раз похожая ситуация.
И по-моему Excel.Application вобще один, а разные "экземпляры" это, например, Excel.Application.Workbooks("1.xls") и Excel.Application.Workbooks("3.xls").

rid2000

Разные объемы.
Экспорт используется для отчетов. там от 100 строк, до 1 000 000. Правда я большие в Аксесс пишу.
В Эксель, пока ограничение 195000, т.е. 3 листа.

rid2000

POI - падает на 20 000 - 40 000 строках. (Out of memmory)
На сколько я пробовал, частично сохранять нельзя.

rid2000

И это пробовал.
60 000 строк занимает 52 метра. Эксель долго его подымает (относительно).
А через COM - 120 000 строк занимает 27 метров. и Эксель его открывает в одно дыхание

rid2000

Там ничего не путается. по этому поводу все нормально.
идет речь об экземплярах COM

Andbar

В ответ на:
А если Excel.Application.Workbooks(1).WorkSheets(1).Cells(1,1).Value = 1 или Excel.Application.ActiveWorkbook.WorkSheets(1).Cells(1,1).Value = 1, то может произойти как раз похожая ситуация.
ну если сохранить интерфейс к воркбуку во временной переменной, то почему что-то должно путаться?
А то каждый раз искать интерфейс, делая обращение через интерфейс ExcelApplication - это может оказаться долго

nawok

Если можно забить на всякое форматирование, то пиши просто в текстовый файл формата CSV, Excel умеет его читать.

Corrector

 В ответ на:
Выгрузка может длиться пару минут.

Если документ большой, то выгружать его по клеткам нет смысла - очень долго.
Можно выгружать целыми блоками, используя объект range, но у меня возникали проблемы, если в какой-нибудь клетке оказывалось слишком длинное текстовое поле либо размер блока был слишком велик.
Лучше сохранять в какой-либо текстовый формат, а потом считывать из него (но тут возможно ньюансы с неправильным сохранением кавычек, символа возврата каретки)
либо написать макрос, который будет сохранять в удобный тебе формат.

Selena

согласен.
Оставить комментарий
Имя или ник:
Комментарий: