Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.09.21;
Скачать: [xml.tar.bz2];

Вниз

тонкости работы с 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.007 c
15-1217338253
проходил мимо решил зайти
2008-07-29 17:30
2008.09.21
QReport


2-1217946538
Dmitry S
2008-08-05 18:28
2008.09.21
Аналог следующего update на Access-e


2-1218102039
9899100
2008-08-07 13:40
2008.09.21
Пункт меню из DLL


2-1218444298
Neon-w
2008-08-11 12:44
2008.09.21
Собрать из двух один)


2-1218434218
Mops
2008-08-11 09:56
2008.09.21
TWebbrowser и IE





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский