|
Информационная система начальника жилищно-эксплуатационной службы
Информационная система начальника жилищно-эксплуатационной службы
47
КУРСОВОЙ ПРОЕКТ по курсу «Структуры и организация данных в ЭВМ» на тему «Информационная система начальника жилищно-эксплуатационной службы» ВведениеТема данного курсового проекта - «Информационная система начальника жилищно-эксплуатационной службы». При этом по заданию к курсовому проекту необходимо использовать структуру данных типа вектор и сортировку 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+10100+8=170108 | | Scheme | TVector | 170108 | | Gk | TVector | 170108 | | People | TVector | 170108 | | FlatAtr | TVector | 170108 | | | Кроме того, в программе для временных нужд объявляются переменные: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: Каждый элемент одного вектора занимает 16 байт памяти. Соответственно FArr будет занимать (100*100)*16=160000 байт. Логическая схема структуры вектора имен FNames: Каждый элемент вектора занимает 101 байт памяти. Соответственно вектор FNames будет занимать 100*101 =10100 байт. 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;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, ExtCtrls, math, Grids, Buttons, Mask, Calendar, ComCtrls,Spin, MyTypes, Unit2;TypeTInputForm = 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;varInputForm: TInputForm;Implementation{$R *.DFM}procedure TInputForm. FormCreate (Sender: TObject);beginKPod:=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);varx, i, j: integer;St: String;beginReadln (Ft, x); Vec. Cols:= x;for i:=1 to Vec. Cols dobegin Readln (Ft, St); Vec. Names[i]:= St; end;Readln (Ft, x); Vec. Size:= x;for i:=1 to Vec. Size dobeginfor j:=1 to Vec. Cols dobegin 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;beginWriteln (Ft, Vec. Cols);for i:=1 to Vec. Cols doWriteln (Ft, Vec. Names[i]);Writeln (Ft, Vec. Size);for i:=1 to Vec. Size dobeginfor j:=1 to Vec. Cols doWriteln (Ft, Vec.X [i, j]);end;end; // Чтение данных из файлаprocedure TInputForm. LoadButtonClick (Sender: TObject);beginOpenDialog1. 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); // Сохраниение данных в файлеbeginif not SaveDialog1. Execute then exit; // Выполнение стандартного диалога выбора имени файлаbeginFileNameT:= SaveDialog1. FileName; // Возвращение имени дискового файлаAssignFile (Ft, FileNameT); // Связывание файловой переменной Fz с именем файла{$I-}Rewrite(Ft); // Открытие нового файла{$I+}if not((IOResult = 0) and (FileNameT <> «)) thenbeginApplication. MessageBox ('Не возможно открыть файл!', 'Ошибка', MB_OK);exit;end;end;WriteVec(Kvart); // Запись в файлWriteVec(Scheme);WriteVec(GK);WriteVec(People);WriteVec(FlatAtr);CloseFile(Ft); // Закрытие файлаend; // Процедура заполнения объекта StringGrid данными из Вектора Vecprocedure TInputForm. FillStringGrid (SG: TStringGrid; Vec: TVector);var i, j: integer;beginSg. ColCount:= Vec. Cols+1;if Vec. Size=0then Sg. RowCount:=2else Sg. RowCount:=Vec. Size+1;for i:=1 to Vec. Cols doSg. Cells [i, 0]:= Vec. Names[i];for i:=1 to Vec. Size dobeginSg. Cells [0, i]:= IntToStr(i);for j:=1 to Vec. Cols doSg. Cells [j, i]:= Vec.X [i, j];end;Sg. ColWidths[0]:= 25;end;procedure TInputForm. PageControl1Change (Sender: TObject);begincase PageControl1. ActivePageIndex of0: 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);varSG: TStringGrid;Vec: TVector;beginSg:= FSGVector [PageControl1. ActivePageIndex+1];Vec:= GetVec;Vec. Add;FillStringGrid (SG, Vec);end;procedure TInputForm.SGDblClick (Sender: TObject);varNRooms, NKv, NKvart, NPod, NFloor: integer;porch: array [0..MaxN] of integer;SG: TStringGrid;Vec: TVector;i, j, x, k, l: integer;InputString: String;beginSg:= TStringGrid(Sender);i:= Sg. Selection. Left;j:= Sg. Selection. Top;Vec:= GetVec;if (i<1) then exit; // За пределами редактирования // Установим особые параметры для таблицы КВАРТ - StringGrid1if (Sg. Name = 'StringGrid1') and (i in [2,3,4,5]) thenbeginApplication. 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; // Заполним при необходимости остальные поля для таблицы КВАРТ - StringGrid1if (Sg. Name = 'StringGrid1') and (i = 1) thenbeginNKvart:= Vec.X [j, i];porch[0]:= 0; x:= 0;for i:=1 to Scheme. Size dobeginporch[i]:= 2;if Scheme.X [i, 3]=''then porch[i]:= 2else if Scheme.X [i, 4]=''then porch[i]:= 3 else porch[i]:=4;if NKvart <= x + (porch[i]*M) thenbeginNPod:= i; // Определили номер подъездаNFloor:= (NKvart-x) div M +1; // Определили номер этажаNKv:= (NKvart-x) mod M; // Определили номер кв. на этажеif NKv=0then 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 dobeginif FlatAtr.X [i, 1]= NRooms then // совпадает количество комнатbegin //x - атр. 4 = сумма площадей всех комнат, взятых из таблицы С,x:= 0;for l:=1 to NRooms dotryx:= x + StrToInt (FlatAtr.X [k, 2+l]);exceptend; // Запишем жилую площадь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 // Кликнули за пределами области данныхbeginVec. Add; FillStringGrid (SG, Vec);end;end;function TInputForm. GetVec: TVector;begincase PageControl1. ActivePageIndex of0: result:= Kvart;1: result:= Scheme;2: result:= GK;3: result:= People;4: result:= FlatAtr;else result:= Kvart;end;end;procedure TInputForm. DelBtnClick (Sender: TObject);varSG: TStringGrid;Vec: TVector;i: integer;beginSg:= FSGVector [PageControl1. ActivePageIndex+1];i:= Sg. Selection. Top; // удаляемая строкаVec:= GetVec;Vec. Delete(i);FillStringGrid (SG, Vec);end;procedure TInputForm. SortBtnClick (Sender: TObject);varSG: TStringGrid;Vec: TVector;i: integer;beginSg:= 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);beginKPod:= KSpinEdit. Value;end;procedure TInputForm.MSpinEditChange (Sender: TObject);beginM:= MSpinEdit. Value;end;procedure TInputForm.SGKeyPress (Sender: TObject; var Key: Char);beginif Key =#13 then // Если нажата клавиша Enter то…SGDblClick(Sender);end;procedure TInputForm. FormDestroy (Sender: TObject);beginPeople. Destroy;GK. Destroy;Scheme. Destroy;FlatAtr. Destroy;Kvart. Destroy;end;procedure TInputForm. CopyBtnClick (Sender: TObject);varSG: TStringGrid;Vec: TVector;i: integer;beginSg:= FSGVector [PageControl1. ActivePageIndex+1];i:= Sg. Selection.top; // Будем копировать эту строкуVec:= GetVec;Vec. AddCopy(i);FillStringGrid (SG, Vec);end;procedure TInputForm. FindBtnClick (Sender: TObject);varSG: TStringGrid;Vec: TVector;res,Row, Col: integer;InputString: String;beginSg:= 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 thenbeginApplication. MessageBox ('Указанное значение не найдено!', 'Ошибка', MB_OK);exit;end;Sg. Row:= res;end;procedure TInputForm.FButtonClick (Sender: TObject);varNKvart, 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 dobeginNKvart:= People.x [k, 3]; // Номер квартирыfl:= 0;for i:=1 to GK. Size dobeginif Gk.X [i, 1]=NKvart thenbegin 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 dobeginif Scheme.X [i, 3]=''then p:= 2else if Scheme.X [i, 4]=''then p:= 3 else p:=4;if NKvart <= x + (p*M) thenbegin NPod:= i; break; end;end;for i:=1 to Kvart. Size doif Kvart.X [i, 1]= NKvart thenbegin // получили искомую строку квартиры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;interfaceuses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,Buttons, ComCtrls, ExtCtrls;typeTReportForm = class(TForm)Panel1: TPanel;Panel2: TPanel;OKBtn: TButton;CancelBtn: TButton;ListBox1: TListBox;private{Private declarations}public{Public declarations}end;varReportForm: TReportForm;implementation{$R *.DFM}end.unit MyTypes;interfaceuses Sysutils, Contnrs;const MaxN = 100;typeTVarType = Variant; //TVarRec;TVarMas = array [1..MaxN] of TVarType;TVector = class (TInterfacedObject)private{Private declarations}FArr: array [1..MaxN] of TVarMas; //source dataFNum: integer; //number of itemsFCols: integer; //number of columnsFNames: array [1..MaxN] of String[MaxN]; //names of columnsfunction 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;publicSortId: 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;implementationconstructor TVector. Create;beginFNum:= 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);beginFArr[Index1] [Index2]:= value;end;function TVector. GetX (Index1, Index2: integer): TVarType;beginresult:= FArr[Index1] [Index2];end;function TVector. GetName (Index: integer): String;beginresult:= FNames[Index];end;procedure TVector. SetName (Index: integer; value: String);beginFNames[Index]:= Value;end;procedure TVector. Add();beginFNum:= FNum + 1;end;procedure TVector. AddCopy (Index: integer);beginFNum:= FNum + 1;FArr[FNum]:= FArr[Index];end;procedure TVector. Delete (Index: integer);var i: integer;beginif 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;beginif (X < Y) and (SortMode=1) // по возрастаниюthen Less:=trueelse Less:=false;end;vari, j, x: integer;y: TVarMas; //Variant;begini:= l; j:= r; x:= (l+r) DIV 2;repeatwhile 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 thenbeginy:= 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<>0then SortMode:= xMode;QSort (1, Size);if xMode=0 then // Поменяем режим сортировкиbeginif SortMode = 1then SortMode:=2 else SortMode:=1;end;end; // Процедура поиска значения Value в столбце Col с позиции Row // возвращает индекс найденой строки или 0 если ничего не найденоfunction TVector. Find (Col, Row: integer; Value: Variant): integer;var i: integer;beginresult:= 0;for i:=Row to FNum doif FArr[I] [Col] = Value thenbegin result:= i; exit; end;end;end.
|
|