Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.09.21;
Скачать: CL | DM;

Вниз

тонкости работы с excel   Найти похожие ветки 

 
Arinyshka   (2008-08-05 19:28) [0]

подскажите, можно ли из кода программы организовать стандартную группировку данных при экспорте в excel?
Уточню: я скидываю в Excel данные из вирт. таблицы (заполнена запросом из БД, не суть важно). Первая колонка будет Подгруппа товара, данные в ней повторяются для многих из второй колонки Товар. Нужна автоматическая группировка по первой колонке... Данные отсортированы еще хранимой.
Можно ли это сделать напрямую в коде? спасибо


 
Palladin ©   (2008-08-05 20:19) [1]

конечно можно, записать макрос и воспроизвести


 
arinyshka   (2008-08-06 12:00) [2]

Не получается...

procedure ExcelFillData(ADataSet: TDataset);
var
  Range, Cell1, Cell2, ArrayData  : Variant;
  BeginCol, BeginRow, i, j : integer;
begin

/// заполняю вирт таблицу
BeginCol:=3;
BeginRow:=9;
RowCount:=ADataSet.RecordCount;
 oleExcelDocument.Worksheets.Item[1].Activate;
 oleExcelDocument.Application.EnableEvents := false;
 ArrayData := VarArrayCreate([1, RowCount, 1, ColCount], varVariant);
  for I := 1 to RowCount-1 do
   begin
     for J := 1 to ColCount-1 do
       ArrayData[I, J] :=ADataSet.Fields[j].AsString;
     ADataSet.Next;
   end;

//// скидываю ее в excel

 Cell1 := oleExcelDocument.WorkSheets[1].Cells[BeginRow, BeginCol];
 Cell2 := oleExcelDocument.WorkSheets[1].Cells[BeginRow  + RowCount - 1, BeginCol +ColCount - 1];

 Range := oleExcelDocument.WorkSheets[1].Range[Cell1, Cell2];
 Range.Value := ArrayData;

/// пытаюсь определить столбец, который хочу групировать

  Cell2 := oleExcelDocument.WorkSheets[1].Cells[BeginRow  + RowCount - 1, BeginCol];
  Range := oleExcelDocument.WorkSheets[1].Range[Cell1, Cell2];

  oleExcelDocument.WorkSheets[1].Range.Select;
  oleExcelDocument.WorkSheets[1].Selection.Rows.Group ;

 oleExcelDocument.Visible := true;
end;


Уходит в рантайме с ошибкой "Неверно определено число параметров".
И еще - после закрытия excel он остается висеть в процессах... В приложениях - нет, в списке процессов - есть. Как убить?


 
brother ©   (2008-08-06 12:01) [3]

> Как убить?

послать ему terminate?


 
Vlad   (2008-08-06 12:22) [4]


> brother ©   (06.08.08 12:01) [3]
Закрывать правильно.

> arinyshka

Покажи код, где ты открываешь Excel и где закрываешь.
А по поводу сортировки...Palladin ©   (05.08.08 20:19) [1] все верно сказал. Лучшим пособием при работе с приложениями офиса являются сами эти приложения. Делаешь так, открываешь Excel,сервис->макрос->начать запись. Выполняешь все то, что бы ты хотел(а) сделать из своей программы. Стоп макрос. Сервис->макросы->выбираешь свой макрос->редактировать.
Вот там и смотри, что и как делается. По крайней мере основное поймешь, а дальше поиск в руки )))


 
brother ©   (2008-08-06 12:24) [5]

> > brother ©   (06.08.08 12:01) [3]
> Закрывать правильно.

я про самый сложный случай )


 
arinyshka   (2008-08-06 12:31) [6]

Мне нужно-то преобразовать

Sub макрос1()
   Range("B9:B138").Select
   Selection.Rows.Group
End Sub

в код дельфи... и не получается :(


 
brother ©   (2008-08-06 12:35) [7]

я на будущее тебе скажу (по сектрету), что один код (макрос) на одном языке, может сильно отличаться на другом (код, длина итд) )))) так что

