Смена _запроса_ в рантайме

bakhbakh Санкт-Петербург
отредактировано 03:56 Раздел: FastReport 2.xx VCL
Понадобилось сменить по результатам диалога в рантайме запрос, привязанный к текущему датасету...
Сам датасет для текущего бэнда сменить, как я понимаю, не составляет труда... Но в бэнде 20 с лишним мемок с указанием имени запроса...

Может есть у кого наработанные "методы борьбы с костей сапрыкиным"?..

Комментарии

  • BorisBoris Москва
    отредактировано 03:56
    Мне видится выход из этой ситуации в использовании списка переменных, то есть примерно таким образом:
    with frReport1.Dictionary do
    begin
      if <условие1> then
       Variables['Field1'] := 'Query1."Field1"'
      else
      if <условие2> then
       Variables['Field1'] := 'Query2."Field1"';
    end;
    

    Ну, или так (абстрактный пример):
    with frReport1.Dictionary do
    begin
      if <диалог выполнен> then
       Variables['Field1'] := Диалог1.Параметр1;
    end;
    
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    М-м-м... Имхо, ты меня не совсем правильно понял... ;)

    Есть бэнд BigDataBand, у которого есть датасет, который зовётся _data1...
    Есть запрос, из которого сей датасет берёт данные, зовётся он data1...
    Всё работает, всё красиво...

    Однако, есть на моей форме ещё один датасет _data2 и, соответственно, ещё один запрос data2... Поля в data1 и data2 идентичны...

    По результату работы диалоговой формы я могу поменять BigDataBand.Dataset := _data2... И это хорошо...
    Но в бэнде живёт десятка два мемо, в которых прописано, что их значение [data1."FieldName"]... А вот это уже бяка, т.к. имя поля правильное, но вот запрос - не тот, не [data2."FieldName"]...

    Вот как-то так... ;)
    Перебирать все мемки и присваивать им принудительно?.. Ой, как неохота!.. ;)
  • BorisBoris Москва
    отредактировано 03:56
    Так я же про это и объясняю! ;)
    Елы-палы лес густой...
    В мемке пишешь не [data."FieldName"], а [FieldName], а реальное значение параметра заполняется в списке переменных, т.е
    frReport1.Dictionary.Variables['FieldName'] := 'data1."FieldName"';
    

    Или я опять не в ту степь пошел???
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    (задумчиво) Всё правильно... Всё правильно...
    ;)
    Только ты мне по-моему советуешь это делать перед загрузкой репорта из кода программы?.. А я думал это средствами fr делать...
    Или меня за 5 часов рабочего дня уже совсем переклинило?.. ;)
    Да и вообще-то, честно говоря, не хотелось бы привлекать для этого дела словари... Что-то не нравятся они мне... ;)
  • отредактировано 03:56
    Можна я предложу примитивное решение в виде двух дата-бендов, одному из которых убирать видимость?
  • BorisBoris Москва
    отредактировано 03:56
    Да именно так, из кода программы перед загрузкой отчета. Думаю, что на лету из отчета такое не получится.
    А вот Alexander по-моему классный вариант предложил.

  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    2 Alexander:
    Соглашусь, что решение примитивное и рабочее... ;)
    Но, имхо, тут возможны варианты хождения по граблям: это дело находится в субдетали... Вариантов смены датасета - 5... Соответсвенно, должны меняться и источники у детали...
    (у меня уже едет крыша ;) )
  • BorisBoris Москва
    отредактировано 03:56
    В таком случае, нельзя ли вообще изменить концепцию?
    Я имею ввиду не переключаться между DataSet'ами, а менять сам SQL-запрос.
    Ну, или другой вариант, может проще наклепать 5 одинаковых по структуре отчетов и вызывать нужный в зависимости от того, что возвращает диалог.
    От такого действительно крыша поедет. ;)
  • отредактировано 03:56
    Тогда подойдем более творчески ;)
    Можна в твоем случае написать в качестве источника данных запрос с юнионами и неким ключевым полем? А потом выбирать данные с фильтром только из одного запроса? Или вобще в зависимости от выбранного юзером в ран-тайме строить запрос?
    Оба варианта позволяют не изменять струтуру отчета
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    2 Alexander:
    Нет, этот вариант отпадает... Структура результата не позволит... ;)

    2 Boris:
    Да, скорее всего это будет и проще и результативнее...
    Т.е. в скрипте написать:
    query.close;
    query.sql.text := 'select * from x3';
    query.open;

    Я таки дозрел до понимания сути ДАО?.. ;)

    Кстати, (даже не знаю, говорить ли это тут) было бы неплохо, что по умолчанию поля бы были бы вида ["FieldName"], т.е. без имени запроса... И брались бы из текущего датасета, т.е. привязанного к нему запроса...

    Тогда бы и вопрос у меня не возникал... ;)
  • BorisBoris Москва
    отредактировано 03:56
    Считаю нужным добавить следующий комментарий, так как мне кажется мы немного недопонимаем друг друга.
    Я имел ввиду менять текст запроса до генерации отчета, то есть следующая схема:
    1. Вызов диалога
    2. Выбор пользователем нужного варианта
    3. Формирование запроса на основе возвращенного диалогом значения параметра
    4. Генерация отчета.

    Насчет того, можно ли в скрипте менять текст запроса, то я такого не пробовал и, что из этого может получиться не знаю.
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    Да... Мы опять друг друга недопоняли... ;)
    Мне это надо делать именно из скрипта...
    Диалог происходит не на уровне кода программы, а на уровне самого отчёта...
  • BorisBoris Москва
    отредактировано 03:56
    Не понимаю только одного, почему нужно уже в отчете вызывать диалог, почему нельзя это сделать заранее?
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    Издержки технологии!.. ;)
    Отчётов - до дури, сами они и запросы к ним - все хранятся в базе...
    Модуль отчётов просто вызывает ShowReport или DesignReport в зависимости от степени доступа к базе...
  • отредактировано 03:56
    bakh написал:
    Кстати, (даже не знаю, говорить ли это тут) было бы неплохо, что по умолчанию поля бы были бы вида ["FieldName"], т.е. без имени запроса... И брались бы из текущего датасета, т.е. привязанного к нему запроса...

    Тогда бы и вопрос у меня не возникал... ;)
    Так оно именно так и работает! Даже если без кавычек указать имя поля, то FR сам найдет поле текущего DataSet!
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    Да-да-да!.. Я уже проверил... Действительно работает... ;)
    Так что "животрепыхающий" вопрос практически закрыт...
    А я тут чуть с ума не сошёл и остальных замучал... ;)
    Было бы (опять ИМХО) всё-таки правильнее, если б для умолчального запроса имя запроса не вставлялось...
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    Блин... А впереди ещё 5 рабочих дней!.. ;)

    Не работает (в скрипте!) SubDetail1.DataSource := _data2;
    Есть какие-нибудь мысли на эту тему?..

    Я уже нифига не соображаю... Пойду домой... ;)
  • FOXFOX
    отредактировано 03:56
    Наверно не лучший, но тоже вариант:
    написать user function типа
    chageDS( OldDataSource, NewDataSource)
    которая меняет в полях имена источников данных
    на нужные тебе, а затем в дилоге
    вызвать её с нужными параметрами
    chageDS( 'Data1', 'Data2').



  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    FOX написал:
    написать user function типа
    chageDS( OldDataSource, NewDataSource)
    Мысль, конечно, свежая...
    Только что-то не нравится мне догонять функциональность пакета своими руками... ;)
    Уже и так накололись с вертикальными числами в stretched-бэндах... Поправил, написал в суппорт, ни ответа, ни привета... ;)
    Если уж объявляется некая функциональность:
    Объект "Бэнд" (TfrBandView)
    Свойство	Тип	Описание
    DataSource	String	Источник данных для дата-бэнда.
    
    то, по-моему, это должно быть доступно и из скрипта... ;)
  • bakhbakh Санкт-Петербург
    отредактировано 03:56
    2 FOX: Фигня какая-то: не умеет FR передавать в параметры datasource'ы... ;)

    Блин, я сдохну, наверное, до вторника!.. ;)

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.