Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 866

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!

Создаю некоторое количество компонент run-time (по количеству файлов DBF в папке): dataset, datasource, dbedit, tabsheet, после создания подключаю и всё нормально, т.е. получается несколько вкладок, на каждой из которых dbedit со своим файлом DBF.

Далее мне нужно обратиться к одной из таблиц, к конкретной записи. Как мне найти тот созданный компонент, т.е. как мне узнать его имя.

Пытаюсь запоминать имена во время создания, но что-то не выходит пока.

Приложение:
  1. ListFileDir(Form1.Edit1.Text,Form1.ListBox1.Items);
  2.  
  3. for i:=0 to Form1.ListBox1.Count-1 do
  4. begin
  5. TabSheetMain:=TTabSheet.Create(Form1);
  6. HalcyonDataSetArray[i]:=THalcyonDataSet.Create(Self);
  7. HalcyonDataSetMain:=THalcyonDataSet.Create(Form1);
  8. DBGridMain:=TDBGrid.Create(Form1);
  9. HalcyonNavigatorMain:=THalcyonNavigator.Create(Form1);
  10. DataSourceMain:=TDataSource.Create(Form1);
  11.  
  12. Form1.ProgressBar1.Position:=i;
  13.  
  14. with TabSheetMain do
  15. begin
  16. PageControl:=PageControl2;
  17. Parent := PageControl2;
  18. Caption := Form1.ListBox1.Items[i];
  19. end;
  20.  
  21. with HalcyonDataSetMain do
  22. begin
  23. Active:=false;
  24. DatabaseName:=Form1.Edit1.Text;
  25. TableName:=Form1.ListBox1.Items.Strings[i];
  26. TranslateASCII:=False;
  27. ReadOnly:=True;
  28. CN[i]:=HalcyonDataSetMain.Name;
  29. end;
  30.  
  31. with DataSourceMain do
  32. begin
  33. DataSet:=HalcyonDataSetMain;
  34. end;
  35.  
  36. with DBGridMain do
  37. begin
  38. Parent := PageControl2.Pages[i];
  39. Align:=alClient;
  40. DataSource:=DataSourceMain;
  41. end;
  42.  
  43. with HalcyonNavigatorMain do
  44. begin
  45. Parent := PageControl2.Pages[i];
  46. Align:=alBottom;
  47. DataSource:=DataSourceMain;
  48. end;
  49.  
  50. HalcyonDataSetMain.Active:=true;
  51.  
  52. Form1.PageControl2.ActivePageIndex:=i;
  53. Application.ProcessMessages;
  54. end;


Anton (w) Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Anton (w) (статус: Посетитель)
Вопрос отправлен: 1 сентября 2008, 09:19
Состояние вопроса: открыт, ответов: 3.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, iamantbk!
В целом в задач подобного типа есть классическое решение. Вначале создаётся класс, который заключает в себя нужные компоненты (в Вашем случае - dataset, datasource, dbedit). Для этого класса создаётся конструктор, который умеет все настроить и создать сам. Потом на основе класса TList или TCollection создается массив подобных классов. Против обычных массивов главное приимущество - возможность удалить произвольный элемент или поменять местами без значительных усилий.
В этом, конкретном случае, я бы использовал фреймы. То есть, создал фрейм, на котором есть все нужные элементы и добавил ему метод "загрузись с файла".
на основоной форме ставим TTabControl и загрузка новой вкладки - это просто добавление оной и размещения фрейма. А далее думаю понятно - за пределы фрейма можно вынести нужные методы/свойства и работать будет очень удобно.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 1 сентября 2008, 10:09

Ответ #2. Отвечает эксперт: ANBsoft

Здравствуйте, iamantbk!
Добавлю к предыдущему оратору применительно к Вашему вопросу.
1)Можно задавать имя компонента при его создании, а потом получать к нему доступ через FindComponent.
2)Лучше будет создавать массив, связанный список или коллекцию (как указано выше) нужных Вам объектов, тогда доступ к ним можно будет получить по индексу массива.
Первый способ быстрее в реализации, второй потребует больше усилий, но даст больше возможностей в управлении объектами.

