Информационная система начальника жилищно-эксплуатационной службы

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

КУРСОВОЙ ПРОЕКТ

по курсу «Структуры и организация данных в ЭВМ»

на тему

«Информационная система начальника жилищно-эксплуатационной службы»

Введение

Тема данного курсового проекта — «Информационная система начальника жилищно-эксплуатационной службы». При этом по заданию к курсовому проекту необходимо использовать структуру данных типа вектор и сортировку QuickSort.

Для разработки приложения была выбрана среда программирования Delphi.

Среда визуального объектно-ориентированного проектирования Delphi позволяет:

1. Создавать законченные приложения для Windows самой различной направленности.

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

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

4. Создавать мощные системы работы с базами данных любых типов.

5. Формировать и печатать сложные отчеты, включающие таблицы, графики и т. п.

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

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

Delphi — быстро развивающаяся система. Первая версия Delphi была выпущена в феврале 1995 года, в 1996 году вышла вторая версия, 1997 — третья, 1998 — четвертая, 1999 — пятая, 2001 — шестая. Все версии, начиная с Delphi 2. 0, рассчитаны на разработку 32-разрядных приложений, т. е. приложений для операционных систем Windows 95/98, NT и т. д. В 2002 году вышла седьмая версия, основным нововведением в которой были Интернет-технологии.

Проект данной курсовой работы представляет собой инструмент для управления информационной системой начальника жилищно-эксплуатационной службы.

1. Состав DELPHI-проекта

1. 1 Состав проекта

Данный проект состоит из двух форм: InputForm и ReportForm:

На форме InputForm расположены следующие компоненты (см. рис1):

— компонент AddBtn — верхняя кнопка кнопка в правой части формы для добавления записей данных.

— компонент CopyBtn — кнопка для копирования записей данных.

— компонент DelBtn — кнопка для удаления записей данных.

— компонент SortBtn — кнопка для сортировки выделенного столбца в таблице данных.

— компонент FindBtn — кнопка для поиска определенного пользователем значения в столбце данных.

— компонент SaveBtn — кнопка для сохранения всех табличных данных на форме в текстовых файл.

— компонент LoadBtn — кнопка для загрузки всех табличных данных на форме из текстового файла.

— компонент SaveBtn — кнопка для сохранения всех табличных данных на форме в текстовых файл.

— компонент FBtn — кнопка для отображения формы ReportForm и формирования отчета Ф5.

— компонент BitBtn1 — кнопка для закрытия приложения.

— компонент MSpinEdit — поле ввода для задания количества этажей M.

— компонент KSpinEdit — поле ввода для задания количества подъездов К.

На форме также находятся компоненты Label1, Label2 для отображения подсказок для ввода информации и невизуальные компоненты OpenDialog1, SaveDialog1 для вызова стандартных окон открытия и сохранения файлов.

— компонент PageControl1 — содержит вкладки TabSheet 1−5 на которых отражены данные (соответственно «Квартиры», «СХЕМА», «ГК (Р)», «Жители члены семей ГК (А)», и «Атрибуты квартир (С)»).

Компоненты TabSheet 1−5 содержат в себе элементы таблиц StringGrid 1−5, которые связаны с векторами данных, соответственно «Kvart», «Scheme», «GK», «People», «FlatAtr»).

Рис. 1 — Главная форма программы

На форме ReportForm расположены следующие компоненты (см. рис 2):

— компоненты Panel1, Panel2 — панели на форме для разделения формы на отчет и панель кнопок.

— компонент OkBtn — кнопка для закрытия формы.

— компонент ListBox1 — список для отображения отчета.

Рис. 2 — форма для формирования отчета Ф5.

1. 2 Основные модули и процедуры, входящие в состав программного комплекса

Список модулей:

Программа содержит следующие модули:

Unit1 — модуль главной формы проекта.

Unit2 — модуль отчетной формы проекта.

MyTypes — модуль с описаниями классов данных.

Список основных процедур, входящих в состав программного комплекса:

— procedure LoadButtonClick — процедура загрузки данных из файла в векторы.

— procedure SaveButtonClick — процедура сохранения данных в файл.

— procedure FillStringGrid — процедура инициализации таблиц и заполнения их в соответствии с массивами.

— procedure PageControl1Change — процедура выбора необходимой страницы с данными и вызова перезаполнения соответствующей таблицы.

— procedure SGDblClick — процедура ввода / редактирования данных в текущей ячейки таблицы данных.

— procedure AddBtnClick — процедура добавления строки в текущую таблицу данных и вектор данных.

— procedure DelBtnClick — процедура для удаления записей данных.

— procedure SortBtnClick — процедура для сортировки выделенного столбца в таблице данных.

— procedure KSpinEditChange — процедура для изменения значения количества подъездов К в соответствии с полем ввода.

— procedure MSpinEditChange — процедура для изменения значения количества этажей M в соответствии с полем ввода.

— procedure CopyBtnClick — процедура ввода новой строки данных копированием текущей строки.

— procedure FindBtnClick — процедура для поиска определенного пользователем значения в столбце данных.

— procedure SortBtn — кнопка для сортировки выделенного столбца в таблице данных.

— procedure FButtonClick — процедура для отображения формы ReportForm и формирования отчета Ф5.

— procedure ReadVec — процедура чтения вектора данных из текстового файла.

— procedure WriteVec — процедура записи вектора данных из текстового файла.

2. Данные программы

В программе для хранения данных был спроектирован класс TVector в котором для хранения данных использовался вектор векторов FArr. Для хранения имен колонок использовался вектор FNames, описанный как array [1. 100] of string. В программе были созданы 5 объектов класса TVector:

Kvart: TVector;

Scheme: TVector;

Gk: TVector;

People: TVector;

FlatAtr: TVector;

Имя массива

Тип

Размер в байтах

Kvart

TVector

100*100*16+10 100+8=170 108

Scheme

TVector

170 108

Gk

TVector

170 108

People

TVector

170 108

FlatAtr

TVector

170 108

Кроме того, в программе для временных нужд объявляются переменные:

KPod, M, i, j, k, x, типа integer (каждая по 4 байта);

FileNameT типа string (200 байт);

Ft типа TextFile (460 байт);

FSGVector — вектор ссылок типа TStringGrid (40 байт).

3. Логические структуры данных

Базовой структурой данного проекта является класс TVector в котором для хранения данных использовался вектор векторов FArr и организованы свойства и методы для доступа и обработки данных класса.

Объявление вектора FArr выглядит следующим образом:

FArr: array [1. 100] of TVarMas, где TVarMas = array [1. MaxN] of Variant;

Вектор (array) — это линейная структура данных (список) с элементами одинакового размера в которой адрес элемента однозначно определяется его номером.

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

Логическая схема структуры вектора векторов FArr:

0

1

2

100

1

2

3

100

Каждый элемент одного вектора занимает 16 байт памяти. Соответственно FArr будет занимать (100*100)*16=160 000 байт.

Логическая схема структуры вектора имен FNames:

0

1

2

101

1

2

3

100

Каждый элемент вектора занимает 101 байт памяти. Соответственно вектор FNames будет занимать 100*101 =10 100 байт.

4. Алгоритмы обработки основных структур

Основной операцией обработки структуры в данном программном обеспечении является сортировка QuickSort (по заданию на курсовое проектирование).

Быстрая сортировка (quicksort), часто называемая qsort по имени реализации в стандартной библиотеке языка Си — широко известный алгоритм сортировки, разработанный английским Информатиком Чарльзом Хоаром. Один из быстрых известных универсальных алгоритмов сортировки массивов (в среднем О (n log n) обменов при упорядочении n элементов), хотя и имеющий ряд недостатков.

Алгоритм

Быстрая сортировка использует стратегию «разделяй и властвуй». Шаги алгоритма таковы:

1. Выбираем в массиве некоторый элемент, который будем называть опорным элементом. С точки зрения корректности алгоритма выбор опорного элемента безразличен. С точки зрения повышения эффективности алгоритма выбираться должна медиана, но без дополнительных сведений о сортируемых данных её обычно невозможно получить. Известные стратегии: выбирать постоянно один и тот же элемент, например, средний или последний по положению; выбирать элемент со случайно выбранным индексом.

2. Операция разделения массива: реорганизуем массив таким образом, чтобы все элементы, меньшие или равные опорному элементу, оказались слева от него, а все элементы, большие опорного — справа от него. Обычный алгоритм операции:

1. Два индекса — l и r, приравниваются к минимальному и максимальному индексу разделяемого массива соответственно.

2. Вычисляется индекс опорного элемента m.

3. Индекс l последовательно увеличивается до m до тех пор, пока l-й элемент не превысит опорный.

4. Индекс r последовательно уменьшается до m до тех пор, пока r-й элемент не окажется меньше опорного.

5. Если r = l — найдена середина массива — операция разделения закончена, оба индекса указывают на опорный элемент.

6. Если l < r — найденную пару элементов нужно обменять местами и продолжить операцию разделения с тех значений l и r, которые были достигнуты. Следует учесть, что если какая-либо граница (l или r) дошла до опорного элемента, то при обмене значение m изменяется на r-й или l-й элемент соответственно.

3. Рекурсивно упорядочиваем подмассивы, лежащие слева и справа от опорного элемента.

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

Поскольку в каждой итерации (на каждом следующем уровне рекурсии) длина обрабатываемого отрезка массива уменьшается, по меньшей мере, на единицу, терминальная ветвь рекурсии будет достигнута всегда и обработка гарантированно завершится.

Этот алгоритм в применении к нашему вектору FArr реализован следующи методом класса TVector:

// Процедура сортировки вектора по индексу SortId с режимом xMode

// xMode = 1 — по возрастанию

// xMode = 2 — по убыванию

// xMode = 0-использовать текущий режим SortMode и затем поменять его

procedure TVector. Sort (xMode: integer = 0);

procedure QSort (l, r: Integer);

function Less (var x, y: Variant): boolean;

begin

if (X < Y) and (SortMode=1) // по возрастанию

then Less: =true

else Less: =false;

end;

var

i, j, x: integer;

y: TVarMas; //Variant;

begin

i:= l; j:= r; x:= (l+r) DIV 2;

repeat

while Less (FArr[i] [SortId], FArr[x] [SortId]) do i:= i + 1;

while Less (FArr[x] [SortId], FArr[j] [SortId]) do j:= j — 1;

if i <= j then

begin

y:= FArr[i];

FArr[i]:= FArr[j];

FArr[j]:= y;

i:= i + 1; j:= j — 1;

end;

until i > j;

if l < j then QSort (l, j);

if i < r then QSort (i, r);

end;

begin {QuickSort};

if xMode< >0

then SortMode:= xMode;

QSort (1, Size);

if xMode=0 then // Поменяем режим сортировки

begin

if SortMode = 1

then SortMode: =2 else SortMode: =1;

end;

end;

Оценка эффективности

QuickSort является существенно улучшенным вариантом алгоритма сортировки с помощью прямого обмена (его варианты известны как «Пузырьковая сортировка»), известного, в том числе, своей низкой эффективностью. Принципиальное отличие состоит в том, что в первую очередь меняются местами наиболее удалённые друг от друга элементы массива.

· Лучший случай. Для этого алгоритма самый лучший случай — если в каждой итерации каждый из подмассивов делился бы на два равных по величине массива. В результате количество сравнений, делаемых быстрой сортировкой, было бы равно значению рекурсивного выражения CN = 2CN/2+N. Это дало бы наименьшее время сортировки.

· Среднее. Даёт в среднем O (n log n) обменов при упорядочении n элементов. В реальности именно такая ситуация обычно имеет место при случайном порядке элементов и выборе опорного элемента из середины массива либо случайно.

· 2CN/2 покрывает расходы по сортировке двух полученных подмассивов; N — это стоимость обработки каждого элемента, используя один или другой указатель. Известно также, что примерное значение этого выражения равно CN = N lg N.

· Худший случай. Худшим случаем, очевидно, будет такой, при котором на каждом этапе массив будет разделяться на вырожденный подмассив из одного опорного элемента и на подмассив из всех остальных элементов. Такое может произойти, если в качестве опорного на каждом этапе будет выбран элемент либо наименьший, либо наибольший из всех обрабатываемых.

· Худший случай даёт O (nІ) обменов, но количество обменов и, соответственно, время работы — это не самый большой его недостаток. Хуже то, что в таком случае глубина рекурсии при выполнении алгоритма достигнет n, что будет означать n-кратное сохранение адреса возврата и локальных переменных процедуры разделения массивов.

5. Руководство пользователя

Данное программное обеспечение имеет интуитивно понятный интерфейс и использует все возможности среды Delphi.

Программа имеет пять вкладок. При первоначальном запуске активируется первая — вкладка «Квартиры» (см. рис. 3).

Рис. 3 — Вкладка таблицы квартир

На каждой вкладке с элементами таблицы можно выполнить операции добавления новой строки, удаление существующей, изменение значения ячеек, а также сортировки текущего столбца и поиска заданного значения в текущем столбце. Сортировка выполняется методом быстрой сортировки QuickSort. При выполнении сортировки вначале выполняется сортировка по возрастанию, при следующем нажатии кнопки «Сортировка» выполняется сортировка по убыванию и т. д.

На вкладке «Квартиры» можно изменить только колонки: «Номер квартиры», «Стоимость квартиры», «Признак приват.». Остальные колонки рассчитываются по таблицам «Атрибуты квартир (С)» и «СХЕМА» следующим образом:

Три первых колонки определяются исходя из данных таблицы «СХЕМА». Колонка «Жилая площадь» = сумма площадей всех комнат, взятых из таблицы С.

Колонка «Общая площадь» =атр. 4 + атрибуты 7−9 из таблицы С.

Одновременно после ввода / изменения номера квартиры выдается информационное сообщение (см. рис. 4)

Рис. 4 — Информационное сообщение

В случае попытки редактирования колонок №№ 2−5 выдается следующее сообщение (см. рис. 5).

Рис. 5 — Сообщение о невозможности редактирования ячейки

При переходе на вкладку «СХЕМА» отображается следующее окно (см. рис. 6)

Рис. 6 — Вкладка схемы квартир «СХЕМА»

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

Третья вкладка «ГК (Р)» содержит атрибуты таблицы главных квартиросъемщиков квартир (см. рис. 7).

Рис. 7 — Вкладка таблицы главных квартиросъемщиков ГК (Р)

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

В четвертой вкладке находится таблица жителей квартир — членов семей главных квартиросъемщиков (А). (см. рис. 8)

Рис. 8 — Вкладка таблицы жителей квартир — членов семей главных квартиросъемщиков (А)

На пятой вкладке находится таблица © с атрибутами квартир ©. (см. рис. 9)

Рис. 9 — Вкладка таблицы © с атрибутами квартир

Из всех вкладок доступны кнопки «Сохранить в файл» и «Загрузить из файла» с помощью которых можно сохранить данные всех вкладок в текстовый файл *. dat и загрузить данные из файла.

