Страница 1 из 1

При добавлении записей в таблицу dBase выдает ошибку!?

Добавлено: 20 июн 2006, 12:11
Vet_chv
Помогите разобраться с глюком. Читаю данные из тхт файла построчно и записываю их в таблицу dBase. После добавления нескольких записей выдает ошибку Invalid pointer operation. Не могу понять в чем причина.

Dbf1.TableName:= ifl;
Dbf1.FieldDefs.Add('MES',ftSmallInt,0,false);
Dbf1.FieldDefs.Add('NSC',ftInteger,0,true);
Dbf1.FieldDefs.Add('FIO',ftString,50,true);
Dbf1.FieldDefs.Add('SUMMA',ftFloat,0,true);
Dbf1.CreateTable;
Dbf1.Active:= true;
Dbf1.Edit;

While not Eof(f) do
begin
readln(f,s);
Dbf1.FieldByName('MES').AsInteger:= mes;
Dbf1.FieldByName('NSC').AsInteger:= strtoint(prov(copy(s,15,5)));
Dbf1.FieldByName('FIO').AsString:= TrimRight(copy(s,46,100));
Dbf1.FieldByName('SUMMA').AsFloat:= StrTofloat(copy(s,39,7))/100;
Dbf1.Append;
kz:= kz+1;
end;


kz - подсчитывает количество свормировавшихся записей в таблице.

Добавлено: 20 июн 2006, 21:12
Eugie
Перед разбором строки, считанной readln(f,s), проверяй ее длину.

Проверяй длину

Добавлено: 21 июн 2006, 10:12
Vet_chv
Спасибо за подсказку. Только что именно значит проверять длину: считать её длину? Или думаешь, что строка может оказаться слишком длинной? Дело в том что тхт-файл чётко определенной структуры, все строки одной длины.

Добавлено: 21 июн 2006, 13:11
Eugie
Скорее слишком короткой: представь, что в конце стоит лишний перевод строки - Eof(f) вернет True, а readln(f,s) считает пустую строку...
Я бы не полагался на структуру файла.

Версия не подтвердилась...

Добавлено: 21 июн 2006, 15:15
Vet_chv
Проверял, версия не подтвердилась. Кроме того, иногда ошибка выскакивает на разных записях (то их получается допустим 23 то 27). :(

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

Код: Выделить всё

function prov(ss:string): string;
  var
  p: string;
  j: integer;
  c: array[0..4] of char;
  spec: set of char;
  begin
    p:= ss;
    spec:= ['\','/','-'];
    strpcopy(c,p);
   for j:= 1 to length(c) do
    begin
     if c[j] in spec then
      begin
       Result:= '0';
       break;
      end
     else Result:= ss;
    end;
  end;


procedure TForm1.Button1Click(Sender: TObject);
var
 f: TextFile;
 i,mes,kz: integer;
 s,zsum,ifl: string;
begin
kz:= 0;
 For i:= 0 to FIleListBox1.Items.Count-1 do
    begin
     AssignFile(f, FileListBox1.Items.Strings[i]);
     Reset(f);
     readln(f,s);
     ifl:= copy(s,2,3)+'.dbf';
     mes:= strtoint(copy(s,19,2));
   if length(inttostr(FileListBox1.Items.Count)) = 2 then
     ifl:= 'P'+inttostr(FileListBox1.Items.Count)+copy(s,19,2)+ifl
        else ifl:= 'P'+'0'+inttostr(FIleListBox1.Items.Count)+copy(s,19,2)+ifl;
     zsum:= copy(s,78,3)+' '+copy(s,81,3)+','+copy(s,84,2);
   if copy(zsum,1,2) = '00' then zsum:= copy(zsum,3,8)
       else zsum:= copy(zsum,2,9);
     Label4.Caption:= 'Çàãàëüíà ñóìà: '+zsum;

Dbf1.TableName:= ifl;
Dbf1.FieldDefs.Add('MES',ftSmallInt,0,false);
Dbf1.FieldDefs.Add('NSC',ftInteger,0,true);
Dbf1.FieldDefs.Add('FIO',ftString,50,true);
Dbf1.FieldDefs.Add('SUMMA',ftFloat,0,true);
Dbf1.CreateTable;
Dbf1.Active:= true;
Dbf1.Edit;

While not Eof(f) do
  begin
   readln(f,s);
Dbf1.FieldByName('MES').AsInteger:= mes;
Dbf1.FieldByName('NSC').AsInteger:= strtoint(prov(copy(s,15,5)));
ShowMessage(inttostr(length(TrimRight(copy(s,46,100)))));
Dbf1.FieldByName('FIO').AsString:= TrimRight(copy(s,46,100));
Dbf1.FieldByName('SUMMA').AsFloat:= StrTofloat(copy(s,39,7))/100;
Dbf1.Append;
kz:= kz+1;
  end;

Dbf1.Active:= false;
Label3.Caption:= 'ʳëüê³ñòü çàïèñ³â: '+inttostr(kz);
end;
end;


Кое что обнаружил

Добавлено: 21 июн 2006, 15:20
Vet_chv
При ошибке компилятор указывает на строку
Dbf1.FieldByName('NSC').AsInteger:= strtoint(prov(copy(s,15,5)));
Возможно, проблема в функции prov, только не разберу какая.

Победа!!!

Добавлено: 21 июн 2006, 15:25
Vet_chv
Ещё раз убеждаюсь в одной истине: обсуждение проблемы с другим упорядочивает мысли!
В функии prov не нужно было строку загонять в массив, всего-то на всего. :lol:

Добавлено: 21 июн 2006, 15:35
Eugie
Я бы добавил: строка Result:= '0' в ней выглядит сомнительно :)

Добавлено: 21 июн 2006, 16:13
Игорь Акопян
проверить наличие в строке подстроки удобнее через Pos ;)
имхо проблема именно в длинне строки...
Если строка у тебя будет 17 символов - функция copy(s,15,5) вернёт последние 2 символа
и ещё: в хэлпе про StrPCopy - The destination buffer must have room for at least Length(Source)+1 characters.

'строка Result:= '0' в ней выглядит сомнительно'

Добавлено: 21 июн 2006, 17:17
Vet_chv
'строка Result:= '0' в ней выглядит сомнительно'

Не а! Дело в том, что я пишу конвертер txt->dbf. У нас тут есть какая-то досовская утилитка, которая это делает (но она ужасно неудобна, и далеко не совершенна). А я пишу её аналог под Win. В файле dbf поле NSC имеет числовой тип, а в тхт файле, в значениях для этого поля втречаются спец знаки (я их включил в set). Досовская прога в таких случаях ставит 0. Чем нужно было бы заменять неизвестно. Но такой вариант позволяет работать в дальнейшем. :wink: