| 
| 
 | Вопрос # 1 866/ вопрос открыт / | 
 |  Доброго времени суток, уважаемые эксперты!
 Создаю некоторое количество компонент run-time (по количеству файлов DBF в папке): dataset, datasource, dbedit, tabsheet, после создания подключаю и всё нормально, т.е. получается несколько вкладок, на каждой из которых dbedit со своим файлом DBF.
 
 Далее мне нужно обратиться к одной из таблиц, к конкретной записи. Как мне найти тот созданный компонент, т.е. как мне узнать его имя.
 
 Пытаюсь запоминать имена во время создания, но что-то не выходит пока.
 Приложение:Переключить в обычный режим ListFileDir(Form1.Edit1.Text,Form1.ListBox1.Items);   for i:=0 to Form1.ListBox1.Count-1 do  begin    TabSheetMain:=TTabSheet.Create(Form1);    HalcyonDataSetArray[i]:=THalcyonDataSet.Create(Self);    HalcyonDataSetMain:=THalcyonDataSet.Create(Form1);    DBGridMain:=TDBGrid.Create(Form1);    HalcyonNavigatorMain:=THalcyonNavigator.Create(Form1);    DataSourceMain:=TDataSource.Create(Form1);     Form1.ProgressBar1.Position:=i;     with TabSheetMain do    begin      PageControl:=PageControl2;      Parent := PageControl2;      Caption := Form1.ListBox1.Items[i];    end;     with HalcyonDataSetMain do    begin      Active:=false;      DatabaseName:=Form1.Edit1.Text;      TableName:=Form1.ListBox1.Items.Strings[i];      TranslateASCII:=False;      ReadOnly:=True;      CN[i]:=HalcyonDataSetMain.Name;    end;     with DataSourceMain do    begin      DataSet:=HalcyonDataSetMain;    end;     with DBGridMain do    begin      Parent := PageControl2.Pages[i];      Align:=alClient;      DataSource:=DataSourceMain;    end;     with HalcyonNavigatorMain do    begin      Parent := PageControl2.Pages[i];      Align:=alBottom;      DataSource:=DataSourceMain;    end;     HalcyonDataSetMain.Active:=true;     Form1.PageControl2.ActivePageIndex:=i;    Application.ProcessMessages;  end;
|  |   Вопрос задал: 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) (статус: Посетитель), 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]:Программирование вообще потенциально опасное занятие  Самая безопасная ошибка - это та, на которую ругается компилятор. Но это уже оффтоп |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |