Форум программистов, компьютерный форум, киберфорум
Delphi: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/34: Рейтинг темы: голосов - 34, средняя оценка - 4.82
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64

adoquery и fastreports

23.07.2011, 16:09. Показов 6963. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
У меня возникла проблема при получении данных в отчет по информации из запроса из БД.
У меня имеется таблица, в событие edit.change у меня происходит поиск нужных мне данных из БД. Код следующий:
Code
1
2
3
4
5
6
7
8
procedure TForm1.Edit3Change(Sender: TObject);
begin
Datamodule2.ADOQuery1.Active := false;
Datamodule2.ADOQuery1.SQL.Clear;
Datamodule2.ADOQuery1.SQL.Add('select * from spisok_org where id_organizacii LIKE "%'+Form1.Edit3.Text+'%"');
Datamodule2.ADOQuery1.Active := true;
Datamodule2.ADOQuery1.Open;
end;
В дбгриде отодражается результат поиска. Так вот как данные или из этого грида или из Адо отобразить в отчете, если при передаче в отчет не видно полей, которые нужно отобразить.
Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.07.2011, 16:09
Ответы с готовыми решениями:

ОТЧЕТ fastreports
добрый день! в fastreports создаю отчет, и вместо 136 записей в отчете появляются только первых 4. подскажите, в чем может быть проблема?...

Оформление отчета в FastReports
есть такая фишка, как в MasterData закрашивать строку по условию. Memo 6 закрашиваю по условию <Line> mod 2 = 1 - это условие...

Запрос ADOQuery внутри другого ADOQuery реален?
Помогите сформировать запрос для двух ADOQuery. Есть 2 таблицы БД mssql: sotrudniki , table_hlp(Вспомогательная таблица для делания...

35
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.07.2011, 16:58
Вам нужно "передавать" содержимое отобранных записей (по сути датасета) динамически.
Как - это зависит от того самого "отчета", на который Вы даже не намекнули.
1) Queek, Rave, Fast, Crystal... и т.д. генераторы отчетов.
Все ручками - код должен быть универсален (т.е. создание, разметка, размещение, форматирование и т.д. таблбэндов - исключительно кодом) - громоздкий и трудноотлаживаемый код. ИМХО - самый гнилостный способ

2) Excel, html, xml.. благодаря имеющимся в делфе компонентам код не будет слишком велик и сложен. Как писать - масса статей в инете (особенно по экселю) - просто наберите в гугле например Delphi + Excel и Вы удивитесь сколько хороших ссылок выдаст поисковик. ИМХО - самый правильный способ.

3) Хоть и нехорошо это, но в качестве рекламы... Имеется масса "гридных" компонент третьих лиц, в которые разработчиками заложено умение выгружать содержимое сетки в стандартные форматы (текст, хатмель, xml, эксель, ворд и т.д.) Например, QuantumDBGrid, cxDBGrid, DBGridEh rxDBGrid и т.д. ИМХО - способ для лоботрясов и шарафилов.
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
23.07.2011, 17:11  [ТС]
Т.е. как я понял в Fast выгрузить данные, полученные из запроса так же как из AdoTable не получится? А то руками делать как-то реально нереально ))

Добавлено через 4 минуты
Кстати, все базу делаю в Navicat-e, если создавать там представление и пробовать выводить из него данные, то будет тоже много гемороя?


Цитата Сообщение от MsGuns Посмотреть сообщение
Как - это зависит от того самого "отчета", на который Вы даже не намекнули.
сам отчет, по сути, обычная страничка, содержащая некую информацию, без всяких наваротов и разметок. Главное пока сделать просто и понятно, а там можно и что-то уже думать про красоту.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.07.2011, 17:22
Delphi
1
Т.е. как я понял в Fast выгрузить данные, полученные из запроса так же как из AdoTable не получится?
Я не говорил "не получится", я говорил геморно. Если выгружаемые данные можно привести к "общему знаменателю", т.е. как-то нормализовать, то можно изгильнуться, в дизайне фастрепорта (например) спроектировав некоторый "унивесальный" отчет, годный для всех разновидностей отчетов реальных. А потом программно лишь включая нужные (или запрещая наоборот лишние) колонки. Но это, повторюсь - способ гнилостный. Проверено практическим опытном

По-поводу "обычности"... Да пофиг на титулы и шапки - любой табличный вид информации, предназначенный для просмотра и печати, называется отчетом. Хоть из одной колонки и одной записи - все одно отчет ! И выводится такой отчет просто как набор например эксельных ячеек. А вот "розочки", "финтиклюшки" и прочий "фарш" в виде шапок, итогов, колонтитулов и прочей лабуды - это все можно задвинуть в том же самом экселе в шаблон, отдав таким образом все "красивости" на откуп самому юзверю. Мне лично такой подход кажется наиболее удачным. Я и использую его уже несколько лет, забыв проблему "лизания" отчетов в связи с измененим форм, титулов, шапок и т.д.
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
23.07.2011, 17:37  [ТС]
ну вот а все же, если грузить не в эксель, то что значит это высказывание Ваше:

