问题在某种程度上与这个问题有关,除了我使用参数。 我点击了我的按钮:
procedure TForm1.Button1Click(Sender: TObject);
begin
with ABSQuery1 do begin
ABSQuery1.Close;
ABSQuery1.SQL.Clear;
ABSQuery1.SQL.Add('select * from ROOM_RATES where CENIK_ID = :a4 and ROOM_TYPE = :A1');
ABSQuery1.SQL.Add('and rate_Start_DATE < :a3 AND rate_End_DATE > :a2 ORDER BY rate_Start_DATE ASC ');
ABSQuery1.Params.ParamByName('a1').Value:= cxLookupComboBox2.Text;
ABSQuery1.Params.ParamByName('a2').Value:= cxDateEdit1.Date;
ABSQuery1.Params.ParamByName('a3').Value := cxDateEdit2.Date;
ABSQuery1.Params.ParamByName('a4').Value := cxLookupComboBox1.Text;
ABSQuery1.Open;
end;
end;
这种作品但不是我想要的。问题与这个问题有关: Hotel Booking Rates SQL Problem
问题在于重叠的日期,就像上面提到的超链接一样。现在我得到这个:
如何通过上述示例获得与上述超链接类似的结果?
这是db表的快照:
更新(新): 这是按钮点击的代码:
procedure TForm1.AdvGlowButton1Click(Sender: TObject);
var
nxt : integer;
mem_from : TDateTime;
mem_to : TDateTime;
mem_RATE_ID : integer;
mem_ROOM_TYPE : string[10];
mem_Start_DATE_1 : TDateTime;
mem_End_DATE_1 : TDateTime;
mem_RATE_Price_1 : Currency;
mem_calc_END : TDateTime;
mem_calc_DAYS : integer;
c_from : TDateTime;
c_to : TDateTime;
c_from_test : TDateTime;
c_to_test : TDateTime;
begin
ABSQuery2.Close;
ABSQuery2.SQL.Text:='DELETE from TEMP';
ABSQuery2.ExecSQL;
ABSQuery2.SQL.Text:='SELECT * from TEMP ORDER BY ID ';
ABSQuery2.Open;
c_from := cxDateEdit1.Date;
c_to := cxDateEdit2.Date;
mem_from := cxDateEdit1.Date;
mem_to := cxDateEdit2.Date;
with ABSQuery1 do begin
ABSQuery1.Close;
ABSQuery1.SQL.Clear;
ABSQuery1.SQL.Add('select * from ROOM_RATES where CENIK_ID = :a4 and ROOM_TYPE = :A1');
ABSQuery1.SQL.Add('and rate_Start_DATE < :a3 AND rate_End_DATE > :a2 ORDER BY rate_Start_DATE ASC ');
ABSQuery1.Params.ParamByName('a1').Value:= cxLookupComboBox2.Text;
ABSQuery1.Params.ParamByName('a2').Value:= cxDateEdit1.Date;
ABSQuery1.Params.ParamByName('a3').Value := cxDateEdit2.Date;
ABSQuery1.Params.ParamByName('a4').Value := cxLookupComboBox1.Text;
ABSQuery1.Open;
nxt := 1;
mem_RATE_ID := ABSQuery1.FieldByName('RATE_ID').AsInteger;
mem_ROOM_TYPE := ABSQuery1.FieldByName('ROOM_TYPE').AsString ;
mem_Start_DATE_1 := ABSQuery1.FieldByName('RATE_START_DATE').AsDateTime;
mem_End_DATE_1 := ABSQuery1.FieldByName('RATE_END_DATE').AsDateTime;
mem_RATE_Price_1 := ABSQuery1.FieldByName('RATE_PRICE').AsCurrency;
if mem_to > mem_End_DATE_1 then begin
mem_calc_END := mem_End_DATE_1;
mem_calc_DAYS := Daysbetween(mem_from,mem_End_DATE_1);
end else begin
mem_calc_END := mem_to;
mem_calc_DAYS := Daysbetween(mem_from,mem_calc_END);
end;
end;
if ABSQuery1.RecordCount > nxt then ABSQuery1.Next;
with ABSQuery2 do begin
open;
Insert;
ABSQuery2.FieldByName('RATE_ID').AsInteger:=mem_RATE_ID;
ABSQuery2.FieldByName('ROOM_TYPE').AsString:=mem_ROOM_TYPE;
ABSQuery2.FieldByName('DATE_FROM').AsDateTime:=mem_from;
ABSQuery2.FieldByName('DATE_TO').AsDateTime:= mem_to;//mem_calc_END;
ABSQuery2.FieldByName('RATE_PRICE').AsCurrency:=mem_RATE_PRICE_1;
ABSQuery2.FieldByName('DAYS').AsInteger:=mem_calc_DAYS;
ABSQuery2.FieldByName('TOTAL').AsCurrency:=mem_RATE_PRICE_1 * mem_calc_DAYS;
post;
end; ///////////////////////////////////////////////////////////////////
if ABSQuery1.RecordCount > nxt then begin
inc(nxt);
if mem_to < ABSQuery1.FieldByName('rate_End_DATE').AsDateTime then begin
mem_calc_END := mem_to;
mem_calc_DAYS := Daysbetween(ABSQuery1.FieldByName('rate_Start_DATE').AsDateTime,mem_calc_END);
end else begin
mem_calc_END := ABSQuery1.FieldByName('rate_End_DATE').AsDateTime;
mem_calc_DAYS := Daysbetween(ABSQuery1.FieldByName('rate_Start_DATE').AsDateTime, ABSQuery1.FieldByName('rate_End_DATE').AsDateTime);
end;
mem_RATE_ID := ABSQuery1.FieldByName('RATE_ID').AsInteger;
mem_ROOM_TYPE := ABSQuery1.FieldByName('ROOM_TYPE').AsString;
mem_Start_DATE_1 := ABSQuery1.FieldByName('rate_Start_DATE').AsDateTime;
mem_End_DATE_1 := ABSQuery1.FieldByName('rate_End_DATE').AsDateTime;
mem_Rate_Price_1 := ABSQuery1.FieldByName('RATE_PRICE').AsCurrency;
// calculation : second row.
with ABSQuery2 do begin
Insert;
FieldByName('RATE_ID').AsInteger:=mem_RATE_ID;
FieldByName('ROOM_TYPE').AsString:=mem_ROOM_TYPE;
FieldByName('DATE_FROM').AsDateTime:=mem_Start_DATE_1;
FieldByName('DATE_TO').AsDateTime:= mem_calc_END;
FieldByName('RATE_PRICE').AsCurrency:=mem_RATE_PRICE_1;
FieldByName('DAYS').AsInteger:=mem_calc_DAYS;
FieldByName('TOTAL').AsCurrency:=mem_RATE_PRICE_1 * mem_calc_DAYS;
post;
end;
ABSQuery2.refresh;
end;
end;
我得到的结果是:
从数据库快照中可以看出,价格设置正常。
答案 0 :(得分:1)
使用Delphi 2010进行测试。
您唯一的一个DBGrid与dataset-table-pricelist
相关联匹配两行dataset-table-pricelist,因此在你的ABSQuery1 DBGrid中 显示价目表中的第1行 显示价目表中的第3行。
现在对于两个行程序ABSQuery1CalcFields(DataSet: TDataSet);
用相同的值调用!!
Daysbetween(cxDateEdit1.Date,cxDateEdit2.Date) = allways 19
procedure TForm1.ABSQuery1CalcFields(DataSet: TDataSet);
begin
ABSQuery1.FieldByName('Days').Value := IntToStr(Daysbetween(cxDateEdit1.Date,cxDateEdit2.Date));
ABSQuery1.FieldByName('TOTAL').AsCurrency :=ABSQuery1.FieldByName('Days').Value * ABSQuery1.FieldByName('RATE_PRICE').Value ;
end;
因此,你在DBGrid中有两天是19 From和To这两个字段也来自表价格表 因此,您无法看到自己的数据From和To。
您应该有2个表
在表格价格表上有一个循环,获取价目表所需的数据。
因为我不确切知道你的表是如何设置的,所以你必须使代码适应数据库和你的表。
为了更好地展示必要的步骤,请在此处输入以下代码 更新:这里,现在是完整的代码。
unit PriceList;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, DBGrids, Db, ZAbstractRODataset, ZAbstractDataset,
ZDataset, ZConnection;
type
TForm1 = class(TForm)
ZConnection1: TZConnection;
ABSQuery1: TZQuery;
calculation: TZQuery;
DataSource1: TDataSource;
DataSource2: TDataSource;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
DoCalc: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
RATE_ID: TLargeintField;
CENIK_ID: TLargeintField;
ROOM_TYPE: TWideStringField;
RATE_START_DATE: TDateTimeField;
RATE_END_DATE: TDateTimeField;
RATE_PRICE: TFloatField;
calculationID: TLargeintField;
calcRATE_ID: TLargeintField;
calcROOM_TYPE: TWideStringField;
calcDFROM: TDateTimeField;
calcDTO: TDateTimeField;
calcRATE_PRICE: TFloatField;
calcDAYS: TLargeintField;
calcTOTAL: TFloatField;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
uses DateUtils;
procedure TForm1.DoCalcClick(Sender: TObject);
var
nxt : integer;
mem_from : TDateTime;
mem_to : TDateTime;
mem_RATE_ID : integer;
mem_ROOM_TYPE : string[20];
mem_Start_DATE_1 : TDateTime;
mem_End_DATE_1 : TDateTime;
mem_RATE_Price_1 : Currency;
mem_calc_END : TDateTime;
mem_calc_DAYS : integer;
c_from : string[19];
c_to : string[19];
c_from_test : string[19];
c_to_test : string[19];
begin
calculation.Close;
calculation.SQL.Text:='DELETE from calculation';
calculation.ExecSQL;
calculation.SQL.Text:='SELECT * from calculation ORDER BY ID ';
calculation.Open;
c_from := Edit3.Text;
c_to := Edit4.Text;
c_from_test := copy(Edit3.Text,7,4)+'.'+copy(Edit3.Text,4,2)+'.'+copy(Edit3.Text,1,2); // From 01.01.2013
c_to_test := copy(Edit4.Text,7,4)+'.'+copy(Edit4.Text,4,2)+'.'+copy(Edit4.Text,1,2);
mem_from := StrToDateTime(c_from);
mem_to := StrToDateTime(c_to);
with ABSQuery1 do begin
Close;
SQL.Clear;
SQL.Add('select * from ROOM_RATES where CENIK_ID = "'+Edit1.Text+'" and ROOM_TYPE = "'+Edit2.Text+'"');
SQL.Add('and RATE_START_DATE < '''+c_to_test+''' AND RATE_END_DATE > '''+c_from_test+''' ORDER BY RATE_START_DATE ASC ');
Open;
nxt := 1;
mem_RATE_ID := RATE_ID.AsLargeInt;
mem_ROOM_TYPE := ROOM_TYPE.AsString ;
mem_Start_DATE_1 := RATE_START_DATE.AsDateTime;
mem_End_DATE_1 := RATE_END_DATE.AsDateTime;
mem_RATE_Price_1 := RATE_PRICE.AsCurrency;
if mem_to > mem_End_DATE_1 then begin
mem_calc_END := mem_End_DATE_1;
mem_calc_DAYS := Daysbetween(mem_from,mem_End_DATE_1);
end else begin
mem_calc_END := mem_to;
mem_calc_DAYS := Daysbetween(mem_from,mem_calc_END);
end;
end;
if ABSQuery1.RecordCount > nxt then ABSQuery1.Next;
with calculation do begin
open;
Insert;
calculation.FieldByName('RATE_ID').AsInteger:=mem_RATE_ID;
calculation.FieldByName('ROOM_TYPE').AsString:=mem_ROOM_TYPE;
calculation.FieldByName('DFROM').AsDateTime:=mem_from;
calculation.FieldByName('DTO').AsDateTime:= mem_calc_END;
calculation.FieldByName('RATE_PRICE').AsCurrency:=mem_RATE_PRICE_1;
calculation.FieldByName('DAYS').AsInteger:=mem_calc_DAYS;
calculation.FieldByName('TOTAL').AsCurrency:=mem_RATE_PRICE_1 * mem_calc_DAYS;
post;
end;
if ABSQuery1.RecordCount > nxt then begin
inc(nxt);
if mem_to < rate_End_DATE.AsDateTime then begin
mem_calc_END := mem_to;
mem_calc_DAYS := Daysbetween(rate_Start_DATE.AsDateTime,mem_calc_END);
end else begin
mem_calc_END := rate_End_DATE.AsDateTime;
mem_calc_DAYS := Daysbetween(rate_Start_DATE.AsDateTime, rate_End_DATE.AsDateTime);
end;
mem_RATE_ID := RATE_ID.AsInteger;
mem_ROOM_TYPE := ROOM_TYPE.AsString;
mem_Start_DATE_1 := rate_Start_DATE.AsDateTime;
mem_End_DATE_1 := rate_End_DATE.AsDateTime;
mem_Rate_Price_1 := RATE_PRICE.AsCurrency;
with calculation do begin
Insert;
FieldByName('RATE_ID').AsInteger:=mem_RATE_ID;
FieldByName('ROOM_TYPE').AsString:=mem_ROOM_TYPE;
FieldByName('DFROM').AsDateTime:=mem_Start_DATE_1;
FieldByName('DTO').AsDateTime:= mem_calc_END;
FieldByName('RATE_PRICE').AsCurrency:=mem_RATE_PRICE_1;
FieldByName('DAYS').AsInteger:=mem_calc_DAYS;
FieldByName('TOTAL').AsCurrency:=mem_RATE_PRICE_1 * mem_calc_DAYS;
post;
end;
end;
calculation.refresh;
end;
end.
时间限制代码未优化。只是为了展示必要的步骤。
表room_rates
DROP TABLE IF EXISTS `room_rates`;
CREATE TABLE `room_rates` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CENIK_ID` int(10) unsigned NOT NULL,
`ROOM_TYPE` varchar(45) NOT NULL,
`RATE_START_DATE` datetime NOT NULL,
`RATE_END_DATE` datetime NOT NULL,
`RATE_PRICE` decimal(5,2) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
表calculation
DROP TABLE IF EXISTS `calculation`;
CREATE TABLE `calculation` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`RATE_ID` int(10) unsigned NOT NULL,
`ROOM_TYPE` varchar(45) NOT NULL,
`DFROM` datetime NOT NULL,
`DTO` datetime NOT NULL,
`RATE_PRICE` decimal(5,2) NOT NULL,
`DAYS` int(10) unsigned NOT NULL,
`TOTAL` decimal(7,2) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
更新:
搜索if mem_to > mem_End_DATE_1
要更改Total 0,00€
您必须展开
if mem_to > mem_End_DATE_1 then begin
mem_calc_END := mem_End_DATE_1;
mem_calc_DAYS := Daysbetween(mem_from,mem_End_DATE_1);
end else begin
mem_calc_END := mem_to;
mem_calc_DAYS := Daysbetween(mem_from,mem_calc_END);
end;
更新2 :上面,现在是完整的代码。
更新3 :but still I get from 14/4/2013 to 26/4/2013 11 DAYS !
user763539
此行为来自DaysBetween(..,..)
,而不是来自我的代码
DaysBetween是一个delphi函数!
您是否检查了从cxDateEdit1.Date
和cxDateEdit2.Date
获得的内容。
必须准确14-04-2013 00:00:00
和26-04-2013 00:00:00
。
创建一个新的测试程序。
控制你得到的东西。
DateTimeToString(formattedDateTime, 'c', cxDateEdit1.Date);
Memo1.Lines.Add(formattedDateTime);
循环显示所有ROOM_RATES records
您还应该检查ROOM_RATES
中的所有日期字段。
DateTimeToString(formattedDateTime, 'c', ABSQuery1.FieldByName('RATE_START_DATE').AsDateTime);
Memo1.Lines.Add(formattedDateTime);
所有时间应为00:00:00
例如:
DaysBetween .. 14-04-2013 12:15:10 and
26-04-2013 12:15:05 ==
11天`
更准确:11 Days : 23 Hours : 59 minutes : 55 seconds
。