Ответ отправил: ANBsoft (статус: Студент)
Время отправки: 1 сентября 2008, 11:48

Ответ #3. Отвечает эксперт: Мережников Андрей

Здравствуйте, iamantbk!
В тех случаях когда мне надо создать объект в runtime и запомнить его, для обращения к нему, я использую TStringList. После создания объект добавляю к списку AddObject(<имя для обращения>, <добавленный объект>). Когда мне надо обратиться к объекту, делаю так:(t.Objects[t.IndexOf('имя')]) as <класс объекта>...

Ответ отправил: Мережников Андрей (статус: Абитуриент)
Время отправки: 1 сентября 2008, 18:15


Мини-форум вопроса

Всего сообщений: 7; последнее сообщение — 2 сентября 2008, 05:00; участников в обсуждении: 3.
Anton (w)

Anton (w) (статус: Посетитель), 1 сентября 2008, 09:28 [#1]:

В принципе сам решил использованием массива компонент.

А как Вы поступаете в таких случаях (поступили бы)?
Вадим К

Вадим К (статус: Академик), 1 сентября 2008, 19:06 [#2]:

to Мережников Андрей
Этот способ имеет как минимум два огромных минуса.
Во первых, надо всегда приводить тип. И если имя типа поменялось и о рефакторинге не в курсе, то для большого проекта эта задача превращается в ужас. К тому же есть большой шанс сделать приведение "ни к тому типу" и получить красивую ошибку на этапе выполнения.
Вторая особенность, о которой Вы можете не знать, это то, что TStringList НЕ ВЫЗЫВАЕТ деструкторов по удалению как отдельных строк, так и всего TStringList - а это черевато утечками памяти и другими неприятностями.
Лучше просто написать обвязку (тоесть свой спец класс) и не морочить голову.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 1 сентября 2008, 19:25 [#3]:

Для удаления объектов я использую t.Objects(...).free.
А получить красивую ошибку можно и множеством других способов :-)
Вадим К

Вадим К (статус: Академик), 1 сентября 2008, 19:48 [#4]:

Получить можно, но зачем?
В Вашем примере можно получить ещё одну красивейшею ошибочку.
Дело в том, что при использовании методов Assign/AddStrings указатели на объекты копируются. Сами объекты не копируются.
То есть, скопировав с одного TstringList в другой, мы имеем две ссылки на объект. Главное веселье начинается, когда мы пытаемся дважды удалить объект:)
То есть, в умелых руках это хорош инструмент, но для новичка он ужасен (он не может уследить за всеми перемещениями в памяти) и для более опытного тоже плохой метод -он понимает все глюки, которые могут вылезти и просто берёт и делает объёртку.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 1 сентября 2008, 20:13 [#5]:

to Вадим К
Ошибку можно допустить при реализации любого метода решения задачи. Было бы желание :-). Спрашивается, зачем мне два списка объектов, чтобы из одного копировать в другой? Ваш вариант решения (с обёртками)мне нравится, но он требует определенной подготовки. Поэтому я предложил свой вариант. Этот вариант я реализовал как-то в одной из задач - все работает до сих пор прекрасно.
Вадим К

Вадим К (статус: Академик), 1 сентября 2008, 22:09 [#6]:

to Мережников Андрей
Я не говорю что Ваш вариант нерабочий. Он просто потенциально опасный. Конечно, можно упасть и на ровной трассе, но это не повод ходить по босиком по битому склу, аккуратно выбирая место, что бы ступить.
А копировать - это я просто привожу вполне реальную подзадачу.
Галочка "подтверждения прочтения" - вселенское зло.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 2 сентября 2008, 05:00 [#7]:

Программирование вообще потенциально опасное занятие :-) Самая безопасная ошибка - это та, на которую ругается компилятор. Но это уже оффтоп

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:58
Выполнено за 0.03 сек.