Цитата Сообщение от MsGuns Посмотреть сообщение
нужно "передавать" содержимое отобранных записей (по сути датасета) динамически.
Каким образом передать лучше, т.к. с созданием отчетов столкнулся впервые. Хоть какой-нибудь толчок в том направлении, в котором нужно рыть и разбираться.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.07.2011, 18:05
Например так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function TForm1.ExportQueryToCSV(AConnection: TADOConnection, sSQL: string): boolean;
var
  ls: TStrings;
  i: integer;
  s: string;
begin
  ls = TStringList.Create;
  result := false;
  with TADODataSet.Create(nil) do
    try
      Connection := AConnection;
      CommandText := sSQL;
      try
        Open;
        while not eof do begin
          s := '';
          for i := 0 to Fields.Count-1 do s := s+Fields[i].AsString+';';
          delete(s,length(s),1);
          ls.Add(s);
          next;
        end;
        Close;
        ls.SaveToFile(ExtractFilePath(Application.ExeName)+'selected.csv';
        result := true;
      except
        ShowMessage('Ошибка выборки');
      end;
    finally
      Free;
    end;
  ls.Free;
end;
Добавлено через 1 минуту
Модераторы, а что с форматированием, почему в строчку ???

---
Mawrat: формат подправил.
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
23.07.2011, 18:21  [ТС]
эмм, и что это будет?
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.07.2011, 18:45
Выгрузка в текстовый файл (csv)
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
23.07.2011, 20:50  [ТС]
мм, как все сложно
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.07.2011, 23:02
И что ж там сложного ? Просто скопируейте себе этот код, "причешите" его под Ваш проект и пользуйтесь на здоровье ! Единственное, над чем Вам придется подумать самостоятельно - это над самим текстом "ищущего" запроса. Но надо ж Вам что-то сделать самостоятельно ?
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
24.07.2011, 00:52  [ТС]
ну с запросом это пустяки, только вот не понимаю, в функцию в роли параметров что будет передаваться, адоконекшн и строка подключения чтоль?
и куда пихать результат поиска. С таким не сталкивался, вот и не могу сообразить, может и ничего тяжкого тут нет.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.07.2011, 01:39
Т.к. "ваша" функция "базонезависима", то для того, чтобы она обратилась к нужному серверу/БД, ей следует передать парапметры соединения. Предположив, что в Вашей программе уже имеется соответствующий компонент TADOConnection, я и сделал указатель на него параметром фукнкции.
Можно, конечно, и строку подключения, но логически верно чтобы запрос на поиск выполнялся в контексте "рабочего" соединения, т.е. соединения , на котором был выполнен основной отображающий запрос (если он есть, а он, как мне кажется должен быть)
Что касается результатов поиска, то после того, как код функции перепишет его сначала в строки, а затем в текстовый файл, результаты "погибнут" вместе с "разовым" объектом TADODataSet.
Текстовый файл csv Вы можете показать в мемо или загрузить его в стрингрид или предоставить пользователю поступать с ним как заблагорассудится, например, перегнать в тот же эксель для печати или сохранения в удобном формате. Вы, кстати, так и не объяснили ЧТО Вы планируете делать с результатами поиска. Если они Вам нужны для обработки в виде датасета, то переделайте функцию так, чтобы она не создавала компонент TADODataSet, а использовала Ваш (кстати вместе с текстом запроса, который Вы занесете предварительно) - в этом случае параметр строки с текстом запроса заменитке на параметр ссылки на Ваш TADODataSet. А вот уже этот датасет Вы можете использовать как угодно - например положить его в отдельную сетку и показать пользователю рядом с основной сеткой как результат поиска.

Добавлено через 28 минут
Кстати, в случае датасета, отпадает и первый параметр, а сама функция становится универсальной, т.е. применимой к ЛЮБОМУ датасету и, следовательно, гриду.
Для окончательного "универсализма" ее нужно немного подшаманить и она примет такой вид:
(обратите внимание - из метода класса я превратил код в глобальную процедуру. Зачем - надеюсь объяснять не нужно ?)

procedure PutDataSetToTextFile(DataSet: TDataSet, TxtFile: TFileName, Dmtr: Char = ';');
var
i: integer;
s: string;
sl: TStrings;
bm: TBookMark;
begin
sl = TStringList.Create; // Создать буферный список
with DataSet do
begin
DisableControls; // Чтоб не "моргало"
bm := GetBookMark; // Запомнить текущую активную строку для восстановления тек.позиции НД
First;
// Датасет просматривается и каждая запись интерполируется в группы символов-полей
// разделенных символом разделителем Dmtr (по умолчанию - ';')
while not Eof do
begin
s := '';
for i :=0 to Fields.Count-1 do
s := s+Fields[i].AsString+Dmtr;
Delete(s,length(s),1); // удалить разделитель в конце строки как лишний
end;
GoToBookMark(bm); // Восстановить исходный вид сетки (активную запись)
FreeBookMark(bm); // освободить память, выделенную ранее под закладку
EnableControls; // разрешить реагирование сетки на мышь и клавиатуру
end;
sl.SaveToFile(TxtFile); // Выгрузить сформированный список в текстовый файл
sl.Free;
end;

Пример использования:

PutDataSetToTextFile(DBGrid1.DataSource. DataSet,'D:\outdata1.csv');

Правда, у этой процедуры есть один недостаток - она не сможет обрабатывать большие датасеты. Но это можно поправить, заменив список TStrings на файл (AssignFile,WriteFile etc).
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
24.07.2011, 15:35  [ТС]
хех, спасибо огромнейшее, что называется выручили. Сча буду тестить процедурку. Насчет глобальной все понятно, хоть что-то есть еще в голове ))

Добавлено через 1 минуту
кстати, что нужно подрубить, чтоб работали и определялись
GoToBookMark(bm);
FreeBookMark(bm);
EnableControls

И с датасетом косяк, не определяет Тdataset
печалька (((

Добавлено через 15 минут
Спать хочу, туплю, а вообще, датасет я не использую, запрос проходит через AdoQuery и инфа все отображается в дбгриде. Из грида хотелось бы вытащить инфу все в файл и все. А отчет мне нужен просто для его физуального просмотра, для галочки, что он есть.

Добавлено через 13 часов 28 минут
я немного иначе вытащил все в ворд, тк по Вашему методу не получается чет. Сейчас другая проблема, как сделать нормальное отображение информации в ворде, т.е. нормализовать ее расположение. Может подскажите, код прилагаю
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure TForm1.Button7Click(Sender: TObject);
var v:variant;
begin
Datamodule2.ADOQuery1.Active := false;
Datamodule2.ADOQuery1.SQL.Clear;
Datamodule2.ADOQuery1.SQL.Add('select * from spisok_org where id_organizacii LIKE "%'+Form1.Edit3.Text+'%"');
Datamodule2.ADOQuery1.Active := true;
Datamodule2.ADOQuery1.Open;
 
 v:=CreateOleObject('Word.Application');
 v.documents.add;
 //TableOrders.DisableControls;
 while (not(Datamodule2.ADOQuery1.eof)) do
   begin
  v.application.selection.typetext(Datamodule2.ADOQuery1.FieldByName('id_organizacii').asstring+'            '+
           Datamodule2.ADOQuery1.FieldByName('Naimenovanie').asstring+'               '+
           Datamodule2.ADOQuery1.FieldByName('adres').asstring+'     '+ #13);
  Datamodule2.ADOQuery1.Next;
  end;
 
 //TableOrders.EnableControls;
 v.visible:=true
end;
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.07.2011, 15:37
1. TADOQuery, как это не удивительно, явяляется "датасетом", т.е. потомком TDataSet (F1 на TADOQuery, затем см. иерархию)
2. "Не видит" методы TDataSet, вероятно, потому, что вы эту процедуру запулили в другой юнит. Однако это лечится "прививкой" в виде uses DB (вообще чаще пользуйтест справкой: поставили курсов на любое слово-класс (TDataSet или TBookMark например) и нажали F1. Далее смотрим и учимся
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
24.07.2011, 15:48  [ТС]
Пользуясь Вашими советами запустил прогу с процедурой, но прога виснет при нажатии на кнопку, которая вызывает процедуру. Жаль ((
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.07.2011, 15:52
1.Текст процедуры сюда
2. В какой модуль Вы ее засунули ?

Добавлено через 1 минуту
Обработчик "кнопки" - виновницы тоже сюда
0
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
24.07.2011, 15:56  [ТС]
Код кнопки
Delphi
1
2
3
4
procedure TForm1.Button8Click(Sender: TObject);
begin
PutDataSetToTextFile(DBGrid2.DataSource.DataSet,'D:\outdata1.csv');
end;
Код процедуры
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
procedure PutDataSetToTextFile(DataSet: TDataSet; TxtFile: TFileName; Dmtr: Char = ';');
 var
 i: integer;
 s: string;
 sl: TStrings;
 bm: TBookMark;
 begin
 sl := TStringList.Create; // Создать буферный список
 with DataSet do
 begin
 DisableControls; // Чтоб не "моргало"
 bm := GetBookMark; // Запомнить текущую активную строку для восстановления тек.позиции НД
 First;
 // Датасет просматривается и каждая запись интерполируется в группы символов-полей
 // разделенных символом разделителем Dmtr (по умолчанию - ';')
 while not Eof do
 begin
 s := '';
 for i :=0 to Fields.Count-1 do
 s := s+Fields[i].AsString+Dmtr;
 //Delete(s,length(s),1); // удалить разделитель в конце строки как лишний
 end;
 GoToBookMark(bm); // Восстановить исходный вид сетки (активную запись)
 FreeBookMark(bm); // освободить память, выделенную ранее под закладку
 EnableControls; // разрешить реагирование сетки на мышь и клавиатуру
 end;
 sl.SaveToFile(TxtFile); // Выгрузить сформированный список в текстовый файл
 sl.Free;
 end;
Закоментил удаление, тк ошибка была, дело было в параметрах, кот передавались к удалению. А так вроде все осталось
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.07.2011, 16:56
"Шайба" Вам по копипасту. Где полный код цикла while not eof ?
Почему закомментарено удаление последнего разделителя ?
Почему данные каждой записи не сохраняются в списке, а тупо теряются ?
И в конце-концов, где оператор перехода на след запись NEXT ? Без него цикл будет работать до армагеддона, тщательно и весно тиская первую запись.

Вы, уважаемый, когда передираете что-то хотя бы смотрите ЧТО вы передираете и передирайте ТОЧНО.

Добавлено через 4 минуты
Прошу прощения, накосячил я, спасибо глюкавому форматеру сайта. Правильный код в [6]. Просто когда я набирал второй вариант (именно набирал, а не копипастил), куда-то затерялись две важные строки. Добавьте их в код и наслаждайтесь результатом

Добавлено через 2 минуты
Но кстати мое замечание насчет ревизии того, что передираете, остается актуальным
1
 Аватар для Slimmi
2 / 2 / 0
Регистрация: 28.03.2008
Сообщений: 64
24.07.2011, 17:03  [ТС]
MsGuns, Спасибо! А что в роли sSQL передавать, строку подключения или какую другую строку?

Добавлено через 4 минуты
И вообще, по поводу замечаний не совсем въехал, как я понял там чего-то не хватает?
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.07.2011, 17:18
"Ну какой же Вы тупооой !" (с)
Вам нужно взять код из [12] (что Вы и сделали), но добавить две строчки из [6], которые я пропустил при повторном ручном наборе кода. sSQL в данном варианте процедуры не нужен ибо текст запроса, который он был должен передавать, уже имеется в экземпляре TDataSet (точнее у его потомка TADODataSet/TADOQuery/TADOTable или чего там у Вас используется), указатель на который передается в варианте [12]. В самом деле, когда Вы идете в гости, Вы же не несете с собою в сумке свой рот - он и так при Вас, со всеми зубами

Добавлено через 5 минут
Теперь по теме. как я понял у Вас есть рабочая сетка, в которой Вы показываете содержимое некоторого запроса к Вашей БД.
Вам нужно:
А) - чтобы пользователь мог ввести для любой колонки некоторое значение-обазец, потом нажал кнопку "Найти" и открылась бы новая форма, в которой отобразился бы грид, аналогичный основному, но содержащий только записи, удовлетворяющие введенному образцу. (Фича "Поиск")
Б) - чтобы пользователь мог ввести для любой колонки некоторое значение-обазец, потом нажал кнопку "Найти" и в текущем гриде отобразились бы только те записи, которые удовлетворяют введенному образцу. (Фичо "Фильтр")

Что Вам надо А или Б

Вывод в текстовый файл, как я понял из любой сетки.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.07.2011, 17:18
Помогаю со студенческими работами здесь

Передача символов в переменную FastReports
Кто знает как передать значение текстовой переменной в переменную FastReports ? читал тут топики...пробовал по разному но всегда 1 и...

Как установить компонент FastReports?
Всем привет еще раз)) Установил программу FastReports, а при компиляции выдает ошибку( Помогите как можно еще скомпилировать???? Срочно...

Fastreports net conversion error from string
Пишу запрос: select * from patient INNER JOIN oprs ON patient.uid = oprs.uid INNER JOIN n_otd ON oprs.otd =...

Access violetion in module 'fs10.bpl' FastReports
Кто знает, в чем тут дело ? Выдает ошибку Access violetion at address 003BA99C in module 'fs10.bpl'

Обращение в ADOquery к ADOquery
Доброго времени суток. Вопрос заключается в следующем: Имеется подключенная бд *.mdb к delphi В delphi есть запрос на основе одной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG-файла с альфа-каналом с помощью библиотеки SDL3_image на Android
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru