Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Компоненты и классы
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 22.10.2012, 11:24
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию String как имя объекта и ...

Среда разработки: CodeGear, delphi 2010, Windows 7
Исходничек:
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs,DB, StdCtrls, OleCtnrs, DBClient;

type
  TForm1 = class(TForm)
    ClientDataSet1: TClientDataSet;
    ClientDataSet1id: TIntegerField;
    ClientDataSet1LastName: TStringField;
    ClientDataSet1Name: TStringField;
    ClientDataSet1Patronymic: TStringField;
    ClientDataSet1Post: TStringField;
    ClientDataSet1Salary: TFloatField;
    DataSource1: TDataSource;
    ClientDataSet2: TClientDataSet;
    ClientDataSet2id: TIntegerField;
    ClientDataSet2Processor: TStringField;
    ClientDataSet2Cores: TIntegerField;
    ClientDataSet2Memory: TFloatField;
    DataSource3: TDataSource;
    Label1: TLabel;
    ListBox2: TListBox;
    OleContainer1: TOleContainer;
    ListBox1: TListBox;
    OpenDialog1: TOpenDialog;
    Button2: TButton;
    procedure ListBox2Enter(Sender: TObject);
    procedure CreateDataSourceList(lParent: TComponent);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

type
  DataSourceData = record
    Tag: LongInt;
    FieldsCount: integer;
    FieldDisplayLabels: array [0..500] of string[70];
    IsVisible: array [0..500] of boolean;
  end;

var

dsRecord: array [0..99] of DataSourceData;
DataSourceCount: integer;
DataSourceNames: array[0..99] of string;
  Form1: TForm1;

implementation

{$R *.dfm}

procedure Tform1.CreateDataSourceList(lParent: TComponent);
var DS: TDataSource;
i,j,k:integer;
lIndex:integer;
sstring:string;
begin
Listbox2.clear;
DataSourceCount:=0;
for k := 0 to lParent.ComponentCount - 1 do
  if lParent.Components[k] is TDataSource then
  begin
    DataSourceNames[DataSourceCount]:={lParent.Name+'.'+}lParent.components[k].name;
    inc(DataSourceCount);
    ListBox2.Items.Add(lparent.Components[k].name);
  end;

if (ListBox2.Items.Count=0) or (DataSourceCount=0) then exit;

for I := 0 to ListBox2.Items.Count - 1 do
begin
  DS := TDataSource(DataSourceNames[i]);
  k:=i;
  sstring:=DataSourceNames[i]+' '+inttostr(i);
  if Assigned(DS) then k:=i else continue;
  dsRecord[i].Tag:=DS.Tag;
  dsRecord[i].FieldsCount:=0;
  for j := 0 to DS.DataSet.Fields.Count-1 do
  begin
    dsRecord[i].FieldDisplayLabels[dsRecord[i].FieldsCount]:=DS.DataSet.Fields.Fields[j].DisplayLabel;
    inc(dsRecord[i].FieldsCount);
    dsRecord[i].IsVisible[j]:=false;
  end;
end;
end;

procedure TForm1.ListBox2Enter(Sender: TObject);
begin

CreateDataSourceList(form1);
end;

end.

Описание проблемы:
В итоге на форме имеем 2 DataSource с именами DataSource1 и DataSource3.
Вот в этом месте:
Код:
for I := 0 to ListBox2.Items.Count - 1 do
begin
  DS := TDataSource(DataSourceNames[i]);
на первой итерации естественно выбирается DataSource1, НО ПОЧЕМУ ТО в массив здесь:
Код:
for j := 0 to DS.DataSet.Fields.Count-1 do
  begin
    dsRecord[i].FieldDisplayLabels[dsRecord[i].FieldsCount]:=DS.DataSet.Fields.Fields[j].DisplayLabel;

на этой же, первой итерации записываются дисплейлабелы ВТОРОГО DataSource, то есть DataSource3.
А на второй итерации при выборе DataSource3 на строчке
Код:
  for j := 0 to DS.DataSet.Fields.Count-1 do
выскакивает ошибка Access violation.

Подскажите в чем дело? Я как то не правильно присваиваю переменной DS конкретный DataSource?
Ответить с цитированием
  #2  
Старый 22.10.2012, 11:37
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от одинадцатый
Среда разработки: CodeGear, delphi 2010, Windows 7
Исходничек:
Код:
.....
var
.....
DataSourceNames: array[0..99] of string;
.....

Описание проблемы:
В итоге на форме имеем 2 DataSource с именами DataSource1 и DataSource3.
Вот в этом месте:
Код:
for I := 0 to ListBox2.Items.Count - 1 do
begin
  DS := TDataSource(DataSourceNames[i]);
