Отчет Excel |
Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.
Отчет Excel |
Atreides |
27.04.2011 13:04
Сообщение
#1
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Задача - разложить данные по предприятия в закладки книги файла эксель. Т.е. одна закладка одно предприятие. + имя закладки это имя предприятия из списка. Шапка одна и так же везде должна быть, количество предприятий может меняться. Для вывода отчет использую шаблон и компоненту EXLReport. В один список все прекрасно выходит, а вот как разбить на страницы с именами предприятий и данные разложить вопрос. Не уверен, что верно написал переход по списку предприятий еще...
Вот пример моего вывода: Код procedure TForm5.Button1Click(Sender: TObject); var col: integer; st: string; year, MonthSelected: string; oth: string; sum_03, sum_04, sum_05, sum_1_04, sum_2_04, sum_1_05, sum_2_05: string; provodka: string; data: string; direct: string; IDSOURCE, PR_MEST: string; priznak: string; NO_FAM: string; cods: string; KOD:string; koll:integer; begin // собираем данные year := Form5.Edit1.Text; MonthSelected := FloatToStr(Form5.ComboBox1.ItemIndex + 1); priznak := IntToStr(Form5.ComboBox3.ItemIndex + 1); oth := 'получе5ние отчетного месяца' + MonthSelected + ''; Form5.ClientDataSet1.close; Form5.ClientDataSet1.DataRequest(oth); Form5.ClientDataSet1.open; oth := Form5.ClientDataSet1.fieldbyname('id_otchm').asstring; IDSOURCE := 'выбор источника загрузки ''; Form5.ClientDataSet1.close; Form5.ClientDataSet1.DataRequest(IDSOURCE); Form5.ClientDataSet1.open; IDSOURCE := Form5.ClientDataSet1.fieldbyname('ID_SOURCE').asstring; PR_MEST := Form5.ClientDataSet1.FieldByName('Pr_MEST').AsString; NO_FAM := Form5.ClientDataSet1.FieldByName('NO_ONE_FAM').AsString; direct := 'reestor_bez_mesta.xls'; //получаем список кодов организации begin cods := 'выборка кодов организации ' + ' order by Kodorg asc '; Form5.ClientDataSet1.close; Form5.ClientDataSet1.DataRequest(cods); Form5.ClientDataSet1.open; koll:=Form5.ClientDataSet1.RecordCount; Kod := Form5.ClientDataSet1.FieldByName('KODORG').AsString; while Form5.ClientDataSet1.Eof do begin //по одной организации st := ' запрос данных о предприятии '; Form5.ClientDataSet2.close; Form5.ClientDataSet2.DataRequest(st); Form5.ClientDataSet2.open; { col := Form5.ClientDataSet2.RecordCount; begin if col = 0 then begin ShowMessage('Данные отсуствуют') end else } Form5.ClientDataSet1.Next; begin Form5.EXLReport1.TemplSheet:='Лист 3'; exlReport1.Template := 'H:\808.COM\Andreev\Справочники\Forms\' + direct; if Assigned(Form5.EXLReport1) then Form5.EXLReport1.Show; // открытие окошка эксель end; end; end; end; //end; Сообщение отредактировано: Atreides - 27.04.2011 13:07 -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
28.04.2011 1:49
Сообщение
#2
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Сторонние компоненты не использую, идея - такая:
procedure TForm1.Button2Click(Sender: TObject);Нужные поля допишешь, если понадобится - поменяешь диапазон на листе, куда будет копироваться информация. Датасет вот такой: , все корректно разбивается на 5 листов. |
Atreides |
28.04.2011 8:57
Сообщение
#3
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
XLApp - это ExcelApplication или какой модуль надо подключить? Закладки как имя предприятия принимаются, и в каком месте запрос открывать? Есть возможность использовать шапку и после эту шапку копировать на другие листы? вылетаю по ошибке [DCC Error] Print.pas(360): E2010 Incompatible types: 'TExcelApplication' and 'IDispatch' - несовместимые типы на строке XLApp := CreateOleObject('Excel.Application');
Сообщение отредактировано: Atreides - 28.04.2011 9:12 -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
28.04.2011 10:05
Сообщение
#4
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата XLApp - это ExcelApplication или какой модуль надо подключить? Нет. ЭтоUses ..., ComObj; Цитата Закладки как имя предприятия принимаются, и в каком месте запрос открывать? Еще раз можно этот же вопрос задать, только в более понятной форме? Какой запрос? Запрос - в строке ClientDataSet1.Filter := 'Pr_MEST = ' + QuotedStr(Ls.Strings[i]);Если тебе нужно - задай там критерием фильтрации не только поле Pr_MEST, но и любую другую комбинацию условий по правилам SQL. Цитата Есть возможность использовать шапку и после эту шапку копировать на другие листы? Есть возможность новый лист добавлять из шаблона. Прямо с шапкой, в том формате, который тебе нужен:constВ комментариях описаны все изменения, которые надо внести... Код тестировался на Дельфи 2009 под Excel XP, но ничего страшного и при более новых версиях Офиса произойти не должно, ничем недокументированным я не пользуюсь, все описано в MSDN -> Microsoft.Office.Interop.Excel Namespace (ссылки пока добавлять не могу, так что ищи сам) |
Atreides |
28.04.2011 15:20
Сообщение
#5
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
меня интересует вопрос в каком месте послать запрос и вставлять конструкцию следующего типа или она вообще не нужна?
Код st := ' select ..... '; Form5.ClientDataSet1.close; Form5.ClientDataSet1.DataRequest(st); Form5.ClientDataSet1.open; Запросом я выдаю весь список данных сгруппированные по предприятиям. Вот мне в закладку надо название организации вкрячить. Т.е. есть организация и на листе все записи с ней, на другом листе все записи по второй и так далее... Сообщение отредактировано: Atreides - 28.04.2011 15:25 -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
28.04.2011 15:44
Сообщение
#6
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата меня интересует вопрос в каком месте послать запрос и вставлять конструкцию следующего типа или она вообще не нужна? Такой запрос не нужен. Его роль на себя беретClientDataSet1.Filtered := False;Заметил? Сначала проходим по всей базе и заносим все разные данные из полей "Pr_MEST" в StringList... А потом просто фильтруем данные из набора: каждый раз подставляя новое значение из List-а в фильтр. Я структуры твоего набора данных не знаю. Предположил, что в поле "Pr_MEST" хранится название организации. Если так - то прекрасно. Не так - замени название поля на нужное в двух местах: в строке 33 и строке 44 исходника из 4-го поста. В 44-ой строке набор будет фильтроваться по нужному критерию, и данные для одной организации запишутся на один лист отчета, для другой - на другой лист. Для тех данных, что я показал - получился вот такой результат: Тебе что, присоединить полный исходник? Сам заполнить ClientDataSet так, как на скриншоте из 2-го поста, и проверить, что происходит при запуске программы - не можешь? Цитата Вот мне в закладку надо название организации вкрячить. Цитата Curr := ActiveBook.Sheets.Add (Type := TemplateSheet, After := Curr); Сообщение отредактировано: IUnknown - 28.04.2011 15:50 |
Atreides |
28.04.2011 16:01
Сообщение
#7
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
наверное, лучше исходник прикрепить как целостны пример, его по-кусочкам разбирать буду.
-------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
28.04.2011 16:51
Сообщение
#8
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Ну вот:
XLL.zip ( 6.41 килобайт ) Кол-во скачиваний: 407 Поменяешь там путь к XLT-файлу на правильный... Сначала жмешь кнопку "FillDSet", датасет заполнится (я не стал делать соединения с БД, заполнил все в рантайме. Разницы в обработке данных - никакой, а проблем меньше), а потом - "To XL" |
Atreides |
29.04.2011 11:49
Сообщение
#9
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Почему то в конце столбцов образуются символы (#Н/Д). Чет более трех полей не получается вывести, а мне надо 14
Сообщение отредактировано: Atreides - 29.04.2011 11:55 -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
29.04.2011 12:32
Сообщение
#10
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата Почему то в конце столбцов образуются символы (#Н/Д). Значит, размер областиЦитата Range := Curr.Range[CellStart, CellFinish]; Цитата Чет более трех полей не получается вывести, а мне надо 14 Хоть 114. Инициализируй Data нужного размера (столбцы - это 3 и 4 индексы)Data := VarArrayCreate([1, ClientDataSet1.RecordCount, 1, 14], varVariant); // Будет тебе место под 14 столбцов, и заполняй значениями. А потом переноси, только начальную/конечную ячейки правильно посчитай... |
Atreides |
29.04.2011 12:38
Сообщение
#11
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Код Data := VarArrayCreate([1, ClientDataSet1.RecordCount, 1, 14], varVariant); // Будет тебе место под 14 столбцов Значит я верно разобрался. Косякнул в другом месте ((( А еще такой вопрос, при выполнении происходит открытие экселя и его заполнение, а можно заполнить, а поле отобразить?-------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
29.04.2011 12:59
Сообщение
#12
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Можно. Перенеси
ActiveBook.Sheets[1].Delete; // Помнишь первый добавленный лист? Он не нужен... Где будет Visible присваиваться True - там и будет появляться окно Excel. Но тогда тебе надо будет добавить какой-нибудь ProgressBar (скажем, по количеству обработанных предприятий), потому что если отчет сложный (много данных), то между нажатием на кнопку и получением результата пройдет какое-то время, пользователь может быть в недоумении. |
Atreides |
2.05.2011 11:30
Сообщение
#13
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Еще вопрос такой возник – можно добавить вставку даты в шапку, в заранее заданную ячейку и итог общий по сумму в конце дописать?
-------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
2.05.2011 13:33
Сообщение
#14
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Цитата можно добавить вставку даты в шапку, в заранее заданную ячейку и итог общий по сумму в конце дописать? Если ячейка известна - то разумеется, можно:ToCell := 'A3'; // Var ToCell : String; Цитата и итог общий по сумму в конце дописать? Добавить формулу что-ли в ячейку? И это можно:ToCell := 'A21';- Подставишь свой интервал в формулу, и нужный номер ячейки... Сообщение отредактировано: IUnknown - 2.05.2011 13:34 |
Atreides |
3.05.2011 13:55
Сообщение
#15
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Из константы можно путь в переменную вывести?
-------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
3.05.2011 14:08
Сообщение
#16
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Из константы в переменную - можно, обратно - нельзя.
|
Atreides |
3.05.2011 14:33
Сообщение
#17
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Из константы в переменную - можно, обратно - нельзя. Код var TemplateSheet:string; begin TemplateSheet := 'H:\M6301.XLs'; end; Чет не прокатывает мне. Чет не так делаю ((( -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
3.05.2011 14:51
Сообщение
#18
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Что значит "не прокатывает"? Все прекрасно скомпилировалось и отработало.
|
Atreides |
3.05.2011 14:59
Сообщение
#19
|
Ветеран Броуновского Движения Группа: Пользователи Сообщений: 281 Пол: Мужской Реальное имя: Сергей Репутация: 0 |
Что значит "не прокатывает"? Все прекрасно скомпилировалось и отработало. [DCC Error] Print.pas(452): E2029 ':=' expected but '=' found - посылает по этому в этой строке(( Код begin TemplateSheet = 'H:\808.COM\Andreev\Справочники\Формы\M6301.XLs'; end; -------------------- Отрадно спать, отрадней камнем быть, О, этот век, преступный и постыдный, Не жить, не чувствовать - удел завидный. Прошу, молчи, не смей меня будить!
|
IUnknown |
3.05.2011 15:03
Сообщение
#20
|
a.k.a. volvo877 Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: 627 |
Ну, а какого ты сверху написал ":=", а здесь, ниже, уже пишешь "="? Требуется-то именно присваивание, переменная же...
|
Текстовая версия | 11.05.2024 15:04 |