Требуется разработать программу для работы со списками строк. Структура объектов пользовательского класса следующая: Кадры: имя,номер цеха, разряд; Список содержит строки с идентификатором объекта и связанной со строкой объект. Для визуализации списка используется компонент TListBox. Предусмотреть создание, просмотр и редактирование объектов, а так же сохранение объектов в файле и их загрузку из файла.
Во-первых, объясните пожалуста, что имеется ввиду под: "Список содержит строки с идентификатором объекта и связанной со строкой объект" и как это можно осуществить?
Ещё проблема с определением в главном модуле класса объектов (Кадры: имя,номер цеха, разряд), размещаемых в списке...(сначало нужно опредилить объект, а потом класс этих объектов или как?? покажите пожалуста на моём примере..)
Причём в классе требуется определить конструктор вида:
constructor TMyObject.Create(поле1:тип;....); begin inherited Create; <инициализация полей> end;
18192123
24.04.2008 0:32
Вот что получилось:
interface type TPeople=class Name:string; Workshop:integer; Range:integer; constructor Create(Name:string;Workshop:string;Range:integer); end; var n:integer; MyObject:array[1..18]of TPeople; implementation
constructor TPeople.Create(Name:string;Workshop:string;Range:integer); var i:integer; begin inherited Create; for i:=1 to 18 do begin MyObject[i].Name:=''; MyObject[i].Workshop:=0; MyObject[i].Range:=0; end; end;
Только не знаю, получиться ли таким образом предусмотреть выполнение всего, что нужно по заданию...И как теперь это всё связать с ListBox?
18192123
4.05.2008 0:22
Объясните пожалуста, в чём ошибка..не компилится приложение без ошибок..
unit Unit5;
interface type TPeople=class private
fName:string; fWorkshop:integer; fRange:integer; function GetName:string; procedure SetName(newName:string); function GetWorkshop:integer; procedure SetWorkshop(newWorkshop:integer); function GetRange:integer; procedure SetRange(newRange:integer);
[Error] Unit5.pas(10): Unsatisfied forward or external declaration: 'TPeople.GetName' [Error] Unit5.pas(11): Unsatisfied forward or external declaration: 'TPeople.SetName' [Error] Unit5.pas(12): Unsatisfied forward or external declaration: 'TPeople.GetWorkshop' [Error] Unit5.pas(13): Unsatisfied forward or external declaration: 'TPeople.SetWorkshop' [Error] Unit5.pas(14): Unsatisfied forward or external declaration: 'TPeople.GetRange' [Error] Unit5.pas(15): Unsatisfied forward or external declaration: 'TPeople.SetRange' [Error] Unit5.pas(22): Unsatisfied forward or external declaration: 'TPeople.Create' [Error] Unit5.pas(23): Unsatisfied forward or external declaration: 'TPeople.Destr'
volvo
4.05.2008 0:34
Ошибка - в том, что ты не приводишь реализацию методов, а только описываешь их... Этого недостаточно.
18192123
4.05.2008 1:41
Цитата(volvo @ 3.05.2008 21:34)
Ошибка - в том, что ты не приводишь реализацию методов, а только описываешь их... Этого недостаточно.
Вот что я добавила..Снова ошибки..
implementation Uses Unit1, Unit2, Unit3, Unit4;
function GetName:string; begin Result:=fName; end;
function GetWorkshop:integer; begin Result:=fWorkshop; end;
function GetRange:integer; begin Result:=fRange; end;
procedure SetName(newName:string); begin fName:=newName; end;
procedure SetWorkshop(newWorkshop:integer); begin fWorkshop:=newWorkshop; end;
procedure SetRange(newRange:integer); begin fRange:=newRange; end;
[Error] Unit5.pas(45): Undeclared identifier: 'fName' [Error] Unit5.pas(50): Undeclared identifier: 'fWorkshop' [Error] Unit5.pas(55): Undeclared identifier: 'fRange' [Error] Unit5.pas(60): Undeclared identifier: 'fName' [Error] Unit5.pas(65): Undeclared identifier: 'fWorkshop' [Error] Unit5.pas(70): Undeclared identifier: 'fRange' [Hint] Unit5.pas(7): Private symbol 'fName' declared but never used [Hint] Unit5.pas(8): Private symbol 'fWorkshop' declared but never used [Hint] Unit5.pas(9): Private symbol 'fRange' declared but never used [Error] Unit5.pas(10): Unsatisfied forward or external declaration: 'TPeople.GetName' [Error] Unit5.pas(11): Unsatisfied forward or external declaration: 'TPeople.SetName' [Error] Unit5.pas(12): Unsatisfied forward or external declaration: 'TPeople.GetWorkshop' [Error] Unit5.pas(13): Unsatisfied forward or external declaration: 'TPeople.SetWorkshop' [Error] Unit5.pas(14): Unsatisfied forward or external declaration: 'TPeople.GetRange' [Error] Unit5.pas(15): Unsatisfied forward or external declaration: 'TPeople.SetRange' [Error] Unit5.pas(22): Unsatisfied forward or external declaration: 'TPeople.Create' [Error] Unit5.pas(23): Unsatisfied forward or external declaration: 'TPeople.Destr' [Fatal Error] Project1.dpr(9): Could not compile used unit 'Unit5.pas'
volvo
4.05.2008 2:02
Ты добавила просто процедуры/функции, а надо было добавлять методы класса:
function TPeople.GetName:string; begin Result:=fName; end;
function TPeople.GetWorkshop:integer; begin Result:=fWorkshop; end;
function TPeople.GetRange:integer; begin Result:=fRange; end;
procedure TPeople.SetName(newName:string); begin fName:=newName; end;
procedure TPeople.SetWorkshop(newWorkshop:integer); begin fWorkshop:=newWorkshop; end;
procedure TPeople.SetRange(newRange:integer); begin fRange:=newRange; end;
18192123
5.05.2008 3:24
Итак, продолжу задавать вопросы)
На 1-й форме у меня два ListBox..По нажатию кнопки "Добавить" вызывается ещё одна форма (2-я)..Начала работать над добавлением..Перед этим добавила конструктор для моего класса TPeople:
type TPeople=class private
fName:string; fWorkshop:integer; fRange:integer; function GetName:string; procedure SetName(newName:string); function GetWorkshop:integer; procedure SetWorkshop(newWorkshop:integer); function GetRange:integer; procedure SetRange(newRange:integer);
procedure TForm2.BitBtn1Click(Sender: TObject); var NewPeople:TPeople; begin if Form2.ShowModal=mrOK then begin NewPeople:=TPeople.Create(fName,fWorkshop,fRange); {...} end; end;
Можно задать тебе один вопрос: что ты делаешь вот тут:
Цитата
constructor TPeople.Create(fName:string;fWorkshop:integer;fRange:integer); begin inherited Create; fName:=''; fWorkshop:=0; fRange:=0; end;
?
18192123
5.05.2008 4:34
Цитата(volvo @ 5.05.2008 1:12)
Можно задать тебе один вопрос: что ты делаешь вот тут: ?
инициализирую поля
volvo
5.05.2008 4:43
Я не заметил этого... Ты просто заносишь в параметры конструктора нулевые значения. Да и вообще, тогда зачем передавать что-то в конструктор, если все равно все инициализируется нулями?
Вот так сделай:
constructor TPeople.Create(AName: string; AWorkshop: integer; ARange:integer); begin inherited Create; Name := AName; // property в работе Workshop := AWorkshop; Range := ARange; end;
, а при вызове подставляй фактические параметры. Скажем,
NewPeople:=TPeople.Create('Ivanov', 10, 100);
18192123
8.05.2008 21:45
И снова здраствуйте! В процессе работы у меня возникла проблема с несоответствием типов (TObject и созданного TPeople)...Подскажите пожалуста, как это исправить.. Ситуация вот такая: на Form1 - ListBox1 со списком объектов (фамилии рабочих)..Более подробную информацию об объекте будем просматривать на Form3..
procedure TForm3.BitBtn1Click(Sender: TObject); var CurPeople: TPeople; begin CurPeople:=Form1.ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]; Edit1.Text:=PeopleName; Edit2.Text:=IntToStr(PeopleWorkshop); SpinEdit1.Text:=IntToStr(PeopleRange); end;
volvo
8.05.2008 22:24
Погоди... Я не понял, что происходит? Ты описываешь CurPeoPle, так? Откуда берутся PeopleName, PeopleWorkshop и PeopleRange? Где происходит создание экземпляра CurPeople (в смысле, вызов его конструктора)?
Добавлено через 11 мин. Может, ты имела в виду вот это:
procedure TForm3.BitBtn1Click(Sender: TObject); var CurPeople: TPeople; begin CurPeople := TPeople(Form1.ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]); Edit1.Text := CurPeople.fName; Edit2.Text := IntToStr(CurPeople.fWorkshop); SpinEdit1.Text :=IntToStr(CurPeople.fRange); end;
?
Но учти, что если экземпляры объектов TPeople неправильно связаны с ListBox-ом, то последствия будут непредсказуемые...
18192123
8.05.2008 22:40
Цитата(volvo @ 8.05.2008 19:24)
Погоди... Я не понял, что происходит? Ты описываешь CurPeoPle, так? Откуда берутся PeopleName, PeopleWorkshop и PeopleRange? Где происходит создание экземпляра CurPeople (в смысле, вызов его конструктора)?
Это всё было попыткой обратиться к уже существующему объекту..Конструктор для CurPeople нигде не вызывается..PeopleName, PeopleWorkshop и PeopleRange - поля текущего объекта..т.е. моей целью сейчас является показать подробную ин-ю(ФИО, Цех, Разряд) об объекте, выделенном в ListBox1 на Form1.
18192123
10.05.2008 2:03
Цитата(18192123 @ 8.05.2008 19:40)
Это всё было попыткой обратиться к уже существующему объекту..Конструктор для CurPeople нигде не вызывается..PeopleName, PeopleWorkshop и PeopleRange - поля текущего объекта..т.е. моей целью сейчас является показать подробную ин-ю(ФИО, Цех, Разряд) об объекте, выделенном в ListBox1 на Form1.
Исправила следующим образом (хочу получить на отдельной форме Form3 подробную ин-цию об объекте, выделенном на Form1 в ListBox1):
procedure TForm3.BitBtn1Click(Sender: TObject); var CurPeople: TPeople; begin CurPeople:=TPeople.Create('',0,0); CurPeople:=Form1.ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]; Edit1.Text:=CurPeople.Name; Edit2.Text:=IntToStr(CurPeople.Workshop); SpinEdit1.Text:=IntToStr(CurPeople.Range); end;
Возникла ошибка: [Error] Unit3.pas(36): Incompatible types: 'TPeople' and 'TObject' [Fatal Error] Project1.dpr(9): Could not compile used unit 'Unit3.pas'
Подскажите пожалуста, правильно ли я вообще делаю и как "бороться" с несоответствием типов?
volvo
10.05.2008 4:36
Я показал тебе в предыдущем сообщении, что надо сделать приведение типа (в таком случае, действительно, конструктор не нужен)... Тут вопрос в другом: как ты заносишь информацию в Objects? Если это делается неправильно, то чтение, естественно, работать не будет (а вот при занесении класса в список Objects конструктор как раз обязателен)...
Так что, показывай код, где к ListBox-у присоединяешь данные...
18192123
10.05.2008 6:29
Цитата(volvo @ 10.05.2008 1:36)
Я показал тебе в предыдущем сообщении, что надо сделать приведение типа (в таком случае, действительно, конструктор не нужен)... Тут вопрос в другом: как ты заносишь информацию в Objects? Если это делается неправильно, то чтение, естественно, работать не будет (а вот при занесении класса в список Objects конструктор как раз обязателен)...
Так что, показывай код, где к ListBox-у присоединяешь данные...
Не знаю, насколько правильно я сделала - но заработало)
procedure TForm2.BitBtn1Click(Sender: TObject); //присоединение данных к ListBox1 на Form1 var NewPeople:TPeople; begin NewPeople:=TPeople.Create(Edit1.Text,StrToInt(Edit2.Text),StrToInt(SpinEdit1.Text)); Form1.ListBox1.Items.AddObject(Form2.Edit1.Text, NewPeople as TObject); end;
//и собственно полная информация об объекте procedure TForm3.BitBtn1Click(Sender: TObject); var CurPeople: TPeople; begin CurPeople:=TPeople(Form1.ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]); Edit1.Text:=CurPeople.Name; Edit2.Text:=IntToStr(CurPeople.Workshop); SpinEdit1.Text:=IntToStr(CurPeople.Range); end;
18192123
10.05.2008 21:48
У меня появился ещё один вопрос.. Пусть на Form3 мы получили подробную информацию об объекте и теперь хотим внести здесь изменения, которые должны соответственно отразиться на этом объекте в ListBox1.. Ну и собственно вопрос: покажите пожалуста, как внести изменения в уже существующий объект?
volvo
10.05.2008 22:56
Цитата
как внести изменения в уже существующий объект?
Точно так же: получаешь сам объект и изменяешь его:
procedure TForm3.BitBtn2Click(Sender: TObject); var curPeople: TPeople; begin CurPeople := TPeople(Form1.ListBox1.Items.Objects[Form1.ListBox1.ItemIndex]);
CurPeople.Name := Edit1.Text; // в Edit1 и остальных контролах должны быть уже исправленные значения CurPeople.Workshop := StrToInt(Edit2.Text); CurPeople.Range := StrToInt(SpinEdit1.Text);
// теперь меняем отображаемое имя, отдельно Form1.ListBox1.Items.Strings[Form1.ListBox1.ItemIndex] := CurPeople.Name; end;
18192123
10.05.2008 23:47
Цитата(volvo @ 10.05.2008 19:56)
Точно так же: получаешь сам объект и изменяешь его: ...
Спасибо большое!!) С этим понятно. Мне вот ещё не совсем ясно про случай с удалением объёкта из списка..Не до чего лучше пока не додумалась:
т.е сделала аналогично редактированию..но строка, хоть и пустая в ListBox-е всё-равно остаётся..И сделать именно удаление соответственно не получается.. Подскажите пожалуста, как должно быть??
volvo
11.05.2008 0:00
Ты не удаляешь строку, и естественно не удаляешь объект TPeople...
В Хелпе сказано:
Цитата(BDS Help)
Call Delete to remove a single string from the list. If an object is associated with the string, the reference to the object is removed as well.
. При этом будет удалена как сама строка из ListBox-а, так и связанный с ней Object...
18192123
12.05.2008 1:08
Здраствуйте. У меня вопрос возник по механизму перетаскивания (технология Drag&Drop)..Например мне нужно перетащить объект из ListBox1 в ListBox2 и можно произвести обратную операцию (при этом из списка источника объект удаляется).. Знаю, что работать нужно со свойствами DragCursor, DragKind,DragMode..и ещё нужны будут обработчики событий OnDragDrop и OnDragOver... Вот только разобраться не могу, для какого ListBox (из 2-x) какой обработчик использовать и какие значения задавать для свойств DragCursor, DragKind,DragMode?
Объясните пожалуста!
volvo
12.05.2008 2:13
Значит, смотри: переносим из ListBox2 (источник) в ListBox1 (приемник)...
И источнику и приемнику назначаем DragMode = dmAutomatic, и у приемника в обработчиках OnDragOver/OnDragDrop делаем:
procedure TForm1.ListBox1DragDrop(Sender, Source: TObject; X, Y: Integer); var currPeople: TPeople; begin if Source = ListBox2 then begin // При удалении строки из источника удаляется и объект, поэтому создаем новый !!! currPeople := TPeople.Create( TPeople(TListBox(Source).Items.Objects[TListBox(Source).ItemIndex]).fName, TPeople(TListBox(Source).Items.Objects[TListBox(Source).ItemIndex]).fWorkshop, TPeople(TListBox(Source).Items.Objects[TListBox(Source).ItemIndex]).fRange ); // Добавляем его в приемник TListBox(Sender).Items.AddObject(currPeople.fName, currPeople as TObject); // Удаляем из источника TListBox(Source).Items.Delete(TListBox(Source).ItemIndex); end end;
procedure TForm1.ListBox1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); begin // разрешаем перетаскивание только если источник - ListBox2, и в нем что-то выбрано Accept := (Source = ListBox2) and (TListBox(Source).ItemIndex >= 0); end;
Вот и все в принципе... Для обратной операции - меняешь в обработчиках источник (я специально сделал так, что изменить надо будет только в одном месте)
18192123
12.05.2008 2:55
Цитата(volvo @ 11.05.2008 23:13)
Вот и все в принципе... Для обратной операции - меняешь в обработчиках источник (я специально сделал так, что изменить надо будет только в одном месте)
Спасибо большое за разъяснения!!))) Теперь разобралась!)
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.