Поле Paradox BCD — ошибка «Число вне диапазона»

Я пытаюсь обновить старую таблицу Paradox (BDE) с помощью более старого приложения Delphi XE6. Одна конкретная таблица имеет два поля; поле даты и поле BCD. Я не могу опубликовать новую запись в таблице (FuelSurch) из-за поля BCD (FuelSur), которое выдает ошибку «Число вне диапазона».

Поэтому я написал быстрый тест, но все еще та же проблема. Вот спецификации полей таблицы FuelSurch.

введите здесь описание изображения

Я только что добавил кнопку в форму, и эта процедура срабатывает при нажатии.

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;

Соединение с базой данных подтверждено настолько хорошо, насколько я могу отправлять сообщения в другие таблицы. Просто мне кажется, что этот тип поля BCD вызывает у меня проблемы.

Нужно ли форматировать строку по-другому, прежде чем назначать ее переменной Bcd?


person Hackbrew    schedule 11.09.2020    source источник
comment
В тот же вопрос почти шесть лет назад вы приняли один ответ, который, кажется, вы адаптируете в своем коде здесь. Может приложения не те, но все же, что изменилось между ними. Другой ответ предлагает внести изменения в файл Data.DB.pas. Вы пробовали это? Должны ли мы закрыть этот вопрос как дубликат?   -  person Tom Brunberg    schedule 11.09.2020
comment
@TomBrunberg - В чем-то похоже, но немного отличается тем, что в коде, на который вы ссылаетесь, использовалась налоговая ставка и asFloat. Сейчас я просто пытаюсь изолировать получение строки в поле BCD в таблице Paradox. Я не видел ссылки на Data.DB.pas. Нужно ли мне включать это в мое использование?   -  person Hackbrew    schedule 11.09.2020
comment
Если подумать, я думаю, что это вопрос формата. Какой десятичный разделитель у вас на компьютере?   -  person Tom Brunberg    schedule 11.09.2020
comment
@TomBrunberg - период   -  person Hackbrew    schedule 11.09.2020
comment
Хорошо, тогда это был не десятичный разделитель (и ваш собственный тест showmessage() это уже подтвердил). Я предполагаю, что машина Paradox (если другая) также настроена с точкой в ​​качестве десятичного разделителя, не так ли? Модификация Data.DB.pas была предложена во втором ответе на ваш предыдущий вопрос 6-летней давности. Я не проверял это и поэтому не подтверждаю это.   -  person Tom Brunberg    schedule 11.09.2020
comment
@TomBrunberg - Да, все системы настроены с точкой в ​​качестве десятичного разделителя. Спасибо, я видел модификацию Data.DB.pas, но не смог заставить ее работать. Это кажется довольно простой задачей для базы данных. Я не уверен, почему POE_Data.FuelSurchFuelSur.AsBCD := StrToBcd('2.01'); не работает. Есть ли определенный способ форматирования строки, чтобы база данных (поле BCD) приняла ее?   -  person Hackbrew    schedule 11.09.2020
comment
Вы используете BCD с 3 знаками после запятой, в то время как ваша таблица принимает 2 знака после запятой.   -  person fpiette    schedule 12.09.2020
comment
Я только что отметил то же самое, что и @fpiette, когда внимательно посмотрел на столбец точности.   -  person Tom Brunberg    schedule 12.09.2020
comment
@fpiette - Да, я изменил его на 2 цифры, как видно из комментариев выше, но это все равно не работает POE_Data.FuelSurchFuelSur.AsBCD := StrToBcd('2.01');   -  person Hackbrew    schedule 12.09.2020


Ответы (1)


Внутренне точность BCD определяется общим количеством цифр, а не количеством цифр после десятичного разделителя.

Это всегда четное число (если оно нечетное, к нему добавляется 1). Причина в том, что байт хранит 2 цифры.

Итак, если вы попробуете это:

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

вы увидите 4, потому что используются 3 цифры плюс 1, чтобы сделать их четными.

Ваша точность поля равна только 2. Если она представляет то же самое, что и TBCD.Precision, этого недостаточно.

Обратите внимание, что BcdPrecision() возвращает количество цифр перед десятичным разделителем, что немного сбивает с толку.

person Olivier    schedule 12.09.2020
comment
Это не нравится. Он показывает, что «TFormatSettings» не содержит члена с именем «Invariant». E2003 Необъявленный идентификатор: «Инвариант». - person Hackbrew; 12.09.2020
comment
@Hackbrew Вы можете удалить его, если ваша версия Delphi не поддерживает его. Его цель - установить точку в качестве десятичного разделителя. - person Olivier; 13.09.2020
comment
Поскольку моя точность поля равна только 2, как я могу иметь записи для этого поля в базе данных «11,4 или 10,2»? - person Hackbrew; 14.09.2020