Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.10.23;
Скачать: CL | DM;

Вниз

Пропадают объекты?   Найти похожие ветки 

 
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. Вероятна ситуация когда выделенного пространства памяти не хватает для дальнейшего Inserta. И 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.032 c
4-1124692715
Malignus
2005-08-22 10:38
2005.10.23
Определение активного юзера из сервиса


1-1128062786
webpauk
2005-09-30 10:46
2005.10.23
Список папок


14-1128316205
Ega23
2005-10-03 09:10
2005.10.23
С днем рождения! 1 октября


1-1127968646
Unitay
2005-09-29 08:37
2005.10.23
Сохранение png


9-1118169324
4ECHOK
2005-06-07 22:35
2005.10.23
А сделайте мне дождь !