Для формирования отчета формы Ф5 необходимо нажать на кнопку «Отчет Ф5», при этом открывается новое окно с отчетными данными (см. рис. 10). Закрыть окно можно нажав на кнопку «ОК».

Рис. 9 — Вкладка таблицы © с атрибутами квартир

Заключение

В процессе разработки данного курсового проекта были изучены и закреплены знания по физическим размещениям структур данных и методам их обработки (сортировки). В среде Delphi была разработана информационная система начальника жилищно-эксплуатационной службы. При создании программы не использовались компоненты баз данных данной среды Delphi.

Тестирование данного продукта показало полноту реализованных функций и отсутствие ошибок и недочётов в программе. Были изучены базовая структура данных типа вектор и метод быстрой сортировки QuickSort.

Литература

1

Структуры и организация данных в компьютере. Учебное пособие / Лакин В. И., Романов А. В. — Мн.: БНТУ, 2004 — 176 с.

2

Архангельский А.Я. Delphi 6. Справочное пособие. М.: ЗАО «Издательсво БИНОМ», 2001. 1024 с.

3

Вирт Н. Алгоритмы и структуры данных. СПб: Невский диалект, 2001. — 352 с.

4

Ананий В. Левитин Глава 4. Метод декомпозиции: Быстрая сортировка // Алгоритмы: введение в разработку и анализ = Introduction to The Design and Analysis of Algorithms. — М.: «Вильямс», 2006. — С. 174−179.

5

Кнут Д. Э. Искусство программирования, том 1. Основные алгоритмы. М.: Издательский дом «Вильямс», 2002. 720 с.

6

Кнут Д. Э. Искусство программирования, том 3. Сортировка и поиск. М.: Издательский дом «Вильямс», 2001. 832 с.

7

Гофман В.Э., Хомоненко А. Д. Delphi. Быстрый старт. — СПб: БХВ-Петербург, 2003. — 288 с.: ил

Приложение 1

Листинги программы

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls, ExtCtrls, math, Grids, Buttons, Mask, Calendar, ComCtrls,

Spin, MyTypes, Unit2;

Type

TInputForm = class (TForm)

BitBtn1: TBitBtn;

OpenDialog1: TOpenDialog;

SaveDialog1: TSaveDialog;

LoadButton: TButton;

SaveButton: TButton;

PageControl1: TPageControl;

TabSheet1: TTabSheet;

TabSheet2: TTabSheet;

TabSheet3: TTabSheet;

StringGrid1: TStringGrid;

DelBtn: TBitBtn;

AddBtn: TBitBtn;

StringGrid2: TStringGrid;

SortBtn: TBitBtn;

TabSheet4: TTabSheet;

TabSheet5: TTabSheet;

StringGrid3: TStringGrid;

StringGrid4: TStringGrid;

StringGrid5: TStringGrid;

Label1: TLabel;

KSpinEdit: TSpinEdit;

Label2: TLabel;

MSpinEdit: TSpinEdit;

FindBtn: TBitBtn;

CopyBtn: TBitBtn;

FButton: TButton;

procedure FormCreate (Sender: TObject);

procedure LoadButtonClick (Sender: TObject);

procedure SaveButtonClick (Sender: TObject);

procedure PageControl1Change (Sender: TObject);

procedure AddBtnClick (Sender: TObject);

procedure SGDblClick (Sender: TObject);

procedure DelBtnClick (Sender: TObject);

procedure SortBtnClick (Sender: TObject);

procedure KSpinEditChange (Sender: TObject);

procedure MSpinEditChange (Sender: TObject);

procedure SGKeyPress (Sender: TObject; var Key: Char);

procedure FormDestroy (Sender: TObject);

procedure CopyBtnClick (Sender: TObject);

procedure FindBtnClick (Sender: TObject);

procedure FButtonClick (Sender: TObject);

private

{Private declarations}

public

{Public declarations}

//Fz: file of TVector; // Файл типа запись

KPod, M: integer; // Количество подъездов и этажей

People: TVector; // Вектор — члены семей ГК

GK: TVector; // Вектор — главные квартиросъемщики

Scheme: TVector; // Вектор — СХЕМА

FlatAtr: TVector; // Вектор — Атрибуты квартир

KVART: TVector; // Вектор — КВАРТ

Ft: TextFile; // Текстовой файл

FileNameT: string[200]; // Имя файла

FSGVector: array [1. 10] of TStringGrid;

procedure FillStringGrid (SG: TStringGrid; Vec: TVector);

function GetVec: TVector;

procedure ReadVec (var Vec: TVector);

procedure WriteVec (Vec: TVector); // Запись вектора в файл

end;

var

InputForm: TInputForm;

Implementation

{$R *. DFM}

procedure TInputForm. FormCreate (Sender: TObject);

begin

KPod: =2; M:= 3;

// -

Kvart:= TVector. Create;

Kvart. Cols:= 7;

Kvart. Names[1]:= 'Номер квартиры';

Kvart. Names[2]:= 'число комнат';

Kvart. Names[3]:= 'номер этажа';

Kvart. Names[4]:= 'жилая площадь (кв. м.)';

Kvart. Names[5]:= 'общая площадь (кв. м.)';

Kvart. Names[6]:= 'стоимость квартиры';

Kvart. Names[7]:= 'Приват. ';

// -

Scheme:= TVector. Create;

Scheme. Cols:= 4;

Scheme. Names[1]:= 'Кв. 1';

Scheme. Names[2]:= 'Кв. 2';

Scheme. Names[3]:= 'Кв. 3';

Scheme. Names[4]:= 'Кв. 4';

// -

GK:= TVector. Create;

GK. Cols:= 8;

GK. Names[1]:= 'Номер Квартиры';

GK. Names[2]:= 'Фамилия';

GK. Names[3]:= 'Имя';

GK. Names[4]:= 'Отчество';

GK. Names[5]:= 'Год рождения';

GK. Names[6]:= 'Место работы';

GK. Names[7]:= 'Льготы';

GK. Names[8]:= 'Долг (тыс. руб.)';

// -

// 1.5. Таблица, А содержит список жильцов — членов семей главных квартиросъемщиков:

// 1) фамилия,

// 2) родственное отношение к ГК (мать / отец/муж/жена / дочь/сын),

// 3) номер квартиры,

// 4) признак «пенсионер / учащийся / работает / дошкольник».

People:= TVector. Create;

People. Cols:= 4;

People. Names[1]:= 'Фамилия';

People. Names[2]:= 'Родств. отн-ние';

People. Names[3]:= 'Номер квартиры';

People. Names[4]:= 'Признак';

People. Names[5]:= 'Место работы';

People. Names[6]:= 'Льготы';

People. Names[7]:= 'Долг (тыс. руб.)';

// -

// 1.6. Таблица С содержит следующие атрибуты квартир (в соответствии с числом комнат):

// 1) число комнат,

// 2) месячная квартплата,

// 3) площадь первой комнаты (кв. м.),

// 4) площадь второй комнаты (если она есть),

// 5) площадь третьей комнаты,

// 6) площадь четвертой комнаты,

// 7) площадь коридора,

// 8) площадь кухни,

// 9) общая площадь туалета и ванной комнаты.

FlatAtr:= TVector. Create;

FlatAtr. Cols:= 9;

FlatAtr. Names[1]:= 'Число комн. ';

FlatAtr. Names[2]:= 'Квартплата';

FlatAtr. Names[3]:= 'Пл. ком. № 1';

FlatAtr. Names[4]:= 'Пл. ком. № 2';

FlatAtr. Names[5]:= 'Пл. ком. № 3';

FlatAtr. Names[6]:= 'Пл. ком. № 4';

FlatAtr. Names[7]:= 'Пл. коридора';

FlatAtr. Names[8]:= 'Пл. кухни';

FlatAtr. Names[9]:= 'Пл. туалета';

// -

PageControl1Change (Sender);

FSGVector[1]:= StringGrid1;

FSGVector[2]:= StringGrid2;

FSGVector[3]:= StringGrid3;

FSGVector[4]:= StringGrid4;

FSGVector[5]:= StringGrid5;

end;

procedure TInputForm. ReadVec (var Vec: TVector);

var

x, i, j: integer;

St: String;

begin

Readln (Ft, x); Vec. Cols:= x;

for i: =1 to Vec. Cols do

begin Readln (Ft, St); Vec. Names[i]:= St; end;

Readln (Ft, x); Vec. Size:= x;

for i: =1 to Vec. Size do

begin

for j: =1 to Vec. Cols do

begin Readln (Ft, St); Vec. X [i, j]:= St; end;

end;

Vec. SortId:= 1;

Vec. SortMode:= 1;

end;

procedure TInputForm. WriteVec (Vec: TVector);

var i, j: integer;

begin

Writeln (Ft, Vec. Cols);

for i: =1 to Vec. Cols do

Writeln (Ft, Vec. Names[i]);

Writeln (Ft, Vec. Size);

for i: =1 to Vec. Size do

begin

for j: =1 to Vec. Cols do

Writeln (Ft, Vec. X [i, j]);

end;

end;

// Чтение данных из файла

procedure TInputForm. LoadButtonClick (Sender: TObject);

begin

OpenDialog1. Title:= 'Открыть из файла'; // Изменение заголовка окна диалога

if not OpenDialog1. Execute then exit;

// Выполнение стандартного диалога выбора имени файла

FileNameT:= OpenDialog1. FileName; // Возвращение имени дискового файла

AssignFile (Ft, FileNameT); // Связывание файловой переменной Fz с именем файла

Reset (Ft); // Открытие существующего файла

ReadVec (Kvart); // Чтение вектора из файла

ReadVec (Scheme);

ReadVec (GK);

ReadVec (People);

ReadVec (FlatAtr);

PageControl1Change (Sender);

CloseFile (Ft);

end;

procedure TInputForm. SaveButtonClick (Sender: TObject);

// Сохраниение данных в файле

begin

if not SaveDialog1. Execute then exit;

// Выполнение стандартного диалога выбора имени файла

begin

FileNameT:= SaveDialog1. FileName; // Возвращение имени дискового файла

AssignFile (Ft, FileNameT); // Связывание файловой переменной Fz с именем файла

{$I-}

Rewrite (Ft); // Открытие нового файла

{$I+}

if not ((IOResult = 0) and (FileNameT < > «)) then

begin

Application. MessageBox ('Не возможно открыть файл!', 'Ошибка', MB_OK);

exit;

end;

end;

WriteVec (Kvart); // Запись в файл

WriteVec (Scheme);

WriteVec (GK);

WriteVec (People);

WriteVec (FlatAtr);

CloseFile (Ft); // Закрытие файла

end;

// Процедура заполнения объекта StringGrid данными из Вектора Vec

procedure TInputForm. FillStringGrid (SG: TStringGrid; Vec: TVector);

var i, j: integer;

begin

Sg. ColCount:= Vec. Cols+1;

if Vec. Size=0

then Sg. RowCount: =2

else Sg. RowCount: =Vec. Size+1;

for i: =1 to Vec. Cols do

Sg. Cells [i, 0]:= Vec. Names[i];

for i: =1 to Vec. Size do

begin

Sg. Cells [0, i]:= IntToStr (i);

for j: =1 to Vec. Cols do

Sg. Cells [j, i]:= Vec. X [i, j];

end;

Sg. ColWidths[0]:= 25;

end;

procedure TInputForm. PageControl1Change (Sender: TObject);

begin

case PageControl1. ActivePageIndex of

0: FillStringGrid (StringGrid1, Kvart);

1: FillStringGrid (StringGrid2, Scheme);

2: FillStringGrid (StringGrid3, GK);

3: FillStringGrid (StringGrid4, People);

4: FillStringGrid (StringGrid5, FlatAtr);

end;

end;

procedure TInputForm. AddBtnClick (Sender: TObject);

var

SG: TStringGrid;

Vec: TVector;

begin

Sg:= FSGVector [PageControl1. ActivePageIndex+1];

Vec:= GetVec;

Vec. Add;

FillStringGrid (SG, Vec);

end;

procedure TInputForm. SGDblClick (Sender: TObject);

var

NRooms, NKv, NKvart, NPod, NFloor: integer;

porch: array [0. MaxN] of integer;

SG: TStringGrid;

Vec: TVector;

i, j, x, k, l: integer;

InputString: String;

begin

Sg:= TStringGrid (Sender);

i:= Sg. Selection. Left;

j:= Sg. Selection. Top;

Vec:= GetVec;

if (i< 1) then exit; // За пределами редактирования

// Установим особые параметры для таблицы КВАРТ — StringGrid1

if (Sg. Name = 'StringGrid1') and (i in [2,3,4,5]) then

begin

Application. MessageBox (

'Это поле заполняется автоматически по номеру квартиры и не редактируется!'

'Ошибка', MB_OK);

exit;

end;

InputString:= InputBox ('', 'Введите значение', Vec. X [j, i]);

if InputString=''

then exit;

SG. Cells [i, j]:= InputString;

Vec.X [j, i]:= InputString;

// Заполним при необходимости остальные поля для таблицы КВАРТ — StringGrid1

if (Sg. Name = 'StringGrid1') and (i = 1) then

begin

NKvart:= Vec. X [j, i];

porch[0]:= 0; x:= 0;

for i: =1 to Scheme. Size do

begin

porch[i]:= 2;

if Scheme. X [i, 3]=''

then porch[i]:= 2

else if Scheme. X [i, 4]=''

then porch[i]:= 3 else porch[i]: =4;

if NKvart <= x + (porch[i]*M) then

begin

NPod:= i; // Определили номер подъезда

NFloor:= (NKvart-x) div M +1; // Определили номер этажа

NKv:= (NKvart-x) mod M; // Определили номер кв. на этаже

if NKv=0

then NKv:= M;

NRooms:= Scheme. X [i, NKv]; // Определили кол-во комнат

// Запишем количество комнат в квартире

SG. Cells [2, j]:= IntToStr (NRooms); Vec. X [j, 2]:= NRooms;

// Запишем номер этажа

SG. Cells [3, j]:= IntToStr (NFloor); Vec. X [j, 3]:= NFloor;

for k: =1 to FlatAtr. Size do

begin

if FlatAtr. X [i, 1]= NRooms then // совпадает количество комнат

begin

//x — атр. 4 = сумма площадей всех комнат, взятых из таблицы С,

x:= 0;

for l: =1 to NRooms do

try

x:= x + StrToInt (FlatAtr.X [k, 2+l]);

except

end;

// Запишем жилую площадь

Vec.X [j, 4]:= x; SG. Cells [4, j]:= Vec. X [j, 4];

x:= x + StrToInt (FlatAtr.X [i, 7])+StrToInt (FlatAtr.X [i, 8])+

StrToInt (FlatAtr.X [i, 9]);

// Запишем общую площадь

SG. Cells [5, j]:= IntToStr (x); Vec. X [j, 5]:= x;

break;

end;

end;

InputString:= 'Квартира №'+IntToStr (NKvart)+

' находится в подъезде №'+IntToStr (NPod)+

