1

I'm attempting to update an old Paradox (BDE) table using an older Delphi XE6 application. One particular table has two fields; a Date field, and a BCD field. I'm unable to post a new record to the (FuelSurch) table due to the BCD (FuelSur) field which is throwing a "Number is out of range" error.

So I wrote a quick test, but still the same issue. Here are the FuelSurch table field specifications.

enter image description here

I just added a button to a form and this procedure fires when clicked.

procedure TTestForm.BCDTestBtnClick(Sender: TObject);
var
  Bcd: TBcd;
begin
  POE_Data.FuelSurch.Open;
  POE_Data.FuelSurch.Insert;
  Bcd:= StrToBcd('2.01');
  showMessage('Bcd = ' + BcdToStr(Bcd));  // This works and shows 'Bcd = 2.01'
  POE_Data.FuelSurchFuelSur.AsBCD := Bcd;  // Line produces "Number is out of range." error
  POE_Data.FuelSurch.Post;
  POE_Data.FuelSurch.Close;
end;

The database connection is confirmed as good as I'm able to post to other tables. It just seems like this BCD field type is giving me issues.

Do I need to format the string differently before assigning it to the Bcd variable?

Hackbrew
  • 349
  • 1
  • 10
  • 23
  • In [the same question](https://stackoverflow.com/q/26240053/2292722) nearly six years ago you accepted one answer, which, it seems, you are adapting in your code here. Maybe the applications are not the same, but still, what has changed in between. The other answer suggest changes to the `Data.DB.pas` file. Have you tried that? Shall we close this question as a duplicate? – Tom Brunberg Sep 11 '20 at 18:32
  • @TomBrunberg - Somewhat similar, but it's a bit different in that the code you're referencing was using a tax rate and asFloat. I'm now just trying to isolate getting a string into a BCD field in a Paradox table. I didn't see the reference to Data.DB.pas. Do I need to include that in my uses? – Hackbrew Sep 11 '20 at 19:05
  • On a second thought, I think it is a question of format. What decimalseparator do you have in your computer? – Tom Brunberg Sep 11 '20 at 19:07
  • @TomBrunberg - a period – Hackbrew Sep 11 '20 at 19:10
  • Ok, then it was not the decimal separator (and your own `showmessage()` test already confirmed it). I assume that the Paradox machine (if another one) is also setup with period as decimal separator, is it? The `Data.DB.pas` modification was suggested in the second answer to your previous 6-year old question. I have not checked it and therefore do not endorse it. – Tom Brunberg Sep 11 '20 at 19:23
  • @TomBrunberg - Yes, all systems are set up with period as decimal separator. Thanks, I did see the `Data.DB.pas` modification but was unable to get that to work. This seems like a fairly simple task for a database to handle. I not sure why `POE_Data.FuelSurchFuelSur.AsBCD := StrToBcd('2.01');` doesn't work. Is there a certain way that I can format the string so that the database (BCD field) will accept it? – Hackbrew Sep 11 '20 at 20:45
  • You are using a BCD with 3 decimal places while your table accept 2 decimal places. – fpiette Sep 11 '20 at 21:18
  • I just noted the same as @fpiette when I looked closer at the precision column. – Tom Brunberg Sep 11 '20 at 21:20
  • @fpiette - Yes I changed it to 2 digits as seen in the comments above, but it still doesn't work `POE_Data.FuelSurchFuelSur.AsBCD := StrToBcd('2.01');` – Hackbrew Sep 11 '20 at 21:43

1 Answers1

1

Internally the precision of a BCD is the total number of digits, not the number of digits after the decimal separator.

It's always an even number (when odd, 1 is added to it). The reason is that a byte stores 2 digits.

So if you try this:

procedure TForm1.Button1Click(Sender: TObject);
var
  Bcd: TBCD;
begin
  Bcd := StrToBcd('2.01', TFormatSettings.Invariant);
  ShowMessage(IntToStr(Bcd.Precision));
end;

you will see 4, because 3 digits are used, plus 1 to make it even.

Your field precision is only 2. If it represents the same as TBCD.Precision, it's not enough.

Note that BcdPrecision() returns the number of digits before the decimal separator, which is a bit confusing.

Olivier
  • 13,283
  • 1
  • 8
  • 24
  • It doesn't like that. It shows that 'TFormatSettings' does not contain a member named 'Invariant'. E2003 Undeclared identifier: 'Invariant'. – Hackbrew Sep 12 '20 at 14:21
  • @Hackbrew You can remove it if your Delphi version doesn't support it. Its purpose is to set the dot as the decimal separator. – Olivier Sep 13 '20 at 07:06
  • Since my field precision is only 2, how can I have entries for this field in the database of '11.4 or 10.2'? – Hackbrew Sep 14 '20 at 15:23