Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 5
Всего онлайн: 5
Зарегистрировано юзеров: 6362
Комментариев на сайте: 645
Новый юзер: Pseulairrerve



Последние комментарии
c
Aqel прокомментировал "Урок 71 - Работа с сжатыми файлами":
GZip псевдоархив, на мой вопрос тоже не отвечают, как распаковать отдельные файлы/папки...
Pingitrus прокомментировал "Урок 71 - Работа с сжатыми файлами":
Есть еще кто нибудь живой на этом сайте, кто сможет помочь? Так то все работает, zip и rar распаковывает, но у меня есть файл dat который сжат GZip, почему то его не удается распаковать или так не получится так как этот файл не является архивом или является?)) пишет ошибку что неверная функция



Мы в соцсетях
c
Delphi
Массив из элементов - как с ним бороться или как с ним дружить

Здесь информация о:
Создание массива
Работа с массивом
Заполнение массива во время работы программы
Использование объектов, созданных во время проектирования формы
Получение номера элемента массива в процедуре обработки события

Создание массива

Ну тут всё просто. Объявляем

	var Arr: array[1..n] of TEdit; //к примеру
	
и можно работать! Так-же можно объявить и многомерный и даже динамический массив.
	var Arr1: array [1..7, 1..5] of TEdit;
	  var Arr2: array of TEdit;
	  
Работа с массивом Опасно не падать, а биться о землю, скалы и другие твёрдые предметы. (альпинистско - парашютистская мудрость).

Итак, с созданным массивом надо что-то делать. Ну, для начала, чем-то заполнить. А, в отличие от чисел и строк, которые задаются в виде констант и выражений, объекты, помещаемые в наш массив, нужно создавать. Т.е. если мы описали
	var ByteArr: array[1..2] of byte;
	
то можно написать
	ByteArr[1]:=3;
	
Что же писать после := для массива из объектов? Их же как-то создать надо? (из форума) Здесь у нас есть два пути - создавать объекты с помощью Create во время работы программы или использовать объекты, созданные во время проектирования формы. Каждый путь имеет своих путников (почти по Мао - дзе -дуну).

Заполнение массива во время работы программы.

Этот способ удобен в том случае, когда нужно создать много объектов или число и свойства их заранее неизвестны (в одной программе мне нужно было разбросать по экрану случайным образом все буквы алфавита, а потом еще что-то с ними делать). Действия довольно стандартны. В цикле создаём объекты и присваиваем их элементам массива с помощью следующей конструкции.
	   For i:=<начальное значение> to<конечное значение> do begin
	    <имя массива>[i]:=<имя класса>.Create(Self);
	    <имя массива>[i].Parent:=Self; //за объект ответит форма, на которой он создан
	    //<присвоение других свойств - по необходимости>
	   end; 
	   
После этих действий у нас на форме появятся необходимые компоненты, к которым можно обращаться, используя индекс массива, например так: <имя массива>[i]. В следующем примере по щелчку по кнопке будет предложено ввести требуемое количество полей, которое и будет создано в центре формы.
	procedure TForm1.Button1Click(Sender: TObject);
	var c: string;
	     i,n:integer;
	begin
	 c := InputBox('Введите','число:','7');
	 try
	  n := StrToInt(c);
	 except
	  on EConvertError do ShowMessage('Что-то не срослось...');
	 end;//Try
	 SetLength(Arr2, n);
	  for i:=0 to n-1 do begin
	   Arr2[i] := TEdit.Create(Self);
	   Arr2[i].Parent := Self;
	   //Эти две строки создают компонент, далее произвольные действия.
	   Arr2[i].Top:=i*Arr2[i].Height;
	   Arr2[i].Left:=(ClientWidth-Arr2[i].Width)div 2 ;
	   Arr2[i].Text:='Поле '+IntToStr(i);
	  end;//for
	 Button1.Visible:=FormArraylse;
	end;
	
При заполнении многомерного массива компонентов таким способом никаких подводных камней нет - организуем несколько циклов.
	procedure TForm1.FormCreate(Sender: TObject);
	var i, j: byte;
	begin
	  for i:=1 to 7 do
	   for j:=1 to 5 do begin
	   Arr1[i,j]:=TEdit.Create(Self);
	   Arr1[i,j].Parent := Self;
	  //Эти две строки создают компонент, далее произвольные действия.
	   Arr1[i,j].Top:=(i-1)*Arr1[i,j].Height;
	   Arr1[i,j].Left:=(j-1)*Arr1[i,j].Width;
	   Arr1[i,j].Text:='Поле '+ IntToStr(i*j);
	                        end;//for j
	  end;
	  
Результат - таблица из Edit`ов, с индексированными ячейками.

Таким образом можно создать даже массив из форм. Разместим форму для создаваемого массива в Unit2.
	uses Unit2;//задействуем его
	var FormArray: array [1..5] of TForm2;
	 //Теперь нам нужно создать массив FormArray, разместить его на главной форме и заполнить его изображениями.
	 //Делать это лучше не во время создания формы, а например во время активации.
	 procedure TForm1.FormActivate(Sender: TObject);
	 var i: byte;
	 begin
	  for i:=1 to 5 do begin
	   FormArray[i]:=TForm2.Create(Self);
	   FormArray[i].Parent:=Self;// Создание формы
	   // и что-то с ней делаем
	   FormArray[i].Visible:=True; //Вывод формы на экран
	   FormArray[i].Top:=i*50//Выбор места расположения (здесь ставятся ваши значения)
	                       end;//for
	 end;
	 
Данный способ подойдёт тем, кто не боится большого кода - ведь все требующиеся свойства создаваемых объектов придётся определять вручную и представляет себе как расположатся на форме созданные объекты. В противном случае придётся потратить немало времени на подбор различных свойств. Впрочем, есть и другой путь...

Использование объектов, созданных во время проектирования формы

Раньше как было - код, компиляция, запуск, а лицо невесты можно увидеть только после свадьбы. Сейчас всё намного гуманнее. Есть проект, в нём форма, а на форму ставишь компоненты. И почему бы их не «объединить» в массиве?

Итак, на вашу форму во время проектирования помещено несколько Edit`ов, и вы хотите присвоить их элементам массива Arr. Можно конечно написать Arr[1]:=Edit1; Arr[2]:=Edit2; и т.д., но это как-то не хорошо:(. Значительно лучше просмотреть существующие компоненты и, если компонент - TEdit, поместить его в массив. Вот так:
	   procedure TForm1.FormCreate(Sender: TObject);
	   var i, j: byte;
	   begin
	    j:=1;
	    for i:=0 to ComponentCount-1 do //просматриваем
	     if (Components[i] is TEdit) then begin //если подходит
	      Arr[j]:=(Components[i] as TEdit);//помещаем
	      j:=j+1;
	                                                   end;//if
	   // а теперь посмотрим, в каком порядке они попали в массив
	    for i:=1 to 5 do
	     Arr[i].Text:='Arr['+IntToStr(i)+']';
	   end;
	   
На самом деле, такой способ не намного менее коряв, чем присваивание «напрямую». В массив попадут все Edit`ы, присутствующие на форме, причём в порядке их создания. А как быть, если хочется поместить их не все и в своём порядке? Очевидно, надо указать где-то, кого и в каком порядке мы хотим видеть принятым в члены массива. Под это где-то хорошо заточено свойство Tag - есть у любого компонента, целое число, используется «без вопросов». На этапе проектирования укажите в Tag`е, на каком месте в массиве вы хотите видеть данный компонент. Затем используйте следующий код:
	   procedure TForm1.FormCreate(Sender: TObject);
	   var i: byte;
	   begin
	    for i:=0 to ComponentCount-1 do
	     if Components[i].Tag>0 then //Tag больше нуля
	      Arr[Components[i].Tag]:=(Components[i] as TEdit);//Значит клиент наш!
	   end.
	   
Смотрится значительно лучше. Для организации двух массивов пронумеруйте (протагируйте) компоненты, предназначенные для помещения в первый из массивов как обычно, а во второй, например, с десяти (или с любого другого числа, желательно с круглого - проще считать). Затем напишите что нибудь вроде
	var Arr1: array [1..3] of TEdit;
	    Arr2: array [1..3] of TEdit;
	   procedure TForm1.FormCreate(Sender: TObject);
	   var i: byte;
	   begin
	    for i:=0 to ComponentCount-1 do
	     if Components[i].Tag>0 then 
	      if Components[i].Tag<10 then
	       Arr1[Components[i].Tag]:=(Components[i] as TEdit)
	                                          else
	       Arr2[Components[i].Tag-10]:=(Components[i] as TEdit);
	    end;
	    
При создании многомерного массива используем тот-же приём - немного поработаем с тагом. Edit`ы протагированы 11.12.13.21.22.23:
	var Arr1: array [1..3,1..2] of TEdit;

	procedure TForm1.FormCreate(Sender: TObject);
	var i, j: byte;
	begin
	 for i:=0 to ComponentCount-1 do
	  if Components[i].Tag>0  then
	   Arr1[Components[i].Tag mod 10,Components[i].Tag div 10 ]:=(Components[i] as TEdit);
	//убедимся,  что всё получилось
	for i:=1 to 3 do
	 for j:=1 to 2 do
	  arr1[i,j].text := IntToStr(i)+' '+IntToStr(j);
	end;
	
Если вам надо создать два массива из разных компонентов, то не напрягайтесь со сложным извлечением индекса из тага, а организуйте проверку типа.
	var ArrE: array [1..3] of TEdit;
	     ArrC: array [1..8] of TComboBox;
	procedure TForm1.FormCreate(Sender: TObject);
	var i: byte;
	begin
	for i:=0 to ComponentCount-1 do
	if Components[i].Tag>0 then begin
	 if (Components[i] is TEdit)
	  then ArrE[Components[i].Tag]:=(Components[i] as TEdit);
	 if (Components[i] is TComboBox)
	  then  ArrC[Components[i].Tag]:=(Components[i] as TComboBox);
	                                          end;//if
	end;
	
При необходимости создания более сложных массивов - комбинируйте эти способы.

Лирическое отступление. Присвоение объектов происходит не совсем так, как у «обычных» переменных. Если у переменных присваивние не отоджествляет переменные т.е. после a:=3;b:=a;a:=5; в переменной b находится 3, а не 5, то с объектами всё наоборот. После ArrL[1]:=Label1; ArrL[1] и Label1 cтановятся одним объектом, и например ArrL[1].Caption:='Вася'; изменит надпись Label1. В некоторых языках для разруливания этой ситуации для блондинок введён специальный оператор присваивания объектов (Vb, set). Ну мы то, Дельфийцы, народ умный...

Получение номера элемента массива в процедуре обработки события

Чтобы узнать индекс элемента массива, с которым произошло событие придётся придётся сравнить переменную Sender, использующуюся обработчиком события, со всеми элементами массива и при совпадении извлечь индекс. Похоже только так... Впрочем, может кто знает и лучший способ.
	var ArrB: array [1..3] of TButton;
	    n: byte;// Здесь будет храниться индекс
	procedure TForm1.Clicker(Sender:TObject);
	var i: byte;
	begin
	 for i:=1 to 3 do
	  if Sender = ArrB[i] then n:=i;
	  //находим индекс компонента, к которому относится событие
	 ShowMessage('Нажата кнопка '+IntToStr(n)); //что-то делаем
	end;

	procedure TForm1.FormCreate(Sender: TObject);
	var i: byte;
	begin
	 for i:=0 to ComponentCount-1 do
	  if Components[i].Tag > 0
	   then ArrB[Components[i].Tag]:=(Components[i] as TButton);//наполняем массив
	 for i:=1 to 3 do
	  ArrB[i].OnClick:=Clicker; //устанавливаем обработчик
	end;


Вот и всё, Удачи!

Источник: www.thedelphi.ru
Автор: Савельев Александр
Опубликовано: 29 Марта 2015
Просмотров:


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.