【问题标题】:Error with ToString Function OutputToString 函数输出错误
【发布时间】:2014-07-26 14:28:05
【问题描述】:

“参数类型错误、超出可接受范围或相互冲突”。这是我尝试运行以下代码时收到的运行时错误消息。我正在使用一个类 clsReceipt 以字符串的形式制定收据,以便我可以在丰富的编辑中输出它,供用户在继续购买产品之前查看(各种概述)。我找不到任何错误,因此我需要帮助。请记住,我是一名高中生,知识有限。我在 Windows 上使用 Delphi XE3。

下面是btnPurchase的代码:

procedure TfrmBuy.btnPurchaseClick(Sender: TObject);
var
  i, n, itemNumber, quant : integer;
  found: boolean;
begin
  repeat
    i := strtoint(inputbox('Purchase','Enter the number of items you wish to buy or enter 0              to cancel',''));
  until i>=0;
  if i <> 0 then
  begin
    for n := 1 to i do
    begin
      found := false;
      repeat
        itemnumber := strtoint(inputbox('Item selection','Enter the Item number of purchase no. ' + inttostr(n),''));
        if dm.ADOtbl.Locate('Item number',itemnumber,[]) then
          found := true
        else
          showmessage('The item number you enteres was not found. Please try again.');
      until found = true;
      repeat
        quant := strtoint(inputbox('Quantity selection','Please enter the quantity of the item you wish to purchase','>0'));
      until quant >0;
      Myreciept := TReceipt.create(itemnumber,quant,n,i);
    end;

    richedit1.Lines.Clear;
    richedit1.Lines.Add(myreciept.tostring);
    btnCheckout.Visible := true;
    showmessage('Below is the reciept of your purchase. If you are satisfied, proceed to  checkoutby selecting "Confirm" or restart by selecting "Reset"');
  end;
  repeat
    i := strtoint(inputbox('Purchase','Enter the number of items you wish to buy or enter 0              to cancel',''));
  until i>=0;
  if i <> 0 then
  begin
    for n := 1 to i do
    begin
      found := false;
      repeat
        itemnumber := strtoint(inputbox('Item selection','Enter the Item number of purchase no. ' + inttostr(n),''));
        if dm.ADOtbl.Locate('Item number',itemnumber,[]) then
          found := true
        else
          showmessage('The item number you enteres was not found. Please try again.');
      until found = true;
      repeat
        quant := strtoint(inputbox('Quantity selection','Please enter the quantity of the item you wish to purchase','>0'));
      until quant >0;
      Myreciept := TReceipt.create(itemnumber,quant,n,i);
    end;

    richedit1.Lines.Clear;
    richedit1.Lines.Add(myreciept.tostring);
    btnCheckout.Visible := true;
    showmessage('Below is the reciept of your purchase. If you are satisfied, proceed to  checkoutby selecting "Confirm" or restart by selecting "Reset"');
  end;
end;

下面是类中ToString函数的代码:

function TReceipt.ToString: string;
var
k:integer;
begin
result := '';
result := 'Reciept' + #13 + '===============================================' + #13;
result := result + 'Order ID: ' + fOrderID + #13;
result := result + 'Item Name' + #9 + 'Quantity' + 'Cost' + #13;
for k := 1 to length(arrItemNo) do
begin
dm.ADOtbl.RecNo := arritemno[k];
 result := result + dm.ADOtbl['Item Name'] + #9 + inttostr(arrQuantity[k]) + #9 +       floattostrf((arrQuantity[k] * dm.ADOtbl['Price'] ),ffcurrency,5,2) + #13;

end;
result := result + #13 + #13 + 'Subtotal: ' + floattostrf(getsubtotal,ffcurrency,5,2) +    #13;
result := result + 'VAT: ' + floattostrf(getVat,ffcurrency,5,2) + #13;
result := result + 'Grand Total: ' + floattostrf(ftotal,ffcurrency,5,2) + #13 +   '===============================================';


end;
end.

如果有人能帮助我解决这个问题,那就太好了。

