Разработка однотабличной базы данных
СОДЕРЖАНИЕ
ВВЕДЕНИЕ
. АНАЛИЗ ЗАДАНИЯ И ПОСТАНОВКА ЗАДАЧ
.1 Тема задания
.2 Функциональные требования
.3 Архитектурные требования к
программе
. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
. ПРОЕКТИРОВАНИЕ ПРОГРАММЫ
.1 Модуль Computers
.2 Модуль Hardware
.3 Модуль List
.4 Модуль Main
.5 Модуль View
.6 Модуль Sell
.7 Модульная схема программы
. РЕАЛИЗАЦИЯ ПРОГРАММЫ
.1 Реализация модуля Computers
.2 Реализация модуля Hardware
.3 Реализация модуля List
.4 Реализация модуля Main
.5 Реализация модуля View
.6 Реализация модуля Sell
. ТЕСТИРОВАНИЕ ПРОГРАММЫ
ЗАКЛЮЧЕНИЕ
ЛИТЕРАТУРА
ПРИЛОЖЕНИЕ А - МОДУЛЬНАЯ СХЕМА
ПРОГРАММЫ
ПРИЛОЖЕНИЕ
Б - ФУНКЦИОНАЛЬНАЯ СХЕМА ПРОГРАММЫ
ВВЕДЕНИЕ
Цель курса: ознакомление студента с
конструированием программ на высокоуровневых языках программирования на примере
Pelec C, закрепление и углубление знаний, полученных в процессе изучения
дисциплины «Конструирование программ и языки программирования». Также к задачам
можно отнести приобретение навыков самостоятельного творческого решения
общетеоретических и практических вопросов разработки различных программ.
Курсовая работа состоит в самостоятельном
изучении, анализе и решении инженерной задачи, содержащей элементы
практического и прикладного характера, является решающей оценкой знаний
студента, также умения самостоятельно изучить материал, необходимый для
разработки курсовой работы. Целью же курсовой является разработка программы,
имеющей реальное применение на практике.
В процессе выполнения курсовой работы студент
ознакомляется со специальной научно-технической литературой и документацией,
методическими и другими материалами.
Для студентов заочного отделения предполагается
изучение темы «однотабличная база данных».
1.
АНАЛИЗ ЗАДАНИЯ И ПОСТАНОВКА ЗАДАЧ
1.1 Тема задания
База данных содержит информацию о компьютерных
комплектующих на складе: тип (строка 10 символов),
- описание (строка 15 символов);
- основные характеристики (строка 20
символов);
- серийный номер (целое шестизначное
число);
- дата продажи (дд.мм.гггг);
- цена (целое число).
Дата продажи при вводе записи не указывается.
Дополнительно реализовать сервис продажи (при завершении указывается дата
продажи), а также отчет о продажах за определенный день.
1.2 Функциональные требования
Курсовая работа представляет собой создание
простейшей однотабличной базы данных. Программа должна осуществлять:
- Запись и загрузку файла базы данных
(бинарный файл).
- Добавление новых записей, удаление и
редактирование старых.
- Сортировать записи по любому из
полей базы данных в любом направлении.
- Фильтровать записи по значению
любого поля.
- Осуществлять поиск записей по
значению любого поля.
- Выполнять дополнительную обработку
(с сохранением результата в текстовый файл).
Обработку данных производить в динамическом
списке связанного хранения.
Выделение и освобождение динамической памяти
осуществляется поэлементно. Чтение и запись данных в файл базы данных
производится поэлементно. Программа должна обладать дружественным и интуитивно
понятным интерфейсом и проводить проверку на корректность вводимых данных.
1.3 Архитектурные требования к программе
Результатом выполнения курсовой работы должна
стать разработка программы в соответствии с темой. К программе предъявляются
следующие требования:
- аппаратная архитектура - IBM
PC совместимый
компьютер на базе x86
совместимого процессора;
- операционная система - MS
Windows 9x/ME/XP;
- язык программирования - язык С
стандарта ANSI С99 или C89;
- среда разработки - Pelles
C 4.5 и выше;
- вид приложения - WinGUI
(интерфейс должен быть построен с помощью WinApi).
2.
ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
По согласованию с преподавателем для реализации
проекта выбран язык С++, среда разработки Borland C++ Builder 6.
Выбор обоснован тем, что использование данной
среды позволит быстро сконструировать оконный интерфейс высокого уровня, не
отвлекаясь на его реализацию и настройку, сосредоточившись на реализации
классов бизнес-логики.
Для разработки проекта необходимо решить ряд
более мелких задач, на которые можно разбить проект:
- реализация класса табличной записи о
комплектующем. Потребуется изучить основы объектно-ориентированного
программирования для реализации класса, содержащего указанные по заданию типы
данных;
- реализация класса динамического
списка связного хранения. Потребуется изучить приемы реализации динамических
списков связного хранения, а также методов их обработки, таких как: вставка
элемента, удаление элемента, изменение элемента, сортировка списка, поиск и
фильтрация элементов списка;
- работа с файлами. Потребуется
изучить методы чтения/записи бинарных файлов и записи текстовых файлов;
- создание графического интерфейса
пользователя. Интерфейс должен быть дружелюбным и интуитивно понятным, поэтому
потребуется освоить методы заполнения и получения данных таблиц, а также
текстовых полей.
.
ПРОЕКТИРОВАНИЕ ПРОГРАММЫ
Программа будет разбита три окна: главное окно,
окно просмотра/редактирования комплектующих и окно продажи комплектующих. Также
будет создано три модуля: главный модуль, модуль с классом комплектующего и
модуль с классом динамического списка.
3.1
Модуль Computers
В этом модуле будет находиться главная функция
WINAPI WinMain,
согласовывающая работу модулей и реализующая диалоговую работу с пользователем.
3.2
Модуль Hardware
В этом модуле будет находиться реализация класса
комплектующего.
3.3
Модуль List
В этом модуле будет находиться реализация класса
динамического списка, включающая в себя его реализацию а также все методы
обработки списка, описанные в разделе 2.
3.4
Модуль Main
В этом модуле будет описано главное окно, к нему
буду подключены другие модули с окнами.
3.5 Модуль
View
В этом модуле будет находиться реализация
табличного представления данных, а также текстовые поля, позволяющие
редактировать и вводить новые данные.
3.6
Модуль Sell
В этом модуле будет находиться реализация класса
табличного представления данных, а также сервис продажи комплектующих.
.7 Модульная схема программы
В модуль main.h
будут подключаться интерфейсы других окон view.h
и sell.h.
В каждое из других окон будет подключен интерфейс динамического списка List.h.
Модульная схема программы изображена в приложении А.
.
РЕАЛИЗАЦИЯ ПРОГРАММЫ
4.1
Реализация модуля Computers
В этом модуле находится главная функция WINAPI
WinMain(HINSTANCE,
HINSTANCE, LPSTR,
int), согласовывающая
работу модулей и реализующая диалоговую работу с пользователем. (см. листинг
1):
Computers.cpp
#include
<vcl.h> //подключаем
библиотеку визуальных компонентов
#pragma
hdrstop
//---------------------------------------------------------------------------
USEFORM("main.cpp",
MainForm); //форма главного
окна
USEFORM("view.cpp",
ViewForm); //форма
просмотра комплектющих
USEFORM("sell.cpp",
SellForm); //форма продажи
комплектующих
//---------------------------------------------------------------------------
//HINSTANCE
- идентификатор текущего приложения;
//HINSTANCE
- идентификатор приложения, являющегося родительским для данного приложения;
//LPTSTR
- С-строка, содержащая параметры командной строки;
//int
nCmdShow - код вида
начального отображения окна
WINAPI WinMain(HINSTANCE, HINSTANCE,
LPSTR, int)
{
{>Initialize(); //инициализируем
приложение>CreateForm(__classid(TMainForm), &MainForm); //создаем
главное окно>CreateForm(__classid(TViewForm), &ViewForm); //создаем окно
просмотра комплектующих>CreateForm(__classid(TSellForm), &SellForm);
//создаем окно продажи комплектующих>Run(); //запускаем приложение
}(Exception &exception)
{ //обработка
исключений>ShowException(&exception);
}(...)
{
{Exception("");
}(Exception &exception)
{>ShowException(&exception);
}
}0;
}
4.2
Реализация модуля Hardware
В модуле Hardware
нет глобальных переменных, и интерфейс модуля содержит только прототипы
функций, которые могут быть вызваны в модуле List.cpp,
листинг 2 является листингом интерфейса Hardware.h.
интерфейс Hardware.h
#ifndef
HardwareH
#define HardwareH
#include <vcl.h>
#include <math.h>
#include <stdio.h>
#include <string.h>Hardware
//класс
{:
type[10]; //тип (строка
10 символов)
char
describe[15]; //описание
(строка 15 символов)
char
parametrs[20]; //основные
характеристики (строка 20 символов)
Integer
serial; //серийный номер
(целое шестизначное число)
TDate
dateSell; //дата продажи
(дд.мм.гггг)
Integer
price; //цена (целое
число)
//конструктор
__fastcall Hardware();
__fastcall Hardware(char *
inType,char * inDescribe, char * inParametrs, Integer inSerial, DATE
inDateSell, Integer inPrice);
__fastcall
~Hardware();//деструктор
};
#endif
В Hardware.cpp
находится реализация описанных методов класса (см. листинг 3):
реализация методов Hardware.cpp
#pragma
hdrstop
#include "Hardware.h"
#pragma package(smart_init)
//конструктор
__fastcall
Hardware::Hardware(){};
__fastcall Hardware::Hardware(char *
inType,char * inDescribe, char * inParametrs, Integer inSerial, DATE
inDateSell, Integer inPrice){(type,inType,10);(describe,
inDescribe,15);(parametrs, inParametrs,20);=inSerial;=inDateSell;=inPrice;
};
__fastcall
Hardware::~Hardware(){type;describe;parametrs;
}; //деструктор
4.3
Реализация модуля List
В модуле List
нет глобальных переменных, и интерфейс модуля содержит только прототипы
функций, которые могут быть вызваны в модуле view.cpp
и sell.cpp,
листинг 4 является листингом интерфейса List.h.
интерфейс List.h
#ifndef
ListH
#define
ListH
#include
"Hardware.h"
//класс элемента списка
class
element {
public:
Hardware
* hard; // комплектующее*
next; //Ссылка на следующий элемент списка
__fastcall element();
__fastcall ~element();
};
//класс спискаdyn_list {:*
head; // Первый элемент
(голова) списка* tail; // Последний элемент (хвост) списка
// Создание пустого списка
__fastcall dyn_list();
// Удаление списка
__fastcall ~dyn_list();
// Проверка списка на пустотуchk_empty();
// Включение в список нового
компонентаelement_in(Hardware* n);
// Удаление компонента из
спискаelement_del(Hardware * selHard);
// Изменение значения компонента
void element_edit(int ind, Hardware*
n);
// Изменение
значения
компонентаelement_edit(Hardware*
selHard, Hardware* n);
//загрузка
бинарного
файлаload(char
* fileName);
//перезапись бинарного файла
void
save(char
* fileName);
//перезапись бинарного файла
void saveSellOfDay(char *
fileName,AnsiString dateSell);
// Получение компонента из списка* get(Hardware
* selHard);
// Сортировка списка по типуsortType(bool inc);
// Сортировка списка по описаниюsortDescr(bool
inc);
// Сортировка списка по
характеристикамsortParam(bool inc);
// Сортировка списка по серийному номеруsortSerial(bool
inc);
// Сортировка списка по дате
продажиsortDate(bool inc);
// Сортировка списка по ценеsortPrice(bool inc);
};
#endif
Рассмотрим реализацию методов класса, для
однообразных методов (таких как сортировка) будет рассмотрена одна реализация
(см. листинг 5):
реализация методов List.cpp
#pragma
hdrstop
#include "List.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//конструктор
__fastcall
element::element(){
hard = new
Hardware();
next = NULL;
}
__fastcall
element::~element(){
free(hard);
}
// Создание пустого списка
__fastcall dyn_list::dyn_list(){=
NULL;
}
// Удаление
списка
__fastcall dyn_list::~dyn_list(){(head);
}
// Проверка списка на пустоту
bool dyn_list::chk_empty()
{
return (head==NULL);
}
// Включение в список нового компонента
void dyn_list::element_in(Hardware*
n)
{* c = new
element();(c->hard,n,sizeof(Hardware));>next = NULL;(chk_empty())=
c;>next = c; = c;
};
// Удаление компонента из списка
void dyn_list::element_del(Hardware
* selHard)
{
//поиск по типу* c = new element();=
get(selHard);(c == head)
{= c->next;;
}* r = new element();=
head;(r->next != c)= r->next;>next = c->next;c;
}
// Изменение значения элементаdyn_list::element_edit(Hardware
* selHard, Hardware* n)
{
//получение элемента* select = new
element();= head;(select != NULL){
//сравнение полей выделенного коплектующего с
копмлектующим из списка
if(
(strcmp(select->hard->type,selHard->type)==0)&&
(strcmp(select->hard->describe,selHard->describe)==0)&&
(strcmp(select->hard->parametrs,selHard->parametrs)==0)&&
(select->hard->serial ==
selHard->serial)&&
(select->hard->dateSell ==
selHard->dateSell)&&
(select->hard->price ==
selHard->price)
){ //если есть полное сходство
memcpy(select->hard,n,sizeof(Hardware));
//обновляем элемент новыми значениями
break; //прерываем поиск
}= select->next;
}
}
//загрузка бинарного
файлаdyn_list::load(char * fileName)
{*
f=fopen(fileName,"rb");size = 0;(&size,sizeof(int),1,f);
//обработка списка(int
i=0;i<size;i++) {* buf = new Hardware();(buf,sizeof(Hardware),1,f);_in(buf);
}
//обработка списка(f);
}
//перезапись бинарного
файлаdyn_list::save(char * fileName)
{*
f=fopen(fileName,"wb+");size = 0;
//обработка списка* recovery = new
element();= head;(head != NULL){++;= head->next;
}= recovery;
//обработка
списка(&size,sizeof(int),1,f);
//обработка списка
while(head
!= NULL){
Hardware * buf = new
Hardware();(buf,head->hard,sizeof(Hardware));(buf,sizeof(Hardware),1,f);=
head->next;
}= recovery;
//обработка списка
fclose(f);
}
//перезапись бинарного файла
void dyn_list::saveSellOfDay(char *
fileName,AnsiString dateSell)
{*
f=fopen(fileName,"w");("Продано ",StrLen("Продано
"),1,f);(dateSell.c_str(),strlen(dateSell.c_str()),1,f);(":\n",StrLen(":\n"),1,f);
//обработка списка* recovery = new
element();= head;(head != NULL){* buf = new
Hardware();(buf,head->hard,sizeof(Hardware));(buf->dateSell.DateString()==dateSell){(buf->type,StrLen(buf->type),1,f);("
",1,1,f);(buf->describe,StrLen(buf->describe),1,f);("
",1,1,f);(buf->parametrs,StrLen(buf->parametrs),1,f);("
",1,1,f);
//integer
переводим в строку для корректной записи
char * strBuf = new
char(15);(strBuf,IntToStr(buf->serial).c_str());(strBuf,StrLen(strBuf),1,f);("
",1,1,f);(buf->dateSell.DateString().c_str(),StrLen(buf->dateSell.DateString().c_str()),1,f);("
",1,1,f);
//integer
переводим в строку для корректной записи
strBuf = new
char(10);(strBuf,IntToStr(buf->price).c_str());(strBuf,StrLen(strBuf),1,f);("\n",1,1,f);
}= head->next;
}= recovery;
//обработка списка(f);
}
// Получение
элемента
из
списка*
dyn_list::get(Hardware * selHard)
{
//получение
элемента*
select = new element();= head;(select != NULL){
//сравнение полей выделенного коплектующего с
копмлектующим из списка
if(
(strcmp(select->hard->type,selHard->type)==0)&&
(strcmp(select->hard->describe,selHard->describe)==0)&&
(strcmp(select->hard->parametrs,selHard->parametrs)==0)&&
(select->hard->serial ==
selHard->serial)&&
(select->hard->dateSell ==
selHard->dateSell)&&
(select->hard->price ==
selHard->price)
){ //если есть полное сходство
break;
//прерываем поиск
}= select->next;
}select;
}
// Сортировка списка по
типуdyn_list::sortType(bool inc)
{
bool
swap = true;
//признак того, что была перестановка значений
//обработка списка* recovery = new
element();= head;(swap!=false){ = false;
//считаем что перестановок не будет
//обработка списка(head->next !=
NULL){(((inc==true)&&
(strcmp(head->hard->type,head->next->hard->type)>0))||
((inc==false)&&
(strcmp(head->hard->type,head->next->hard->type)<0))){
//копируем комплектующие в буферы*
buf = new Hardware();(buf,head->hard,sizeof(Hardware));* buf1 = new
Hardware();(buf1,head->next->hard,sizeof(Hardware));
//меняем местами
элементы(head->hard,buf1,sizeof(Hardware));(head->next->hard,buf,sizeof(Hardware));
= true; //устанавливаем
признак перестановки
}
head = head->next;
}= recovery;
//обработка списка
}
head = recovery;
}
…
программа база
данные список
4.4 Реализация модуля Main
В модуле Main
нет глобальных переменных, и интерфейс модуля содержит только прототипы
функций, которые могут быть вызваны в модуле (см. листинг 6):
интерфейс
Main.h
#ifndef mainH
#define mainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include
"view.h" //подключение
формы просмотра комплектующих
#include
"sell.h" //подключение
формы продажи комплектующих
//---------------------------------------------------------------------------TMainForm
: public TForm
{
__published: // IDE-managed
elementonents*Button1;*ButtonSell;__fastcall Button1Click(TObject
*Sender);__fastcall ButtonSellClick(TObject *Sender);: // User
declarations: // User declarations
__fastcall TMainForm(TComponent*
Owner);
};
//---------------------------------------------------------------------------PACKAGE
TMainForm *MainForm;
//---------------------------------------------------------------------------
#endif
Реализация методов модуля представляет собой
вызовы других окон (см. листинг 7):
Main.cpp
#include <vcl.h>
#pragma hdrstop
#include "main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource
"*.dfm"*MainForm;
//---------------------------------------------------------------------------
__fastcall
TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------__fastcall
TMainForm::Button1Click(TObject *Sender)
{>Show();
}
//---------------------------------------------------------------------------__fastcall
TMainForm::ButtonSellClick(TObject *Sender)
{>Show();
}
//---------------------------------------------------------------------------
4.5
Реализация
модуля
View
В модуле View
нет глобальных переменных, и интерфейс модуля содержит только прототипы
функций, которые могут быть вызваны в модуле (см. листинг 8):
интерфейс
view.h
#ifndef viewH
#define viewH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Grids.hpp>
#include
"List.h" //подключаем
класс списка
{
__published: // IDE-managed
elementonents*LabelType;*StringGrid1;*EditType;
…: // User declarations_list *
list; //список комплектующихselectedRow; //выделенная строка таблицы*
selectedHard; //выдыленный
элемент
списка
//направление сортировки для каждого поля
bool
typeInc;
bool
descrInc;paramInc;serialInc;dateInc;priceInc;: // User
declarations __fastcall
chek(); //функция
проверки корректности ввода
void __fastcall
fillFilteredList();
//функция вывод списка учитывая фильтр и поиск
__fastcall TViewForm(TComponent*
Owner);
};
//---------------------------------------------------------------------------PACKAGE
TViewForm *ViewForm;
//---------------------------------------------------------------------------
#endif
В модуле просмотра при отображении списка в
таблицу используется поиск и фильтр по каждому из полей класса. Поиск построено
по принципу вхождения подстроки, представленной значением текстового поля
поиска, в строку поля элемента списка, для вывода элемента достаточно, чтобы
хотя бы одно из полей удовлетворяло данному условию.
Далее список фильтруется используя тот же
принцип вхождения подстроки, однако в данном случае если хоть одно из полей
фильтра будет удовлетворять условию, то элемент списка будет отфильтрован. (см.
листинг 9):
функция обработки списка перед
выводом
void __fastcall TViewForm::fillFilteredList(){
//загружаем список
комплектующих->RowCount=1;//очищаем таблицу
//загружаем список в таблицу
//обработка списка
element * recovery = new element();
//создаем
буфер
recovery = list->head; //присваиваем ему
начало списка(list->head != NULL){ //делаем обход списка* hh = new
Hardware(); //буфер для коплектующего
memcpy(hh,list->head->hard,sizeof(Hardware));
//из
списка
копируем
StringGrid1->RowCount++; //добавляем строку в
таблицу
//заполняем строку таблицы параметрами->Cells[0][StringGrid1->RowCount-1]
= hh->type;
StringGrid1->Cells[1][StringGrid1->RowCount-1]
= hh->describe;->Cells[2][StringGrid1->RowCount-1] =
hh->parametrs;->Cells[3][StringGrid1->RowCount-1] =
hh->serial;->Cells[4][StringGrid1->RowCount-1] =
hh->dateSell;->Cells[5][StringGrid1->RowCount-1] = hh->price;
//осуществляем фильтрацию и поиск(
//если удовлетворяет условиям поиска по любому
из полей
( //длина строки должна быть не нулевой И строка
поиска должна входить в строку ячейки таблицы
((EditTypeSearch->Text.Length()>0)&&(StringGrid1->Cells[0][StringGrid1->RowCount-1].Pos(EditTypeSearch->Text)>0))||
((EditDescribeSearch->Text.Length()>0)&&(StringGrid1->Cells[1][StringGrid1->RowCount-1].Pos(EditDescribeSearch->Text)>0))||
((EditParametrsSearch->Text.Length()>0)&&(StringGrid1->Cells[2][StringGrid1->RowCount-1].Pos(EditParametrsSearch->Text)>0))||
((EditSerialSearch->Text.Length()>0)&&(StringGrid1->Cells[3][StringGrid1->RowCount-1].Pos(EditSerialSearch->Text)>0))||
((EditDateSellSearch->Text.Length()>0)&&(StringGrid1->Cells[4][StringGrid1->RowCount-1].Pos(EditDateSellSearch->Text)>0))||
((EditPriceSearch->Text.Length()>0)&&(StringGrid1->Cells[5][StringGrid1->RowCount-1].Pos(EditPriceSearch->Text)>0)
)
|| //ИЛИ все поля поиска пустые
(
(EditTypeSearch->Text.Length()==0)&&
(EditDescribeSearch->Text.Length()==0)&&
(EditParametrsSearch->Text.Length()==0)&&
(EditSerialSearch->Text.Length()==0)&&
(EditDateSellSearch->Text.Length()==0)&&
(EditDateSellSearch->Text.Length()==0)&&
(EditPriceSearch->Text.Length()==0)
)
) && //И НИ ОДНА ИЗ строк полей фильтра
не входит в ячейки таблицы
!( //длина строки должна быть не нулевой И
строка фильтра должна входить в строку ячейки таблицы
((EditTypeFilter->Text.Length()>0)&&(StringGrid1->Cells[0][StringGrid1->RowCount-1].Pos(EditTypeFilter->Text)>0))||
((EditDescribeFilter->Text.Length()>0)&&(StringGrid1->Cells[1][StringGrid1->RowCount-1].Pos(EditDescribeFilter->Text)>0))||
((EditParametrsFilter->Text.Length()>0)&&(StringGrid1->Cells[2][StringGrid1->RowCount-1].Pos(EditParametrsFilter->Text)>0))||
((EditSerialFilter->Text.Length()>0)&&(StringGrid1->Cells[3][StringGrid1->RowCount-1].Pos(EditSerialFilter->Text)>0))||
((EditDateSellFilter->Text.Length()>0)&&(StringGrid1->Cells[4][StringGrid1->RowCount-1].Pos(EditDateSellFilter->Text)>0))||
((EditPriceFilter->Text.Length()>0)&&(StringGrid1->Cells[5][StringGrid1->RowCount-1].Pos(EditPriceFilter->Text)>0))
)
){ // то оставляем строку в таблице
}else if( //ИНАЧЕ если хотябы одно из полей
введено
(EditTypeSearch->Text.Length()>0)||
(EditDescribeSearch->Text.Length()>0)||
(EditParametrsSearch->Text.Length()>0)||
(EditSerialSearch->Text.Length()>0)||
(EditDateSellSearch->Text.Length()>0)||
(EditDateSellSearch->Text.Length()>0)||
(EditPriceSearch->Text.Length()>0)||
(EditTypeFilter->Text.Length()>0)||
(EditDescribeFilter->Text.Length()>0)||
(EditParametrsFilter->Text.Length()>0)||
(EditSerialFilter->Text.Length()>0)||
(EditDateSellFilter->Text.Length()>0)||
(EditDateSellFilter->Text.Length()>0)||
(EditPriceFilter->Text.Length()>0)
){ //то удаляем строку, так как она не подходит
под все условия->RowCount--; //фильтруем элемент
}>head = list->head->next; //переходим
к следующему элементу
}>head = recovery;
//обработка
списка
}
Перед редактированием элемента или добавлением
нового значения занесенные в текстовые поля проходят проверку на корректность.
Сначала они укорачиваются до допустимой длины. На результат не влияет была ли
превышена длина. Далее поля серийного номера, даты продажи и цены проверяются
на соответствие своим форматам, при несоответствие действие будет отменено и
будет выведено сообщение. (см. листинг 10):
функция проверки вводимых
значений
//функция проверки корректности ввода__fastcall
TViewForm::chek()
{
//отрезаем лишнее, если имеется
EditType->Text =
EditType->Text.SubString(1,10);>Text =
EditDescribe->Text.SubString(1,15);>Text =
EditParametrs->Text.SubString(1,20);>Text =
EditSerial->Text.SubString(1,6);>Text =
EditDateSell->Text.SubString(1,10);
//если не все поля заполнены - отказ
if((EditType->Text.Length()==0)||
(EditDescribe->Text.Length()==0)||
(EditParametrs->Text.Length()==0)||
(EditSerial->Text.Length()==0)||
(EditDateSell->Text.Length()==0)||
(EditPrice->Text.Length()==0)
) {("Не все поля заполнены");false;
}
//если числовые поля не получается преобразовать
- отказ
try
{>Text.ToInt();>Text.ToInt();
} catch( EConvertError &ex ) {("Строка
серийного номера или цены числа не содержит");false;
}
//если числовые поля не получается преобразовать
- отказ
try {>Text.ToInt();>Text.ToInt();
} catch( EConvertError &ex ) {("Строка
серийного номера или цены числа не содержит");false;
}
//если дата имеет неправильный формат
try {dat ;//= new TDate();=
EditDateSell->Text;
} catch( EConvertError &ex ) {
ShowMessage("Дата имеет неверный формат");false;
}true;
}
После успешной проверки может быть вызвана
функция добавления элемента в список (см. листинг 11):
функция добавления элемента в
список
void __fastcall
TViewForm::ButtonAddClick(TObject *Sender)
{((selectedRow >
0)&&(chek()==true)){//если проверка пройдена
//добавляем в динамический список
Hardware * hard = new
Hardware();(hard->type,EditType->Text.c_str());(hard->describe,EditDescribe->Text.c_str());(hard->parametrs,EditParametrs->Text.c_str());>serial
= EditSerial->Text.ToInt();>dateSell = 0;>price =
EditPrice->Text.ToInt();>element_in(hard);
//добавляем
в
таблицу
StringGrid1->RowCount++; //добавляем строку в
таблицу
//заполняем
строку
таблицы->Cells[0][StringGrid1->RowCount-1]
= EditType->Text;->Cells[1][StringGrid1->RowCount-1] = EditDescribe->Text;->Cells[2][StringGrid1->RowCount-1]
= EditParametrs->Text;->Cells[3][StringGrid1->RowCount-1] =
EditSerial->Text;->Cells[4][StringGrid1->RowCount-1] =
"0:00:00";->Cells[5][StringGrid1->RowCount-1] =
EditPrice->Text;
}
}
При выделении строки таблицы данные выделенной
строки копируются в текстовые поля для редактирования (см. листинг 12):
функция обработки выделения
строки таблицы
void __fastcall
TViewForm::StringGrid1SelectCell(TObject *Sender, int ACol,ARow, bool
&CanSelect)
{(ARow > 0){ если
выбрали
не
шапку
таблицы>Text
= StringGrid1->Cells[0][ARow];>Text =
StringGrid1->Cells[1][ARow];>Text =
StringGrid1->Cells[2][ARow];>Text =
StringGrid1->Cells[3][ARow];>Text =
StringGrid1->Cells[4][ARow];>Text = StringGrid1->Cells[5][ARow];= ARow;
//копируем
выделенный
элемент
в
буфер=
new
Hardware();(selectedHard->type,StringGrid1->Cells[0][ARow].c_str());(selectedHard->describe,StringGrid1->Cells[1][ARow].c_str());(selectedHard->parametrs,StringGrid1->Cells[2][ARow].c_str());>serial
= StringGrid1->Cells[3][ARow].ToInt();>dateSell =
StringGrid1->Cells[4][ARow];>price
=StringGrid1->Cells[5][ARow].ToInt();
}
}
4.6 Реализация модуля Sell
Реализация модуля Sell
представляет собой заимствование методов модуля View
с учетом того, что в таблицу отображаются только те комплектующие, которые еще
не были проданы.
.
ТЕСТИРОВАНИЕ ПРОГРАММЫ
При запуске программы на экран будет выведен
рисунок 1.
главное окно
При выборе кнопки «комплектующие» будет открыто
окно просмотра и редактирования как на рисунке 2. Над каждой из колонок
располагается кнопка «сортировать» - при ее нажатии список будет отсортирован
по указанному полю, каждое нажатие меняет направление сортировки на
противоположное.
Для демонстрации работы поиска введем в поиск
характеристик цифру 4, будут отображены все комплектующие кроме последнего, у
которого нет этой цифры в характеристиках. (см. рисунок 3).
Окно просмотра и редактирования
комплектующих
демонстрация работы поиска
Теперь, если ввести в поле фильтра характеристик
цифру 2, то останется только одно комплектующее (см. рисунок 4):
демонстрация работы фильтра
Если заведомо неверно ввести значения в поля
серийного номера, даты продажи комплектующего, то при попытке добавления или
редактирования элемента с введенными значениями будут выведены сообщения об
ошибке, как на рисунке 5 и 6 соответственно:
сообщение об ошибке при
неверном вводе (серийный номер)
сообщение об ошибке при
неверном вводе (серийный номер)
Все произведенные изменения (редактирование,
удаление, добавление) сохраняются в бинарном файле после нажатия кнопки
«сохранить».
При выборе в главном окне кнопки «продажа» будет
открыто окно, как на рисунке 7, в нем будут отображаться только те
комплектующие, дата продажи у которых еще не установлена.
окно сервиса продажи
комплектующих
Для осуществления продажи достаточно выбрать
комплектующее и указать дату продажи, после чего нажать кнопку «продать». При
успешной проверки формата данных выбранное комплектующее исчезнет из
отображаемого списка.
Для получения отчета о продажах в текстовый файл
требуется в поле даты ввести требуемый день, после этого нажать кнопку «Продажи
за день» - будет сформирован текстовый файл «продажи.txt»
Сделанные изменения также требуется сохранять.
ЗАКЛЮЧЕНИЕ
В ходе реализации использование WINAPI
в основном ограничилось главной функцией WinMain,
остальные визуальные компоненты были использованы из библиотеки vlc,
это сделано с расчетом более быстрого создания интерфейса более высокого уровня
и более сложного, чем при использовании WINAPI.
Во время выполнения курсовой работы были
закреплены, систематизированы, углублены и развиты теоретические и практические
знания среды Borland
C++ Builder
6.0, знания по объектно-ориентированному программированию, выработан
индивидуальный подход по поиску, изучению и анализу специальной
научно-технической литературы и документации, справочников, стандартов,
методических и других материалов.
Программа реализована с дружественным,
интуитивно понятным и соответствующим функциональным требованиям интерфейсом.
Программа может быть легко усовершенствована
благодаря модульному строению, добавление новых модулей.
ЛИТЕРАТУРА
1 А.Я.
Архангельский «Программирование в C++ Builder 6», «Бином» г. Москва 2003
с.1150.
Бобровский
С. «Технологии С++ Builder. Разработка приложений для бизнеса» 2007 «ПИТЕР» с.
560.
Ю.П.Федоренко
«Алгоритмы и программы на C++ Builder» «ДМК Пресс» Москва 2010 с. 345
ПРИЛОЖЕНИЕ А –
МОДУЛЬНАЯ СХЕМА ПРОГРАММЫ
ПРИЛОЖЕНИЕ Б –
ФУНКЦИОНАЛЬНАЯ СХЕМА ПРОГРАММЫ