Лекция 23. Многомерные массивы

В этой лекции вы познакомитесь с многомерными массивами и с сетками ввода. Изучите способы обработки многомерных массивов, познакомитесь со свойствами сеток. Научитесь в сетке создавать маску для ввода текста.

Мы уже научились работать со статическими и с динамическими массивами, однако все эти массивы были одномерными. Посмотрите пример:

a : array [0..9] of String;

Здесь мы объявили массив строк из 10 элементов. Этот массив можно представить в виде таблицы с десятью колонками и одной строкой:

Таблица 23.1. Представление одномерного массива
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru

А как быть, если нам нужно обработать таблицу с более чем одной строкой, например такую:

Таблица 23.2. Представление двухмерного массива
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru
Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru Лекция 23. Многомерные массивы - student2.ru

Тут на помощь приходят многомерные массивы. Чтобы объявить массив из 10 колонок и 5 строк, мы делаем такое объявление:

a : array [0..4, 0..9] of string;

Как видите, вначале задается диапазон индексов строк, затем через запятую диапазон индексов столбцов. Работа с такими массивами ничем не отличается от одномерных массивов, только в качестве индекса придется указывать сразу два элемента – строку и столбец. Например, код

a[1][0] := 'Строка';

присвоит строку "Строка" второй строке первого столбца (не забывайте, что нижним индексом мы объявили ноль). Можно воспользоваться и другим вариантом адресации:

a[1, 0] := 'Строка';

Оба эти варианта идентичны и сделают одно и то же – присвоят второй строке и первому столбцу строку "Строка". В дальнейшем мы можем вызвать эту строку, например, таким образом:

ShowMessage(a[1,0]);

Однако, для Delphi двухмерные массивы – не предел. Можно объявлять и трехмерные, и четырехмерные, и сколько угодно мерные, вот только обрабатывать такие массивы будет сложней с каждой новой размерностью. Давайте посмотрим пример присвоения всем элементам одномерного массива какой-то строки:

var

a : array [0..9] of string;

i : Integer;

s : string;

begin

for i := 0 to 9 do begin

a[i] := 'Строка №'+IntToStr(i);

s := s + a[i]+#13+#10;

end; //for

ShowMessage(s);

end; //конец процедуры

В данном примере, с помощью цикла for мы в элемент массива a[i] присваивали строку "Строка №0", причем номер строки менялся при каждом проходе цикла. Затем полученную строку мы добавляли в строковую переменную s, также добавляли и символы перехода на новую строку, чтобы в конце вывести все это с помощью ShowMessage(). Попробуйте сделать новое приложение с одной кнопкой на форме, и присвойте этот код обработке кнопки.

Теперь рассмотрим такой же пример, но уже для двухмерного массива:

var

a : array [0..9, 0..4] of string;

i,j : Integer;

s : string;

begin

for i := 0 to 9 do

for j := 0 to 4 do begin

a[i, j] := 'Строка №'+IntToStr(i)+

' Столбец №'+IntToStr(j);

s := s + a[i,j]+#13+#10;

end; //for 2

ShowMessage(s);

end; //конец процедуры

Как видите, теперь нам приходится использовать два цикла for – один для строк, и один для столбцов. Вначале выполняется цикл для первой строки, и управление передается на вложенный цикл. Там происходит обработка массива от первого до последнего столбца первой строки.

Потом программа возвращается в первый цикл, прибавляет к счетчику единицу и происходит такая же обработка для второй строки, от первого до последнего столбца. И так далее, пока не будет обработан последний столбец последней строки!

Трехмерные массивы обрабатывать еще сложней. Такая таблица будет выглядеть уже как кубическая:

Лекция 23. Многомерные массивы - student2.ru

Рис. 23.1. Представление трехмерного массива

Объявляться такой массив будет уже так:

a : array [0..9, 0..4, 0..7] of string;

И для его циклической обработки потребуется уже три цикла for! Как будет выглядеть четырехмерный массив, графическим образом вообще невозможно описать. Несмотря на то, что у вас есть возможность работать хоть с десятимерным массивом, надобность более, чем в трехмерном в практике программиста почти не встречается, а чаще всего приходится работать с одно- и двухмерными массивами.

Сетка строк StringGrid

Теперь на практике познакомимся с сеткой строк, похожей на ту, что используется в файлах MS Excel. Создайте новое приложение, установите на форму сетку StringGrid с вкладки компонентов Additional. Рядом находится еще сеточка DrawGrid. Разница между ними небольшая, но первую используют чаще. Сетка StringGrid самостоятельно прорисовывает данные в ячейках, при использовании сетки DrawGrid эти данные придется прорисовывать самостоятельно. Сетку DrawGrid обычно используют для прорисовки графики, и нужда в ней возникает намного реже, чем в StringGrid.

Как видите, сетка StringGrid очень похожа на ту, что вы видели в MS Excel. Пока еще она пуста. Выделите ее и посмотрите на свойства.

BorderStyle отвечает за стиль обрамления. Может иметь только два значения – с обрамлением и без него.

ColCount – количество колонок в сетке. По умолчанию их 5.

DefaultColWidth – ширина колонок по умолчанию. К сожалению, всем колонкам устанавливается одинаковая ширина. Однако во время работы программы ширину каждой колонки можно будет изменить программно.

DefaultDrawing – прорисовка данных по умолчанию. Если стоит True, то компонент сам будет отображать введенные данные, иначе это придется делать программисту.

DefaultRowHeight – высота строк по умолчанию. Установлено 24 пикселя, но этот размер великоват, поэтому строки получаются такими высокими.

FixedCols – количество фиксированных колонок. Они выделяются серым цветом, и всегда первые. Это свойство можно назвать заголовком строк. Практически не бывает необходимости делать более одной такой колонки. По умолчанию как раз одна колонка и есть, попробуйте сделать две, а затем верните одну.

FixedRows – количество фиксированных строк. По умолчанию тоже одна, и работает также, как и FixedCols. Как правило, эта строка служит заголовком колонок.

GridLineWidth – толщина разделительных линий. Попробуйте поставить ноль – линии исчезнут. Верните единицу.

Options – самое главное свойство компонента. Оно содержит много настроек, которые раскроются, если щелкнуть по плюсу слева от названия свойства. Эти дополнительные свойства имеют следующие назначения:

  • goFixedVertLine – рисовать ли вертикальные линии у фиксированных ячеек? По умолчанию True.
  • goFixedHorzLine – прорисовка горизонтальных линий у фиксированных ячеек.
  • goVertLine – прорисовка вертикальных линий у всех остальных (нефиксированных) ячеек.
  • goHorzLine – прорисовка горизонтальных линий у нефиксированных ячеек.
  • goRangeSelect – разрешение выделять несколько ячеек. Не работает, если включен элемент goEdit.
  • goDrawFocusSelect – разрешено выделять ячейку, которая находится в фокусе ввода.
  • goRowSizing – разрешено изменять высоту строки перетаскиванием мышью.
  • goColSizing – разрешено изменять ширину колонки перетаскиванием мышью.
  • goRowMoving – можно ли мышью перемещать строки на другое место.
  • goColMoving – можно ли мышью перемещать колонки на другое место.
  • goEditing – можно ли редактировать сетку? То есть, вводить данные с клавиатуры. Игнорируется, если включен элемент goRowSelect.
  • goTabs – можно ли переключаться на другие ячейки с помощью клавиши <Tab>.
  • goRowSelect – выделяется вся строка. Если равно False, то только одна ячейка.
  • goAlwaysShowEditor – если True, то редактировать ячейку можно сразу при выделении. Если False, то для редактирования нужно нажать <Enter> или <F2>.
  • goThumbTracking – разрешена ли прорисовка данных в ячейках при прокрутке. Если нет, то данные будут обновлены после прокрутки.

RowCount – количество строк в сетке.

С остальными свойствами вы уже знакомы по прошлым компонентам, здесь они практически ничем не отличаются.

Итак, приступим к примеру. Мы уже говорили, что по умолчанию дается слишком большая высота строк, уменьшите ее до 16 (свойство DefaultRowHeight). У нас должно быть 5 строк и 5 колонок, причем фиксированными будут по одной колонке и одной строке. Далее, пользователь должен иметь возможность вводить данные в ячейки, поэтому в разделе Options в свойстве goEditing установим True.

Теперь создаем для формы событие onShow, и вписываем следующий код:

begin

//заполняем значениями первую колонку:

StringGrid1.Cells[0,1]:= 'Иванов';

StringGrid1.Cells[0,2]:= 'Петров';

StringGrid1.Cells[0,3]:= 'Николаев';

StringGrid1.Cells[0,4]:= 'Бонд';

//заполняем значениями первую строку:

StringGrid1.Cells[1,0]:= 'Год рожд.';

StringGrid1.Cells[2,0]:= 'Место рожд.';

StringGrid1.Cells[3,0]:= 'Прописка';

StringGrid1.Cells[4,0]:= 'Семейное положение';

//меняем ширину колонок

StringGrid1.ColWidths[4]:= 120;

StringGrid1.ColWidths[3]:= 90;

StringGrid1.ColWidths[2]:= 90;

end;

Как видите, обращение к отдельным ячейкам здесь точно такое, как к двухмерному массиву. Первым индексом служит строка, вторым – колонка. Нумерация индексов начинается с нуля, поэтому верхняя левая ячейка будет иметь индекс [0, 0].

Свойство ColWidths[i] устанавливает ширину колонки с индексом i.

Сохраните проект, скомпилируйте его и посмотрите результат. Если ваша сетка слишком маленькая или наоборот, слишком большая, то измените ее размер, чтобы все колонки умещались в сетке.

Улучшим наш пример, добавив маску для ввода даты к столбцу "Год рождения". Делается это совсем просто – выделяете сетку, переходите на вкладку Events и генерируете событие onGetEditMask. Это событие происходит, когда пользователь редактирует сетку. Там вписываете только одну строку:

if ACol=1 then value := '99.99.9999 г.'

Если вы посмотрите на параметры этого события, то увидите, что в него передаются такие параметры, как ACol и ARow. Это – индекс текущей колонки и текущей строки. Параметр Value содержит текст маски. То есть, если пользователь редактирует колонку с индексом 1 – это вторая колонка, где указывается год рождения, мы устанавливаем маску ввода даты.

Как видите, работа с сеткой не такая уж сложная. Принцип работы такой сетки заключается в том, что вы заполняете сетку данными, как правило, заголовками строк и столбцов, а затем позволяете пользователю их редактировать. После чего введенные пользователем данные можно переписать в двухмерный массив, или в массив с записями, а затем сохранить в файл.

Наши рекомендации