При добавлении записей в таблицу dBase выдает ошибку!?
Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду
Помогите разобраться с глюком. Читаю данные из тхт файла построчно и записываю их в таблицу 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 - подсчитывает количество свормировавшихся записей в таблице.
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 - подсчитывает количество свормировавшихся записей в таблице.
Перед разбором строки, считанной readln(f,s), проверяй ее длину.
Спасибо за подсказку. Только что именно значит проверять длину: считать её длину? Или думаешь, что строка может оказаться слишком длинной? Дело в том что тхт-файл чётко определенной структуры, все строки одной длины.
Скорее слишком короткой: представь, что в конце стоит лишний перевод строки - Eof(f) вернет True, а readln(f,s) считает пустую строку...
Я бы не полагался на структуру файла.
Я бы не полагался на структуру файла.
Проверял, версия не подтвердилась. Кроме того, иногда ошибка выскакивает на разных записях (то их получается допустим 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;
При ошибке компилятор указывает на строку
Dbf1.FieldByName('NSC').AsInteger:= strtoint(prov(copy(s,15,5)));
Возможно, проблема в функции prov, только не разберу какая.
Dbf1.FieldByName('NSC').AsInteger:= strtoint(prov(copy(s,15,5)));
Возможно, проблема в функции prov, только не разберу какая.
Ещё раз убеждаюсь в одной истине: обсуждение проблемы с другим упорядочивает мысли!
В функии prov не нужно было строку загонять в массив, всего-то на всего. :lol:
В функии prov не нужно было строку загонять в массив, всего-то на всего. :lol:
Я бы добавил: строка Result:= '0' в ней выглядит сомнительно 

- Игорь Акопян
- Сообщения: 1440
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
проверить наличие в строке подстроки удобнее через Pos 
имхо проблема именно в длинне строки...
Если строка у тебя будет 17 символов - функция copy(s,15,5) вернёт последние 2 символа
и ещё: в хэлпе про StrPCopy - The destination buffer must have room for at least Length(Source)+1 characters.

имхо проблема именно в длинне строки...
Если строка у тебя будет 17 символов - функция copy(s,15,5) вернёт последние 2 символа
и ещё: в хэлпе про StrPCopy - The destination buffer must have room for at least Length(Source)+1 characters.

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