Разработка клиент-серверного приложения управления персоналом предприятия

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    629,25 Кб
  • Опубликовано:
    2013-06-08
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Разработка клиент-серверного приложения управления персоналом предприятия

МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ БЕЛАРУСЬ

Учреждение образования «Гомельский государственный университет имени Франциска Скорины»

Математический факультет

Кафедра вычислительной математики и программирования








Дипломная работа

Разработка клиент-серверного приложения управления персоналом предприятия

Исполнитель Д.Г. Герман

Научный руководитель Л.А. Цурганова

Рецензент Е.И. Сукач



Гомель 2013

Содержание

Введение

. СУБД Oracle

.1 Как развивалось Oracle

.2 Архитектура Oracle

.3 Основные структуры данных

.4 Язык Oracle PL/SQL

.4.1 Типы данных и константы

.4.2 Управляющие операторы

.4.3 Циклы в PL/SQL

.4.4 Обработка исключений

. Delphi XE

.1 Создание простого проекта

. Разработка клиент-серверного приложения

.1 Постановка задачи

.2 Разработка базы данных

.3 Разработка клиент-серверного приложения

.4 Инструкция работы с приложением «Отдел кадров»

Заключение

Список использованных источников

Приложения

Введение


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

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

Интегральные системы, предназначенные для работы с базами данных, основаны на двух взаимодействующих компонентах - клиенте, отвечающем за организацию диалога с пользователем и несущем на себе бизнес-логику, и сервере, обеспечивающем многопользовательскую работу с данными и их целостность. Уровень зависимости бизнеса от информационных систем очень высок. Разработчики занимаются задачами реализации адекватной техническим требованиям функциональности и пользовательского интерфейса, оптимизацией обмена данными между различными компонентами системы. Корпоративные системы обладают высоким уровнем сложности, поэтому они должны быть надёжными и легкоуправляемыми. В результате таких требований появляется необходимость выделения из клиентской и серверной части системы компонентов, несущих строго определенную служебную функциональность.

Целью данной дипломной работы является разработка полнофункционального клиент-серверного приложения на языке Delphi XE, реализующего возможность управления персоналом на предприятии. Источником данных для дипломной работы должна стать СУБД Oracle.

1. СУБД Oracle


За последние 30 лет корпорация Oracle из рядового поставщика программного обеспечения в области баз данных выросла в признанного лидера рынка СУБД. Если ранние продукты были типичными для начинающей компании, то теперь качество и глубина СУБД Oracle таковы, что многие считают ее технические возможности передовыми в отрасли. В каждой новой версии совершенствуются масштабируемость, функциональность и средства управления базой данных.

В состав программного обеспечения, предлагаемого корпорацией Oracle, входит сервер приложений Application Server и ПО промежуточного слоя Fusion Middleware, средства бизнес-анализа и бизнес- приложения (E-Business Suite, PeopleSoft, JD Edwards, Siebel, Hyperion и Project Fusion).

1.1 Как развивалось Oracle


В 1983 году компания Relational Software Incorporated была переименована в Oracle Corporation, чтобы ее не путали с компанией Relational Technologies Incorporated. Тогда-то разработчики приняли критически важное решение написать на языке С переносимую версию Oracle (версию 3), которая могла бы работать не только в системе Digital VAX/VMS, но также в UNIX и на других платформах. К 1985 году было заявлено, что Oracle может работать более чем на 30 платформах. Некоторые из них сейчас воспринимаются как исторический курьез, однако другие все еще функционируют. (Помимо VMS, в число операционных систем, поддерживаемых ранними версиями Oracle, входили IBM MVS, HP/UX, IBM AIX и Solaris - вариант UNIX, созданный компанией Sun.) Корпорация Oracle сумела обратить в свою пользу и даже ускорить рост числа мини-компьютеров и UNIX-серверов, наблюдавшийся в 1980-е. Сегодня Oracle перенесена и на такие операционные системы, как Microsoft Windows и Linux. Помимо поддержки многочисленных платформ не потеряли актуальности и другие решения, принятые Oracle в 1980-е, в том числе дополнительные инструменты разработки программного обеспечения и поддержки принятия решений (бизнес-анализ), поддержка стандарта ANSI SQL на всех платформах и возможность работы в стандартных сетях. Начиная с середины 1980-х изменялась и модель развертывания: от выделенных серверов базы данных к архитектуре клиент/сервер и далее к интернет-вычислениям, когда клиенты на базе браузеров обращаются к приложениям базы данных.

По мере изменения моделей вычислений и развертывания корпорация Oracle включала в свою СУБД многие инновационные технические решения (от первой распределенной базы данных до поддержки виртуальной Java-машины в ядре базы данных и реализации grid-вычислений). Oracle предлагает поддержку новых стандартов, например языка XML, имеющего огромное значение для развертывания сервис-ориентированных архитектур (SOA). В таблице 1.1 приведен краткий перечень основных достижений Oracle по годам.

Таблица 1.1 - История достижений Oracle

Год

Функция

1977

Ларри Эллисон, Боб Майнер и Эд Оутс основали компанию Software Development Laboratories

1979

Oracle version 2: первая коммерческая реляционная СУБД, в которой применялся язык SQL

1983

Oracle version 3: единый набор исходных текстов Oracle для разных платформ

1984

Oracle version 4: переносимый набор инструментов, согласованность по чтению

1986

Oracle version 5: клиент-серверная реляционная СУБД

1987

Инструменты CASE и 4GL

1988

Oracle Financial Applications на основе реляционной СУБД

1989

Oracle6: блокировка на уровне строк и резервное копирование без остановки работы

1991

Oracle Parallel Server на массивно-параллельных платформах Oracle7: оптимизатор по стоимости

1993

Oracle version 7.1: распараллеливание операций, включая запросы, загрузку и создание индексов

1994

Универсальная база данных с механизмом расширения SQL за счет картриджей, тонким клиентом и сервером приложений

1996

Oracle8: объектно-реляционные расширения и поддержка сверхбольших баз данных (Very Large Database, VLDB)

1997

Oracle8i: виртуальная Java-машина (JVM) в ядре СУБД

1999

Oracle9J Application Server: инструменты Oracle, интегрированные в ПО промежуточного слоя

2001

Oracle9J Database Server: кластеры Real Application Cluster, OLAP и добыча данных, реализованные в СУБД

2003

Oracle Database 10g и Oracle Application Server 10g: grid-вычисления в Oracle Database 10g автоматизированы ключевые задачи управления

Год

Функция

2005

Oracle приобретает компанию PeopleSoft и объявляет о намерении приобрести компанию Siebel, тем самым расширяя линейку ERP- и CRM- приложений и свои предложения в области систем бизнес-анализа.

2007

Oracle Database 11g расширение средств автоматической настройки и сквозного управления изменениями с приобретением компании Hyperion в состав предлагаемых продуктов включена не зависящая от базы данных подсистема OLAP и приложения Financial Performance Management


1.2 Архитектура Oracle


Многие пользователи Oracle употребляют термины экземпляр и база данных как синонимы. На самом деле это разные (хотя и взаимосвязанные) вещи. Различие существенно, так как проливает свет на архитектуру Oracle.

В Oracle термином база данных описывается физическое хранилище информации, а термином экземпляр - программное обеспечение, работающее на сервере и предоставляющее доступ к информации в базе данных. Экземпляр исполняется на конкретном компьютере или сервере; база данных хранится на дисках, подключенных к этому серверу.

База данных - физическая сущность: она состоит из файлов, хранящихся на дисках. Экземпляр - сущность логическая: он состоит из структур в оперативной памяти и процессов, работающих на сервере. Например, Oracle использует область разделяемой памяти System Global Area (SGA, системная глобальная область) и области памяти в каждом процессе - Program Global Area (PGA, программная глобальная область). Экземпляр может быть частью одной и только одной базы данных. Напротив, с одной базой данных может быть ассоциировано несколько экземпляров. Время жизни экземпляров ограничено, тогда как база данных при должном обслуживании может существовать вечно.

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

База данных состоит из табличных пространств, управляющих файлов, журналов, архивных журналов, файлов трассировки изменения блоков, ретроспективных журналов и файлов резервных копий (RMAN).

Любые данные, хранящиеся в базе Oracle, должны находиться в каком- то табличном пространстве. Табличное пространство (tablespace) - это логическая структура; нельзя попросить операционную систему показать вам табличное пространство. Каждое табличное пространство состоит из физических структур, называемых файлами данных (data- files). В одном табличном пространстве может быть один или несколько файлов данных, тогда как каждый файл данных принадлежит ровно одному табличному пространству. При создании таблицы можно указать, в какое табличное пространство ее поместить. Тогда Oracle найдет для нее место в одном из файлов данных, составляющих указанное табличное пространство.

Начиная с версии Oracle Database l0g Release 2 для всех типов таблиц по умолчанию подразумеваются локально управляемые табличные пространства. В таком табличном пространстве можно создавать большие файлы, то есть при работе в 64-разрядных системах задействуется возможность создавать сверхбольшие файлы.

В Oracle9i появился механизм файлов, управляемых Oracle (Oracle Managed Files, OMF), позволяющий автоматически создавать, именовать и, если понадобится, удалять все файлы, составляющие базу данных. OMF упрощает обслуживание базы данных, поскольку не нужно помнить имена всех составляющих ее файлов. К тому же не возникают проблемы из-за ошибок человека, ответственного за именование файлов. Начиная с версии Oracle Database 10g сочетание OMF и табличных пространств с большими файлами делает работу с файлами данных совершенно прозрачной.

Максимальное количество файлов данных в базе Oracle - 64 000. Поскольку табличное пространство с большими файлами может содержать файл, который в 1024 раза больше файла в табличном пространстве с малыми файлами, а размер блока в табличном пространстве с большими файлами для 64-разрядных операционных систем составляет 32 Кбайт, общий размер базы данных Oracle может достигать 8 экзабайт (1 экзабайт = 1 000 000 терабайт). Табличные пространства с большими файлами предназначены для использования совместно с подсистемой автоматического управления хранением Automatic Storage Management (ASM), иными менеджерами логических томов, поддерживающими расслоение, и RAID-массивами.

База данных Oracle состоит из физических файлов трех основных типов:

.        управляющие файлы (control files);

.        файлы данных (datafiles);

.        журнальные файлы, или журналы (redo log files).

В управляющем файле хранится информация о местонахождении других физических файлов, составляющих базу данных, - файлов данных и журналов. Там же хранится важнейшая информация о содержимом и состоянии базы данных:

·        имя базы данных;

·        время создания базы данных;

·        имена и местонахождение файлов данных и журнальных файлов;

·        информация о табличных пространствах;

·        информация о файлах данных в автономном режиме;

·        история журналов и информация о порядковом номере текущего журнала;

·        информация об архивных журналах;

·        информация о наборах и фрагментах резервных копий, файлах данных и журналах;

·        информация о копиях файлов данных;

·        информация о контрольных точках.

Управляющие файлы не только содержат важную информацию, необходимую при запуске экземпляра, они полезны и при удалении базы данных. Начиная с версии Oracle Database 10g с помощью команды DROP DATABASE можно удалить все файлы, перечисленные в управляющем файле базы данных, а также сам управляющий файл.

При запуске экземпляра Oracle считываются параметры инициализации. Они определяют, как база данных должна использовать физическую инфраструктуру и иную конфигурационную информацию об экземпляре. Параметры инициализации хранятся в файле параметров инициализации экземпляра, который обычно называют просто INIT.ORA или, начиная с версии Огас1е9g, в репозитории, который называется файлом параметров сервера (или SPFILE). Количество обязательных параметров инициализации уменьшается с выходом каждой новой версии Oracle. В дистрибутиве Oracle есть пример файла инициализации, пригодный для запуска базы данных. Либо можно воспользоваться программой Database Configuration Assistant (DCA), которая подскажет обязательные значения.

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

Местоположение управляющих файлов определяется параметром инициализации CONTROL_FILES. Он позволяет задать несколько управляющих файлов, например:

_files = (/u00/oradata/control.001.dbf,

/u01/оradata/control.002.dbf,

/u02/oradata/control.003.dbf)

Этот параметр сообщает экземпляру, где искать управляющие файлы. Oracle гарантирует, что все копии управляющего файла одинаковы, то есть любые изменения вносятся синхронно. Если параметр не задан, Oracle создаст управляющий файл с именем по умолчанию или прибегнет к услугам компонента Oracle Managed Files (если тот активирован).

Многие базы данных Oracle развертываются на том или ином варианте RAID-массива, например RAID-1 или RAID-5, чтобы избежать потери данных в случае выхода диска из строя. Напрашивается вывод, что можно обойтись без нескольких копий, сохранив управляющий файл в защищенной дисковой памяти, и что утрата диска еще не означает утраты управляющего файла. Но этот вывод неправомерен по двум причинам:

Если в массиве с расслоением (striped array) или в зеркальной паре (mirror-pair) отказывает больше одного диска, то все данные, хранящиеся на этих дисках, теряются. Статистически это редкое событие, но все же такое случается, и тогда есть угроза повреждения или утраты управляющего файла. Поскольку вы и так будете по горло заняты восстановлением после множественных сбоев диска, вероятно, лучше при этом избежать хотя бы воссоздания управляющих файлов. Создание дополнительных копий, пусть даже хранящихся в избыточной дисковой памяти, - это дополнительный уровень защиты.

Избыточная дисковая память не поможет защититься от человеческих ошибок. Кто-то может случайно удалить или переименовать управляющий файл, затереть его другим или переместить в другое место. И зеркалированный диск честно отразит эти изменения. А при резервировании управляющих файлов хотя бы одна копия да останется. Не стоит беспокоиться о том, что запись в несколько управляющих файлов понизит производительность. Обновление управляющих файлов - ничто по сравнению с другими операциями дискового ввода/вывода, производимыми Oracle.

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

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

Журнальный файл содержит протокол всех изменений, произведенных в базе данных в результате выполнения транзакций и внутренних операций Oracle. Обычно измененные блоки кэшируются в памяти, поэтому в случае сбоя экземпляра может оказаться, что какие-то блоки не записались в файлы данных. Тогда можно воспользоваться протоколом, хранящимся в журнальных файлах, чтобы воспроизвести изменения, оставшиеся не записанными в момент сбоя, и тем самым обеспечить согласованность транзакции.

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

Экземпляр Oracle можно определить как область разделяемой памяти и набор фоновых процессов. Область разделяемой памяти экземпляра называется системной глобальной областью (System Global Area, SGA). Фактически SGA является не одной большой однородной областью памяти, а состоит из различных компонентов. Все процессы экземпляра, как системные, так и пользовательские, совместно обращаются к SGA. До версии Oracle9i размер SGA устанавливался при запуске экземпляра Oracle. Единственным способом изменения размера SGA или какой- то ее составляющей было изменение соответствующих параметров инициализации, остановка и перезапуск экземпляра. В Oracle9i мож но изменять размер SGA и ее компонентов, не останавливая экземпляр. В Oracle9i также введено понятие гранулы, то есть наименьшего объема памяти, который можно добавить или удалить из SGA.

В версии Oracle Database 10g появился механизм автоматического управления разделяемой памятью (Automatic Shared Memory Management, ASMM), а в Oracle Database 11g- механизм автоматического управления памятью (Automatic Memory Management, AMM) для компонентов SGA и PGA. Если задан параметр инициализации MEMORY_ TARGET (появился в Oracle Database llg) или SGA_TARGET, то база данных автоматически распределяет память между различными компонентами SGA, обеспечивая оптимальное управление памятью. К автоматически распределяемым компонентам относятся разделяемый пул (его размер вручную устанавливается с помощью параметра SHARED_POOL_SIZE), большой пул (LARGE_POOL_SIZE), пул Java (JAVAJPOOL_SIZE), кэш буферов (DB_CACHE_SIZE) и пул Streams (STREAMS_POOL_SIZE). Параметры инициализации, относящиеся к автоматическому управлению памятью, можно задать в Oracle Enterprise Manager.

Фоновые процессы взаимодействуют с операционной системой и между собой, управляя структурами памяти экземпляра. Эти процессы также управляют собственно базой данных на диске и выполняют общие действия по обслуживанию экземпляра.

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

Таблицы словаря данных всегда находятся в табличном пространстве SYSTEM. Имена динамических таблиц начинаются с префиксов V$ или GV$. Имена статических таблиц могут начинаться с одного из префиксов DBA_, ALL_ или USER_, обозначающего область видимости представленных в таблице объектов.

1.3 Основные структуры данных


В этом разделе описаны три основные структуры данных Oracle - таблицы, представления и индексы.

Таблица (table)- это базовая структура данных в любой реляционной СУБД. Таблица представляет собой набор строк. Каждая строка таблицы состоит из одного или нескольких столбцов. Если вы незнакомы с реляционными базами данных, то можете считать таблицу аналогом файла, а строку - аналогом записи в нереляционной базе.

В версии Oracle9i появились внешние таблицы. Как легко понять, данные внешней таблицы хранятся вне базы данных, обычно в плоском (неструктурированном) файле. Внешняя таблица допускает только чтение, обновить находящиеся в ней данные нельзя. Кроме прочего, внешняя таблица удобна для загрузки данных из файла или для выгрузки в файл.

В Oracle Database 11 g добавлена возможность создавать в таблице виртуальные столбцы. Они определяются выражением и, хотя результаты вычисления выражения не хранятся, приложение может обращаться к таким столбцам.

Представлением (view) в Oracle называется структура данных, определяемая SQL-командой. Эта SQL-команда хранится в базе данных. Когда в запросе встречается представление, выполняется определяющий его запрос и пользователю возвращаются данные из базовой таблицы. Сами представления не содержат данных, а лишь позволяют взглянуть на них так, как это определено в запросе.

Представления можно использовать в разных целях:

·        Чтобы упростить доступ к данным, хранящимся в разных таблицах;

·        Чтобы реализовать специальные требования к безопасности данных в таблице (например, создав представление с предложением WHERE, ограничивающим набор данных, доступных через это представление). Начиная с версии Oracle9i эту задачу можно решить с помощью механизма детального контроля доступа (finegrained access control), позволяющего автоматически ограничивать доступ к данным в зависимости от значения, хранящегося в строке;

·        Чтобы скрыть от приложения точную структуру базовых таблиц.

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

В общем случае в одной команде SQL допускается запись в столбец только одной какой-то базовой таблицы, указанной в определении представления. Есть дополнительные ограничения на операции INSERT, UPDATE и DELETE. Кроме того, при наличии в SQL-команде некоторых предложений обновить данные представления вообще невозможно.

Осуществить запись в не обновляемое представление позволяет триггер INSTEAD OF.

В версии Oracle8i появились материализованные представления. По существу, это не представления в описанном выше смысле, а физические таблицы, в которых хранятся заранее агрегированные данные, что позволяет заметно повысить производительность хранилищ данных.

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

Сервер Oracle автоматически модифицирует хранящиеся в индексе значения при изменении значений в соответствующих столбцах. Поскольку в индексе хранится меньше данных, чем в полной строке таблицы, и поскольку индексы организованы в виде специальной структуры, ускоряющей чтение, для доступа к данным в индексе требуется меньше операций ввода/вывода. Выборка строк по значениям индексированных столбцов может оказаться быстрее выборки по значениям, хранящимся только в базовой таблице. Кроме того, большинство индексов хранятся в отсортированном виде (по возрастанию или убыванию значений в зависимости от способа создания индекса). Из-за этого выборка строк по диапазону значений или возврат строк в отсортированном порядке гораздо быстрее выполняется по проиндексированным столбцам.

Индекс может быть уникальным (то есть в таблице не может быть двух строк с одинаковым значением индексного ключа) или неуникальным. Строки, для которых значение индексного ключа равно NULL, не включаются в индекс.

Индекс в Oracle - это физическая структура, используемая внутри базы данных. Ключом называется логическая сущность, обычно значение, хранящееся в индексе. Как правило, в документации Oracle эти термины взаимозаменяемы.

1.4 Язык Oracle PL/SQL

/SQL - это процедурное расширение языка SQL (Structured Query Language - структурированный язык запросов). SQL сегодня является повсеместно распространенным языком для выполнения запросов и изменений (хоть в его названии об этом и не говорится) в реляционных базах данных. Корпорация Oracle ввела в употребление PL/SQL для того, чтобы избавиться от некоторых ограничений, существующих в SQL, а также для того, чтобы иметь возможность предложить более полное программное решение разработчикам жизненно важных приложений, работающих с базами данных Oracle.

Как и в большинстве процедурных языков, в PL/SQL наименьшей значимой единицей группировки кода является блок. Блок - это конструкция, обеспечивающая выполнение фрагмента кода и определяющая границы видимости переменных и область действия обработчиков исключений. PL/SQL позволяет создавать анонимные блоки (блоки кода, не имеющие названия) и именованные блоки (это могут быть процедуры, функции или триггеры).

Блок PL/SQL может включать в себя до четырех разделов, лишь один из которых является обязательным.

<Заголовок>

<раздел объявлений>

<раздел исполнения>

<раздел исключений>;

·        Заголовок (Необязательный раздел) Используется только для именованных блоков. Заголовок определяет, каким образом будет вызываться именованный блок или программа.

·        Раздел объявлений (Необязательный раздел) Определяет переменные, курсоры и подблоки, которые упоминаются в разделах исполнения и исключений.

·        Раздел исполнения (Обязательный раздел) Содержит операторы, которые будет выполнять ядро PL/SQL при исполнении блока.

·        Раздел исключений (Необязательный раздел) Обрабатывает исключительные (по отношению к нормальной работе) ситуации (предупреждения и ошибки).

Если кто-то хочет сохранить анонимность, он не называет своего имени. Именно так и поступает анонимный блок в PL/SQL, в нем просто отсутствует раздел заголовка, такой блок начинается с DECLARE или BEGIN. Это означает, что его нельзя будет вызвать из какого-то другого блока, так как не на что установить ссылку. Анонимные блоки служат контейнерами для операторов PL/SQL и обычно включают в себя вызовы процедур и функций.

В общем виде синтаксис анонимного блока PL/SQL будет таким:

[ DECLARE...объявления...]

...один или несколько исполняемых операторов ...

[ EXCEPTION...операторы обработки исключений...];

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

При объявлении переменной или константы вы должны назначить ей тип данных. (PL/SQL за очень небольшими исключениями является языком со строгой типизацией.) PL/SQL предлагает полный набор предопределенных скалярных и составных типов данных, вы также можете создавать собственные пользовательские типы (которые также называют абстрактными типами данных).

1.4.1 Типы данных и константы

Все имеющиеся предопределенные типы данных определены в PL/ SQL-пакете STANDARD. Например, туда включены операторы, определяющие логический тип данных и два числовых типа:

OR REPLACE PACKAGE STANDARD ISBOOLEAN is (FALSE, TRUE);NUMBER is NUMBER_BASE;INTEGER is NUMBER(38,);

/SQL поддерживает все привычные типы данных и множество других. В разделе будет приведен лишь краткий обзор разнообразных предопределенных типов данных./SQL поддерживает строки как фиксированной, так и переменной длины, представленные как в традиционных кодировках, так и в кодировках Unicode. CHAR и NCHAR - это типы строк фиксированной длины, а VARCHAR2 и NVARCHAR2 - типы строк переменной длины. Рассмотрим объявление строки переменной длины, которая может вмещать до 2000 символов: DECLARE stroka VARCHAR2(2000);также поддерживает очень длинные символьные строки - типы LONG и LOB. Эти типы данных позволяют хранить и обрабатывать огромные объемы данных: LOB может содержать до 128 терабайт информации в Oracle Database 10g (используйте тип LONG только для совместимости с уже существующим кодом. Будущее за типами LOB!). К символьным типам данных LOB относятся CLOB (character large object - большой символьный объект) и NCLOB (National Language Support character large object - большой символьный объект с поддержкой национальных языков, многобайтный формат)./SQL поддерживает все более широкое множество числовых типов данных. Долгие годы рабочей лошадкой числовых типов данных был тип NUMBER, который можно использовать для десятичных значений с фиксированной и плавающей точкой, а также для целых значений. Приведем несколько примеров объявлений типа NUMBER:

NUMBER(9,2); -- фиксированная точка, семь

знаков слева и два справа_factor NUMBER; -- десятичное число с

плавающей точкой_to_pay NUMBER(2); -- целое число:= 1234567.89;_factor := 0.05;_to_pay := 52;;

Десятичная природа типа NUMBER оказывается чрезвычайно полезной при работе с денежными величинами. Вам не придется беспокоиться о возможных ошибках округления при переводе числа в двоичное представление. Например, записывая число 0.95, не стоит бояться, что от него через некоторое время останется только 0.949999968.

До выпуска версии Oracle Database 10g тип NUMBER был единственным числовым типом данных PL/SQL, полностью соответствующим типу данных базы данных. Это одна из причин столь широкого использования типа NUMBER. В Oracle Database 10g появилось еще два двоичных типа с плавающей точкой: BINARY.FLOAT и BINARY.DOUBLE. Как и NUMBER, оба новых типа поддерживаются как в PL/SQL, так и в базе данных. Правильно применяя их, можно добиться значительного повышения производительности за счет того, что математические операции над новыми типами выполняются аппаратной частью (когда это позволяет аппаратная платформа). PL/SQL поддерживает ряд числовых типов и подтипов, которые не соответствуют типам базы данных, но, тем не менее, весьма полезны. Упомянем особо PLS.INTEGER, целочисленный тип, для которого арифметические операции выполняются аппаратно. Счетчики циклов FOR реализованы типом PLS.INTEGER.

До появления версии Oracle9i Database мир дат Oracle ограничивался типом DATE, который позволял хранить как дату, так и время (с точностью до секунд). В Oracle9i Database появились два набора новых связанных типов данных: INTERVAL и TIMESTAMP. Новые типы значительно расширили возможности разработчиков PL/SQL по созданию программ, обрабатывающих и хранящих значения дат и времени с очень высокой точностью, а также вычисляющих и хранящих интервалы времени.

Приведем в качестве примера функцию, вычисляющую возраст человека:

OR REPLACE FUNCTION age (dob.in IN DATE)INTERVAL YEAR TO MONTHretval INTERVAL YEAR TO MONTH;(SYSDATE - dob.in) YEAR TO MONTH;;

/SQL поддерживает настоящий логический (булев) тип данных. Переменная этого типа может иметь лишь одно из трех значений: TRUE, FALSE и NULL.

Логические переменные позволяют сделать код удобочитаемым, даже в том случае, когда он содержит сложные логические выражения. Рас смотрим пример объявления переменной типа Boolean с присваиванием ей значения по умолчанию:

_eligible_for_discount BOOLEAN :=_in.balance > min_balance AND customer_in.pref_type = 'MOST FAVORED' AND customer_in.disc_eligibility;

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

Для объявления используется следующая синтаксическая конструкция:

Имя тип_данных [NOT NULL] [значение_по_умолчанию];

имя - это имя объявляемой переменной или константы, а тип_данных - это тип или подтип значений, которые могут присваиваться этой переменной. Включение в объявление выражения NOT NULL означает, что если в коде будет предпринята попытка присвоения вашей переменной значения NULL, то Oracle инициирует исключение. Выражение [значение по умолчанию] позволяет инициализировать переменную; оно необязательно для всех объявлений, кроме объявлений констант.

Для задания значения по умолчанию ключевое слово DEFAULT и оператор присваивания эквиваленты и взаимозаменяемы.

Существует всего два отличия в объявлениях переменных и констант: объявление константы включает в себя ключевое слово CONSTANT, и в нем обязательно указывается значение по умолчанию (которое на самом деле является не значением по умолчанию, а единственно возможным значением). Синтаксис объявления константы будет таким:

имя CONSTANT тип_данных [NOT NULL] := DEFAULT

значение_по_умолчанию;

1.4.2 Управляющие операторы

В PL/SQL существует два вида управляющих операторов: условные операторы и операторы перехода. Условные операторы, направляющие поток выполнения в определенную точку программы в зависимости от некоторого условия, необходимы практически в каждом фрагменте создаваемого кода. К таким операторам относятся IF-THEN-ELSE и CASE (операторы CASE доступны в версиях Oracle9/ Database и Oracle Database 10g) Существенно реже используется оператор безусловного перехода GOTO или явное указание на необходимость «ничего-не-делать» с помощью оператора NULL.

Оператор IF позволяет использовать в программах условную логику. Условие, указанное между IF и THEN, определяет, должно ли быть выполнено множество операторов, находящееся между THEN и END IF. Если условие вычислено как FALSE, то код не выполняется.

Оператор CASE позволяет выбрать для исполнения одну из нескольких последовательностей операторов. Операторы CASE появились в стандарте SQL уже в 1992 году, но Oracle SQL стал поддерживать CASE только в версии Oracle8i Database, а PL/SQL не поддерживал CASE вплоть до версии Oracle9/ Database Release 1.

1.4.3 Циклы в PL/SQL

PL/SQL поддерживает три вида циклов, обеспечивая тем самым возможность создания оптимального кода для решения любой конкретной задачи. В большинстве случаев, требующих использования цикла, применима любая из циклических конструкций. Однако выбор не самой удачной для конкретного случая конструкции может повлечь за собой написание множества дополнительных строк кода. В итоге получившийся модуль будет сложнее для восприятия и дальнейшего сопровождения.

Чтобы показать, как разные виды циклов по-разному решают поставленную перед ними задачу, рассмотрим далее три типа циклов. В каждом случае процедура вызывает display_total_sales для каждого года, номер которого находится в диапазоне между начальным и конечным значением аргумента.

Очевидно, в рассмотренных примерах цикл FOR требует наименьшего объема кода. Но использование данного типа цикла возможно лишь потому, что заранее известно, что тело цикла будет выполняться определенное количество раз. Во множестве других случаев количество проходов цикла должно быть переменным, так что применение цикла FOR будет невозможно.

Простой цикл называется простым, потому что он начинается просто со слова LOOP и заканчивается оператором END LOOP. Цикл завершается при выполнении внутри цикла оператора EXIT, EXIT WHEN или RETURN (или если внутри цикла инициировано исключение):

EXIT WHEN l_current_year > end_year_in; display_total_sales (l_current_year); l_current_year := l_current_year + 1;LOOP;

поддерживает циклы FOR со счетчиком и с курсором. Для цикла FOR со счетчиком вы указываете начальное и конечное целые значения, а все остальное за вас делает PL/SQL: проходит все значения внутри заданного диапазона и завершает цикл:

l_current_year IN start_year_in..end_year_in_total_sales (l_current_year);LOOP;

Цикл FOR с курсором имеет такую же базовую структуру, только в данном случае вместо указания верхней и нижней границ целочисленного диапазона следует явно задать курсор или использовать оператор SELECT:

l_current_year IN (* FROM sales_datayear BETWEEN start_year_in AND end_year_in)

- Теперь эта процедура принимает запись, неявно

- объявленную как sales_data%ROWTYPE..._total_sales (l_current_year);LOOP;

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

display_multiple_years (_year_in IN PLS_INTEGER ,_year_in IN PLS_INTEGER)l_current_year PLS_INTEGER := start_year_in; BEGIN(l_current_year <= end_year_in)_total_sales (l_current_year);_current_year := l_current_year + 1;LOOP;display_multiple_years;

1.4.4 Обработка исключений

В языке PL/SQL ошибки любого рода трактуются как исключения - нештатные ситуации для вашей программы. Исключения могут быть следующих видов:

·        Ошибка, инициированная системой (например, «недостаточно памяти» или «повторение значений в индексе»);

·        Ошибка, вызванная действиями пользователя;

·        Предупреждение, выдаваемое пользователю приложением./SQL перехватывает ошибки и реагирует на них, используя механизм обработчиков исключений. Обработчики исключений позволяют аккуратно отделить код обработки ошибок от исполняемых операторов. Для обработки ошибок используется событийная модель исполнения кода, а не линейная. Другими словами, вне зависимости от того, где было инициировано исключение, оно будет обработано одним и тем же обработчиком исключений в разделе исключений.

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

2. Delphi XE


Среда разработки Delphi является одним из популярнейших инструментов разработки прикладных программ. Она поддерживает так называемую быструю разработку, основанную на технологии визуального проектирования и событийного программирования, суть которой состоит в том, что среда разработки берет на себя большую часть рутины, оставляя программисту работу по созданию диалоговых окон (визуальное проектирование) и процедур обработки событий (событийное программирование). Производительность программиста при этом просто фантастическая!- это среда быстрой разработки приложений (RAD-среда, от Rapid Application Development - быстрая разработка приложений) на языке Delphi, в основе которого лежит хорошо знакомый многим программистам язык Pascal.

Изначально, вплоть до седьмой версии, Delphi была ориентирована на разработку Win32-приложений. После того как Microsoft стала продвигать технологию .NET, появилась Delphi 8 for The Microsoft .NET Framework - среда разработки .NET-приложений. Следующие версии Delphi выпускались в двух вариантах: для разработки Win32- и .NET-приложений. Теперь программистам стала доступна очередная версия Delphi - Embarcadero Delphi ХЕ. Embarcadero - новое имя выделенного из Borland подразделения (изначально оно называлось CodeGear). отвечающего за инструменты разработки приложений.ХЕ существует в трех вариантах: Professional, Enterprise и Architect. Каждый комплект включает набор средств и компонентов, обеспечивающих разработку высокоэффективных приложений различного назначения, в том числе работы с базами данных InterBase, Blackfish SQL, Firebird, MySQL, Microsoft SQL Server, Oracle и др. Чем выше уровень пакета, тем больше возможностей он предоставляет программисту. Так, например, в Enterprise и Architect есть компоненты, позволяющие работать с удаленным сервером Blackfish SQL, а в Professional - только с локальным.

Среда Delphi ХЕ доступна как отдельный инструмент разработки, а также как элемент Embarcadero RAD Studio ХЕ.ХЕ может работать в среде операционных систем Microsoft Windows ХР Home или Professional (SP2 или SP3), Microsoft Windows Vista SP2, Microsoft Windows Server 2003 (SP1) или 2008. а также в Microsoft Windows 7. Особых требований, по современным меркам, к ресурсам компьютера среда не предъявляет: процессор должен быть класса Intel Pentium (или совместимый) с частотой 1.4 ГГц (рекомендуется 2 ГГц и выше), 1 Гбайт оперативной памяти (рекомендуется 2 Гбайт и больше), 3.75 Гбайт свободного места на жестком диске (в том числе 750 Мбайт для Microsoft .NET Framework и Microsoft .NET SDK).

2.1 Работа в Delphi XE


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

Рисунок 2.1 - Окно приложения

Чтобы начать работу над новым приложением, нужно в меню File выбрать команду New - VCL Forms Application-Delphi.

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

Настройка формы (а также компонентов) осуществляется путем изменения значений свойств. Свойства объекта (формы, компонента) определяют его вид и поведение. Например, свойство caption определяет текст заголовка окна, а свойство Position - положение окна в момент появления на экране.

Для изменения значений свойств объектов используется вкладка Properties окна Object Inspector. В левой колонке этой вкладки перечислены свойства объекта, выбранного в данный момент, в правой - указаны значения свойств. Имя выбранного объекта отображается в верхней части окна Object Inspector, которое представлено на рисунок 2.2.

Рисунок 2.2 - Окно Object Inspector, вкладка Preporties

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

Компоненты, которые программист может использовать в процессе разработки программы, находятся в палитре компонентов (Tool Palette). На вкладках Standard, Additional и Win32 располагаются часто используемые компоненты пользовательского интерфейса

Чтобы на форму добавить компонент, например Edit, надо:

·        В палитре компонентов (окно Tool Palette) раскрыть вкладку Standard;

·        Сделать щелчок на значке компонента Edit (рис. 2.7). Здесь следует обратить внимание, что в палитре компонентов, рядом со значком указывается тип компонента, а не его название.

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

·        Сделать щелчок левой кнопкой мыши.

В результате на форме появляется поле редактирования - компонент Edit, что можно увидеть на рисунок 2.3

Рисунок 2.3 - Форма с полем для редактирования Edit

Каждому добавленному компоненту среда разработки присваивает имя, которое состоит из названия компонента и его порядкового номера. Например, первый компонент Edit получает имя Edit1, второй - Edit2. Программист путем изменения значения свойства Name может поменять имя компонента. Однако в простых программах имена компонентов, как правило, не изменяют.

Вид созданной формы подсказывает, как работает программа. Очевидно, что пользователь должен ввести в поля редактирования исходные данные и сделать щелчок на кнопке «Выполнить». Щелчок на изображении командной кнопки - это пример того, что называется событием.

Событие (event) - это то, что происходит во время работы программы. У каждого события есть имя. Например, щелчок кнопкой мыши - это событие click, двойной щелчок мышью - событие DblClick.

Следует понимать, что одни и те же действия, но выполненные над различными объектами, вызывают разные события. Например, щелчок (событие click) на кнопке «Выполнить» и щелчок на кнопке «Завершить» - это два разных события.

Реакцией на событие должно быть какое-либо действие. В Delphi реакция на событие реализуется как процедура обработки события. Таким образом, для того чтобы программа выполняла некоторую работу в ответ на действия пользователя, программист должен написать процедуру обработки соответствующего события.

Методику создания процедуры обработки события рассмотрим на примере обработки события click, которое возникает в результате щелчка на кнопке «Выполнить».

Чтобы приступить к созданию процедуры обработки события, сначала надо выбрать компонент, для которого создается процедура обработки события. Для этого в окне конструктора формы надо сделать щелчок левой кнопкой мыши на нужном компоненте (компонент можно выбрать также в раскрывающемся списке, который находится в верхней части окна Object Inspector). Затем в окне Object Inspector нужно открыть вкладку Events, рисунок 2.4.

Рисунок 2.4 - Окно Object Inspector, вкладка Events

Для того, что бы создать процедуру обработки события, сначала на вкладке Events надо выбрать событие, процедуру обработки которого необходимо создать, затем сделать двойной щелчок левой кнопкой мыши в поле редактирования, которое находится справа от имени события. В результате имя процедуры обработки события сформирует Delphi (имя процедуры обработки события образуется путем объединения имени компонента, для которого создается процедура обработки события, и имени события, например Button1Click), после чего написать тело процедуры.

TForm1.Button1Click(Sender: TObject);(handle, PWideChar('Добрый день: ' + Edit1.Text), 'Приветствие!', MB_ICONINFORMATION + MB_OK);;

Пробный запуск программы можно выполнить непосредственно из Delphi, не завершая работу со средой разработки. Для этого в меню Run надо выбрать команду Run или Run Without Debugging. Можно также сделать щелчок на кнопке Run, рисунок 2.5 или нажать клавишу <F9>.

Рисунок 2.5 - Запуск приложения

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

3. Разработка клиент-серверного приложения


3.1 Постановка задачи


Сегодня, наверное, нет ни одного предприятия, на котором нет ни одного сотрудника, хотя бы пару человек, но должно быть. Если сотрудников и всего пару человек, то можно вести учет их на бумажном носителе. А если представить себе предприятие, на котором работает не одна, и даже не две тысячи человек, а, к примеру, тысячи четыре, и таких предприятий достаточно в стране, тогда учет сотрудников вести на бумажном носителе будет затруднительно. Хотя нет, если люди постепенно приходят, то их дела можно оформлять постепенно, и это не создаст большого труда. Но сотрудники не всегда только приходят, они переводятся на другие должности, получают благодарственные письма, так же могут быть и выговоры, все это необходимо заносить в личное дело.

Если представить себе сотрудницу отдела кадров, у которой четыре тысячи дел, и к ней придет служебная записка, что сотрудник «Иванов», переводится на новую должность, и это надо занести в личное дело, поиск этого дела может занять большой промежуток времени. Вот тут как раз и приходят на помощь современные вычислительные системы, а именно, клиент-серверные приложения. Если разобрать всю туже ситуацию с переводом сотрудника «Иванова» на новую должность, но с учетом современных вычислительных систем, то все становится намного проще. Если даже база данных большая, и организованна не совсем правильно, на поиск сотрудника уйдет максимум 10 минут времени, и при этом сотруднице отдела кадров ничего делать не надо, просто сидеть и ждать, пока компьютер сам все сделает.

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

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

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

3.2 Разработка базы данных


Для решения поставленной задачи была разработана база данных, в которой будут храниться все данные. Для полноценной работы приложения в СУБД Oracle было создано 30 таблиц (таблица 3.1) Более детальное описание таблиц можно посмотреть в приложении А.

Таблица 3.1 - Список таблиц базы данных

Название таблицы

Описание таблицы

DOLSHNOST

Названия всех должностей на предприятии

DOLSHNOST PREFIX

Возможные префиксы должностей

DOLSHOST SUFIX

Возможные суффиксы должностей

INVALIDNOST

Перечень всех сотрудников, у которых имеется та или иная инвалидность

KEM VIDAN

Список органов, которые могут выдавать паспорта

KONTAKTNIE DANIE

Контактные данные сотрудников

LICO

Список всех лиц, которые, так или иначе, относятся к предприятию

MESTO RABOTI

Перечень всевозможных мест работы

MESTO SHITELSTVA

Полный адрес места жительства сотрудника

NASELENI PUNKT

Список населенных пунктов

OBLAST

Список областей

OBRAZOVANIE

Сведения об образовании сотрудников

PASPORT

Паспортные данные на сотрудника

PENSIONERI

Список пенсионеров предприятия

POL

Пол сотрудника

PRICHINA VIXODA NA PENSIE

Причина, по которой сотрудник вышел на пенсию

RABOTA

Информация о текущем и старом месте работы всех сотрудников предприятия

RAEN

Список районов

SPECIALNOST

Название специальности, которую сотрудник получил по окончании обучения

SROCHNAIA SLUSHBA

Информация о прохождении срочной службы

STRANA

Список стран

TIP INVALIDNOSTI

Перечень возможных инвалидностей

TIP NAS PUNKTA

Перечень типов населенных пунктов

TIP KONTAKT DANNIX

Перечень возможных контактных данных

TIP MESTA SHITELSTVA

Перечень возможных мест жительства

TIP PASPORTA

Перечень возможных типов паспорта

TIP UCH ZAVEDENIA

Перечень типов учебных заведений

UCHEBNOE ZAVEDENIE

Список названий учебных заведений

ULICA

Список улиц

ZVANIE

Список званий, которые сотрудники получали по окончании срочной службы


Схему таблиц базы данных можно увидеть на рисунке 3.1

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

Рисунок 3.1 - Схема таблиц базы данных

Листинг 3.1 - Создание таблицы, первичного ключа, связей, индекса

CREATE TABLE LICONUMBER(6) NOT NULL,VARCHAR2(100 BYTE) NOT NULL,VARCHAR2(100 BYTE) NOT NULL,VARCHAR2(100 BYTE) NOT NULL,_ROSHDENIA DATE NOT NULL,_POL NUMBER(6) NOT NULL,_MESTO_ROSHDENIA NUMBER(6) NOT NULL,_SROCH_SLUSHBA NUMBER(6),BLOB)TABLE LICO ADD (LICO_PKKEYTABLE LICO ADD (LICO_MESTO_ROSHDENIA_FKKEY (ID_MESTO_ROSHDENIA)NASELENI_PUNKT (ID),LICO_POL_FKKEY (ID_POL)POL (ID),LICO_SROCH_SLUSHBA_FKKEY (ID_SROCH_SLUSHBA)SROCHNAIA_SLUSHBA (ID));UNIQUE INDEX LICO_PK ON LICO

(ID);

Так как в СУБД Oracle нет механизма для автоматической генерации уникальных значений первичных ключей, для этой цели, для каждой таблицы базы данных, были созданы последовательности. Пример создания последовательности для выше описанной таблицы можно увидеть на листинге 3.2

Листинг 3.2 - Создание последовательностиSEQUENCE SQ_LICOWITH 00;

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

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

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

Мы пойдем вторым путем, т.к. наиболее наглядный для дальнейшего разработчика приложения, и ему нет необходимости знать SQL команды, он может просто вызвать хранимую процедуру и передать в нее соответствующие параметры. У этого метода есть еще один плюс, все эти команды будут выполнять на сервере приложения, что значительно ослабит нагрузку на сеть.

Хранимые процедуры были так же созданы для каждой таблицы, в зависимости от процедуры было описано разное количество параметров. Пример хранимой процедуры для добавления данных можно увидеть на листинге 3.3, пример приведен все для той же таблицы LICO. Все процедуры для добавления в новых данных в таблицы были объединены в один пакет INSERT_TO_TABLE, это было сделано для последующего удобства поиска процедур на добавление, ведь теперь они все в одном месте. Но это не главная причина для создания пакета, если вдруг были произведены какие-либо изменения в базе данных, не надо будет искать все процедуры и заново их компилировать на поиск возможных ошибок, достаточно просто перекомпилировать один пакет.

Листинг 3.3 - Создание процедуры для добавления записей в таблицуInsert_LICO (IN VARCHAR2,IN VARCHAR2,IN VARCHAR2,_ROSHDENIA IN DATE,_POL IN NUMBER,_MESTO_ROSHDENIA IN NUMBER,_SLUSHBA IN NUMBER,_PHOTO IN BLOB)INTO lico(sq_lico.NEXTVAL,,,,_roshdenia,_pol,_mesto_roshdenia,_slushba,_PHOTO);;;

Теперь мы можем добавлять данные, но иногда их надо изменять. Для этого создадим еще один пакет, и теперь назовем его UPDATE_TO_TABLE, в этом пакете будут храниться все процедуры на изменения данных в таблицах.

Пример процедуры на изменения данных можно посмотреть на листинге 3.4. Как видно из листинга типы данных переменных не совсем обычные, это не совсем типы данных, это ссылки на типы данных, с которыми мы будем работать. Это сделано для предотвращения возможных ошибок, т.к. таблица может быть обновлена, и, на пример, размер текстового поля в таблице увеличен, и чтобы не редактировать процедуру, она сразу берет тип столбца.

Листинг 3.4 - Создание процедуры для обновления данных в таблицеUPDATE_LICO (_id IN LICO.ID%TYPE,_fam IN lico.familia%TYPE,_imia IN lico.imia%TYPE,_otch IN LICO.OTCHESTVO%TYPE,_data_r IN LICO.DATA_ROSHDENIA%TYPE,_mesto_r IN LICO.ID_MESTO_ROSHDENIA%TYPE)licoLICO.FAMILIA = p_fam,.IMIA = p_imia,.OTCHESTVO = p_otch,.DATA_ROSHDENIA = p_data_r,.id_mesto_roshdenia = p_mesto_rLICO.ID = p_id;;UPDATE_LICO;

Для удаления записей в таблицах не было ничего сделано, т.к. СУБД Oracle сама все сделает за нас. Для этого достаточно написать пару слов при создании связей, а именно ON DELETE CASCADE. Пример использования этого оператора можно увидеть на листинге 3.5. Если будет удален сотрудник из базы данных, то вместе с ним удалиться вся информация о нем.

Листинг 3.5 - Создание связи с каскадным удалением данныхRABOTA_LICO_FKKEY (ID_SOTR) REFERENCES LICO (ID)DELETE CASCADE

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

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

Таблица 3.2 - Список представлений базы данных

Название представления

Описание представления

VW_FULL_RABOTA

Полная информация о местах работы

VW_FULL_REPORT

Полная информация о сотруднике и текущем месте работы

VW_FULL_SOTRUDNIKI

Полная информация о сотрудниках

VW_INVALIDNOST

Список сотрудник с инвалидностью

VW_KONTAKTI_SOTR

Все контакты сотрудников

VW_MESTO_SHITELSTVA

Места жительства сотрудников

VW_OBRAZOVANIE

Список полученных и получаемых образований сотрудниками

VW_PASPORTA

Информация о паспортах сотрудников

VW_PENSIONERI

VW_RABOTA

Краткая информация о текущем месте работы

VW_RABOTA_PENSIONERI

Последнее место работы пенсионеров

VW_SLUSHBA

Список мест службы сотрудников

VW_SOTRUDNIKI

Краткая информация о сотрудниках

Пример создания представления можно увидеть на листинге 3.6

Листинг 3.6 - Создание представленияOR REPLACE FORCE VIEW VW_FULL_RABOTA (,PREF, ID_PREF, DOLSHNOST, ID_DOLSHNOST, SUF, ID_SUF,_RAB, ID_MESTO_RABOTI, DATA_PRIEMA, DATA_OKONCHANIA,_SOTR)A.ID, A.NAZVANIE AS PREF, A.ID_PREF,.NAZVANIE AS DOLSHNOST,.ID AS ID_DOLSHNOST,.NOMER AS SUF, A.ID_SUF,_RABOTI.NAZVANIE AS mesto_rab,_RABOTI.ID AS ID_MESTO_RABOTI,.DATA_PRIEMA, RABOTA.DATA_OKONCHANIA,.ID_SOTR(SELECT P.ID,.NAZVANIE,.ID_PREF,.NOMER,.ID_SUF(SELECT RABOTA.ID,_PREFIX.NAZVANIE,_PREFIX.ID AS ID_PREFrabotaJOIN_prefixRABOTA.ID_DOLSH_PREF = DOLSHNOST_PREFIX.ID) PJOIN

(SELECT RABOTA.ID,_SUFIX.NOMER,_SUFIX.ID AS ID_SUFrabotaJOIN_sufixRABOTA.ID_DOLSH_SUF = DOLSHOST_SUFIX.ID) SP.ID = S.ID) A,,,_rabotiA.ID = RABOTA.IDRABOTA.ID_DOLSHNOSTI = DOLSHNOST.IDRABOTA.ID_MESTO_RAB = MESTO_RABOTI.IDBY RABOTA.DATA_PRIEMA DESC;

Так же было создано еще два пакета с процедурами, для добавления данных и редактирования, ADD_LICO и EDIT_LICO соответственно.

3.3 Разработка клиент-серверного приложения


Разработку клиент-серверного приложения начнем с создания нового проекта, с именем «OtdelKadrov.dproj», а главный модуль приложения назовем «Main.pas».

При окончании создания приложения, она состоит из 18 визуальных модулей, 2 оконных модулей и 2 не визуальных модулей, схему модулей приложения можно увидеть на рисунке 3.2.

Рисунок 3.2 - Схема приложения

Главный модуль приложения Main.pas является главным. Т.к. приложение организованно как MDI приложение, то мы для модуля Main установим свойство FormStyle равным fsMDIForm. Это означает что все формы, у которых свойство FormStyle будет установлено fsMDIChild будут отображаться внутри главной формы, т.е. они будут являться дочерними формами по отношению к главной форме.

Для соединения с базой данных были выбраны драйверы dbExpress, потому что они небольшие по объему и быстрые. Каждый драйвер выполнен в виде dll (на платформе Windows) или как so (shared library на Linux). Драйвер dbExpress предоставляет пять интерфейсов для выборки метаданных, выполнения операторов SQL и хранимых процедур, и возможность чтения записей из выборки в одном направлении (unidirectional cursor). При установке клиента от Oracle для работы с базой данных установлены необходимые dll - библиотеки, а именно dbxora.dll и oci.dll.

Для соединения с БД разработана процедура, пример которой можно увидеть на листинге 3.7

Листинг 3.7 - Соединение с базой данныхSQLConnection1 do;:= False;:= 'Oracle';Params do;('Database=' + DB);('User_name=' + user);('Password=' + pas);('Create=false');;;.ExecuteDirect('alter session set_numeric_characters=' + QuotedStr('.,'));

В данной процедуре происходит соединения с БД, а также необходимая настройка клиента. Соединение происходит при помощи компонента TSQLConnection. Для работы с базой данных одного лишь соединения недостаточно, т.е. доступ к данным есть, но посмотреть их мы не можем. Для просмотра данных необходимо использовать соответствующие компоненты. В данном случае использовались TSQLQuery (выполнение запросов к БД), TSQLStoredProc (выполнение хранимых процедур) и TSimpleDataSet (выполнение процедур, запросов или отображение таблиц).

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

Листинг 3.8 - Сохранение данных для авторизации:= TInifile.Create(ExtractFileDir(Application.ExeName) +

'\Auth.ini');.WriteString('Auth', 'DB', DB);.WriteString('Auth', 'user', user);.WriteString('Auth', 'pas', pas);.WriteBool('Auth', 'Check', True);

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

Листинг 3.9 - Динамическое создание формы:= TForm7.Create(Form1);.ShowModal;(Form7);;

Все команды управления приложением созданы в менеджере действий «ActionManager». Менеджер действий позволяет организовать логические группы действий, которые впоследствии могут быть повторно использованы в меню, навигационных панелях и панелях кнопок. Такие группы действий становятся доступными автоматически - по мере их добавления к объекту.

Для приложения выбран тип интерфейса Ribbon. При использовании интерфейса Ribbon большинство функций распределяются по вкладкам новой панели. Некоторые функции перенесены в выпадающие меню, появляющиеся при нажатии на кнопку слева от вкладок (кнопка «Office» в Office 2007 или «Файл» в 2010-м), и дополнительную кнопку в заголовке (меню быстрого вызова). Кнопки функций, которые нужны постоянно (отменить, повторить, сохранить), вынесены в заголовок окна. Для связи интерфейса и менеджера действий в свойстве интерфейса Ribbon, ActionManager установлено значение нашего менеджера действий ActionManager1.

Для группировки сотрудников написана процедура, листинг 3.10, с ее помощью фамилии сотрудников заносятся в ту или иную ветку дерева, а если нет соответствующей ветки, она создается и в нее помещается соответствующий сотрудник. Дерево реализовано с помощью компонента TreeView.

Листинг 3.10 - Формирование дерева сотрудниковTreeView1.Items do;SimpleDataSet1 do;not Eof do(obj);:= FieldByName('FAMILIA').AsString[1];^ := FieldByName('ID').AsInteger;:= FindNode(ferst);Node = nil then.Items.Add(nil, ferst);:= FindNode(ferst);;.Items.AddChildObject(Node,('FAMILIA').AsString + ' ' +('IMIA').AsString + FieldByName('OTCHESTVO').AsString, obj);;

Все узлы компонента TTreeView хранятся в свойстве Items класса TTreeNоdes и имеют тип TTreeNоde. У класса TTreeNоde нас интересуют два свойства Data - данное свойство принадлежит к типу Pоinter и является указателем для связанного с узлом объекта и Text - текст, который выводится в узле. Как видно из листинга 3.10, а именно из метода(Nоde:TTreeNоde; cоnst S:string; Ptr:Pоinter)

Где Node - узел, в который добавляется запись, S - это наше свойства Text, и Ptr - свойство Data.

В свойство Data мы заносим ID сотрудника, а в Text фамилию имя и отчество. Сделано это, что бы однозначно определить, какой сотрудник сейчас выбран и, конечно, для удобства пользователя, ведь ему нет необходимости знать первичный ключ выбранного сотрудника. Что бы извлечь первичный ключ достаточно выполнить одну строчку:= integer(Node.Data^);

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

Для реализации фильтрации сотрудников на форму был установлен компонент TEdit. Чтобы обновление найденных сотрудников происходило при каждом изменении значения данных в поле ввода, использовалось событие компонента OnChange. Пример обработчика можно увидеть на листинге 3.11. Фильтрация реализуется при помощи свойства Filter и Filtered компонента TSimpleDataSet. В свойстве Filter устанавливается значение фильтра, но фильтрация данных не происходит, для фильтрации и обновления набора данных, необходимо изменить значение свойства Filtered на True. Если же потребность в фильтрации пропадает, достаточно установить свойство Filtered в False.

Листинг 3.11 - Фильтрация данных

// настройка фильтраComboBox1.ItemIndex of

::= 'FAMILIA ';

::= 'IMIA ';

::= 'OTCHESTVO ';;.Filter := str + ' LIKE ' +(Edit1.Text + '%');.Filtered := True;

// перестроение спискаform2.Spisok = Alfavit then(False, Asceding)(False, Asceding);

Все отчеты приложения создаются в RaveReport. Для создания отчетов нам понадобятся TRvProject - основной компонент отчета, TRvSystem - для генерации отчетов и вывода их на принтер или в окно просмотра, а так же TRvDataSetConnection - для взаимодействия с источником данных, в нашем случае TSimpleDataSet. Соответственно, следует связать компонент TRvDataSetConnection с TSimpleDataSet, установив у него в свойстве DataSet значение SimpleDataSet1. Что касается компонента TRvProject, то его следует связать с компонентом RvSystem, для чего в свойстве Engine следует установить значение RvSystem1. Так же нас интересует свойство ProjectFile компонента TRvProject, сделано оно для выбора отчета, который будет в данный момент отображен. Для отчетов был создан отдельный каталог «Report», который находится в одном месте с приложением. Пример выполнения отчета можно увидеть на листинге 3.12

Листинг 3.12 - Выполнение отчета.Close;FileExists(ExtractFileDir(Application.ExeName) +

'\Report\Spisok.rav') then.ProjectFile:=ExtractFileDir(Application.ExeName)

+ '\Report\Spisok.rav';.Execute;;

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

3.4 Инструкция работы с приложением «Отдел кадров»


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

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

По мере возможности выполнения того или иного действия, становятся доступными соответствующие элементы управления.

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

При выборе тех или иных параметров соединения, процесс соединения может отличаться. К примеру, если отметить пункт «Больше не показывать это окно», то при последующем соединении с БД окно авторизации не отобразиться, и соединение будет произведено под сохраненными данными. Эти данные так же можно ввести вручную либо отменить сохранение данных, это можно сделать, вызвав настройки приложения.

Команда «Отсоединиться» наоборот, разрывает связь с базой данных. Остальные команды предназначены для управления дочерними формами, с помощь этих команд можно выполнить одно из действий:

·        Расположить все дочерние окна каскадно;

·        Расположить все дочерние окна по вертикали;

·        Расположить все дочерние окна по горизонтали;

·        Свернуть все дочерние окна;

·        Закрыть все дочерние окна.

Вся работа с приложением сосредоточена на вкладке «Отдел кадров»

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

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

Для удобства пользования приложением отображение списка организованно не просто в виде списка, а автоматически происходит группировка по первой букве фамилии, как видно на рисунке 3.7. Но этого может оказаться мало, к примеру, мы знаем в каком цехе или отделении работает сотрудник, но не знаем его имени и фамилии, для этого можно организовать группировку по месту работу, выбрав «Список» - «По местам работы», либо нажав «CTRL+F2». Для перехода обратно к группировке по алфавиту придется нажать «CTRL+F1», либо же «Список» - «По алфавиту». Кроме этого, для облегчения поиска нужного сотрудника имеется возможность поиска сотрудника по одному из фильтров: фамилии, имени или отчеству.

Чтобы еще немного упростить работу пользователя, можно выбирать порядок вывода сотрудников в список: по возрастанию или убыванию. Так же можно одним нажатием развернуть либо свернуть все дерево в независимости от того, в каком виде отображается список сотрудников. Для этих команд также реализованы горячие клавиши. Как видно на рисунках 3.7 и 3.8, при выборе одного из сотрудников, справа появляется наиболее востребованная информация о нем, а именно:

·        ФИО, пол, возраст, фото;

·        Актуальные контактные данные;

·        Текущее место работы.

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

·        нажав на панели инструментов «Личная карточка»;

·        двойным кликом левой клавиши мыши в дереве по его имени сотрудника;

·        воспользоваться сочетанием клавиш «CTRL+L».

На экране появится окно с детальной информацией

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

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

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

Для сохранения или отмены редактирования информации организованны соответствующие элементы управления «Сохранить» и «Отменить», которые представлены в виде пиктограмм птички и крестика соответственно. Они становятся доступны только после открытия информации на редактирование.

Если же информацию нельзя сразу поместить в элементы редактирования, то для них организованны дополнительные элементы управления и вспомогательные окна.

На окнах присутствуют дополнительные элементы, а именно кнопки «Добавить», с пиктограммой «Плюс», добавлены они для оперативного добавления информации в базу данных, если такой еще не имеется

Теперь мы можем просматривать информацию и редактировать ее, теперь надо иметь возможность добавлять новых сотрудников в нашу базу данных. Для этих целей организован пошаговый мастер, для вызова необходимо выбрать «Мастер», либо воспользоваться сочетанием клавиш CTRL+M.

Идя по мастеру, необходимо обязательно заполнять поля помеченные «*», остальные же поля заполняются по желанию пользователя. Во избежание непонимания того или иного поля для заполнения, мастер оборудован интерактивными подсказками. Для их отображения достаточно подвести указатель к непонятному полю, и в нижней части окна, появиться текст, описывающий это поле. Поле, где отображаются подсказки, расположено в нижней части окна на каждом шаге мастера.

После выполнения всех шагов мастера, предлагается еще раз посмотреть всю введенную информацию о сотруднике

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

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

В базе данных хранятся не только текущие работники завода, но так же и бывшие - пенсионеры. Для их отображения надо воспользоваться кнопкой «Пенсионеры». На экране приложения появится окно схожее с тем, в котором отображаются сотрудники, только с небольшим исключением, а именно, в окне с более востребованной информацией теперь выводиться не текущее место работы, а последнее и отображается дата выхода на пенсию.

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

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

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

Имеются еще небольшие изменения в работе с записями пенсионеров, теперь в личной карточке нельзя будет изменять место работы. И для просмотра дерева пенсионеров доступна группировка лишь по алфавиту. В остальном работа с записями пенсионеров полностью идентична работе с записями сотрудников. Тут также доступен поиск по записям, выбор порядка вывода записей, управление деревом, удаление записей.

На этом рассмотрение вкладки «Отдел кадров» почти завершено, осталась пару команда, одна из них «Печать». Команда предназначена для печати информации о сотрудниках. Она реализована в виде выпадающего списка

При выборе того или иного отчета на печать, пользователю предлагается на выбор список действий:

·        Предварительный просмотр отчета;

·        Вывод сразу на принтер, без предварительного просмотра;

·        Сохранение в файл.

Это все то, что касалось одного сотрудника, теперь перейдем к последней команде «Отчеты» на вкладке «Отдел кадров». Здесь собраны все отчеты, которые касаются всех сотрудников предприятия. Команда также организованна как выпадающий список.

Рассмотрим самый интересный из всех этих отчетов «Сотрудники (с параметрами)». Перед выполнением отчета, на экран выводится окно с предварительной настройкой фильтра. Здесь пользователь может настроить фильтры по своему желанию, после чего нажать на кнопку «Ок», и на экран выведется отчет с его фильтрами. Если отчет пользователя не удовлетворит, или пользователь точно не знает, какие ему нужны параметры, он может снять галочку с пункта «Закрыть окно после выполнения отчета». Если она стоит, после закрытия отчета окна тоже закроется, и всю введенную информацию придется вводить заново. Что может быть не совсем удобно, если точно не определенны параметры отчета.

Создадим отчет со следующими параметрами:

·        Место работы - АСУП

·        Возраст - 18-30

После чего запустим его на выполнение, и на экране появиться отчет

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

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

Но не все справочники удобно просматривать в виде списка, к примеру, справочник «Место работы», на рисунке 3.28 (справа), имеет ссылку сам на себя, такой справочник удобнее просматривать в виде дерева, что в приложении и организовано. В таком же виде, в виде дерева, организован справочник «Населенные пункты», на рисунке 3.28 (слева). Как видно из рисунка 3.26, на вкладке «Справочники» присутствует группа элементов «Управление», она содержит следующие команды:

·        Переход на первую строку справочника;

·        Переход на предыдущую строку;

·        Переход на следующую строку;

·        Переход на последнюю строку;

·        Обновить справочник;

·        Добавить новую строку;

·        Удалить строку;

·        Редактировать строку;

·        Сохранить изменения;

·        Отменить сделанные изменения.

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

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

Окнами можно управлять и через эти вкладки, для этого необходимо вызвать контекстное меню вкладки, которое содержит следующие пункты:

·        Свернуть;

·        Развернуть;

·        Восстановить;

·        Закрыть.

серверный персонал клиент кадр

Заключение


В данной работе разработано клиент-серверное приложение "Отдел кадров". Для разработки приложение использовалась интегрированная среда разработки Delphi XE, и СУБД Oracle 11g r2. Главным преимуществом данной среды является быстрота разработки программного обеспечения, благодаря наличию визуальных средств проектирования приложения, таких, как формы и набор визуальных и не визуальных компонентов, обладающих богатым функционалом. СУБД Oracle была взята за основу за свою надежность, функциональность и гибкость.

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

Данное клиент-серверное приложение можно внедрять и использовать на любом предприятии, на котором есть желание автоматизировать работу отдела кадров.

Список использованных источников


1)      Генник, Жд. Oracle SQL*Plus. Карманный справочник. 2-е издание. - СПб.: Питер. - 2004. - 189 с., ил.

)        Нанда, А., Фейерштейн, С. Oracle PL/SQL для администраторов баз данных. - Пер. с англ. - СПб: Символ-Плюс, 2008. - 496 с., ил.

)        Р. Гринвальд, Р. Стаковьяк, Жд. Стерн. Oracle 11g. Основы, 4-е издание. - Пер. с англ. - СПб.: Символ-Плюс, 2009. - 464 с., ил.

)        Наместников, А.М. Построение баз дынных в среде Oracle. Практический курс: Учеб. пособие для вузов. Ульяновск: УлГТУ, 2008. 118 с.

)        Культин, Н. Б. Основы программирования в Delphi XE. - СПб.: БХВ-Петербург, 2011. - 416 с.: ил. + CD-ROM - (самоучитель)

)        Осипов, Д.Л. Базы данных и Delphi. Теория и практика - СПб.: БХВ-Петербург, 2011. - 752 с.: ил. + DVD - (Профессиональное программирование)

)        Хомоненко, А.Д., Гофман, В.Э. Работа с базами данных в Delphi. - 3-е изд., перераб. и доп. - СПб.: БХВ-Петербург, 2005. - 640 с.: ил

8)      Русскоязычный форум по программированию [Электронный ресурс] // Русскоязычный форум по программированию - 2000. - Режим доступа - <http://www.sql.ru/>. - Дата доступа: 08.04.2013.

Приложения

 

Приложение А. Описание таблиц базы данных


Таблица A.1 - Таблица DOLSHNOST

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название должности


Таблица A.2 - Таблица DOLSHNOST_PREFIX

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название префикса должности


Таблица A.3 - Таблица DOLSHNOST_SUFIX

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NOMER

Number

Суффикс должности


Таблица A.4 - Таблица INVALIDNOST

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_TIP_INVALIDNOSTI

Number

Id типа инвалидности сотрудника

ID_LICO

Number

Id сотрудника

DATA_POLUCHENIA

Date

Дата получения инвалидности


Таблица A.5 - Таблица KEM_VIDAN

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название органа, который выдал паспорт

ID_OBLAST

Number

Id области, в которой выдали паспорт



Таблица A.6 - Таблица KONTAKTNIE_DANIE

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_TIP_DANNIX

Number

Id типа контактных данных

DANNIE

Varchar2

Контактные данные

ID_LICO

Number

Id сотрудника


Таблица A.7 - Таблица MESTO_RABOTI

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название места работы

ID_PODRAZDELENIE

Number

Id места работы


Таблица A.8 - Таблица LICO

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

FAMILIA

Varchar2

Фамилия сотрудника

IMIA

Varchar2

Имя сотрудника

OTCHESTVO

Varchar2

Отчество сотрудника

DATA_ROSHDENIA

Date

Дата рождения сотрудника

ID_POL

Number

Id пола сотрудника

ID_MESTO_ROSHDENIA

Number

Id места рождения сотрудника

ID_SROCH_SLUSHBA

Number

Id срочной служба

PHOTO

Blob

Фото сотрудника


Таблица A.9 - Таблица MESTO_SHITELSTVA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_NAS_PUNKTA

Number

Id населенного пункта

ID_ULICA

Number

Id улицы

DOM

Number

Номер дома

KVARTIRA

Number

Номер квартиры

KORPUS

Varchar2

Номер корпуса

DATE_ZASELENIA

Date

Дата заселения

DATE_VIPISKI

Date

Дата выписки

ID_TIP_MESTA_SH

Number

Id типа места жительства

ID_LICO

Number

Id сотрудника


Таблица A.10 - Таблица NASELENI_PUNKT

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название населенного пункта

ID_TIP_NAS_PUNKTA

Number

Id типа населенного пункта

ID_RAEN

Number

Id района, в котором расположен населенный пункт


Таблица A.11 - Таблица OBLAST

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE


Название области

ID_STRANI

Number

Id страны, в которой расположена область


Таблица A.12 - Таблица POL

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название пола

Таблица A.13 - Таблица OBRAZOVANIE

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_LICO

Number

Id сотрудника

ID_UCH_ZAVEDENIA

Number

Id учебного заведения

DATA_OKONCHANIA

Date

Дата окончания

NOMER_DIPLOMA

Varchar2

Номер полученного диплома

ID_SPECIALNOST

Number

Id полученной специальности

DATA_POSTUPLENIA

Date

Дата поступления


Таблица A.14 - Таблица PASPORT

Название столбца

Тип столбца

Описание

ID

Первичный ключ

ID_LICO

Number

Id сотрудника

ID_TIP_PASPORTA

Number

Id типа паспорта

NOMER

Number

Номер паспорта

SERIA

Varchar2

Серия паспорта

ID_KEM_VIDAN

Number

Id кем выдан паспорт

DATA_VIDACHI

Date

Дата выдачи паспорта

DATA_OKONCHANIA

Date

Дата окончания действия паспорта


Таблица A.15 - Таблица PENSIONERI

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_SOTR

Number

Id сотрудника

DATA_VIXODA

Date

Дата выхода на пенсию

ID_PRICHINA

Number

Id причина выхода на пенсию


Таблица A.16 - Таблица PRICHINA_VIXODA_NA_PENSIE

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Причина выхода на пенсию


Таблица A.17 - Таблица SROCHNAIA_SLUSHBA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_NAS_PUNKTA

Number

Id населенного пункта, где расположена часть

CHAST

Varchar2

Номер части

ID_ZVANIE

Number

Id звания по окончанию службы

DATA_NACHALA

Date

Дата начала служба

DATA_OKONCHANIA

Date

Дата окончания службы


Таблица A.18 - Таблица RABOTA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

ID_DOLSHNOSTI

Number

Id должности

ID_DOLSH_PREF

Number

Id префикса должности

ID_DOLSH_SUF

Number

Id суффикса должности

ID_MESTO_RAB

Number

Id места работы

DATA_PRIEMA

Date

Дата приема на работу

DATA_OKONCHANIA

Date

Дата окончания работы

ID_SOTR

Number

Id сотрудника



Таблица A.19 - Таблица RAEN

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название района

ID_OBL

Number

Id области, в которой находится район


Таблица A.20 - Таблица SPECIALNOST

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название специальности по окончанию учебы


Таблица A.21 - Таблица STRANA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название страны


Таблица A.22 - Таблица TIP_INVALIDNOSTI

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа инвалидности


Таблица A.23 - Таблица TIP_KONTAKT_DANNIX

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа контактных данных


Таблица A.24 - Таблица TIP_MESTA_SHITELSTVA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа места жительства



Таблица A.25 - Таблица TIP_NAS_PUNKTA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа населенного пункта


Таблица A.26 - Таблица TIP_PASPORTA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа паспорта


Таблица A.27 - Таблица TIP_UCH_ZAVED

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название типа учебного заведения


Таблица A.28 - Таблица UCHEBNOE_ZAVEDENIE

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название учебного заведения

ID_NAS_PUNKT

Number

Id населенного пункта, где расположено учебное заведение

ID_TIP_ZAVEDENIA

Number

Id типа учебного заведения


Таблица A.29 - Таблица ULICA

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название улицы


Таблица A.30 - Таблица ZVANIE

Название столбца

Тип столбца

Описание

ID

Number

Первичный ключ

NAZVANIE

Varchar2

Название звания по завершению срочной служба



Приложение Б. Модуль приложения Main.pas

Main;, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,, Ribbon, ActnMenus, RibbonActnMenus, ImgList, ActnList, ActnMan,, ActnCtrls, RibbonLunaStyleActnCtrls, Tabs, Menus,, ScreenTips, StdActns, DBActns, DB, DBClient, SimpleDS, RpBase,, RpRave, RpDefine, RpCon, RpConDS, DBXOracle, SqlExpr,, RibbonObsidianStyleActnCtrls, ComCtrls, FMTBcd;= class(TForm): TRibbon;: TRibbonPage;: TActionManager;_32_e: TImageList;: TRibbonApplicationMenuBar;: TRibbonQuickAccessToolbar;: TTabSet;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TRibbonGroup;: TAction;: TAction;: TRibbonPage;: TRibbonGroup;_16_e: TImageList;_32_d: TImageList;_16_d: TImageList;: TRibbonGroup;: TScreenTipsManager;: TRibbonGroup;: TWindowCascade;: TWindowTileHorizontal;: TWindowTileVertical;: TWindowMinimizeAll;: TWindowArrange;: TAction;: TAction;: TRibbonGroup;: TRibbonGroup;: TAction;: TPopupMenu;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;: TAction;: TRibbonPage;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TRibbonGroup;: TAction;: TRibbonGroup;: TDataSetFirst;: TDataSetPrior;: TDataSetNext;: TDataSetLast;: TDataSetInsert;: TDataSetDelete;: TDataSetEdit;: TDataSetPost;: TDataSetCancel;: TDataSetRefresh;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TSQLQuery;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;: TAction;AcConnectExecute(Sender: TObject);AcDisconnectExecute(Sender: TObject);N1Click(Sender: TObject);N2Click(Sender: TObject);N3Click(Sender: TObject);N5Click(Sender: TObject);PMTabSetPopup(Sender: TObject);TabSet1Change(Sender: TObject; NewTab: Integer; var AllowChange: Boolean);FormCreate(Sender: TObject);FormClose(Sender: TObject; var Action: TCloseAction);AcSettingExecute(Sender: TObject);AcExitExecute(Sender: TObject);FormShow(Sender: TObject);AcSotrudnikiExecute(Sender: TObject);AcPolExecute(Sender: TObject);AcDolshnostExecute(Sender: TObject);AcGalleryButtonExecute(Sender: TObject);blaExecute(Sender: TObject);AcMasterAddExecute(Sender: TObject);FindForm(Caption: string): Boolean;AcDeleteExecute(Sender: TObject);AcKartochkaExecute(Sender: TObject);AcPrintExecute(Sender: TObject);AcVsiaRabotaExecute(Sender: TObject);ScreenTipsManager1ShowScreenTip(Manager: TObject; Action: TBasicAction;ShowScreenTip: Boolean);WindowArrange1Execute(Sender: TObject);acAlfavitExecute(Sender: TObject);acMestoRabotiExecute(Sender: TObject);Action1Execute(Sender: TObject);acRefreshExecute(Sender: TObject);acSearchExecute(Sender: TObject);acFullCollapseExecute(Sender: TObject);acFullExpandExecute(Sender: TObject);acSortAscExecute(Sender: TObject);acSortDescExecute(Sender: TObject);acOProgrammeExecute(Sender: TObject);acPensioneriExecute(Sender: TObject);acNaselPunktiExecute(Sender: TObject);acVseSotrudnikiExecute(Sender: TObject);acReportExecute(Sender: TObject);acVsePensioneriExecute(Sender: TObject);acVozrastnoiExecute(Sender: TObject);acVseSotrudnikiParamExecute(Sender: TObject);acDolshnostPrefExecute(Sender: TObject);acDolshnostSufExecute(Sender: TObject);acInvaidnostExecute(Sender: TObject);acKemVidanExecute(Sender: TObject);acPrichinaNaPensiuExecute(Sender: TObject);acSpecialnostExecute(Sender: TObject);acTipKontaktDanixExecute(Sender: TObject);acTipMestaShitelstvaExecute(Sender: TObject);acTipNasPunktaExecute(Sender: TObject);acTipPasportaExecute(Sender: TObject);acTipUcZavedExecute(Sender: TObject);acUchZavedExecute(Sender: TObject);acUlocaExecute(Sender: TObject);acZvanieExecute(Sender: TObject);acMestoRabExecute(Sender: TObject);

{ Private declarations }

{ Public declarations }: string;: Integer;: Integer;;: TForm2;: TIniFile;= 0;= 1;= 'asc';= 'desc';= 0;= 1;Login, DataModule, Lico, Setting, Sotrudniki, Spravochnik, MasterAdd,, OProgramme, Pensioneri, SpravochnikNaselPunkt, Report,;

{$R *.dfm}TForm2.acAlfavitExecute(Sender: TObject);form5.Panel3.Visible then.Panel3.Visible := False;;Spisok <> Alfavit then.showAlfavit(True, Asceding);;TForm2.AcConnectExecute(Sender: TObject);

// Соединение с БДForm4.RadioButton2.Checked thenFileExists(ExtractFileDir(Application.ExeName) + '\Auth.ini') then:= TIniFile.Create(ExtractFileDir(Application.ExeName) + '\Auth.ini');.Connect(ini.ReadString('Auth', 'DB', ''), ini.ReadString('Auth', 'user', ''),.ReadString('Auth', 'pas', ''));;(0, pWideChar('Файл не найден!'), 'Не норм', MB_ICONWARNING + MB_OK);;:= TForm1.Create(Application);.ShowModal;.Free;;;

// удалить сотрудниками, со всеми ему подчиненными даннымиTForm2.AcDeleteExecute(Sender: TObject);: Integer;ActiveForm of::= Sotrudniki.id;::= Pensioneri.id;;MessageBox(handle,(

'Вы действительно хотитет удалить сотрудника?'#10#13'Вместе с сотрудником будут удаленны всего его данные!'),

'Удаление записи', MB_ICONQUESTION + MB_OKCANCEL) = mrOk thenSQLQuery1 do:= DataModule1.Login;;.Clear;.Add('delete from lico where id = :id');('id').AsInteger := id;();;ActiveForm = Sotrudnik thenSpisok = Alfavit then.showAlfavit(True, Asceding).ShowMestoRaboti(True, Asceding).ShowPensioneri(True, Asceding);;;TForm2.AcDisconnectExecute(Sender: TObject);

// Разрыв соединения с БД.Disconnect;;TForm2.FindForm(Caption: string): Boolean;: Integer;:= False;TabSet1.Tabs.IndexOf(Caption) > -1 theni := 0 to Form2.MDIChildCount - 1 doMDIChildren[i].Caption = Caption then[i].Show;:= True;;;TForm2.AcDolshnostExecute(Sender: TObject);not FindForm('Справочник - Должность') then:= 'DOLSHNOST';:= TForm6.Create(Form2);.Caption := 'Справочник - Должность';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acDolshnostPrefExecute(Sender: TObject);not FindForm('Справочник - Должность преффикс') then:= 'DOLSHNOST_PREFIX';:= TForm6.Create(Form2);.Caption := 'Справочник - Должность преффикс';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acDolshnostSufExecute(Sender: TObject);not FindForm('Справочник - Должность суффикс') then:= 'DOLSHOST_SUFIX';:= TForm6.Create(Form2);.Caption := 'Справочник - Должность суффикс';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.AcExitExecute(Sender: TObject);;;TForm2.acFullCollapseExecute(Sender: TObject);ActiveForm of:.TreeView1.FullCollapse;:.TreeView1.FullCollapse;;;TForm2.acFullExpandExecute(Sender: TObject);ActiveForm of:.TreeView1.FullExpand;:.TreeView1.FullExpand;;;TForm2.AcGalleryButtonExecute(Sender: TObject);

//;TForm2.acInvaidnostExecute(Sender: TObject);not FindForm('Справочник - Тип инвалидности') then:= 'TIP_INVALIDNOSTI';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип инвалидности';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.AcKartochkaExecute(Sender: TObject);ActiveForm of:form5.TreeView1.Selected.getFirstChild = nil then:= TForm3.Create(form5);.ShowModal;(Form3);;:form14.TreeView1.Selected.getFirstChild = nil then:= TForm3.Create(form14);.ShowModal;(Form3);;;;TForm2.acKemVidanExecute(Sender: TObject);not FindForm('Справочник - Кем выдан паспорт') then:= 'KEM_VIDAN';:= TForm6.Create(Form2);.Caption := 'Справочник - Кем выдан паспорт';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.AcMasterAddExecute(Sender: TObject);:= TForm7.Create(nil);.ShowModal;(Form7);;;TForm2.acMestoRabExecute(Sender: TObject);form19 = nil then:= TForm19.Create(Application);.Tabs.AddObject(form19.Caption, TObject(form19));.TabIndex := TabSet1.Tabs.Count - 1;.Show;;TForm2.acMestoRabotiExecute(Sender: TObject);form5.Panel3.Visible then.Panel3.Visible := False;;Spisok <> MestoRaboti then.ShowMestoRaboti(True, Asceding);;TForm2.acNaselPunktiExecute(Sender: TObject);form17 = nil then:= TForm17.Create(Application);.Tabs.AddObject(form17.Caption, TObject(form17));.TabIndex := TabSet1.Tabs.Count - 1;.Show;;TForm2.acOProgrammeExecute(Sender: TObject);:= TForm12.Create(Form2);.ShowModal;(Form12);;;TForm2.acPensioneriExecute(Sender: TObject);form14 = nil then:= TForm14.Create(Application);.Tabs.AddObject(form14.Caption, TObject(form14));.TabIndex := TabSet1.Tabs.Count - 1;.Show;;TForm2.AcPolExecute(Sender: TObject);not FindForm('Справочник - Пол') then:= 'POL';:= TForm6.Create(Form2);.Caption := 'Справочник - Пол';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acPrichinaNaPensiuExecute(Sender: TObject);not FindForm('Справочник - На пенсию') then:= 'PRICHINA_VIXODA_NA_PENSIE';:= TForm6.Create(Form2);.Caption := 'Справочник - На пенсию';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.AcPrintExecute(Sender: TObject);: Integer;ActiveForm of::= Sotrudniki.id;::= Pensioneri.id;;DataModule2 do_report.Close;_report.DataSet.Close;_report.Connection := DataModule1.SQLConnection1;_report.DataSet.SchemaName := DataModule1.Login;_report.DataSet.CommandText := 'select * from VW_REPORT where id = :id';_report.DataSet.ParamByName('id').AsInteger := id;_report.DataSet.Open;_report.Open;_report_2.Close;_report_2.DataSet.Close;_report_2.Connection := DataModule1.SQLConnection1;_report_2.DataSet.SchemaName := DataModule1.Login;_report_2.DataSet.CommandText :=

'select * from VW_KONTAKTI_SOTR where ID_LICO = :id';_report_2.DataSet.ParamByName('id').AsInteger := id;_report_2.DataSet.Open;_report_2.Open;_report_3.Close;_report_3.DataSet.Close;_report_3.Connection := DataModule1.SQLConnection1;_report_3.DataSet.SchemaName := DataModule1.Login;_report_3.DataSet.CommandText :=

'select ID_LICO, UCH_ZAVED, SPECIAL, DATA_POSTUPLENIA, DATA_OKONCHANIA, NOMER_DIPLOMA from VW_OBRAZOVANIE where id_lico = :id';_report_3.DataSet.ParamByName('id').AsInteger := id;_report_3.DataSet.Open;_report_3.Open;_report_4.Close;_report_4.DataSet.Close;_report_4.Connection := DataModule1.SQLConnection1;_report_4.DataSet.SchemaName := DataModule1.Login;_report_4.DataSet.CommandText :=

'select NAS_PUNKT, TIP_MESTA_SH, ULICA, KVARTIRA, KORPUS, DOM from VW_MESTO_SHITELSTVA where ID_LICO = :id and DATE_VIPISKI is null';_report_4.DataSet.ParamByName('id').AsInteger := id;_report_4.DataSet.Open;_report_4.Open;.Close;FileExists(ExtractFileDir(Application.ExeName) + '\Report\Kartochka.rav') then.ProjectFile := ExtractFileDir(Application.ExeName) + '\Report\Kartochka.rav';.Execute;(handle, pWideChar('Файл отчета не найден!'), 'Файл не найден',_ICONWARNING + MB_OK);;;TForm2.acRefreshExecute(Sender: TObject);Spisok = MestoRaboti then.ShowMestoRaboti(True, Asceding).showAlfavit(True, Asceding);;TForm2.acReportExecute(Sender: TObject);

//;TForm2.acSearchExecute(Sender: TObject);ActiveForm of:not form5.Panel3.Visible then.Edit1.Clear;.ComboBox1.ItemIndex := 0;.Panel3.Visible := True;.Edit1.SetFocus;;:not form14.Panel3.Visible then.Edit1.Clear;.ComboBox1.ItemIndex := 0;.Panel3.Visible := True;.Edit1.SetFocus;;;;TForm2.AcSettingExecute(Sender: TObject);.ShowModal;;TForm2.acSortAscExecute(Sender: TObject);ActiveForm of:Spisok = Alfavit then.showAlfavit(True, Asceding).ShowMestoRaboti(True, Asceding);:.ShowPensioneri(True, Asceding);;;TForm2.acSortDescExecute(Sender: TObject);ActiveForm of:Spisok = Alfavit then.showAlfavit(True, Desceding).ShowMestoRaboti(True, Desceding);:.ShowPensioneri(True, Desceding);;;TForm2.AcSotrudnikiExecute(Sender: TObject);form5 = nil then:= TForm5.Create(Application);.Tabs.AddObject(form5.Caption, TObject(form5));.TabIndex := TabSet1.Tabs.Count - 1;.Show;;TForm2.acSpecialnostExecute(Sender: TObject);not FindForm('Справочник - Специальность') then:= 'SPECIALNOST';:= TForm6.Create(Form2);.Caption := 'Справочник - Специальность';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.Action1Execute(Sender: TObject);(IntToStr(form5.TreeView1.Items.Item[0].Level));;TForm2.acTipKontaktDanixExecute(Sender: TObject);not FindForm('Справочник - Тип контактных данных') then:= 'TIP_KONTAKT_DANNIX';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип контактных данных';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acTipMestaShitelstvaExecute(Sender: TObject);not FindForm('Справочник - Тип места жительства') then:= 'TIP_MESTA_SHITELSTVA';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип места жительства';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acTipNasPunktaExecute(Sender: TObject);not FindForm('Справочник - Тип населенного пункта') then:= 'TIP_NAS_PUNKTA';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип населенного пункта';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acTipPasportaExecute(Sender: TObject);not FindForm('Справочник - Тип паспорта') then:= 'TIP_PASPORTA';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип паспорта';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acTipUcZavedExecute(Sender: TObject);not FindForm('Справочник - Тип учебного заведения') then:= 'TIP_UCH_ZAVEDENIA';:= TForm6.Create(Form2);.Caption := 'Справочник - Тип учебного заведения';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acUchZavedExecute(Sender: TObject);not FindForm('Справочник - Учебное заведение') then:= 'UCHEBNOE_ZAVEDENIE';:= TForm6.Create(Form2);.Caption := 'Справочник - Учебное заведение';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acUlocaExecute(Sender: TObject);not FindForm('Справочник - Улицы') then:= 'ULICA';:= TForm6.Create(Form2);.Caption := 'Справочник - Улицы';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.acVozrastnoiExecute(Sender: TObject);not FileExists(ExtractFileDir(Application.ExeName) + '\Report\Statistika.rav') then(handle, 'Файл отчета не найден!', 'Ошибка', MB_ICONWARNING + MB_OK);;;DataModule2 do_report.Close;_report.DataSet.Close;_report.Connection := DataModule1.SQLConnection1;_report.DataSet.SchemaName := DataModule1.Login;_report.DataSet.CommandText := 'select * from VW_STASTIKA';_report.DataSet.Open;_report.Open;.Close;.ProjectFile := ExtractFileDir(Application.ExeName) + '\Report\Statistika.rav';.Execute;;;TForm2.acVsePensioneriExecute(Sender: TObject);not FileExists(ExtractFileDir(Application.ExeName) + '\Report\Pensioneri.rav') then(handle, 'Файл отчета не найден!', 'Ошибка', MB_ICONWARNING + MB_OK);;;DataModule2 do_report.Close;_report.DataSet.Close;_report.Connection := DataModule1.SQLConnection1;_report.DataSet.SchemaName := DataModule1.Login;_report.DataSet.CommandText := 'select ROWNUM, A.* from (' +

'Select FAMILIA, IMIA, OTCHESTVO from VW_PENSIONERI order by FAMILIA) A';_report.DataSet.Open;_report.Open;.Close;.ProjectFile := ExtractFileDir(Application.ExeName) + '\Report\Pensioneri.rav';.Execute;;;TForm2.acVseSotrudnikiExecute(Sender: TObject);not FileExists(ExtractFileDir(Application.ExeName) + '\Report\Sotrudniki.rav') then(handle, 'Файл отчета не найден!', 'Ошибка', MB_ICONWARNING + MB_OK);;;DataModule2 do_report.Close;_report.DataSet.Close;_report.Connection := DataModule1.SQLConnection1;_report.DataSet.SchemaName := DataModule1.Login;_report.DataSet.CommandText := 'select ROWNUM, A.* from (' +

'Select FAMILIA, IMIA, OTCHESTVO from VW_SOTRUDNIKI order by FAMILIA) A';_report.DataSet.Open;_report.Open;.Close;.ProjectFile := ExtractFileDir(Application.ExeName) + '\Report\Sotrudniki.rav';.Execute;;;TForm2.acVseSotrudnikiParamExecute(Sender: TObject);:= TForm18.Create(Form2);.ShowModal;(Form18);;;TForm2.AcVsiaRabotaExecute(Sender: TObject);DataModule2 do_report.Close;_report.DataSet.Close;_report.Connection := DataModule1.SQLConnection1;_report.DataSet.SchemaName := DataModule1.Login;_report.DataSet.CommandText :=

'select DATA_PRIEMA, DATA_OKONCHANIA, PREF, DOLSHNOST, SUF, MESTO_RAB ' +

' from VW_FULL_RABOTA' + ' where ID_SOTR = :id and DATA_OKONCHANIA is not null' +

' order by DATA_PRIEMA';_report.DataSet.ParamByName('id').AsInteger := Sotrudniki.id;_report.DataSet.Open;_report.Open;_report_2.Close;_report_2.DataSet.Close;_report_2.Connection := DataModule1.SQLConnection1;_report_2.DataSet.SchemaName := DataModule1.Login;_report_2.DataSet.CommandText := 'select * from VW_REPORT where id = :id';_report_2.DataSet.ParamByName('id').AsInteger := Sotrudniki.id;_report_2.DataSet.Open;_report_2.Open;.Close;FileExists(ExtractFileDir(Application.ExeName) + '\Report\Spisok.rav') then.ProjectFile := ExtractFileDir(Application.ExeName) + '\Report\Spisok.rav';.Execute;;;;TForm2.acZvanieExecute(Sender: TObject);not FindForm('Справочник - Звания') then:= 'ZVANIE';:= TForm6.Create(Form2);.Caption := 'Справочник - Звания';.Tabs.AddObject(Form6.Caption, TObject(Form6));.TabIndex := TabSet1.Tabs.Count - 1;;;TForm2.blaExecute(Sender: TObject);

//;TForm2.FormClose(Sender: TObject; var Action: TCloseAction);

// Сохранение размера и положения окна при закрытии:= TIniFile.Create(ExtractFileDir(Application.ExeName) + '\Options.ini');WindowState = wsNormal then.WriteInteger('Form', 'Top', Top);.WriteInteger('Form', 'Left', Left);.WriteInteger('Form', 'Height', Height);.WriteInteger('Form', 'Width', Width);;.WriteBool('Form', 'WindowState', WindowState = wsMaximized);.Free;;;TForm2.FormCreate(Sender: TObject);

// var

// Item: TRibbonTabItem;

// Group: TCustomRibbonGroup;

// Настройки положения окна:= TIniFile.Create(ExtractFileDir(Application.ExeName) + '\Options.ini');:= ini.ReadInteger('Form', 'Top', 200);:= ini.ReadInteger('Form', 'Left', 200);:= ini.ReadInteger('Form', 'Height', 370);:= ini.ReadInteger('Form', 'Width', 620);ini.ReadBool('Form', 'WindowState', False) then:= wsMaximized:= wsNormal;.Free;;

// настройка ribbon панели.Groups[1].Visible := False;.Groups[2].Visible := False;.Groups[3].Visible := False;

// Item := Ribbon1.Tabs.Add;

// Item.Caption := 'Сотрудники';;TForm2.FormShow(Sender: TObject);

// Настройки аутентификации:= TIniFile.Create(ExtractFileDir(Application.ExeName) + '\Options.ini');ini.ReadBool('Conn DB', 'SaveAuth', False) then.RadioButton2.Checked := True.RadioButton1.Checked := True;.Free;;Form4.RadioButton2.Checked then:= TIniFile.Create(ExtractFileDir(Application.ExeName) + '\Auth.ini');.LabeledEdit3.Text := ini.ReadString('Auth', 'DB', 'Opa');.LabeledEdit1.Text := ini.ReadString('Auth', 'user', 'Opa');.LabeledEdit2.Text := ini.ReadString('Auth', 'pas', 'Opa');.Free;;;;TForm2.N1Click(Sender: TObject);(TabSet1.Tabs.Objects[TabSet1.TabIndex]).WindowState := wsMinimized;;TForm2.N2Click(Sender: TObject);(TabSet1.Tabs.Objects[TabSet1.TabIndex]).WindowState := wsMaximized;;TForm2.N3Click(Sender: TObject);(TabSet1.Tabs.Objects[TabSet1.TabIndex]).WindowState := wsNormal;;TForm2.N5Click(Sender: TObject);(TabSet1.Tabs.Objects[TabSet1.TabIndex]).Close;;TForm2.PMTabSetPopup(Sender: TObject);EnabledPopupMenu(Enabled: Boolean);.Enabled := Enabled;.Enabled := Enabled;.Enabled := Enabled;.Enabled := Enabled;;TabSet1.Tabs.Count = 0 then(False)(True);;TForm2.ScreenTipsManager1ShowScreenTip(Manager: TObject; Action: TBasicAction;ShowScreenTip: Boolean);

// ряд 1 из 3(Action = WindowCascade1) or (Action = WindowTileHorizontal1) or

(Action = WindowTileVertical1) then.DisplayOffset.Y := 69