' на этаже №'+IntToStr (NFloor)+

' ('+IntToStr (NRooms)+' комната (ы)). ';

Application. MessageBox (PChar (InputString), '', MB_OK);

exit;

end;

x:= x + porch[i]*M;

end;

Application. MessageBox ('Указанная квартира не найдена по схеме дома',

'Ошибка', MB_OK);

SG. Cells [2, j]:= «; Vec. X [j, 2]:= «;

SG. Cells [3, j]:= «; Vec. X [j, 3]:= «;

end;

if (j> Vec. Size) then // Кликнули за пределами области данных

begin

Vec. Add; FillStringGrid (SG, Vec);

end;

end;

function TInputForm. GetVec: TVector;

begin

case PageControl1. ActivePageIndex of

0: result:= Kvart;

1: result:= Scheme;

2: result:= GK;

3: result:= People;

4: result:= FlatAtr;

else result:= Kvart;

end;

end;

procedure TInputForm. DelBtnClick (Sender: TObject);

var

SG: TStringGrid;

Vec: TVector;

i: integer;

begin

Sg:= FSGVector [PageControl1. ActivePageIndex+1];

i:= Sg. Selection. Top; // удаляемая строка

Vec:= GetVec;

Vec. Delete (i);

FillStringGrid (SG, Vec);

end;

procedure TInputForm. SortBtnClick (Sender: TObject);

var

SG: TStringGrid;

Vec: TVector;

i: integer;

begin

Sg:= FSGVector [PageControl1. ActivePageIndex+1];

i:= Sg. Selection. Left; // Будем сортировать этот столбец

Vec:= GetVec;

if (i< 1) then exit; // За пределами редактирования

Vec. SortId:= i; // установим сортируемый столбец

Vec. Sort;

FillStringGrid (SG, Vec);

end;

procedure TInputForm. KSpinEditChange (Sender: TObject);

begin

KPod:= KSpinEdit. Value;

end;

procedure TInputForm. MSpinEditChange (Sender: TObject);

begin

M:= MSpinEdit. Value;

end;

procedure TInputForm. SGKeyPress (Sender: TObject; var Key: Char);

begin

if Key =#13 then // Если нажата клавиша Enter то…

SGDblClick (Sender);

end;

procedure TInputForm. FormDestroy (Sender: TObject);

begin

People. Destroy;

GK. Destroy;

Scheme. Destroy;

FlatAtr. Destroy;

Kvart. Destroy;

end;

procedure TInputForm. CopyBtnClick (Sender: TObject);

var

SG: TStringGrid;

Vec: TVector;

i: integer;

begin

Sg:= FSGVector [PageControl1. ActivePageIndex+1];

i:= Sg. Selection. top; // Будем копировать эту строку

Vec:= GetVec;

Vec. AddCopy (i);

FillStringGrid (SG, Vec);

end;

procedure TInputForm. FindBtnClick (Sender: TObject);

var

SG: TStringGrid;

Vec: TVector;

res,

Row, Col: integer;

InputString: String;

begin

Sg:= FSGVector [PageControl1. ActivePageIndex+1];

Col:= Sg. Selection. Left;

Row:= Sg. Selection. Top;

Vec:= GetVec;

if (Col< 1) then exit; // За пределами редактирования

InputString:= InputBox ('', 'Введите значение для поиска', «);

if InputString=''

then exit;

res:= Vec. Find (Col, Row, InputString);

if res=0 then

begin

Application. MessageBox ('Указанное значение не найдено!', 'Ошибка', MB_OK);

exit;

end;

Sg. Row:= res;

end;

procedure TInputForm. FButtonClick (Sender: TObject);

var

NKvart, NPod: integer;

fl, i, k, x, p: integer;

St, FIO: String;

begin

//

ReportForm. ListBox1. Items. Clear;

ReportForm. ListBox1. Items. Add (

' Cписок всех жильцов дома, проживающих в квартирах, '+

'в которых ГК имеет льготы по квартплате');

for k: =1 to People. Size do

begin

NKvart:= People. x [k, 3]; // Номер квартиры

fl:= 0;

for i: =1 to GK. Size do

begin

if Gk. X [i, 1]=NKvart then

begin fl:= 1; break; end;

end;

if (fl=0) or ((fl=1) and (Gk.X [i, 7]< >'да'))

then continue; // У ГК нет льгот;

FIO:= People. X [k, 1];

x:= 0; NPod:= 0;

for i: =1 to Scheme. Size do

begin

if Scheme. X [i, 3]=''

then p:= 2

else if Scheme. X [i, 4]=''

then p:= 3 else p: =4;

if NKvart <= x + (p*M) then

begin NPod:= i; break; end;

end;

for i: =1 to Kvart. Size do

if Kvart. X [i, 1]= NKvart then

begin // получили искомую строку квартиры

St:= FIO+' кв. №'+IntToStr (NKvart)+' подъезд №'+IntToStr (NPod)+' - '+

IntToStr (Kvart.X [i, 2])+' комн. ';

if Kvart. X [i, 7]='да'

then St:= St + ' - кв-ра приватизирована '

else St:= St + ' - кв-ра не приватизирована ';

// списка: Фамилия жильца, номер квартиры, подъезд, число комнат, признак

// приватизации.

ReportForm. ListBox1. Items. Add (St);

end;

end;

ReportForm. ShowModal;

end;

end.

unit Unit2;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,

Buttons, ComCtrls, ExtCtrls;

type

TReportForm = class (TForm)

Panel1: TPanel;

Panel2: TPanel;

OKBtn: TButton;

CancelBtn: TButton;

ListBox1: TListBox;

private

{Private declarations}

public

{Public declarations}

end;

var

ReportForm: TReportForm;

implementation

{$R *. DFM}

end.

unit MyTypes;

interface

uses Sysutils, Contnrs;

const MaxN = 100;

type

TVarType = Variant; //TVarRec;

TVarMas = array [1. MaxN] of TVarType;

TVector = class (TInterfacedObject)

private

{Private declarations}

FArr: array [1. MaxN] of TVarMas; //source data

FNum: integer; //number of items

FCols: integer; //number of columns

FNames: array [1. MaxN] of String[MaxN]; //names of columns

function GetSize: Integer;

procedure SetSize (value: Integer);

function GetCols: Integer;

procedure SetCols (value: Integer);

procedure SetX (Index1, Index2: integer; value: TVarType);

function GetX (Index1, Index2: integer): TVarType;

procedure SetName (Index: integer; value: String);

function GetName (Index: integer): String;

public

SortId: integer; // Текущий сортируемый столбец

SortMode: integer; // Текущий режим сортировки

constructor Create;

property X [Index1, Index2: Integer]: TVarType read GetX write SetX;

property Names [Index: Integer]: String read GetName write SetName;

property Size: Integer read GetSize write SetSize;

property Cols: Integer read GetCols write SetCols;

procedure Sort (xMode: integer = 0);

procedure Add ();

procedure AddCopy (Index: integer);

procedure Delete (Index: integer);

function Find (Col, Row: integer; Value: Variant): integer;

end;

implementation

constructor TVector. Create;

begin

FNum:= 0; SortId:= 0; SortMode:= 1;

end;

function TVector. GetSize: Integer;

begin result:= FNum; end;

procedure TVector. SetSize (value: Integer);

begin FNum:= value; end;

function TVector. GetCols: Integer;

begin result:= FCols; end;

procedure TVector. SetCols (value: Integer);

begin FCols:= value; end;

procedure TVector. SetX (Index1, Index2: integer; value: TVarType);

begin

FArr[Index1] [Index2]:= value;

end;

function TVector. GetX (Index1, Index2: integer): TVarType;

begin

result:= FArr[Index1] [Index2];

end;

function TVector. GetName (Index: integer): String;

begin

result:= FNames[Index];

end;

procedure TVector. SetName (Index: integer; value: String);

begin

FNames[Index]:= Value;

end;

procedure TVector. Add ();

begin

FNum:= FNum + 1;

end;

procedure TVector. AddCopy (Index: integer);

begin

FNum:= FNum + 1;

FArr[FNum]:= FArr[Index];

end;

procedure TVector. Delete (Index: integer);

var i: integer;

begin

if FNum=0 then exit; // Вроде как нечего удалять

for i: =Index+1 to FNum do // Перенесем строки

FArr [I-1]:= FArr[I];

FNum:= FNum -1; // уменьшаем количество

end;

// Процедура сортировки вектора данных по индексу SortId с режимом xMode

// xMode = 1 — по возрастанию

// xMode = 2 — по убыванию

// xMode = 0 — использовать текущий режим SortMode и затем поменять его

procedure TVector. Sort (xMode: integer = 0);

procedure QSort (l, r: Integer);

function Less (var x, y: Variant): boolean;

begin

if (X < Y) and (SortMode=1) // по возрастанию

then Less: =true

else Less: =false;

end;

var

i, j, x: integer;

y: TVarMas; //Variant;

begin

i:= l; j:= r; x:= (l+r) DIV 2;

repeat

while Less (FArr[i] [SortId], FArr[x] [SortId]) do i:= i + 1;

while Less (FArr[x] [SortId], FArr[j] [SortId]) do j:= j — 1;

if i <= j then

begin

y:= FArr[i];

FArr[i]:= FArr[j];

FArr[j]:= y;

i:= i + 1; j:= j — 1;

end;

until i > j;

if l < j then QSort (l, j);

if i < r then QSort (i, r);

end;

begin {QuickSort};

if xMode< >0

then SortMode:= xMode;

QSort (1, Size);

if xMode=0 then // Поменяем режим сортировки

begin

if SortMode = 1

then SortMode: =2 else SortMode: =1;

end;

end;

// Процедура поиска значения Value в столбце Col с позиции Row

// возвращает индекс найденой строки или 0 если ничего не найдено

function TVector. Find (Col, Row: integer; Value: Variant): integer;

var i: integer;

begin

result:= 0;

for i: =Row to FNum do

if FArr[I] [Col] = Value then

begin result:= i; exit; end;

end;

end.

ПоказатьСвернуть
Заполнить форму текущей работой