【问题标题】:Error on IF STATEMENT with multiple AND conditions带有多个 AND 条件的 IF 语句出错
【发布时间】:2020-01-20 13:25:04
【问题描述】:

我有这些控件 TDateTimePicker、TComboBox、Tedit 和 TButton。默认情况下禁用 TButton。我想要实现的是在所有其他控件都已填充或不为空时启用 TButton。

使用以下代码,填充时以 TDateTimePicker 开头的所有 3 个控件都没有任何问题,它按预期工作。

当我填充 TComboxBox 后跟 TEdit 时出现错误,即使 TDateTimePicker 尚未填充,它也会启用 TButton。反之亦然,我将填充 TEdit,然后填充 TComboBox,它启用了 TButton。

从下面的代码中,我预计 TButton 不会启用,除非所有 3 个控件都被填充。

我(一整天)一直在试图弄清楚这个错误是如何发生的。

我会感谢那里的任何人帮助我解决这个问题。

procedure TfrmHolidays.EnableSaveButton;
begin
if (edtHolidayName.Text <> NullAsStringValue) and (cmbHolidayType.ItemIndex <> -1)and (dtpHolidayDate.Date <> 0) then
  begin
    btnHolidaySave.Enabled := True;
  end
  else
  begin
    btnHolidaySave.Enabled := False;
  end;
end;

procedure TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
begin
  EnableSaveButton;
end;

procedure TfrmHolidays.cmbHolidayTypeChange(Sender: TObject);
begin
  EnableSaveButton;
end;

procedure TfrmHolidays.edtHolidayNameChange(Sender: TObject);
begin
  EnableSaveButton; // triggers enable btnHolidaySave button
end;

顺便说一句,我有更多与使 TDateTimePicker 为空白相关的代码,我认为这没有问题。我还尝试在 If 语句中嵌套每个条件,但仍然出现错误。此外,我一次测试了每个条件,它工作正常。

更新: 以下是我初始化 dtpHolidayDate.Date 的方式:

procedure TfrmHolidays.FormCreate(Sender: TObject);
begin
  DateTime_SetFormat(dtpHolidayDate.Handle, ' ');
  FDTMDateEmpty := True;
end;

procedure TfrmHolidays.dtpHolidayDateCloseUp(Sender: TObject);
begin
  DateTime_SetFormat(dtpHolidayDate.Handle, PChar('MMM dd yyyy (ddd)'));
end;

procedure TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
begin
  FDTMDateEmpty := False;
  EnableSaveButton; // same and updated procedure above
end;

【问题讨论】:

  • 调试EnableSaveButton过程,看看dtpHolidayDate.Date的值是多少
  • AFAIK,TDateTimePicker 使用当前日期时间初始化。我们看不到初始化 TDateTimePicker 的代码,因此 dtpHolidayDate.Date 0 可能从一开始就返回 true。您还应该告诉我们您的 Delphi 版本,因为根据所使用的 Delphi,某些控件的行为会有所不同。
  • TDateTimePicker 默认没有空值。你必须做点什么like this
  • 与您描述的问题无关,但我会写 edtHolidayName.Text &lt;&gt; '' 而不是 edtHolidayName.Text &lt;&gt; NullAsStringValue。此处无需涉及变体。
  • 在程序执行时使用调试器检查各种变量和属性的值。如果你这样做了,那么你就会知道发生了什么,所以我只能假设你还没有学会如何调试。没有这项技能,就不可能成为一名有效的程序员。让学习如何调试成为您的使命。

标签: delphi


【解决方案1】:

正如上面的 cmets 所指出的,您没有 TDateTimePicker 的初始化值。

你想要的是让它默认为一个合理的日期,而不是设置为 0 - 这对用户没有任何帮助。

我会介绍一个布尔标志,一旦设置了 TDateTimePicker,您就可以自行设置。

您可以在 OnChange 事件处理程序中设置此标志。

比如:


interface

protected
  blMyDTFlag: Boolean;
...

implementation
  function TfrmHolidays.dtpHolidayDateChange(Sender: TObject);
  begin
    Self.blMyDTFlag:=True;
  end

procedure TfrmHolidays.EnableSaveButton;
begin
if (edtHolidayName.Text <> '') and
   (cmbHolidayType.ItemIndex <> -1) and
   (Self.dtMyDTFlag) then
    btnHolidaySave.Enabled := True
  else
    btnHolidaySave.Enabled := False;
end;

【讨论】:

  • 只是一个快速的。我在自我声明时遇到了问题,错误提示 TfrmHolidays 没有成员。我知道这是非常基本的,但我将不胜感激。
  • @Mel - Self 是对象(因此是表单方法的表单)并且是可选的(我已经将它告诉我使用它)所以没有它它应该可以正常工作。您是否在表单的界面部分声明了您的标志?
  • 感谢您的澄清。从您的代码中,您提供了一种新的编码方法——。欣赏它。不过,这次我看起来对我来说并不那么复杂。
【解决方案2】:

虽然问题中没有显示,但我可以猜到您将日期初始化为

dtpHolidayDate.Date := 0;

此后,针对 0 测试日期将(很可能)失败,因为时间部分仍包含创建控件的时间。

你可以初始化

dtpHolidayDate.DateTime := 0;

然后您可以照常测试日期。

您也可以使用SameDate 进行比较。

uses
  dateutils;


if (edtHolidayName.Text <> NullAsStringValue) and (cmbHolidayType.ItemIndex <> -1)
    and (not SameDate(dtpHolidayDate.Date, 0)) then

【讨论】:

  • 将 TDatePickers DateTime 初始化为 0 对用户没有帮助 - 它将日历发送到 1899-12-30 00:00:00 !用户必须从那时起滚动到更新和适用的日期。 (见docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/…
  • @Rob - 这就是发帖人想要的,正如comment 中所述。
  • 感谢您指出这一点......这对我来说毫无意义,但如果这是他们想要的,那就足够公平了!
  • @SertacAkyuz 看起来你编辑的对我来说很有意义。我试试看。
  • 从您的编辑到问题,除非您将对象检查器中的日期设置为 30-12-1899,否则它不应该起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 2018-04-12
  • 2019-12-23
  • 1970-01-01
  • 2021-04-01
相关资源
最近更新 更多