Модераторы: Akella
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Суммирование в FastReport, Суммирование групп в fastReport 2.5 
:(
    Опции темы
Evgen76
  Дата 3.10.2005, 14:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.7.2004

Репутация: нет
Всего: нет



Добрый день! Помогите пожалуйста, третий раз принимаюсь за эту проблему и никак решение не найду smile :
Вот такая проблема: имеется отчёт вида:
группа_по ширине
группа_ассоримент
группа_цвет

химия, плотность, вес, норма_химии, метраж(план), расход(кг.), расход(руб.)

данные aa,1,10, 0.1, 10.2, (), 1000, 554.3

итоги
группа_цвет 1,10, 0.1, 10.2, (а вот сюда я вывожу метраж(не итог)),1000, 554.3

группа_ассоримент цвет 1,10, 0.1, 10.2 , (? итог по группе ассотимент),1000, 554.3
группа_по ширине 1,10, 0.1, 10.2 , (? итог по группе ширина),1000, 554.3


Вопрос: как посчитать метраж по всем остальным группам, а то он считает по всем строкам данных. Например: мераж=1000 м.
химии=10 строк 1000 * 10=10000 м., а мне этого не нужно!!!, так как метраж на данный цвет один. smile И еще вопрос, можно ли
из FastReport вызвать пользовательскую функцию, если можно, то как??? smile smile
PM MAIL   Вверх
Alex
Дата 3.10.2005, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

Репутация: нет
Всего: 162



Модератор: Пожалуйста, один топик - один вопрос.
Добавлено @ 20:16
Цитата(Evgen76 @ 3.10.2005, 15:51)
И еще вопрос, можно ли
из FastReport вызвать пользовательскую функцию, если можно, то как???

Из документации:
Цитата
2.22. Как подключить свою функцию (например, сумму прописью)?

Используйте обработчик TfrReport.OnUserFunction. Вот простой пример такого
обработчика (определяется функция SumPropis):

procedure TForm1.frReport1UserFunction(const Name: String;
  p1, p2, p3: Variant; var val: Variant);
begin
  if AnsiCompareText('SUMPROPIS', Name) = 0 then
    val := My_Convertion_Routine(frParser.Calc(p1));
end;

Теперь функцию можно использовать в любом месте отчета (текст, скрипт)
в форме SumPropis(Value).


(но такой подход работает только для одного компонента TfrReport. А если
я хочу сделать свою функцию доступной везде?)

Самый простой вариант - сделать обработчик события OnUserFunction общим
для всех компонентов. Если этот вариант не подходит, придется писать
библиотеку функций. Простой пример того, как это сделать:

type
  TMyFunctionLibrary = class(TfrFunctionLibrary)
  public
    constructor Create; override;
    procedure DoFunction(FNo: Integer; p1, p2, p3: Variant;
      var val: Variant); override;
  end;

constructor TMyFunctionLibrary.Create;
begin
  inherited Create;
  with List do
  begin
    Add('DATEPROPIS');
    Add('SUMPROPIS');
  end;
end;

procedure TMyFunctionLibrary.DoFunction(FNo: Integer; p1, p2, p3: Variant;
  var val: Variant);
begin
  val := 0;
  case FNo of
    0: val := My_DateConvertion_Routine(frParser.Calc(p1));
    1: val := My_SumConvertion_Routine(frParser.Calc(p1));
  end;
end;

Регистрация библиотеки осуществляется процедурой
frRegisterFunctionLibrary(TMyFunctionLibrary);
Удаление библиотеки осуществляется процедурой
frUnRegisterFunctionLibrary(TMyFunctionLibrary);


(а как зарегистрировать функцию в списке функций (диалог "Вставка функции")?)

Используйте процедуру frAddFunctionDesc (модуль FR_Class):

frAddFunctionDesc(FuncLib, 'SUMPROPIS', 'Мои функции',
  'SUMPROPIS(<Число>)/Возвращает сумму прописью.');

Обратите внимание: символ "/" в описании функции обязателен! Он отделяет
описание синтаксиса от описания самой функции.
FuncLib - это ссылка на библиотеку функций (может быть nil, если библиотека
не используется). Когда библиотека удаляется процедурой
frUnRegisterFunctionLibrary, все связанные с ней функции удаляются из
списка функций.

Добавлено @ 20:17
Цитата(Evgen76 @ 3.10.2005, 15:51)
как посчитать метраж по всем остальным группам, а то он считает по всем строкам данных.

подсчитывай скриптом


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
Evgen76
Дата 4.10.2005, 06:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.7.2004

Репутация: нет
Всего: нет



Спасибо за пример, сейчас попробую.
Цитата
подсчитывай скриптом

Как? В документации я нашел, что можно суммировать по Bands вида (Sum[metrezh], band1) но ничего не получается, обычно ничего на этом месте нет и нет никакой ошибки? smile
PM MAIL   Вверх
Evgen76
Дата 5.10.2005, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 6.7.2004

Репутация: нет
Всего: нет



В общем я разобрался smile раз не получилось суммировать по бендам, то нуждые данные я вставил через функции. Получилось вот что, может кому будет интересно. Код взят реальный:

Код

/ функция для извлечения значения из CV_RIS планового метража (plan_metr) для отчёта
Function MaxSum(Cod_gl : Integer; Cod_rec : Integer): Integer;
var
 tmpQuery : TADOQuery;
 SumCV : Integer;
begin
//создаём временный компонент TADOQuery c именем tmpQuery
  tmpQuery:= TADOQuery.Create(nil);
//подсоединяем к основной базе
  tmpQuery.ConnectionString := dm.ADOConnection.ConnectionString ;
//закрываем tmpQuery
   tmpQuery.Close;
//пишем запрос с двумя параметрами: код главный (Cod_gl) и код рецепта (Cod_rec)
  tmpQuery.SQL.Text := 'SELECT plan_metr '+
                       'FROM cv_ris '+
                       'WHERE Код_осн = '+  IntToStr(Cod_gl) + ' AND Код_рец = ' + IntToStr(Cod_rec) + ';';
//выполняем запрос
  tmpQuery.Open ;
//в результате получается одно единственное число
//проверяем, не пустое ли это значение
   if tmpQuery.Fields[0].value<> NULL then
//если нет, то присваиваем его переменной SumCV (SumCV - сумма по цвету)
     SumCV:= tmpQuery.Fields[0].Value
     else
//иначе присваиваем ноль
     SumCV:=0;

//возвращаем результат работы функции
    result:= SumCV;
//высвобождаем переменную tmpQuery
   tmpQuery.Free ;
//вот и всё ;о)
end;

//всё по аналогии с фукцией MaxSum, только параметр здесь один (Cod_gl)
// возвращает сумму по артикулу
Function SUM_ART(Cod_gl : Integer): Integer;
var
 tmpQuery : TADOQuery;
 SumArt :Integer;
begin
  tmpQuery:= TADOQuery.Create(nil);
  tmpQuery.ConnectionString := dm.ADOConnection.ConnectionString ;
  tmpQuery.Close;
  tmpQuery.SQL.Text := 'SELECT sum(plan_metr) as SUM_art '+
                       'FROM cv_ris '+
                       'WHERE Код_осн = '+  IntToStr(Cod_gl) + ' and HIM =true;';
  tmpQuery.Open ;

   if tmpQuery.Fields[0].value<>0 then
     SumArt:= tmpQuery.Fields[0].Value
     else
     SumArt:=0;

    result:= SumArt;
   tmpQuery.Free ;

end;


//всё по аналогии с фукцией SUM_ART, возвращает сумму для группы по ширине
Function SummaItog_Shir(Sh : Integer): Integer;
var
SummaItogShir :Integer;
tmpQuery : TADOQuery;
begin
 tmpQuery:= TADOQuery.Create(nil);
  tmpQuery.ConnectionString := dm.ADOConnection.ConnectionString ;
  tmpQuery.Close;
  tmpQuery.SQL.Text := 'SELECT sum(Cv_ris.plan_metr) as SUM_SHIR '+
                       'FROM spr_assortiment INNER JOIN (Cv_ris INNER JOIN Главная ON Cv_ris.код_осн=Главная.код) ON spr_assortiment.nasvan=Главная.Арт '+
                       'WHERE (((IIf([spr_assortiment.shirina_surovja]<=120,0,1))='+  IntToStr(Sh) + ') AND ((Cv_ris.Him)=True));';


  tmpQuery.Open ;
  tmpQuery.RecordCount ;

if tmpQuery.Fields[0].value <> Null then
     SummaItogShir:= tmpQuery.Fields[0].Value
     else
     SummaItogShir :=  0;

 result := SummaItogShir;
 tmpQuery.Free
end;


//функция вообще без параметров, возвращает сумму всего планового метража
Function SummaItog :Integer;
var
 tmpQuery : TADOQuery;
 Itog :Integer;
begin
  tmpQuery:= TADOQuery.Create(nil);
  tmpQuery.ConnectionString := dm.ADOConnection.ConnectionString ;
  tmpQuery.Close;
  tmpQuery.SQL.Text := 'SELECT sum(plan_metr) as SUM_ITOG '+
                       'FROM cv_ris '+
                       'WHERE HIM =true;';
  tmpQuery.Open ;

   if tmpQuery.Fields[0].value<>Null then
     Itog:= tmpQuery.Fields[0].Value;

    result:= Itog;
   tmpQuery.Free ;
End ;




procedure Tfrm_frReport.frReport1UserFunction(const Name: String; p1, p2,
  p3: Variant; var Val: Variant);
begin
// проверка на вызов из отчёта функции MaxSum
    if AnsiCompareText('MaxSum', Name) = 0 then
// val - получаемое значение, MaxSum(frParser.Calc(p1)-первый пераметр,frParser.Calc(p2)-второй параметр)
    val := MaxSum(frParser.Calc(p1),frParser.Calc(p2))
  ELSE
//далее по аналогии:  проверка на вызов из отчёта функции SUM_ART
     if AnsiCompareText('SUM_ART', Name) = 0 then
    val := SUM_ART(frParser.Calc(p1))
  ELSE
//проверка на вызов из отчёта функции SummaItog_Shir
     if AnsiCompareText('SummaItog_Shir', Name) = 0 then
    val := SummaItog_Shir(frParser.Calc(p1))
  ELSE
//проверка на вызов из отчёта функции SummaItog
     if AnsiCompareText('SummaItog', Name) = 0 then
    val := SummaItog();

end;



Эти фукции я вставил в нужные места в отчёте и NO PROBLEMS! smile


Может это возможно упростить, но вроде и так пока работает. Буду благодарен за подсказки и советы!
А так вроде тема закрыта!
PM MAIL   Вверх
Valdemaras
Дата 3.4.2006, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 30.1.2006

Репутация: нет
Всего: нет



подскажите как подсчитать скриптом сумму по группе!?
например:

qqq
100
200
итого: 300

www
500
450
Итого: 950

ИТОГО:1250
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Репортинговые системы | Следующая тема »


 




[ Время генерации скрипта: 0.0452 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.