на первой итерации естественно выбирается DataSource1,
Как это ты так лихо превращаешь строку в TDataSource?
Цитата:
Сообщение от одинадцатый
А на второй итерации при выборе DataSource3 на строчке
Код:
  for j := 0 to DS.DataSet.Fields.Count-1 do
выскакивает ошибка Access violation.
Не удивительно. Ты же к строке обращаешься как к TDataSource. Это ну никак не совместимые типы.
Ответить с цитированием
  #3  
Старый 22.10.2012, 11:38
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Я такой способ обращения где то нагуглил...
Ну первый DataSource же увидел таким способом...
Ответить с цитированием
  #4  
Старый 22.10.2012, 11:41
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

А можно ли как-нибудь обратиться к объекту используя его имя как строку? Или может есть какой-то другой Идентификатор объекта на форме, фрейме?
Вообще такой способ нужен для того как раз, что бы из фрейма считать список DataSource на форме, на которой лежит этот самый фрейм и забить его в ListBox.
Ответить с цитированием
  #5  
Старый 22.10.2012, 11:43
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

ComponentByName наверное.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #6  
Старый 22.10.2012, 11:44
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

Код:
function FindComponent(const AName: string): TComponent;
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
Этот пользователь сказал Спасибо NumLock за это полезное сообщение:
одинадцатый (22.10.2012)
  #7  
Старый 22.10.2012, 11:57
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Сделал так:
Код:
DS := FindComponent(DataSourceNames[i]) as TDataSource;

Но конечная цель не достигнута. Дело в том что если так искать компонент с формы, на которой ищем компонент то всё функционирует нормально, а если этим методом искать из фрейма то, по всей видимости, он ищет на самом фрейме, а не на форме, на которой лежит фрейм.
Как быть?
Ответить с цитированием
  #8  
Старый 22.10.2012, 12:02
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Так а ты у кого этот метод то вызываешь?
Вызовешь у фрейма, будет искать на фрейме, на форме - на форме.
И еще, проверку на nil добавь, а то AV 00000000 получишь.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
одинадцатый (22.10.2012)
  #9  
Старый 22.10.2012, 12:11
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

А разве строка
Код:
if Assigned(DS) then k:=i else continue;
не есть проверка на nil?

Дак с формы не хотелось бы вызывать(
Надо сделать фрейм как можно более... автономным что ли. То есть что бы в юнит, на которую он натянут пришлось добавлять как можно меньше кода.
Ответить с цитированием
  #10  
Старый 22.10.2012, 12:33
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Цитата:
Сообщение от одинадцатый
А разве строка
Код:
if Assigned(DS) then k:=i else continue;
не есть проверка на nil?

Я на эту смотрел, верхние посты по диагонали читал
Код:
DS := FindComponent(DataSourceNames[i]) as TDataSource;

Я бы ссылки на датасеты сложил бы в ObjectList (а лучше в TStrings, он как ассоциативный может работать), оттуда брал бы их, чтоб не изгаляться
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
одинадцатый (22.10.2012)
  #11  
Старый 22.10.2012, 12:37
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от одинадцатый
А разве строка
Код:
if Assigned(DS) then k:=i else continue;
не есть проверка на nil?
Да, Assigned это проверка на nil.
Цитата:
Сообщение от одинадцатый
Дак с формы не хотелось бы вызывать(
Надо сделать фрейм как можно более... автономным что ли. То есть что бы в юнит, на которую он натянут пришлось добавлять как можно меньше кода.
Parent у фрейма даст элемент управления на котором лежит фрейм.
GetParentForm найдёт форму на которой располагается фрейм.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
одинадцатый (22.10.2012)
  #12  
Старый 22.10.2012, 13:26
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Большое спасибище!
Сделал в итоге как-то так:
Код:
DS := GetParentForm(self).Components[DataSourceIndexes[i]] as TDataSource;
Ответить с цитированием
  #13  
Старый 22.10.2012, 19:56
одинадцатый одинадцатый вне форума
Новичок
 
Регистрация: 16.04.2009
Сообщения: 95
Репутация: 10
По умолчанию

Ой, а подскажите еще: нужно что бы при FormCreate на которой лежит фрейм вызывался метод фрейма. Можно ли это сделать, опять же, не прибегая к добавлению кода в юнит формы?

Сделал через OnEnter фрейма, но это малёха не то.
Ответить с цитированием
  #14  
Старый 29.10.2012, 17:58
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от одинадцатый
Ой, а подскажите еще: нужно что бы при FormCreate на которой лежит фрейм вызывался метод фрейма. Можно ли это сделать, опять же, не прибегая к добавлению кода в юнит формы?
Можно в модуле фрейма переопределить (override) конструктор или метод Loaded.
Цитата:
Сообщение от одинадцатый
Сделал через OnEnter фрейма, но это малёха не то.
Это явно не то Событие OnEnter срабатывает всякий раз когда фрейм активизируется (получает фокус).
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 14:58.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter