【问题标题】:Distinct Count in fastreport快速报告中的不同计数
【发布时间】:2017-08-18 23:38:22
【问题描述】:

有人知道如何在 fastreport 中进行不同的计数吗? 例子 我有报告:

 Name   sex
 João    m
 João    m
 Maria   f

在正常计数中,结果将是 3,但我想要一个只取不重复字段名称的行数的结果。 在这种情况下,结果将是 2。 谁能帮我?这只是一个例子。 我不能在 SQL 中进行分组,因为我有多个字段。

【问题讨论】:

  • 你有 SQL Server 吗?
  • 不...火鸟...

标签: delphi fastreport


【解决方案1】:

我不擅长使用FastReport,但我在FastReport 的官方论坛上找到了this page

我认为您可以通过根据您的场景调整示例来更改示例(请注意,语法可能需要一些调整)。

乐队:

GroupHeader1 <Sex> 
MasterData1 [Name, Sex, ...] 
GroupFooter1 [GetDistinctCount]

脚本(仅适用于按字段排序的数据集):

var 
  LastValue : string;
  DistinctCount : integer;

//create this event by double-clicking the event from the Object Inspector
procedure OnGroupHeader1.OnBeforePrint;
begin
  if LastValue <> (<Datasetname."Sex">) then
    Inc(DinstinctCount);

  LastValue := <Datasetname."Sex">
end;

function GetDistinctCount: string;
begin
  Result := IntToStr(DistinctCount);
end;

基本思想是每次字段值更改时,DistinctCount 变量都会递增。

脚本(应该也适用于未排序的数据集):

var 
  FoundValues : array of string;


(* !!IMPORTANT!!
You need to initialize FoundValues array before to start counting: *)
SetLength(FoundValues, 0);


function IndexOf(AArray : array of string; const AValue : string) : integer;
begin
  Result := 0;
  while(Result < Length(AArray)) do
  begin
    if(AArray[Result] = AValue) then
      Exit;
    Inc(Result);
  end;
  Result := -1;
end;

//create this event by double-clicking the event from the Object Inspector
procedure OnGroupHeader1.OnBeforePrint;
begin
  if(IndexOf(FoundValues, <Datasetname."Sex">) = -1) then
  begin
    SetLength(FoundValues, Length(FoundValues) + 1);
    FoundValues[Length(FoundValues) - 1] := <Datasetname."Sex">;
  end;
end;

function GetDistinctCount: string;
begin
  Result := IntToStr(Length(FoundValues));
end;

基本思想是将找到的每个不同值添加到FoundValues 数组中。

【讨论】:

  • 这样它工作得很好......但前提是它按我想要的项目排序。如果它是混乱的,它会不断出现,以错误的方式出现......例如: Name sex Joao m Joao m Maria f count = 2 的结果是正确 Name sex Joao m Maria f Joao m 结果是 3 ...不正确
  • @sounobre:我已经通过添加一个应该也适用于未排序数据集的方法来更新答案
  • SetLength(FoundValues, 0);在 setlength ':' 预期后显示错误
  • 我无法初始化 FoundValues
  • @sounobre:我对 FastReport 不熟悉,我认为您应该将 SetLength(FoundValues, 0); 放在一个事件中,否则其他任何东西都执行一次并且 之前 i> 使用FoundValues 数组。 (必须删除从“!!!IMPORTANT!!!”到“...开始计数:”的部分,这只是一个警告,因为我认为如果不初始化数组它将无法工作)
【解决方案2】:

你可以在没有GROUP BY 的情况下在 Firebird 中做到这一点:

DECLARE @T TABLE (ID INT IDENTITY (1,1), Name NVARCHAR(25) , Sex CHAR(1));

INSERT INTO @T VALUES
('Sami','M'),
('Sami','M'),
('Maria','F');

SELECT DISTINCT Name , Sex FROM @T

您也可以创建一个View,然后在您的报告中使用它。

如果您确实需要在 FastReport 中执行此操作,则必须使用 GroupHeaderGroupFooter

如何?

您必须在OnBeforePrint 事件中编写脚本。

procedure OnGroupHeader1.OnBeforePrint; 

通过在对象检查器中双击事件来创建这个。

【讨论】:

  • 如果一定要写脚本,可以不用GroupHeader,只要是可以显示值的控件即可。但这似乎是矫枉过正。我敢打赌有一个简单的方法。
  • 这个脚本会是什么样子?
  • 这个选项“procedure OnGroupHeader1.OnBeforePrint;”这就是我的想法..只是不知道如何处理它......
  • @Victoria,一个更简单的选择将是理想的...... kk
  • 我认为你可以在你的数据集中创建一个聚合字段(分组级别 2)在一个组合索引上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多