Форум: "Основная";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
ВнизПропадают объекты? Найти похожие ветки
← →
G0ga © (2005-09-28 16:33) [0]Уважаемые мастера столкнулся с такой проблемой. В наличии есть таблица (неважно какая). Из нее берется 5 полей и помещается в TObject. Который потом "заталкивается" в TObjectList (методом Insert). В качестве индекса берется уникальное строковое поле из 6ти цифр - преобразованное в целое число(FieldByName("...").AsInteger). На этапе отладки строка "100002" заносится в TObjectList, а по завершении процесса эта строка и ещё серия строк - пропадает. Где может сабака зарыта?
P.S. При значении индекса > TObjectList.Count меняю значение Count на значение индекса и провожу Insert.
← →
erika © (2005-09-28 16:53) [1]какая БД и листинг, пожалуйста
← →
G0ga © (2005-09-28 17:11) [2]БД MSAccess
...
srcRecord.Open;
Price:=TObjectList.Create;
srcRecord.Last;
Price.Capacity:=srcRecord.RecordCount;
srcRecord.First;
while Not srcRecord.Eof do
begin
New(temp);
temp^:=TPriceInfo.Create;
temp.BaseCode:=srcRecord.FieldByName("BaseCode").AsString;
temp.Name:=srcRecord.FieldByName("Name").AsString;
temp.Factory:=srcRecord.FieldByName("Factory").AsString;
temp.Country:=srcRecord.FieldByName("Country").AsString;
temp.Artikul:=srcRecord.FieldByName("Artikul").AsString;
temp.CostValue:=srcRecord.FieldByName("Cost").AsInteger;
temp.Suffix:="р.";
temp.Cost2Value:=srcRecord.FieldByName("For_Cost2").AsInteger;
temp.Date:=Date();
try
i:=srcRecord.FieldByName("BaseCode").AsInteger;
if Price.Count<=i then
Price.Count:=i+1;
Price.Insert(i,temp^);
except
Price.Add(temp^);
end;
srcRecord.Next;
end;
srcRecord.Close;
...
← →
Германн © (2005-09-28 17:17) [3]Insert сам увеличивает Count. Зачем ты это делаешь?
← →
umbra © (2005-09-28 17:18) [4]
> В качестве индекса берется уникальное строковое поле из
> 6ти цифр
В TObjectList элементы нумеруются числами начиная с нуля. Элементами TObjectList являются указатели (адреса памяти) на объекты, "затолкнутые" в список. В методе Insert параметр Index - номер элемента в списке, в котором будет содержаться указатель. Нужет ли список, в котором 99999 пустых элементов и только 100000-ый занят?
← →
G0ga © (2005-09-28 17:20) [5]Нет
← →
umbra © (2005-09-28 17:33) [6]
try
i:=srcRecord.FieldByName("BaseCode").AsInteger;
if Price.Count<=i then
Price.Count:=i+1;
Price.Insert(i,temp^);
except
Price.Add(temp^);
end;
Здесь написано, что в случае ошибки надо добавить элемент в конец списка. Довольно необычное поведение - не интересуясь, что за ошибка, делать, в принципе, то же, что и в блоке try. Элементы, скорее всего, исчезают потому, что какая-то ошибка случается, например переполнение стека или потеря коннекта с базой данных, и, соответственно после нее все уже каким то образом неправильно. В блокеexcept
лучше обрабатывать не все возможные ошибки, а только некоторые, которые можно обработать
← →
G0ga © (2005-09-28 17:59) [7]Убрал обработку
except
думал она портит кртину. Оказалось проблема продолжается.
← →
umbra © (2005-09-28 18:08) [8]
> Убрал обработку except
То есть вообще теперь нет блока try ... except? И табличек об ошибках программа не выдает?
← →
G0ga © (2005-09-28 18:13) [9]Убрал
except
Price.Add(temp^);
end;
← →
umbra © (2005-09-28 18:23) [10]ну, для начала - если убираете
except
Price.Add(temp^);
end;
то убирайте и словоtry
выше. Когда убереште, запустите прогу. Могу спорить, что она выдаст ошибку. Если напишеште, какую, то, возможно и разберемся в чем дело.
← →
G0ga © (2005-09-28 18:51) [11]Интересное наблюдение при попытке взять
TOP 30000
ошибки не наблюдается.
← →
G0ga © (2005-09-28 18:55) [12]Может проблема в
Price.Capacity:=
иPrice.Count:=
?
← →
umbra © (2005-09-28 18:59) [13]весь этот процесс присходит в процедуре (или функции)? и выскакивают ли таблички с красными крестами и сообщением наподобие "raised exception EStackOverflow at address ....."? Просто недостаточно информации, чтобы можно было определить проблему. Подробнее, пожалуйста!
← →
umbra © (2005-09-28 19:00) [14]
> G0ga © (28.09.05 18:55) [12]
Проблема, скорее всего в том, что список адресов слишком большой для локальной переменной, объявленной в процедуре
← →
G0ga © (2005-09-28 19:30) [15]Ошибки возникают только в
i:=srcRecord.FieldByName("BaseCode").AsInteger;
, но для этого и стоитtry except end;
.
← →
G0ga © (2005-09-28 19:34) [16]В "Библиях" неочень точно описан механизм свойства Capacity. Вероятна ситуация когда выделенного пространства памяти не хватает для дальнейшего
Insert
a. И TObjectList начинает терять объекты.
← →
umbra © (2005-09-28 19:50) [17]
> Ошибки возникают только в i:=srcRecord.FieldByName("BaseCode").
> AsInteger;, но для этого и стоит try except end;.
>
Ну вот, теперь ясно в чем дело. В справке о свойстве AsInteger объекта типа TField написано, что TField не поддерживает полей целого типа и при попытке чтения ВСЕГДА возникает ошибка.
Пэтому, чтобы ошибок не было вообще, надо вместоi:=srcRecord.FieldByName("BaseCode").AsInteger;
поставить что-то вродеi := inttostr(temp.BaseCode)
Помогло?
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.04 c