![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Excel
snake77 © (2005-12-08 16:51:00)Здравствуйте!
Нашел на сайте кусок исходника экспортирующий в эксель заданную выборку,
все нормально, но толко если я вызываю эту процедуру раза три , то на четвертом или раньше программа на строке
ExcelApp.Visible := True;
просто зависает не отображая эксель , хотя в списке процессов висит эксель.
Че не так??
может надо как то освобождать переменную ExcelApp??
текст процедуры
Var
ShFile: String; Querys:TDataSet;
ExcelApp, Workbook, Range, Cell1, Cell2, ArrayData: Variant;
BeginCol, BeginRow, j: integer;
RowCount, ColCount: Integer;
Begin
BeginCol := 1;
BeginRow := 3;
Querys:=DBGrid1.DataSource.DataSet;
// Размеры выводимого массива данных
ColCount := Querys.FieldDefs.Count;
// Создание Excel
ExcelApp := CreateOleObject('Excel.Application');
// Отключаем реакцию Excel на события, чтобы ускорить вывод информации
ExcelApp.Application.EnableEvents := false;
// Создаем Книгу (Workbook)
// Если заполняем шаблон, то
Workbook := ExcelApp.WorkBooks.Add(ShFile);
// Заполняем массив
ShowMessageForm('Подготовка экспорта',true);
Querys.DisableControls;
Querys.First;
while not Querys.Eof do
Begin
Inc(RowCount);
Querys.Next;
end;
CloseMEssageForm;
For J := 1 To Querys.FieldDefs.Count Do
Begin
Cell1 := WorkBook.WorkSheets[1].Cells[1,j];
Cell1.NumberFormat:='@';
Cell1.Value:=Querys.Fields[j - 1].DisplayLabel;
Cell1.Columns.AutoFit;
end;
ShowPrMessageForm('экспорт данных в XLS формат',0,RowCount,0);
Querys.First;
While Not Querys.eof Do
Begin
ShowProgress(Querys.RecNo);
For J := 1 To Querys.FieldDefs.Count Do
Begin
Cell1 := WorkBook.WorkSheets[1].Cells[Querys.RecNo+1,j];
Cell1.NumberFormat:='@';
Cell1.Value:=Querys.Fields[j - 1].AsString;
Cell1.Columns.AutoFit;
End;
Querys.Next;
End;
Querys.EnableControls;
CloseMessageform;
// Делаем Excel видимым
ExcelApp.Visible := True;
Digitman (2005-12-09 09:22:00) [1]
> snake77 (08.12.05 18:13) [10]
подобные "вИсы" при выполнении обращений к Excel (да и не только к нему - как правило ко многим внешним серверам автоматизации) часто возникают из-за того, что при исполнении метода сервер обнаружил, например, ошибку, требующую интерактивное вмешательство юзера (сервер открывает модальное диалоговое окно)
в состоянии Visible = False юзер, разумеется, этого окна не видит, поэтому окно остается открытым, но вызванный метод при этом ждет его закрытия до бесконечности
убедиться в правильности такого предположения можно просмотрев список окон, принадлежащих серверу, сразу после обнаружения зависания вызванного метода ... например, средствами Spy++
MU (2005-12-08 19:35:00) [2]Может, завести у формы член xlApp : OleVariant, а не в функции?
procedure Form1.OnClick()
begin
//Если Excel уже запущен, то получить его, а не запускать новый
try
xlApp := GetActiveOleObject('Excel.Application');
except
end;
if VarIsNull(xlApp) then
try
xlApp := CreateOleObject('Excel.Application');
except
end;
end;
if VarIsNull(xlApp) then Exit; //No Excel ?
....
end;
destructor Form.Destroy
begin
xlApp := UnAssigned;
end;
NiGGa (2005-12-08 19:26:00) [3]бррр. тогда без ExcelApp.Quit; но обезательно с Visible := True; иначе кто его закрывать будет?
А вообще советую поекспериментировать :)
snake77 (2005-12-08 18:54:00) [4]поидее нет, пользователь то должен посмотреть на это безобразие и ежели оно его устраивает то сохранить куданить
NiGGa (2005-12-08 18:27:00) [5]Гы. А что не должен?
snake77 (2005-12-08 18:13:00) [6]блин а после ExcelApp.Quit;
эксель просто закрывается сам собой :(
snake77 (2005-12-08 18:03:00) [7]
> и Ексель из процессов выгружается?
;)
спасибо что сказал
неа , висит там родный
причем видимо со временем закрывается потому как я прбовал раз 10
его запустить а висит их там чтуки 4
snake77 (2005-12-08 18:01:00) [8]
> 3. И полседнее по порядку но не по важности
> Workbook := ExcelApp.WorkBooks.Add(ShFile);
> что в ShFile ?
имя файла
> 2. Очень тормознутый подход к перекидыванию данных....
тормознутый не спорю %)
но данных перекидывается не много , да и честно говоря хотелось самому немного разобраться ;)
чем нежели использовать полностью готовый исходник
> 1. Эта мессага возникает?
угу, при трассировке зависала именно на ExcelApp.Visible := True;
NiGGa (2005-12-08 17:59:00) [9]
> сработало и просто null
> тока вот чейто я н понимаю в чем прикол то?
и Ексель из процессов выгружается?
NiGGa (2005-12-08 17:56:00) [10]1. Эта мессага возникает?
ShowPrMessageForm('экспорт данных в XLS формат',0,RowCount,0);
2. Очень тормознутый подход к перекидыванию данных, никто так не делает(потому что смотри справку), вобщем это из-за тормознутости ОЛИ. Используется что-то вида
function ReferenceToCell(const ARow, ACol: Cardinal): string;
begin
Result := Chr(Ord('A') + ACol - 1) + IntToStr(ARow);
end; {Reference to Cell}
xlData := VarArrayCreate([0, rowCount, 0, colCount], varVariant);
xlSheet := xlApp.Workbooks[1].WorkSheets[1];
xlSheet.Range[ReferenceToCell(1, 1), ReferenceToCell(rowCount + 1, colCount + 1)].Value := xlData;
Заполняется же с квери xlData (тип OLEVariant, если не догадался).
при таком подходе весь массив за раз перекидывается.
3. И полседнее по порядку но не по важности
Workbook := ExcelApp.WorkBooks.Add(ShFile);
что в ShFile ?
4. Конешно ExcelApp нужно освобождать.
Где-то так:
ExcelApp.DisplayAlerts := False;
ExcelApp.Quit;
ExcelApp := Unassigned;
snake77 (2005-12-08 17:43:00) [11]сработало и просто null
тока вот чейто я н понимаю в чем прикол то?
объект то я не освобождаю таким образом а всего то обнуляю указатель
вчем тут криминал, ведь я то переменную использую локальную т.е. она всеравно удаляется после завершения процедуры
MetalFan (2005-12-08 17:28:00) [12]или null
MetalFan (2005-12-08 17:28:00) [13]простите за флуд) савсем запутался)
ExcelApp := UnAssigned;
MetalFan (2005-12-08 17:26:00) [14]ExcelApp := nil; ?
snake77 (2005-12-08 17:22:00) [15]Удалено модератором