// ряд 2 из 3if Action = WindowMinimizeAll1 then.DisplayOffset.Y := 47

// ряд 1 из 2if (Action = AcMasterAdd) or (Action = acFullExpand) or (Action = acFullCollapse) or

(Action = DataSetFirst1) or (Action = DataSetPrior1) or (Action = DataSetNext1) or

(Action = DataSetLast1) or (Action = DataSetRefresh1) then.DisplayOffset.Y := 61

// ряд 2 из 2if (Action = acSortAsc) or (Action = acSortDesc) or (Action = acReport) then.DisplayOffset.Y := 30.DisplayOffset.Y := 25;;TForm2.TabSet1Change(Sender: TObject; NewTab: Integer; var AllowChange: Boolean);: Integer;(TForm(TabSet1.Tabs.Objects[NewTab]) is TForm6) theni := 0 to MDIChildCount - 1 doMDIChildren[i].Caption = TabSet1.Tabs[NewTab] then[i].Show;(TabSet1.Tabs.Objects[NewTab]).Show;;TForm2.WindowArrange1Execute(Sender: TObject);MessageBox(handle, pWideChar('Вы действительно хотете закрыть все окна приложения?'),

'Закрыть все', MB_ICONQUESTION + MB_YESNO) = mrYes thenForm2.MDIChildCount > 0 do.MDIChildren[Form2.MDIChildCount - 1].Close;;

Приложение В. Модуль приложения Sotrudniki.pas

unit Sotrudniki;, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,, ToolWin, ComCtrls, ExtCtrls, StdCtrls, FMTBcd, DB, SqlExpr, DBClient,, ImgList, Menus, Ribbon, ActnList, ActnMan, Buttons;= class(TForm): TPanel;: TSplitter;: TPanel;: TTreeView;_16: TImageList;: TScrollBox;: TLabel;: TLabel;: TLabel;: TLabel;: TStaticText;: TStaticText;: TStaticText;: TSQLQuery;: TLabel;: TLabel;: TLabel;: TStaticText;: TStaticText;: TStaticText;: TImage;: TLabel;: TLabel;: TLabel;: TLabel;: TLabel;: TStaticText;: TStaticText;: TStaticText;: TStaticText;: TLabel;: TLabel;: TLabel;: TLabel;: TStaticText;: TStaticText;: TStaticText;: TPanel;: TEdit;: TSimpleDataSet;: TComboBox;: TPopupMenu;: TMenuItem;: TMenuItem;: TMenuItem;: TMenuItem;: TSimpleDataSet;: TMenuItem;: TSpeedButton;: TToolBar;: TBevel;FormActivate(Sender: TObject);FormClose(Sender: TObject; var Action: TCloseAction);ClearTree;TreeView1Change(Sender: TObject; Node: TTreeNode);FormCreate(Sender: TObject);Edit1Change(Sender: TObject);Edit1KeyPress(Sender: TObject; var Key: Char);ComboBox1Change(Sender: TObject);N1Click(Sender: TObject);N2Click(Sender: TObject);PopupMenu1Popup(Sender: TObject);N4Click(Sender: TObject);TreeView1DblClick(Sender: TObject);SpeedButton1Click(Sender: TObject);N6Click(Sender: TObject);

{ Private declarations }

{ Public declarations }showAlfavit(Active: boolean; Sort: string);ShowMestoRaboti(Active: boolean; Sort: string);;: TForm5;_StaticText: array [1 .. 4] of TStaticText;: integer;Main, DataModule, Lico, Pensioneri;

{$R *.dfm}

// Отображение дерева сотрудников по алфавитуTForm5.showAlfavit(Active: boolean; Sort: string);

// Поиск родителяFindNode(c: Char): TTreeNode;: integer;:= nil;i := 0 to TreeView1.Items.Count - 1 doTreeView1.Items.Item[i].Text = c then:= TreeView1.Items.Item[i];;;;: ^integer;: Char;: TTreeNode;

// если Active = True, перечитываю данные с БД,

// если False работаю с тем же набором данныхActive thenSimpleDataSet1 do;.Close;.SchemaName := DataModule1.Login;.CommandText := 'select ID, FAMILIA, IMIA, OTCHESTVO from VW_SOTRUDNIKI';.SortFieldNames := 'FAMILIA ' + Sort;.Open;;;;;TreeView1.Items do;SimpleDataSet1 do;not Eof do(obj);:= FieldByName('FAMILIA').AsString[1];^ := FieldByName('ID').AsInteger;:= FindNode(ferst);Node = nil then.Items.Add(nil, ferst);:= FindNode(ferst);;.Items.AddChildObject(Node, FieldByName('FAMILIA').AsString + ' ' +('IMIA').AsString + FieldByName('OTCHESTVO').AsString, obj);;;;;;.Spisok := Alfavit;;

// Отображение дерева сотрудников по месту работыTForm5.ShowMestoRaboti(Active: boolean; Sort: string);

// Поиск родителяFindNode(c: integer): TTreeNode;: integer;:= nil;i := 0 to TreeView1.Items.Count - 1 dointeger(TreeView1.Items.Item[i].Data^) = c then:= TreeView1.Items.Item[i];;;;: ^integer;: TTreeNode;

// если Active = True, перечитываю данные с БД,

// если False работаю с тем же набором данныхActive thenSimpleDataSet2 do;.Close;.SchemaName := DataModule1.Login;.CommandText := 'Select * from MESTO_RABOTI ' + 'where id_podrazdelenie is not null';.Open;;;SimpleDataSet1 do;.Close;.CommandText :=

'select lico.id, FAMILIA, IMIA, OTCHESTVO, id_mesto_rab, MESTO_RABOTI.nazvanie ' +

'from lico, rabota, MESTO_RABOTI ' + 'where lico.id = rabota.id_sotr ' +

'and rabota.id_mesto_rab = mesto_raboti.id and rabota.data_okonchania is null';.SortFieldNames := 'FAMILIA ' + Sort;.Open;;;;;TreeView1.Items do;SimpleDataSet2 do;not Eof do(obj);^ := FieldByName('ID').AsInteger;:= FindNode(FieldByName('ID_PODRAZDELENIE').AsInteger);(Node, FieldByName('NAZVANIE').AsString, obj);;;;SimpleDataSet1 do;not Eof do(obj);^ := FieldByName('id').AsInteger;:= FindNode(FieldByName('id_mesto_rab').AsInteger);(Node, FieldByName('FAMILIA').AsString + ' ' + FieldByName('IMIA').AsString +

' ' + FieldByName('OTCHESTVO').AsString, obj);;;;;;.Spisok := MestoRaboti;;TForm5.SpeedButton1Click(Sender: TObject);.Visible := False;.Filtered := False;form2.Spisok = Alfavit then(False, Asceding)(False, Asceding);.SetFocus;;TForm5.FormActivate(Sender: TObject);form2.TabSet1.Tabs.IndexOf(Form5.Caption) <> -1 then.TabSet1.TabIndex := form2.TabSet1.Tabs.IndexOf(Form5.Caption);

// TreeView1Change(TreeView1, TreeView1.Selected);;.RibbonPage2.Groups[1].Items[form2.RibbonPage1.Groups[1].Items.Count - 1].Visible := True;.RibbonPage2.Groups[1].Items[form2.RibbonPage1.Groups[1].Items.Count - 2].Visible := True;

// form2.acAlfavit.Enabled := True;.ActiveForm := Sotrudnik;;TForm5.FormClose(Sender: TObject; var Action: TCloseAction);;.TabSet1.Tabs.Delete(form2.TabSet1.Tabs.IndexOf(Form5.Caption));form14 = nil then.RibbonPage2.Groups[1].Visible := False;.RibbonPage2.Groups[2].Visible := False;.RibbonPage2.Groups[3].Visible := False;;;:= nil;;TForm5.FormCreate(Sender: TObject);: integer;

// очишаю все staticTexti := 0 to ComponentCount - 1 do(Components[i] is TStaticText) then

(Components[i] as TStaticText).Caption := '';_StaticText[1] := StaticText7;_StaticText[2] := StaticText8;_StaticText[3] := StaticText9;_StaticText[4] := StaticText10;

// настраиваем sqlquery и simpleDataset.SchemaName := DataModule1.Login;.DataSet.SchemaName := DataModule1.Login;.DataSet.SchemaName := DataModule1.Login;

// Строим дерево по алфавиту(True, Asceding);.RibbonPage2.Groups[1].Visible := True;.RibbonPage2.Groups[2].Visible := True;.RibbonPage2.Groups[3].Visible := True;

// form2.RibbonPage2.Groups[1].Items[form2.RibbonPage1.Groups[1].Items.Count - 1].Visible := False;

// form2.RibbonPage2.Groups[1].Items[form2.RibbonPage1.Groups[1].Items.Count - 2].Visible := False;;

// свернуть все деревоTForm5.N1Click(Sender: TObject);.FullCollapse;;

// развернуть все деревоTForm5.N2Click(Sender: TObject);.FullExpand;;

// показать личную карточкуTForm5.N4Click(Sender: TObject);.AcKartochkaExecute(form2.AcKartochka);;

// удалить сотрудеикаTForm5.N6Click(Sender: TObject);.AcDeleteExecute(form2.AcDelete);;

// настройка контекстноо меню при выборе элемента дереваTForm5.PopupMenu1Popup(Sender: TObject);EnablePopupMenu(Enabled: boolean);.Enabled := Enabled;.Enabled := Enabled;;TreeView1.Selected.getFirstChild = nil then(True)(False);;

// очистка дереваTForm5.ClearTree;: integer;i := 0 to TreeView1.Items.Count - 1 doTreeView1.Items.Item[i].Data <> nil then(TreeView1.Items.Item[i].Data);.Items.Clear;;

// изменение поля поиска по деревуTForm5.ComboBox1Change(Sender: TObject);.Clear;.SetFocus;;

// поля для ввода фильтра записей в наборе данныхTForm5.Edit1Change(Sender: TObject);: string;: integer;

// если ничего не введеноLength(Trim(Edit1.Text)) = 0 then.Filtered := False;form2.Spisok = Alfavit then(False, Asceding)(False, Asceding);

// настройка фильтраComboBox1.ItemIndex of

::= 'FAMILIA ';

::= 'IMIA ';

::= 'OTCHESTVO ';;.Filter := str + ' LIKE ' + QuotedStr(Edit1.Text + '%');.Filtered := True;

// перестроение спискаform2.Spisok = Alfavit then(False, Asceding)(False, Asceding);:= TreeView1.Items.Count - 1;form2.Spisok = MestoRaboti thenTreeView1.Items.Count > 0 theni >= 0 do(TreeView1.Items.Item[i].getFirstChild = nil) and

(TreeView1.Items.Item[i].Level < 2) then.Items.Delete(TreeView1.Items.Item[i]);(i);;

// развернуть все дерево.FullExpand;;;

// запрет ввода цифр, преобразование первого символа в загланую буквуTForm5.Edit1KeyPress(Sender: TObject; var Key: Char);: string;Key = #27 thenClick(SpeedButton1);;;Key in ['1' .. '9'] then:= #0;Edit1.SelStart = 0 then:= AnsiUpperCase(Key):= AnsiLowerCase(Key);:= s[1];;

// отображение информации о выбраном сотрулнике в деревеTForm5.TreeView1Change(Sender: TObject; Node: TTreeNode);: integer;: TMemoryStream;Node.getFirstChild <> nil then.AcKartochka.Enabled := False;.AcDelete.Enabled := False;.AcPrint.Enabled := False;.AcKartochka.Enabled := True;.AcDelete.Enabled := True;.AcPrint.Enabled := True;;Node.getFirstChild = nil then:= integer(Node.Data^);SQLQuery2 do

// Общая инфа;.Clear;.Add('select * from vw_FULL_SOTRUDNIKI where id = :id');('id').AsInteger := id;;.Caption := FieldByName('familia').AsString;.Caption := FieldByName('imia').AsString;.Caption := FieldByName('Otchestvo').AsString;.Caption := FieldByName('Pol').AsString;.Caption := FieldByName('vozrast').AsString;.Caption := FormatDateTime('DD MMM, YYYY', FieldByName('data_roshdenia')

.Value) + ' г.';

// загрузка картинки, если есть(FieldByName('photo') as TBlobField).IsNull = False then:= TMemoryStream.Create;

(FieldByName('photo') as TBlobField).SaveToStream(M);.Position := 0;.Picture.Bitmap.LoadFromStream(M);.Free;.Picture := nil;;

// контактные данниеi := 1 to 4 do_StaticText[i].Caption := '-';.Clear;.Add('select * from vw_kontakti_sotr where id_lico = :id');('id').AsInteger := id;;not Eof doFieldByName('NAZVANIE').AsString = 'Домашний' then.Caption := FieldByName('DANNIE').AsStringif FieldByName('NAZVANIE').AsString = 'Мобильный' then.Caption := FieldByName('DANNIE').AsStringif FieldByName('NAZVANIE').AsString = 'Рабочий' then.Caption := FieldByName('DANNIE').AsString.Caption := FieldByName('DANNIE').AsString;;;;

// Место работы.Clear;.Add('Select * from vw_rabota where id_sotr = :id');('id').AsInteger := id;;.Caption := FieldByName('MESTO_RABOTI').AsString;.Caption := FieldByName('DOLSHNOST').AsString;.Caption := FieldByName('DATA_PRIEMA').AsString;;;

// вызов личной карточки сотрудникаTForm5.TreeView1DblClick(Sender: TObject);.AcKartochkaExecute(Self);.

Похожие работы на - Разработка клиент-серверного приложения управления персоналом предприятия

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!