【问题讨论】:

  • 如果您告诉我们错误所在,我们可以更轻松地为您提供帮助。并且还启用编译器提示和警告。您应该处理一些问题。
  • 如果可以的话我会的,因为在编译时没有显示错误或警告。我只是在运行程序期间收到上面的粗体消息。一旦它到达被输入richedit 的ToString 函数,它就会出现,很可能是当它到达ToSTring 代码中的for 循环时。希望这有助于澄清事情
  • 尝试并准确描述发生了什么。如果 ide 不能精确定位代码行,那就太令人惊讶了。在调试器中单步执行。
  • 所有代码运行良好,因为它接受了所有输入,例如数量等。然后发生的一切就是粗体消息显示为错误消息,当我关闭它时什么也没有否则,代码将停止运行。我已经使用了这个步骤,没有任何问题。
  • 我认为您引用的错误消息来自用于访问数据库的 Windows ADO 子系统。所以它可能是由你的代码引起的,但它不是来自它。您引用 ADOtbl 的地方看起来都不太可能导致它,所以我认为原因可能在您的代码中的其他地方。

标签: function delphi output


【解决方案1】:

(其他读者:显然这是一项正在进行的工作,因为 OP 可能需要比 cmets 更多的指导。无论如何...)

在这种情况下,如前面的 cmets 所述,消息不是来自您的应用程序,而是来自您的应用程序调用的 MS ADO 数据访问层,通过操作您的代码 正在对您项目中的 TADOxxx 组件进行。

冒着明显的风险,调试 + 修复这样的问题通常是 一个多步骤过程:a)找出错误发生的位置,b)找出什么是 导致它并 c) 修复或解决它。

a) 可能比听起来更棘手,尤其是对于找到自己的脚的人来说 起初,但通过练习确实会变得更容易,并且调试器在这方面非常有帮助 它与 IDE 和用户交互以将错误位置归零。

首先要让您的项目处于最佳调试状态,为此您的第一站是 项目 |选项 |编译器。关闭优化,打开堆栈帧,打开使用调试 DCU 和(如果您的代码可以使用它运行)范围检查。转到 IDE 中的调试器选项 (自 Delphi 7 等旧版本以来,它一直在移动)。在 XE+ 版本中,转到工具 |选项,向下滚动到调试器选项 | Embarcadero 调试器并选中“通知语言异常”框。

接下来,对您的项目进行完整构建,然后运行它,直到出现错误为止。如果错误表现为异常,这会使事情变得更容易 - 只需使用 F9 运行应用程序,当异常发生时调试器将从它手中夺取控制权。此时,转到查看 |调试窗口,调用堆栈:发生异常的位置将在窗口的顶部,通常在 RTL 或 VCL 源代码中,而不是在您的项目中。在列表的下方,您应该在自己的代码中看到例程——如果是您所追求的,则位于最前面的例程。在其入口点放置一个断点,关闭异常消息并执行以下动作 再次引发错误。这一次,调试器应该在你的断点处停止,并且 单步执行应该会带您到发生错误的确切位置。

通常,问题的原因很明显,您可以当场解决。如果你不能, 这是决定您的 SO 问题中应该包含哪些代码的起点。

在针对您的实际问题尝试上述方法之前,请先快速练习一下。在表单中添加一个按钮,并在其 Click 事件中输入“raise Exception.Create('I am an error');”。然后编译 + 运行应用程序并单击按钮。

对于您的真正错误,我首先在 ToString 函数中“开始”下方的第一行放置一个断点,然后运行应用程序直到 b.point 跳闸并从那里单步 (F8) 直到您到达发生异常的行。然后再试一次,这次追踪到 (F7) 那行...

“参数”在错误消息的意义上是为参数“占位符”提供的值,一个例程,无论是在您自己的代码中,还是它正在调用的东西,都期望接收。

错误消息所指的参数是您的应用试图通过 ADO 层发送到数据库的数据,通常作为源自项目 ADO 组件操作的参数或文本。因此,它只可能是您对可能引发错误的对象之一执行某些操作的语句。一旦您找到了位置,我们将需要一些信息来输入 q,并且可能大多数现有代码都可能不相关。

【讨论】:

  • 如果您使用我在其 OnClick 事件中描述的“raise ...”语句将按钮添加到您的项目中,那么当您单击时您不能得到异常它在运行时。
  • @David Heffernan,来自你,这让我很开心。
  • @MartynA 很抱歉这么久才回复您。我最终设法做到了你所说的,简而言之,我修复并调整了一些东西,现在它可以工作了。感谢您的帮助!
  • 很高兴你把它整理好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多