Страница 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. Чем нужно было бы заменять неизвестно. Но такой вариант позволяет работать в дальнейшем.