> Мне нужно-то преобразовать
>
> Sub макрос1()
>   Range("B9:B138").Select
>   Selection.Rows.Group
> End Sub
>
> в код дельфи... и не получается :(

это звучит как-то не так)


 
arinyshka   (2008-08-06 12:37) [8]

Закрываю вот так:



var   oleExcelDocument: OleVariant;

procedure ExcelSaveClose;
begin
 oleExcelDocument.ActiveWorkbook.Close(True);
 oleExcelDocument.Quit;
 oleExcelDocument := UnAssigned;
end;



Процедура вызывается на Form.Close. В случае, когда файл открылся корректно - все работает. А вот когда он не создался из-за ошибки - excel провисает в процессах, почему-то считая файл созданным...

Вот я его создаю:


function ExcelCreate: Boolean;
begin
 Result := True;
 try
   oleExcelDocument := GetActiveOleObject("Excel.Application");
 except
   try
      oleExcelDocument := CreateOleObject("Excel.Application");
     except
      MesDlg("Âîçìîæíî íå óñòàíîâëåí Excel!", mtWarning, [mbAbort], 0);
      Result := False;
    end;
 end;
end;


Вот открываю:


function ExcelOpenWorkBook(APathTemplate, ATemplateFile: String): String;
var
 szSourceFullName: String;
 szFullName: String;
begin
 try
  szFullName := "G:\Mercury\Templates\RepGoodsPrices.xls";
   szSourceFullName := APathTemplate + ATemplateFile;
   CopyFile(PAnsiChar(szSourceFullName), PAnsiChar(szFullName),False);
   oleExcelDocument.WorkBooks.Open(szFullName);
   Result := szFullName;
 except
   raise;
 end;
end;


 
arinyshka   (2008-08-06 12:39) [9]


> я на будущее тебе скажу (по сектрету), что один код (макрос)
> на одном языке, может сильно отличаться на другом (код,
> длина итд) )))) так что

да я догадываюсь :))) Уж очень хочется по пути наименьшего сопротивления :)))


 
arinyshka   (2008-08-06 12:42) [10]

Хи :) справилась...

oleExcelDocument.WorkSheets[1].Range[Cell1, Cell2].Rows.Group ;

то есть пришлось явно указывать ячейки,  а не пользоваться  Selection.Rows.Group


 
arinyshka   (2008-08-06 12:44) [11]

И все-таки, если происходит ошибка при создании файла - почему excel остается в процессах в уверенности, что файл существует? как его разубедить?


 
Павел Калугин ©   (2008-08-06 13:41) [12]

> [11] arinyshka   (06.08.08 12:44)

почитайте про обработку исключений и в частности про конструкцию
try
except
end


 
arinyshka   (2008-08-06 14:21) [13]

конструкция-то знакомая :) Я не совсем понимаю, как закрыть процесс. Вот тут:

function ExcelCreate: Boolean;
begin
Result := True;
try
  oleExcelDocument := GetActiveOleObject("Excel.Application");
except
  try
     oleExcelDocument := CreateOleObject("Excel.Application");
    except
     MesDlg("Âîçìîæíî íå óñòàíîâëåí Excel!", mtWarning, [mbAbort], 0);
     Result := False;
   end;
end;
end;


Или тут:


function ExcelOpenWorkBook(APathTemplate, ATemplateFile: String): String;
var
szSourceFullName: String;
szFullName: String;
begin
try
 szFullName := "G:\Mercury\Templates\RepGoodsPrices.xls";
  szSourceFullName := APathTemplate + ATemplateFile;
  CopyFile(PAnsiChar(szSourceFullName), PAnsiChar(szFullName),False);
  oleExcelDocument.WorkBooks.Open(szFullName);
  Result := szFullName;
except
  raise;
end;
end;


 
Vlad Oshin ©   (2008-08-06 14:31) [14]

oleExcelDocument.quit во всех местах исключения


 
arinyshka   (2008-08-06 14:37) [15]


> oleExcelDocument.quit во всех местах исключения

спасибо


 
MsGuns ©   (2008-08-06 16:23) [16]

Не советую создание и редактирование макросов встромлять в делфу - намного удобнее (а главное, совершенно независимо от программы) создать и отладить макрос в самой книге экселя, ктороую сохранить как шаблон, а в программе просто выполнять его, предварительно проверив наличие его в книге или библиотеке макросов.
В шаблоне, кстати, удобно также выполнить и разметку документа (отчета): титул, заголовок, подвал и т.д. В дальнейшем при любом изменении в форме отчета достаточно поправить шаблон, что легко сделать даже непосредственно с ПК полдьзователя, не имею под рукою ни Делфи, ни исходника проекта.

Мы в последнее время вообще делаем так: из делфи просто перегоняем в шаблон данные (которые чаще всего получаются как результат работы хранимки на сервере), а потом запускаем макрос, который все оформление, включая разметку, группировки, итоги и т.д. делает самостоятельно.
По такому принципу у нас на разработку идет только время, требуемое для написания хранимки и макроса. Сама программа делфи, которая организует диалог с пользователем, запускает нужную хранимку, перегоняет результаты в нужный xls/xlt и запускает нужный макрос.
Все "нужное" легко укладывается в две таблички БД на сервере. для коррекции которой (добавления или удаления отчетов) есть еще одна программка. Сами шаблоны вместе с макросами также записаны в БД.
В результате при разработке подавляющего большинства отчетов мы вообще не используем делфу.


 
arinyshka   (2008-08-06 16:33) [17]

Хммм... новая проблемка. Вот если взять такую последовательность:

 Cell1 := oleExcelDocument.WorkSheets[1].Cells[BeginRow, BeginCol];
 Cell2 := oleExcelDocument.WorkSheets[1].Cells[BeginRow  + RowCount - 11, BeginCol];
 oleExcelDocument.WorkSheets[1].Range[Cell1, Cell2].Rows.Group ;

 Cell1 := oleExcelDocument.WorkSheets[1].Cells[BeginRow + RowCount - 10, BeginCol];
 Cell2 := oleExcelDocument.WorkSheets[1].Cells[BeginRow  + RowCount - 1, BeginCol];
 oleExcelDocument.WorkSheets[1].Range[Cell1, Cell2].Rows.Group ;

то на мой взгяд, она должна группировать строки с первой до (последняя-11) и отдельно с (последняя-10) до конечной...
а в реале уровень группировки только 1, с первой по последнюю... Почему?
Можно ли сделать группировку как в Промежуточных итогах - но без подсчета итогов?


 
arinyshka   (2008-08-06 16:35) [18]


> а в программе просто выполнять его, предварительно проверив
> наличие его в книге или библиотеке макросов.

очень интересно... а как? как запустить макрос из кода?


 
Vlad Oshin ©   (2008-08-06 17:48) [19]

VBA
+ google
+ http://www.delphikingdom.com/


 
MsGuns ©   (2008-08-06 20:09) [20]

>Vlad Oshin ©   (06.08.08 17:48) [19]
>VBA

? Достаточно VBS


 
Игорь Шевченко ©   (2008-08-06 23:11) [21]

насчет того, как завершать работу с Excel

ExcelApplication.Quit;
ExcelApplication := Null;

такая связка меня не подводила


 
arinyshka   (2008-08-07 11:48) [22]


> такая связка меня не подводила

Угу... а то только Quit не спас, как оказалось...



Страницы: 1 вся ветка

Текущий архив: 2008.09.21;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.022 c
2-1218459576
Mops
2008-08-11 16:59
2008.09.21
PageController & Popupmenu


15-1217229349
Пробежал...
2008-07-28 11:15
2008.09.21
Хранилище данных


6-1192447120
Адепт
2007-10-15 15:18
2008.09.21
Изменяем октеты в ip адресе. Изменяем Маску подсети. КАК?


15-1217338253
проходил мимо решил зайти
2008-07-29 17:30
2008.09.21
QReport


3-1206503403
Drowsy
2008-03-26 06:50
2008.09.21
Изменение длины "стрингового" поля