我有代码的问题其用于计算从最新的周数。该应用程序是报表生成器。语言是:报告应用程序编程(RAP)的RAP语言是相同的Object Pascal中。
我写的代码工作的年2017年至2018年,但它不`吨工作,为2019年和2020年。
是否有人有一个想法是什么I'm做错了什么?
if (AVX['P_DELDATE'] >= 42737) and (AVX['P_DELDATE'] <= 43100) {= Jahr 2017} then begin
Value:= (AVX['P_DELDATE'] - 1 - (42737-1) + 7-((AVX['P_DELDATE'] -1 - (42737-1) ) mod 7))/7;
end else begin
if (AVX['P_DELDATE'] >= 43101) and (AVX['P_DELDATE'] <= 43465) {= Jahr 2018} then begin
Value:= (AVX['P_DELDATE'] - 1 - (43101-1) + 7-((AVX['P_DELDATE'] -1 - (43101-1) ) mod 7))/7;
end;
end else begin
if (AVX['P_DELDATE'] >= 43466) and (AVX['P_DELDATE'] <= 43830) {= Jahr 2019} then begin
Value:= (AVX['P_DELDATE'] - 1 - (43466-1) + 7-((AVX['P_DELDATE'] -1 - (43466-1) ) mod 7))/7;
end;
end else begin
if (AVX['P_DELDATE'] >= 43831) and (AVX['P_DELDATE'] <= 44196) {= Jahr 2020} then begin
Value:= (AVX['P_DELDATE'] - 1 - (43831-1) + 7-((AVX['P_DELDATE'] -1 - (43831-1) ) mod 7))/7;
end;
end;
end;
你不说你为什么问在RAP代码做周数计算。除了事实,我找不到任何的RAP文档中AVX
函数的定义,试图计算RAP使用AVX
周数显然是容易出错,而不是自我记录,并且是所有,但undebuggable办法做到这一点。
显然,你的函数(?或者也许是一个报表字段)AVX
返回一个数字值,其整数部分对应于TDateTime类型值的整数部分。在下面的例子项目 - 我已经包括显示处理问题的更容易且不易出错的方式,我包括这(我希望)相匹配的RAP功能的功能,如下所示:
function WeekNumber(Day : Integer) : Double;
begin
if (Day >= 42737) and (Day <= 43100) {= Jahr 2017} then begin
result:= (Day - 1 - (42737-1) + 7-((Day -1 - (42737-1) ) mod 7))/7;
end
else begin
if (Day >= 43101) and (Day <= 43465) {= Jahr 2018} then begin
result:= (Day - 1 - (43101-1) + 7-((Day -1 - (43101-1) ) mod 7))/7;
end
else begin
if (Day >= 43466) and (Day <= 43830) {= Jahr 2019} then begin
result:= (Day - 1 - (43466-1) + 7-((Day -1 - (43466-1) ) mod 7))/7;
end
else begin
if (Day >= 43831) and (Day <= 44196) {= Jahr 2020} then begin
result:= (Day - 1 - (43831-1) + 7-((Day -1 - (43831-1) ) mod 7))/7;
end;
end;
end;
end;
end;
(顺便说一句,在做这个转换,我不得不修复了一些在你的RAP代码语法错误的哪个,如果你自己尝试转换你很快就会发现。)
然后,我添加了一个程序来测试这个功能:
procedure TForm1.TestWeekNumber;
var
Date : TDateTime;
i : integer;
procedure TestInner(Date : TDateTime);
var
WN1,
WN2 : Double;
S,
SError : String;
begin
WN1 := WeekOf(Date);
WN2 := WeekNumber(Trunc(Date));
if WN1 = WN2 then
SError := ''
else
SError := '***';
S := Format('Date: %s WeekOf: %g WeekNumber: %g %s',[ DateTimeToStr(Date), WN1, WN2, SError]);
if SError <> '' then
Memo1.Lines.Add(S);
end;
begin
Date := StrToDateTime('01/01/2017');
Memo1.Lines.BeginUpdate;
try
for i := 0 to 1999 do
TestInner(Date + i);
finally
Memo1.Lines.EndUpdate;
end;
end;
这是你WeekNumber
与DateUtils.Pas标准WeekOf
函数,该函数将返回周数由ISO 8601标准定义的,TDateTime类型的输入值,并且当它们产生不同的结果的值写入到一个TMemo进行比较。以下是从输出的提取物:
Date: 01/01/2017 WeekOf: 52 WeekNumber: 1.13989900694441E-307 ***
Date: 31/12/2018 WeekOf: 1 WeekNumber: 53 ***
Date: 07/01/2019 WeekOf: 2 WeekNumber: 1 ***
Date: 14/01/2019 WeekOf: 3 WeekNumber: 2 ***
Date: 21/01/2019 WeekOf: 4 WeekNumber: 3 ***
Date: 28/01/2019 WeekOf: 5 WeekNumber: 4 ***
Date: 04/02/2019 WeekOf: 6 WeekNumber: 5 ***
Date: 11/02/2019 WeekOf: 7 WeekNumber: 6 ***
[...]
Date: 06/01/2020 WeekOf: 2 WeekNumber: 1 ***
Date: 07/01/2020 WeekOf: 2 WeekNumber: 1 ***
Date: 13/01/2020 WeekOf: 3 WeekNumber: 2 ***
Date: 14/01/2020 WeekOf: 3 WeekNumber: 2 ***
Date: 20/01/2020 WeekOf: 4 WeekNumber: 3 ***
Date: 21/01/2020 WeekOf: 4 WeekNumber: 3 ***
Date: 27/01/2020 WeekOf: 5 WeekNumber: 4 ***
Date: 28/01/2020 WeekOf: 5 WeekNumber: 4 ***
Date: 03/02/2020 WeekOf: 6 WeekNumber: 5 ***
Date: 04/02/2020 WeekOf: 6 WeekNumber: 5 ***
Date: 10/02/2020 WeekOf: 7 WeekNumber: 6 ***
正如你所看到的,事情开始于2018年底脚麻,在此之后,错误的价值观似乎“由一休”之类的错误的建议的。我离开你自己调查并解决这个问题。
我之所以还没有研究它的任何进一步的我是在我看来,你正在做的方式是凌乱的,本可避免复杂。这几乎是微不足道的通过添加计算字段与weeknumber值作供给报告中的数据集,以周数支持添加到您的RBuilder报告。代码做如下所示。
另外,您也可以使用报表制作的工厂到WeekNumber
功能添加到可以采取任何时间值(例如,从任何数据集的日期时间字段值)的RAP运行时的语言。例如见Extending RAP - RAP Pass-Through Functions
在现有的报表制作工具开发人员指南这里的P213:Report Builder Developer's Guide。什么是描述有可能是堆焊在一份报告中一个Delphi函数的最灵活的方法,虽然ISTR还有其他的。
代码(为简单起见不包括RBuilder部件)
type
TForm1 = class(TForm)
CDS1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
procedure FormCreate(Sender: TObject);
procedure CDS1CalcFields(DataSet: TDataSet);
private
procedure CreateDataSetFields;
protected
public
end;
[...]
implementation
uses
DateUtils;
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
CreateDataSetFields; // see below
CDS1.CreateDataSet;
// Insert one row per day for current year
for i := 1 to 365 do begin
CDS1.InsertRecord([i, i + Now - DayOfTheYear(Now)]);
end;
CDS1.First;
end;
procedure TForm1.CDS1CalcFields(DataSet: TDataSet);
begin
// This sets the WeekNo calculated field to the value returned by the DateUtils.WeekOf function
DataSet.FieldByName('WeekNo').AsInteger := WeekOf(DataSet.FieldByName('Date').AsDateTime);
end;
procedure TForm1.CreateDataSetFields;
var
Field : TField;
begin
Field := TIntegerField.Create(Self);
Field.FieldKind := fkData;
Field.FieldName := 'ID';
Field.Name := 'ID';
Field.DataSet := CDS1;
Field := TDateTimeField.Create(Self);
Field.FieldKind := fkData;
Field.FieldName := 'Date';
Field.Name := 'Date';
Field.DataSet := CDS1;
Field := TIntegerField.Create(Self);
Field.FieldKind := fkInternalCalc;
Field.FieldName := 'WeekNo';
Field.Name := 'WeekNo';
Field.DataSet := CDS1;
end;