Изучаем компоненты borland c builder


Содержание

Иллюстрированный самоучитель по C++ Builder

Начало работы

Запускается C++ Builder обычным образом, т. е. выбором из меню Borland C++Builder 6 команды C++Builder 6 (рис. 1.1).

Рис. 1.1. Запуск C++Builder

Вид экрана после запуска C++ Builder несколько необычен (рис. 1.2). Вместо одного окна на экране появляются пять:

  • главное окно – C++Builder 6;
  • окно стартовой формы – Form1;
  • окно редактора свойств объектов – Object Inspector;
  • окно просмотра списка объектов – Object TreeView;
  • окно редактора кода – Unitl.cpp.

Окно редактора кода почти полностью закрыто окном стартовой формы.

Рис. 1.2. Вид экрана после запуска C++ Builder

В главном окне (рис. 1.3) находится меню команд, панели инструментов и палитра компонентов.

Окно стартовой формы (Form1) представляет собой заготовку главного окна разрабатываемой программы (приложения).

Рис. 1.3. Главное окно

Начинаем работать в C++Builder

Введение

Borland C++Builder — выпущенное компанией Borland средство быстрой разработки приложений, позволяющее создавать приложения на языке C++, используя при этом среду разработки и библиотеку компонентов Delphi. В настоящем занятии рассматривается среда разработки C++Builder и основные приемы, применяемые при проектировании пользовательского интерфейса.

Среда разработки C++Builder

C++Builder представляет собой SDI-приложение, главное окно которого содержит настраиваемую инструментальную панель (слева) и палитру компонентов (справа). Помимо этого, по умолчанию при запуске C++Builder появляются окно инспектора объектов (слева) и форма нового приложения (справа). Под окном формы приложения находится окно редактора кода.

Рис.1. Среда разработки C++Builder

Формы являются основой приложений C++Builder. Создание пользовательского интерфейса приложения заключается в добавлении в окно формы элементов объектов C++Builder, называемых компонентами. Компоненты C++Builder располагаются на палитре компонентов, выполненной в виде многостраничного блокнота. Важная особенность C++Builder состоит в том, что он позволяет создавать собственные компоненты и настраивать палитру компонентов, а также создавать различные версии палитры компонентов для разных проектов.

Компоненты C++Builder

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

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

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

Каждый компонент C++Builder имеет три разновидности характеристик: свойства, события и методы.

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

Рис.3. Инспектор объектов

Свойства компонентов

Свойства являются атрибутами компонента, определяющими его внешний вид и поведение. Многие свойства компонента в колонке свойств имеют значение, устанав иваемое по умолчанию (например, высота кнопок). Свойства компонента отображаются а странице свойств (Properties). Инспектор объектов отображает опубликованные (published) свойства компонентов. Помимо published-свойств, компоненты могут и чаще всего имеют общие (public), опубликованные свойства, которые доступны только во время выполнения приложения. Инспектор объектов используется для установки свойств во время проектирования. Список свойств располагается на странице свойств инспектора объектов. Можно определить свойства во время проектирования или написать код для видоизменения свойств компонента во время выполнения приложения.

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

События

Страница событий (Events) инспектора объектов показывает список событий, распознаваемых компонентом (программирование для операционных систем с графическим пользовательским интерфейсом, в частности, для Windows, предполагает описание реакции приложения на те или иные события, а сама операционная система занимается постоянным опросом компьютера с целью выявления наступления какого-либо события). Каждый компонент имеет свой собственный набор обработчиков событий. В C++Builder следует писать функции, называемые обработчиками событий, и связывать события с этими функциями. Создавая обработчик того или иного события, вы поручаете программе выполнить написанную функцию, если это событие произойдет.

Для того, чтобы добавить обработчик событий, нужно выбрать на форме с помощью мыши компонент, которому необходим обработчик событий, затем открыть страницу событий инспектора объектов и дважды щелкнуть левой клавишей мыши на колонке значений рядом с событием, чтобы заставить C++Builder сгенерировать прототип обработчика событий и показать его в редакторе кода. При этом автоматически генерируется текст пустой функции, и редактор открывается в том месте, где следует вводить код. Курсор позиционируется внутри операторных скобок < . >. Далее нужно ввести код, который должен выполняться при наступлении события. Обработчик событий может иметь параметры, которые указываются после имени функции в круглых скобках.

Рис.4. Прототип обработчика событий.

Методы

Метод является функцией, которая связана с компонентом, и которая объявляется как часть объекта. Создавая обработчики событий, можно вызывать методы, используя следующую нотацию: ->, например:

Отметим, что при создании формы связанные с ней модуль и заголовочный файл с расширением *.h генерируются обязательно, тогда как при создании нового модуля он не обязан быть связан с формой (например, если в нем содержатся процедуры расчетов). Имена формы и модуля можно изменить, причем желательно сделать это сразу после создания, пока на них не появилось много ссылок в других формах и модулях.

Менеджер проектов

Файлы, образующие приложение — формы и модули — собраны в проект. Менеджер проектов показывает списки файлов и модулей приложения и позволяет осуществ ять навигацию между ними. Можно вызвать менеджер проектов , выбрав пункт меню View/Project Manager. По умолчанию вновь созданный проект получает имя Project1.cpp.

Рис.5. Менеджер проектов

По умолчанию проект первоначально содержит файлы для одной формы и исходного кода одного модуля. Однако большинство проектов содержат несколько форм и модулей. Чтобы добавить модуль или форму к проекту, нужно щелкнуть правой кнопкой мыши и выбрать пункт New Form из контекстного меню. Можно также добавлять существующие формы и модули к проекту, используя кнопку Add контекстного меню менеджера проектов и выбирая модуль или форму, которую нужно добавить. Формы и модули можно удалить в любой момент в течение разработки проекта. Однако, из-за того, что форма связана всегда с модулем, нельзя удалить одно без удаления другого, за исключением случая, когда модуль не имеет связи с формой. Удалить модуль из проекта можно, используя кнопку Remove менеджера проектов.

Если выбрать кнопку Options в менеджере проектов, откроется диалоговая панель опций проекта, в которой можно выбрать главную форму приложения, определить, какие формы будут создаваться динамически, каковы параметры компиляции модулей (в том числе созданных в Delphi, так как C++Builder может включать их в проекты) и компоновки.

Рис. 6. Установка опций проекта

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

Разумеется, C++Builder обладает встроенной системой контекстно-зависимой помощи, доступной для любого элемента интерфейса и являющейся обширным источником справочной информации о C++Builder.

Создание приложений в С++ Builder

Первым шагом в разработке приложения C++Builder является создание проекта. Файлы проекта содержат сгенерированный автоматически исходный текст, который становится частью приложения, когда оно скомпилировано и подготовлено к выполнению. Чтобы создать новый проект, нужно выбрать пункт меню File/New Application.

C++Builder создает файл проекта с именем по умолчанию Project1.cpp, а также make-файл с именем по умолчанию Project1.mak. При внесении изменений в проект, таких, как добавление новой формы, C++Builder обновляет файл проекта.

Рис.7 Файл проекта

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

  • Файл формы с расширением.DFM, содержащий информацию о ресурсах окон для конструирования формы
  • Файл модуля с расширением.CPP, содержащий код на C++.
  • Заголовочный файл с расширением .H, содержащий описание класса формы.

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

Для того чтобы добавить одну или более форм к проекту , выберите пункт меню File/New Form. Появится пустая форма, которая будет добавлена к проекту. Можно воспользоваться пунктом меню File/New, выбрать страницу Forms и выбрать подходящий шаблон из репозитория объектов.

Рис.8 Шаблоны форм

Для того, чтобы просто откомпилировать текущий проект, из меню Compile нужно выбрать пункт меню Compile. Для того, чтобы откомпилировать проект и создать исполняемый файл для текущего проекта, из меню Run нужно выбрать пункт меню Run. Компоновка проекта является инкрементной (перекомпилируются только изменившиеся модули).

Если при выполнении приложения возникает ошибка времени выполнения, C++Builder делает паузу в выполнении программы и показывает редактор кода с курсором, установленным на операторе, являющемся источником ошибки. Прежде чем делать необходимую коррекцию, следует перезапустить приложение, выбирая пункт меню Run из контекстного меню или из меню Run, закрыть приложение и лишь затем вносить изменения в проект. В этом случае уменьшится вероятность потери ресурсов Windows.

Пример: создание простейшего приложения

Теперь попробуем создать простейшее приложение, позволяющее вводить текст в редактируемое поле и добавлять этот текст к списку при нажатии мышью на кнопку. Выберем пункт меню File/New Application для создания проекта и сохраним его главную форму под именем samp1.cpp, а сам проект под именем samp.mak. Поместим на форму компоненты Button, Edit и ListBox со страницы Standard палитры компонент.

Рис. 9. Размещение компонентов на форме

После этого выберем на форме компонент Edit и удалим текущее значение свойства Text. Затем установим свойство Caption для Button1 равным «Добавить».

Чтобы добавить обработчик события OnClick для кнопки Добавить, нужно выбрать эту кнопку на форме, открыть страницу событий в инспекторе объектов и дважды щелкнуть мышью на колонке справа от события OnClick. В соответствующей строке ввода появится имя функции. C++Builder сгенерирует прототип обработчика событий и покажет его в редакторе кода. После этого следует ввести следующий код в операторные скобки < . >тела функции:

Для компиляции приложения в меню Run выберем пункт Run. Теперь можно что-нибудь ввести в редактируемое поле, нажать мышью на кнопку Добавить и убедиться, что вводимые строки добавляются к списку.

Рис.10. Так выглядит готовое приложение.

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

Рис. 11. Модифицированное приложение

Для кнопки Удалить: Для кнопки Выход:

Сохраним и скомпилируем приложение, а затем протестируем его.

Итак, мы познакомились со средой разработки Borland C++Builder и создали простое приложение.

Виктор Алексанкин, Наталия Елманова
Компьютер-Пресс, 1997, N 4.

НОВОСТИ ФОРУМА
Рыцари теории эфира
01.10.2020 — 05:20: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]69vJGqDENq4[/Youtube][/center]
[center]14:36[/center]
Osievskii Global News
29 сент. Отправлено 05:20, 01.10.2020 г.’ target=_top>Просвещение от Вячеслава Осиевского — Карим_Хайдаров.
30.09.2020 — 12:51: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Ok]376309070[/Ok][/center]
[center]11:03[/center] Отправлено 12:51, 30.09.2020 г.’ target=_top>Просвещение от Дэйвида Дюка — Карим_Хайдаров.
30.09.2020 — 11:53: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ — Upbringing, Inlightening, Education ->
[center][Youtube]VVQv1EzDTtY[/Youtube][/center]
[center]10:43[/center]

интервью Раввина Борода https://cursorinfo.co.il/all-news/rav.
мой телеграмм https://t.me/peshekhonovandrei
мой твиттер https://twitter.com/Andrey54708595
мой инстаграм https://www.instagram.com/andreipeshekhonow/

[b]Мой комментарий:
Андрей спрашивает: Краснодарская синагога — это что, военный объект?
— Да, военный, потому что имеет разрешение от Росатома на манипуляции с радиоактивными веществами, а также иными веществами, опасными в отношении массового поражения. Именно это было выявлено группой краснодарцев во главе с Мариной Мелиховой.

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

[center][Youtube]CLegyQkMkyw[/Youtube][/center]
[center]10:22 [/center]

Доминико Риккарди: Россию ждёт страшное будущее (хотелки ЦРУ):
https://tainy.net/22686-predskazaniya-dominika-rikardi-o-budushhem-rossii-sdelannye-v-2000-godu.html

Завещание Алена Даллеса / Разработка ЦРУ (запрещено к ознакомлению Роскомнадзором = Жид-над-рус-надзором)
http://av-inf.blogspot.com/2013/12/dalles.html

[center][b]Сон разума народа России [/center]

Изучаем компоненты borland c builder

Знакомство со средой программирования Borland C++ Builder. Компоненты: форма, поле вывода текста, образ, электронная кнопка и их свойства. Событие и функция обработки события. Компиляция проекта

После запуска C++ Builder в верхней части экрана вашего компьютера вы увидите главное окно, содержащее систему меню и палитру компонентов, состоящую из множества вкладок, каждая из которых включает в себя свой набор компонентов (объектов). В главном окне расположены так же некоторые часто используемые быстрые кнопки, которые дублируют основные команды системы меню. Как правило, в левой части экрана расположено окно Object TreeView (Окно списка объектов). Немного ниже находится окно Object Inspector (Окно свойств объектов). Это окно разбито на две вкладки Properties (Свойства) и Events (События). В центре экрана вы увидите окно стартовой формы с именем Form1, это и есть ваше будущее приложение для Windows! Это самый главный компонент – фундамент, на котором вы будете строить вашу программу, используя другие необходимые компоненты. Ну и, конечно же, в этом строительстве вы непременно будете заниматься написанием программного кода, который будет отвечать за логику программы. Строки вашей программы вы будете размещать в окне редактирования программного кода, которое можно вызвать, например, кликнув два раза мышью по форме Form1. Это окно имеет и более короткое название – редактор кода. При наборе текста программы редактор кода автоматически выделяет ключевые слова полужирным шрифтом, а комментарии курсивом. Так с первого взгляда будет выглядеть мощная среда программирования Borland C++ Builder. Запустить проект вашего будущего приложение для Windows можно прямо сейчас. Для этого достаточно нажать на функциональную клавишу F9 или кликнуть мышью на кнопку Run в виде зеленого треугольника, находящейся в главном окне. И третья возможность – воспользуйтесь системой меню. После запуска проекта приложения не забудьте завершить его работу стандартным для Windows-приложений образом.

Для начала познакомимся с некоторыми свойствами компонента форма. В окне Object Inspector найдите свойство Color (Цвет) компонента Form1. Установите для этого свойства значение clPurple (фиолетовый). Значение этого же свойства можно изменить во время работы приложения программным способом. Вызовите окно программного кода, кликнув на форму два раза. Затем в окне Object Inspector выберите вторую вкладку Events и кликните на событие OnClick (одиночный клик мышью). Рядом появится небольшое поле ввода. Кликните по этому полю два раза – в окне программного кода появится функция FormClick обработки события OnClick (одиночный клик мышью по форме). В данную процедуру прерывания внутри фигурных скобок впишите инструкцию:

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

void __fastcall TForm1::FormClick(TObject *Sender)

Form1->Color = clRed; //красный цвет для формы

Среда быстрой разработки C++ Builder автоматически оформляет подобным образом и другие функции обработки событий, понимаемых операционной системой Windows. Здесь словосочетание fastcall буквально означает – быстрый вызов. В нашем примере это быстрый вызов функции FormClick обработки события OnClick. Любая функция обработки события начинается с открывающейся фигурной скобки и завершается закрывающейся фигурной скобкой. Внутри этих скобок вы будете записывать одну или несколько инструкций, которые компьютер должен выполнить при наступлении указанного события. Запись каждой инструкции должна обязательно заканчиваться точкой с запятой.

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

Измените заголовок формы вашего приложения. В окне Object Inspector выберите свойство Caption (Надпись) и запишите в поле ввода новое значение, например, «Мое первое приложение для Windows».

Разместите на форме какой-либо текст. Для чего во вкладке Standard (Стандартные компоненты) панели управления выберите компонент Label (Поле вывода текста), кликнув на значок с изображением буквы «А» и поместите объект Label1 на форме. В окне Object Inspector для свойства Caption задайте новое произвольное значение, например, «Волшебная страна Borland C++ Builder». Увеличьте размер шрифта надписи. Воспользовавшись составным свойством Font (Шрифт), кликните на «плюс» и ниже выберите Size (Размер). Измените размер шрифта с «8» на «24». Выкрасите надпись в желтый цвет: выберите свойство Color и измените его значение на clYellow.

Теперь разместите на форме вашего приложения два изображения. Достигнуть поставленной цели можно, применив компонент Image (Образ). Достаньте этот компонент из панели управления, кликнув по вкладке Additional (Дополнительные компоненты), а затем на кнопку Image. Для установки указанного компонента на форме вашего приложения, кликните по форме в любой ее свободной области. На форме появится область, очерченная пунктирной линией. Новый объект автоматически получает имя – Image1. Теперь необходимо загрузить в этот компонент какое-либо небольшое по размерам изображение, имеющееся на вашем компьютере. В окне Object Inspector, во вкладке Properties, воспользовавшись полосой прокрутки, выберите одно из многочисленных свойств компонента Image – свойство Picture (Рисунок), кликнув по нему мышью. Рядом вы увидите значение этого компонента – None (Нет). Кликните по кнопке с изображением многоточия, и тут же появится окно для загрузки изображения Picture Editor. Нажмите на кнопку Load (Загрузка) и выберите нужный вам рисунок или фотографию, например, с расширением BMP. После того как картинка окажется на форме, размеры полезной области объекта Image1 можно откорректировать вручную. Еще проще это сделать, если у свойства AutoSize (Авторазмер) его значение false (ложь) изменить на новое значение true (истина), например, кликнув по надписи false два раза. Перетащите изображение, удерживая мышью, в нужную вам часть формы. Подобным образом разместите на форме еще одно изображение. Если появится необходимость, то измените размеры самой формы с помощью мыши до запуска проекта. Запустите проект приложения на выполнение, а затем закройте его.

Если выбранный вами рисунок имеет фон одного цвета, то этот фон при необходимости можно сделать прозрачным, то есть невидимым. Для этого установите свойству Transparent (Прозрачность) значение true.

Если вы хотите изменить размеры изображения, то свойству Stretch (Растяжение) придайте значение true. При этом для свойства AutoSize обязательно установите значение false. К сожалению изображения формата BMP при изменении размера теряют в качестве, а вот виндовские резиновые файлы изображения формата WMF таким недостатком не обладают.

Посмотрим, как можно смонтировать на форму электронную кнопку. Во вкладке Standard панели управления выберите компонент Button (электронная кнопка) и разместите ее на форме. Кликните по вновь созданной кнопке Button1 два раза, и вы окажетесь в функции обработки Button1Click (кликнуть на кнопку). В эту событийную процедуру прерывания впишите инструкцию:

Image1->Visible = false; //скрыть первый рисунок

Это значит, что для компонента Image1 его свойству Visible (Видимость) будет присвоено значение false, что приведет к исчезновению первого рисунка. Запустите проект и проверьте работоспособность электронной кнопки. Изготовьте еще одну кнопку, которая будет заставлять рисунок вновь появляться. Для второй кнопки понадобится инструкция:

Image1->Visible = true; //показать первый рисунок

Создайте еще две кнопки для второго рисунка, которые будут работать аналогично. На каждой кнопке поместите подходящие на ваш взгляд надписи, поясняющие действие кнопок. Для этого у компонента Button свойству Caption придайте значение – название электронной кнопки на русском. И в завершении установите на форме пятую кнопку, которая позволит пользователю закрывать приложение, для чего наберите инструкцию:

Close(); //завершение работы приложения

Проверьте работоспособность созданной кнопки и поместите на ней надпись «Выход», изменив значение свойства Caption.

Для того чтобы сохранить проект приложения, в меню «File» (Файл) выберите команду «Save Project As…» (Сохранить проект как…), выберите нужные вам диск и папку. Сохраните проект. Если вы захотите доработать проект или просмотреть его программный код, кликните по файлу проекта с расширением BPR.

Для создания исполняемого файла вашей программы с расширением EXE зайдите в меню «Project», выберите команду «Make Project1» (Изготовить проект) или с клавиатуры отработать клавишный аккорд Ctrl+F9. Такой процесс сборки файлов проекта в единый EXE-файл называется компиляцией. Исполняемый самостоятельный файл можно перенести на другой компьютер. В том случае, если ваше приложение является мультимедийным, то файлы музыки, звука, видео, например, MID, MP3, WAV, AVI нужно будет скопировать вместе с исполняемым файлом. А вот файлы изображений переносить не надо, так как они впитываются в исполняемый файл в процессе компиляции.

Если вы хотите избавиться от проблем с установкой вашей программы на другом компьютере, связанных с отсутствием на нем необходимых библиотек, то следует изменить некоторые свойства проекта. Для этого войдите в меню «Project», выберите команду «Options…» во вкладке «Linker» уберите галочку «Use dynamic RTL», а во вкладке «Packages» уберите галочку «Build with runtime packages». В первом случае в EXE-файл включается RTL-библиотека времени выполнения, а во втором – динамические библиотеки в которых находятся используемые компоненты и системные функции. При этом размер исполняемого файла существенно увеличится, зато теперь вы сможете перенести его на другой компьютер простым копированием. Файл останется работоспособным также после переустановки операционной системы Windows на вашем компьютере.

BorlandC++Builder1

Для компиляции приложения в меню Run выберем пункт Run. Теперь можно что-нибудь ввести в редактируемое поле, нажать мышью на кнопку Добавить и убедиться, что вводимые строки добавляются к списку.

Рис.10. Так выглядит готовое приложение.

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

Рис. 11. Модифицированное приложение

Для кнопки Удалить:

void __fastcall TForm1::Button2Click(TObject *Sender)
<
if (!(ListBox1->ItemIndex == -1))
ListBox1->Items->Delete( ListBox1->ItemIndex);
>

Для кнопки Выход:

Сохраним и скомпилируем приложение, а затем протестируем его.

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

Изучаем компоненты Borland C++ Builder

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

Содержание

  • Выбор компонентов для групповых операций
  • Установка разделяемых свойств компонентов
  • Изменение размера компонентов
  • Выравнивание компонентов
  • Пример: Создание текстового редактора
    • Проектирование формы приложения
    • Создание обработчиков событий
    • Создание меню

Выбор компонентов для групповых операций

Для эффективной разработки пользовательских интерфейсов приложений C++ Builder нередко возникает необходимость в манипулировании компонентами на формах.. Большинство операций для манипулирования компонентами находятся в меню Edit: К различным опциям этого меню следует обращаться после того, как на форме вы ран один или несколько компонентов, свойства которых требуется изменить.

Выбрать один компонент можно следующими способами:

  • Выбрав с помощью мыши компонент на форме
  • Выбрав имя компонента в селекторе объектов.
  • Переходом к компоненту на форме, нажимая клавишу Tab.

Выбрать несколько компонентов можно следующими способами:

  • Удерживая нажатой клавишу Shift, щелкнуть мышью на каждом компоненте
  • Нажать левую клавишу мыши и окружить нужные компоненты прямоугольным контуром

Установка разделяемых свойств компонентов

Большинство визуальных компонентов имеют общие свойства, (например, Visible, Width, Left). Для установки одинаковых значений общих свойств для нескольких компонентов необходимо выполнить следующие действия:

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

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

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

Рис.2 показывает результаты изменения свойства Font и Left . Все выбранные компоненты приобрели одинаковые значения этих свойств.

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

Изменение размера компонентов

Изменение размера компонента можно проводить как при добавлении его на форму, так и после этого.

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

Рис. 3. Изменение размера компонента при его добавлении на форму.

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

Для изменения размеров нескольких компонентов следует выбрать их одним из описанных выше способов. Далее нужно выбрать пункт меню Edit/Size. Появится диалоговое окно Size. Выберите опции размера. Для точной установки размера в пикселах можно ввести числа в поля Width и Height. Далее нужно нажать кнопку OK.

Рис. 4. Установка свойств компонентов c использованием меню EDIT/SIZE

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

Выравнивание компонентов

Для выравнивания компонентов на форме можно использовать следующие комбинации клавиш:

Shift + стрелки Изменяет размер компонента на один пиксел в направлении выбранной стрелки
Shift + Ctrl + стрелки Перемещает компонент на одну единицу сетки в направлении выбранной стрелки
Ctrl + стрелки Перемещает компонент на один пиксел в направлении выбранной стрелки

Можно также выровнять компоненты, используя пункт меню View/Alignment Palette. Для этого нужно:

  1. Выбрать компоненты для выравнивания.
  2. Выбрать пункт меню View/Alignment Palette.
  3. Выбрать нужную кнопку (см. рис. 5).

Рис.5 Выравнивание компонентов с помощью View/Alignment Palette

Можно выровнять компоненты, используя пункт меню Edit/Align. Для этого нужно:

  1. Выбрать компоненты для выравнивания.
  2. Выбрать пункт меню Edit/Align. Появится диалоговое окно Alignment.
  3. Выбрать нужную опцию и нажать на кнопку OK (рис 6).

Рис.6. Выравнивание компонентов с помощью меню Edit/Align

Можно изменить условия выравнивания компонент, используя пункт меню Options/Environment. Для этого нужно:

1. Выбрать пункт меню Options/Environment. Диалоговое окно Environment появится открытым на странице Preferences.

2. В группе Form designer можно выбрать следующие опции:

  • Display grid — сделать сетку из точек на форме видимой для выравниваемых компонентов
  • Snap to grid — заставить левые и верхние стороны компонентов расположиться а линиях сетки.

3. Для того, чтобы изменить расстояние между узлами сетки, нужно ввести новые значения вместо имеющихся. Значение по умолчанию — 8 пикселей по оси X (по горизонтали) и по оси Y (по вертикали).

Рис. 7. Выравнивание компонентов с помощью страницы Preferences диалоговой панели Environment

Пример: Создание текстового редактора

Проектирование формы приложения

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

На пустой форме разместим компонент TPanel — будущую инструментальную панель нашего редактора. Свойству Align полученного компонента Panel1 присвоим значение alTop, а свойству Caption — пустую строку.

Далее разместим на форме компонент TMemo и присвоим его свойству Align значение alClient, свойству ScrollBars — значение ssVertical, а свойству Lines — пустой массив строк (редактор свойств, являющихся строковыми массивами, как п авило, представляет собой обычный текстовый редактор).

Вспомним о том, что наш будущий текстовый редактор должен открывать и сохра ять файлы. Для этой цели воспользуемся стандартными диалогами Windows 95, содержащимися в библиотеке comdlg32.dll. Для этого поместим на форму два диалога со страницы Dialogs: TOpenDialog и TSaveDialog. Изменим свойство Filter созданного только что компонента OpenDialog1, внеся две строки в диалоговую панель Filter Editor и нажав кнопку OK (рис. 8).

Рис. 8. Установка свойства Filter компонента OpenDialog1.

Теперь можно взять в буфер обмена строку, образовавшуюся в колонке значений апротив свойства Filter, выбрать компонент SaveDialog1 и вставить содержимое буфера обмена в строку напротив свойства Filter. Этим самым мы установим такое же значение свойства Filter для второго диалога. При желании можно изменить заголовки диалоговых панелей (свойство Caption) и другие параметры (свойство Options).

Обратите внимание на то, что языковая версия библиотеки может быть в общем случае как русской, так и английской, так как это ресурс Windows, а не вашего приложения. Поэтому, если вашим пользователям нужно, чтобы стандартные диалоги Windows были русскоязычными, рекомендуйте им установить русскую версию Windows 95 или Windows NT Workstation, либо попробуйте заменить на компьютерах пользователей имеющуюся версию comdlg32.dll на русскоязычную. Впрочем, на странице System имеется достаточное количество компонент для создания «самодельных» диалогов для работы с файлами.

И, наконец, разместим на форме компонент StatusBar со страницы Win95. Отредактируем его свойство Panels (это свойство представляет собой набор компонентов- панелей, на которых выводится необходимая пользователю информация). Редактор этого свойства представляет собой диалог (рис.9). Создадим панель, на которой будет появляться имя редактируемого файла. Для этого нажмем кнопку New и изменим параметр Width созданной панели, сделав его равным 100. В поле Text введем значение «Без имени». Затем нажмем кнопку ОК.

Рис. 9. Установка свойства Panels компонента StatusBar1.

Далее выберем с помощью мыши компонент Panel1 и разместим на нем девять компонентов типа TSpeedButton. Сделать это проще всего, нажав клавишу Shift и выбрав SpeedButton со страницы Additional палитры компонентов.

Компоненты Borland C++ Builder

Выбор компонентов для групповых операций

Для эффективной разработки пользовательских интерфейсов приложений C++ Builder нередко возникает необходимость в манипулировании компонентами на формах. Большинство операций для манипулирования компонентами находятся в меню Edit: К различным опциям этого меню следует обращаться после того, как на форме вы ран один или несколько компонентов, свойства которых требуется изменить.

Выбрать один компонент можно следующими способами:

· Выбрав с помощью мыши компонент на форме

· Выбрав имя компонента в селекторе объектов.

· Переходом к компоненту на форме, нажимая клавишу Tab.

Выбрать несколько компонентов можно следующими способами:

· Удерживая нажатой клавишу Shift, щелкнуть мышью на каждом компоненте.

· Нажать левую клавишу мыши и окружить нужные компоненты прямоугольным контуром.

Установка разделяемых свойств компонентов

Большинство визуальных компонентов имеют общие свойства, (например, Visible, Width, Left). Для установки одинаковых значений общих свойств для нескольких компонентов необходимо выполнить следующие действия:

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

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

Изменение размера компонентов

Изменение размера компонента можно проводить как при добавлении его на форму, так и после этого.

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

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

Для изменения размеров нескольких компонентов следует выбрать их одним из описанных выше способов. Далее нужно выбрать пункт меню Edit/Size. Появится диалоговое окно Size. Выберите опции размера. Для точной установки размера в пикселях можно ввести числа в поля Width и Height. Далее нужно нажать кнопку OK.

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

Для выравнивания компонентов на форме можно использовать следующие комбинации клавиш:

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

Shift + Ctrl + стрелки

Перемещает компонент на одну единицу сетки в направлении выбранной стрелки

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

Можно также выровнять компоненты, используя пункт меню View/Alignment Palette. Для этого нужно:

1. Выбрать компоненты для выравнивания.

2. Выбрать пункт меню View/Alignment Palette.

3. Выбрать нужную кнопку.

Можно выровнять компоненты, используя пункт меню Edit/Align. Для этого нужно:

1. Выбрать компоненты для выравнивания.

2. Выбрать пункт меню Edit/Align. Появится диалоговое окно Alignment.

3. Выбрать нужную опцию и нажать на кнопку OK.

Можно изменить условия выравнивания компонент, используя пункт меню Options/Environment. Для этого нужно:

1. Выбрать пункт меню Options/Environment. Диалоговое окно Environment появится открытым на странице Preferences.

2. В группе Form designer можно выбрать следующие опции:

· Display grid — сделать сетку из точек на форме видимой для выравниваемых компонентов

· Snap to grid — заставить левые и верхние стороны компонентов расположиться на линиях сетки.

3. Для того, чтобы изменить расстояние между узлами сетки, нужно ввести новые значения вместо имеющихся. Значение по умолчанию — 8 пикселей по оси X (по горизонтали) и по оси Y (по вертикали).

Самоучитель C++ Builder, Культин Н.Б., 2004

Самоучитель C++ Builder, Культин Н.Б., 2004.

Книга является руководством по программированию в среде Borland C++ Builder. В ней рассматривается весь процесс разработки программы — от компоновки диалогового окна и написания функций обработки событий до отладки и создания справочной системы при помощи программы Microsoft HTML Help Workshop и установочного CD-ROM в InstallShield Express, разбираются вопросы работы с графикой, мультимедиа и базами данных, приведено описание процесса создания анимации в Macromedia Flash 5. Прилагаемый к книге компакт-диск содержит проекты, приведенные в издании в качестве примеров.
Для начинающих программистов.

Редактор кода.
Во время набора текста программы редактор кода автоматически выделяет элементы программы: полужирным шрифтом — ключевые слова языка программирования (if, else, int, float и др.), курсивом — комментарии. Это делает текст программы более выразительным, что облегчает восприятие структуры программы.

В процессе разработки программы часто возникает необходимость переключения между окном редактора кода и окном формы. Сделать это можно при помощи командной кнопки Toggle Form/Unit, которая находится на панели инструментов View (рис. 2.20), или нажав клавишу . На панели инструментов View находятся командные кнопки View Unit и View Form, используя которые можно выбрать нужный модуль или форму в случае, если проект состоит из нескольких модулей или форм.

Содержание
Предисловие
C++ Builder — что это?
Об этой книге
ЧАСТЬ I. СРЕДА РАЗРАБОТКИ C++ BUILDER
Глава 1. Начало работы
Глава 2. Первый проект
Форма
Компоненты
Событие и функция обработки события
Редактор кода
Система подсказок
Навигатор классов
Шаблоны кода
Справочная система
Сохранение проекта
Компиляция
Ошибки
Предупреждения и подсказки
Компоновка
Запуск программы
Ошибки времени выполнения
Внесение изменений
Настройка приложения
Название программы
Значок приложения
Перенос приложения на другой компьютер
Структура простого проекта
ЧАСТЬ II. ПРАКТИКУМ ПРОГРАММИРОВАНИЯ
Глава 3. Графика
Холст
Карандаш и кисть
Графические примитивы
Линия
Ломаная линия
Прямоугольник
Многоугольник
Окружность и эллипс
Дуга
Сектор
Текст
Точка
Иллюстрации
Битовые образы
Мультипликация
Метод базовой точки
Использование битовых образов
Загрузка битового образа из ресурса программы
Создание файла ресурсов
Подключение файла ресурсов
Глава 4. Мультимедиа
Компонент Animate
Компонент Media Player.
Воспроизведение звука
Просмотр видеороликов
Создание анимации
Глава 5. Базы данных
База данных и СУБД
Локальные и удаленные базы данных
Структура базы данных
Псевдоним
Компоненты доступа и манипулирования данными
Создание базы данных
Доступ к базе данных
Отображение данных
Манипулирование данными
Выбор информации из базы данных
Перенос программы управления базой данных на другой компьютер
Глава 6. Компонент программиста
Выбор базового класса
Создание модуля компонента
Тестирование компонента
Установка компонента
Ресурсы компонента
Установка
Проверка компонента Настройка палитры компонентов
Глава 7. Консольное приложение
Ввод/вывод
Функция printf
Функция scanf
Создание консольного приложения
Глава 8. Справочная система
Создание справочной системы при помощи Microsoft Help Workshop
Подготовка справочной информации
Проект справочной системы
Вывод справочной информации
HTML Help Workshop
Подготовка справочной информации
Использование Microsoft Word
Использование HTML Help Workshop
Создание файла справки
Компиляция
Вывод справочной информации
Глава 9. Создание установочного диска
Программа InstallShield Express
Новый проект
Структура
Выбор устанавливаемых компонентов
Конфигурирование системы пользователя
Настройка диалогов
Системные требования
Создание образа установочной дискеты
Глава 10. Примеры программ
Система проверки знаний
Требования к программе
Файл теста
Форма приложения
Отображение иллюстрации
Доступ к файлу теста
Текст программы
Игра «Сапер»
Правила игры и представление данных
Форма приложения
Игровое поле
Начало игры
Игра
Справочная информация
Информация о программе
Текст программы
Очистка диска
Приложение 1. C++ Builder — краткий справочник
Компоненты
Форма
Label
Edit
Button
Memo
Radio Button
Check Box
ListBox
Combo Box
StringGrid
Image
Timer
Animate Media Player
Speed Button
Up Down
Table
Query
Data Source
DВEdit, DВMemo, DBText
DВGrid
DBNavigator
Графика
Canvas
Pen
Brush
Функции
Функции ввода и вывода
Математические функции
Функции преобразования
Функции манипулирования датами и временем
События
Исключения
Приложение 2. Содержимое компакт-диска
Рекомендуемая литература
Предметный указатель.

Бесплатно скачать электронную книгу в удобном формате, смотреть и читать:
Скачать книгу Самоучитель C++ Builder, Культин Н.Б., 2004 — fileskachat.com, быстрое и бесплатное скачивание.


Скачать pdf
Ниже можно купить эту книгу по лучшей цене со скидкой с доставкой по всей России. Купить эту книгу

С.В. Лаптева ВИЗУАЛЬНОЕ ПРОГРАММИРОВАНИЕ В СРЕДЕ BORLAND C++BUILDER 6.0. Учебное пособие

    Зинаида Ваталина 2 лет назад Просмотров:

1 С.В. Лаптева ВИЗУАЛЬНОЕ ПРОГРАММИРОВАНИЕ В СРЕДЕ BORLAND C++BUILDER 6.0 Учебное пособие Тольятти 2008

2 ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ Тольяттинский государственный университет Факультет математики и информатики Кафедра информатики и вычислительной техники С.В. Лаптева ВИЗУАЛЬНОЕ ПРОГРАММИРОВАНИЕ В СРЕДЕ BORLAND C++BUILDER 6.0 Учебное пособие Допущено Учебно-методическим объединением по образованию в области прикладной информатики в качестве учебного пособия для студентов высших учебных заведений, обучающихся по специальности «Прикладная информатика (по областям)» и другим специальностям Тольятти 2008

3 УДК ББК Л24 Рецензенты: кандидат технических наук, доцент, замдиректора по учебной работе Самарского государственного аэрокосмического университета (Тольяттинский филиал) А.В. Очеповский; кандидат технических наук, доцент кафедры информатики и вычислительной техники Тольяттинского государственного университета В.В. Сенько; кандидат педагогических наук, доцент кафедры информатики и вычислительной техники Тольяттинского государственного университета И.П. Дудина. Л24 Лаптева, С.В. Визуальное программирование в среде Borland C++Builder 6.0 : учеб. пособие / С.В. Лаптева. Тольятти : ТГУ, с. Учебное пособие знакомит с принципами визуальной работы в среде Borland C++Builder 6.0. В первой части рассматриваются основы языка С++, алгоритмические структуры и структуры данных. Вторая часть книги посвящена вопросам разработки баз данных и информационных систем. Адресовано студентам специальности «Прикладная информатика (по областям)», аспирантам, преподавателям, а также инженерно-техническим работникам и слушателям курсов по современным системам программирования. Рекомендовано к изданию научно-методическим советом Тольяттинского государственного университета. isbn Тольяттинский государственный университет, 2008 С.В. Лаптева,

4 Введение Проблема быстрого создания эффективных Windows-приложений была впервые решена в среде визуального программирования Delphi, которая завоевала сердца многих начинающих и профессиональных программистов. Однако прошло некоторое время, и разработчики обратили внимание на систему, которая по принципам была похожа на Delphi, но в основе лежал язык программирования С++. Поработав в данной среде, программисты быстро оценили возможности системы, которые увеличивались с каждой версией. В настоящее время среда быстрой разработки программ Borland C++Builder заняла достойное место среди программного обеспечения по реализации крупномасштабных информационных систем. Программный продукт компании Borland C++Builder одна из ведущих сред разработки для создания Интернет-приложений, «настольных» и распределенных приложений, а также приложений, основанных на модели клиент/сервер. C++Builder сочетает простоту среды быстрой разработки программ, или RAD (Rapid Application Deveploment RAD), с мощью и производительностью языка С++, совместим со стандартом ANSI. Компания Borland предлагает мощный набор собственных расширений языка С++, обеспечивающий поддержку VCL (Visual Component Library библиотека визуальных компонентов). Разработчик может использовать не только готовые компоненты, но и создавать собственные. Кроме того, Borland C++Builder 6.0 является одним из лучших средств для обучения программированию на языке С++. Основная часть работы по созданию приложений выполняется в интегрированной среде разработки (Intergrated Deveploment Environment IDE) C++Builder. Пакет содержит все необходимое начинающему разработчику Windows-приложений: визуальную среду разработки, программымастера, примеры готовых приложений и справочник. Предлагаемое пособие снабжено богатым иллюстративным материалом, множеством демонстрационных примеров и условно разделено на две большие темы: 1. «Компонентное программирование» с разработкой приложений с однодокументным (Simple Document Interface, SDI) и многодокументным (Multiple Document Interface, MDI) интерфейсом. 2. «Разработка информационных систем» с построением баз данных, разработкой интерфейса приложения, запросов и отчетов различного уровня сложности. Это пособие рекомендуется использовать на практических занятиях и лабораторных работах по программированию для студентов, обучающихся по специальности «Прикладная информатика (по областям)» 3

5 и смежным специаильностям, а также для всех, кто самостоятельно решил изучить основы языка С++ и систему Borland C++Builder 6.0. Пособие также может быть рекомендовано и для пользователей, знакомых с основами языка С++ и желающих научиться разрабатывать информационные системы с использованием одной из мощных сред программирования. 4

6 1. ОСНОВНЫЕ ПРИНЦИПЫ И ПРИЁМЫ РАБОТЫ В СРЕДЕ РАЗРАБОТКИ ПРОГРАММ BORLAND C++BUILDER Начальные сведения о Borland C++Builder 6.0 Borland C++Builder 6.0 это мощная среда быстрой разработки высокоэффективных информационных систем, включая и приложения для электронного бизнеса. Среда включает обширный набор средств, повышающих производительность труда разработчиков и сокращающих продолжительность реализации программного проекта. Система представляет собой интегрированную среду разработки, т. е. средства редактирования исходных текстов программ, их компиляции и отладки объединены в одну программу. Borland C++Builder 6.0 позволяет вывести программиста на качественно новый уровень разработки приложений на С++. К ключевым особенностям данной версии среды относятся следующие: технология быстрой разработки программ; наличие высокопромежуточного программного обеспечения для веб-служб и быстрая разработка веб-приложений; эффективная работа с корпоративными базами данных; полная поддержка стандартных протоколов SOAP, XML, WSDL и XSL; встроенный менеджер объектных запросов Borland VisiBroker для разработки распределенных систем CORBA-приложений; и др. Таким образом, Borland C++Builder 6.0 является надежным, высокоэффективным средством разработки крупномасштабных информационных систем различного назначения Элементы интерфейса Borland C++Builder C++ Builder, как и любая программа Windows, может быть запущена на выполнение выбором соответствующей команды из главного меню Windows: Пуск Программы Borland C++ Builder 6 C++ Builder 6. При этом загружается файл bcb.exe, находящийся в папке Borland\ CBuilder6\Bin. Интерфейс C++ Builder 6.0 представлен несколькими окнами, которые частично занимают пространство рабочего стола (рис. 1.1). В отличие от дочерних окон обычных приложений, окна среды C++Builder могут свободно перемещаться по экрану. 5

7 6 Рис Окно пустого проекта Вид экрана после запуска C++Builder включает в себя пять окон: главное окно C++ Builder 6; окно стартовой формы Form1; окно инспектора объектов Object Inspector; окно просмотра списка объектов Object TreeView; окно редактора кода Unit1.cpp, в котором оформляется текст программы. Главное окно программы содержит меню программы, кнопки панели быстрого доступа к командам меню и палитру компонентов. Остальные окна системы предназначены для разработки приложений методом визуального программирования. Это окно редактора формы, окно инспектора объектов и окно просмотра иерархии объектов Главное окно проекта В верхней части экрана расположено окно проекта с именем Project1, которое по умолчанию задается новому приложению. Под заголовком находится строка меню, под ней панель инструментов и палитра компонентов. Главное меню содержит большой список команд, многие из которых «дублируются» из среды Windows и его приложений: 1. Разделы меню File (файл) позволяют создать новый проект, новую форму, открыть ранее созданный проект или форму, сохранить проекты или формы в файлах с заданными именами.

8 2. Разделы меню Edit (правка, редактирование) позволяют выполнять обычные для приложений Windows операции обмена с буфером Clipboard, а также дают возможность выравнивать группы размещенных на форме компонентов по размерам и местоположению. 3. Разделы меню Search (поиск) позволяют осуществлять поиск и контекстные замены в коде приложения. 4. Разделы меню View (просмотр) позволяют вызывать на экран различные окна, необходимые для проектирования. 5. Разделы меню Project (проект) позволяют добавлять и убирать из проекта формы, задавать опции проекта, компилировать проект без его выполнения и делать много других полезных операций. 6. Меню Run (выполнение) дает возможность выполнять проект в нормальном или отладочном режимах, продвигаясь по шагам, останавливаясь в указанных точках кода, рассматривая значения переменных и т. д. 7. Меню Component (компонент) позволяет создавать и устанавливать новые компоненты, конфигурировать палитру компонентов, работать с пакетами. 8. Разделы меню Database (база данных) позволяют использовать инструментарий для работы с базами данных. 9. Меню Tools (инструментарий) включает ряд разделов, позволяющих настраивать интегрированную среду разработки и выполнять различные вспомогательные программы. 10. Разделы меню Window (окно) позволяют переключаться между различными оконами, которые были открыты в текущем сеансе работы с проектом. 11. Меню Help (справка) содержит разделы, помогающие работать со встроенной в C++Builder справочной системой Кнопки панели инструментов Кнопки панели инструментов предназначены для работы с файлами проекта. Пиктограммы приведены в табл. 1. Таблица 1 Описание пиктограмм стандартной панели инструментов Пиктограммы Команда меню Пояснение команды File New Other Создать проект или другой компонент проекта File Open File Reopen Открыть файл проекта, модуля, пакета. Кнопочка со стрелкой справа от основного изображения соответствует команде Reopen, позволяющей открыть файл из списка недавно использовавшихся 7

9 Пиктограммы Команда меню Пояснение команды File Save As Сохранить файл модуля, с которым File Save в данный момент идет работа (CTRL+S) File Save All File Open Project (Ctrl+F11) Project Add to Project (Shift+F11) Project Remove from Project Сохранить все (все файлы модулей и файл проекта) Открыть файл проекта Добавить файл в проект Удалить файл из проекта Продолжение табл. 1 Help C++Builder Help View Units (Ctrl+F12) View Forms (Shift+F12) View Toggle Form/ Unit (F12) File New Form Run Run (F9) Run Program Pause Run Trace Into (F7) Run Step Other (F8) Вызов страницы встроенной справки Переключиться на просмотр текста файла модуля, выбираемого из списка Переключение на просмотр формы, выбираемой из списка Переключение между формой и соответствующим ей файлом модуля Включить в проект новую форму Выполнить приложение. Кнопочка со стрелкой справа от основного изображения позволяет выбрать выполняемый файл, если вы работаете с группой приложений Пауза выполнения приложения и просмотр информации CPU. Кнопка и соответствующий раздел меню доступны только во время выполнения приложения Пошаговое выполнение программы с заходом в функции Пошаговое выполнение программы без захода в функции 8

10 Палитра компонентов Палитра компонентов это набор кнопок, за каждой из которых закреплена действующая подпрограмма или элемент интерфейса Windows. Компоненты объединены в группы по общим признакам (Standard, Additional и т. д.), каждая из которых вызывается «щелчком» мыши на соответствующей закладке. Описание некоторых групп компонентов приведено в табл. 2. Таблица 2 Описание основных вкладок (групп компонентов) палитры компонентов Обозначение вкладки Standard Additional System Data Access Data Controls BDE ADO Interbase Qreport Dialogs Samples ActiveX Описание вкладки Стандартная. Содержит наиболее часто используемые компоненты Дополнительная. Содержит дополнительные компоненты. Системная. Содержит такие компоненты, как таймеры, плееры и ряд других Доступ к данным, в C++Builder 6.0 большинство компонентов, размещающихся ранее на этой странице, перенесено на страницу BDE Компоненты отображения и редактирования данных Доступ к данным через Borland Database Engine Связь с базами данных через Active Data Objects множество компонентов ActiveX, использующих для доступа к информации баз данных MS OLE DB Прямая связь с базой данных Interbase, минуя BDE и ADO Компоненты для подготовки отчетов Диалоги, системные диалоги типа «открыть файл» и др. Образцы, различные, интересные, но не до конца документированные компоненты Примеры компонентов ActiveX Окно главной формы Основой почти всех приложений C++Builder является форма. Ее можно понимать как типичное окно Windows. Форма является основой, на которой размещаются другие компоненты. Во время проектирования форма покрыта сеткой из точек, во время выполнения приложения эта сетка, конечно, не видна. Сама форма это уже готовая к исполнению программа. 9

11 Окно инспектора объектов Окно инспектора кода имеет две страницы. Выше них имеется выпадающий список всех компонентов, размещенных на форме. В нем можно выбрать тот компонент, свойства и события которого необходимо установить. Страница редактора свойств объектов (Properties) предназначена для редактирования значений свойств объектов. В терминологии визуального проектирования объекты это диалоговые окна и элементы управления (поля ввода и вывода, командные кнопки, переключатели и др.). Свойства объекта это характеристики, определяющие вид, положение и поведение объекта. Например, свойства W >) приведен на рис Рис Внешний вид программы «Сила тока»

12 Для создания данного проекта необходимо выполнить следующие действия: 1. Создать проект командой File New Application. 2. Активизировать форму Form1 «щелчком» левой кнопкой мыши. 3. В Инспекторе объектов свойству Caption присвоить значение «Сила тока». 4. Для ввода информационного сообщения поместить компонент Label из палитры компонентов Standard. Для этого выполнить «двойной щелчок» мышью по пиктограмме Label (см. прил. 4). 5. С помощью курсора мыши задать компоненту Label1 необходимые размеры и положение на форме. Установить значения свойств: AutoSize false, WordWrap true, Caption «Введите напряжение и величину сопротивления, затем нажмите кнопку ». 6. Аналогично поместить на форму компоненты Label2 и Label3 для вывода информации о назначении полей ввода. С помощью курсора задать необходимые размеры и положения на форме. Установить значения свойств: AutoSize true, WordWrap false, Caption «Напряжение (вольт)» (Label2) и «Сопротивление (Ом)» (Label3). 7. Аналогично поместить на форму компонент Label4 для вывода результата расчета (величины тока в цепи). С помощью курсора задать необходимые размеры и положения на форме. Установить значения свойств: AutoSize false, WordWrap true, Caption. 8. Для ввода исходных данных поместить на форму компонент Edit из палитры компонентов Standard. Для этого выполнить «двойной щелчок» мышью по пиктограмме Edit. С помощью курсора мыши задать компоненту Edit1 необходимые размеры и положение на форме. «Очистить» значение свойства Text. 9. Аналогично разместить на форме еще один компонент Edit Для вычисления необходимо использовать компонент Button (кнопка). Чтобы разместить на форме кнопку, нужно «щелкнуть» на пиктограмме Button, а затем произвести «щелчок» в любом месте формы. 11. В Инспекторе объектов в свойстве Caption вместо Button1 записать «Вычислить». 12. Для завершения программы аналогично разместить компонент Button2 и установить значения свойства Caption «Завершить». 13. По желанию можно установить цвет фона, размер и цвет шрифта компонентов, используя свойства Color и Font. Окончательный вид формы разрабатываемого приложения приведен на рис

13 Рис Окончательный вид формы 14. Перейти в программный код обработки события нажатием кнопки . Для этого необходимо произвести «двойной щелчок» на указанной кнопке, после чего на экране появится окно программного кода с мигающим курсором, дающим возможность ввести необходимый текст (рис. 1.4). 12 Рис Окно редактора кодов с процедурой обработки события нажатием кнопки 15. Ввести следующий текст программы: // КОММЕНТАРИЙ К ПРОГРАММЕ ОФОРМЛЯЕТСЯ // С ПОМОЩЬЮ ДВОЙНОГО СЛЕША // Объявление переменных напряжение u, сопротивление // r, сила тока i float u;

14 float r; float i; // Получение данных из полей ввода u = StrToFloat(Edit1->Text); r = StrToFloat(Edit2->Text); // Вычисление силы тока i = u/r; // Вывод результат в поле метки Label4->Caption = Ток: + FloatToStrF(i,ffGeneral,7,3); 16. Перейти в программный код обработки события нажатием кнопки . Для этого необходимо произвести «двойной щелчок» на указанной кнопке и в окне программного кода набрать текст программы: void fastcall TForm1::Button2Click(TObject *Sender) < Form1->Close(); > В результате щелчка на кнопке программа должна завершить работу. Чтобы это произошло, надо закрыть окно программы методом Close. Для сохранения проекта необходимо воспользоваться командой File Save all, после чего запустить программу на выполнение командой Run. Функция StrToFloat преобразует строковые значения из полей Edit1-> Text (содержимое поля Edit1) и Edit2->Text (содержимое поля Edit2) в их численные представления и сохраняет результаты в переменных u и r. Вычисленная величина силы тока выводится в поле Label4 путем присваивания значения свойству Caption. Для преобразования числа в строку символов (свойство Caption строкового типа) используется функция FloatToStrF. Необходимо также заметить, что программный код описывается в файле с расширением.cpp, сам проект хранится в файле.bpr. Вопросы для самоконтроля 1. Перечислить и кратко охарактеризовать окна интерфейса среды C++Builder, появляющиеся при загрузке системы. 2. Охарактеризовать назначение окна формы. В чем его отличие от самой формы? 3. С какой целью используется компонент Label? Какие его свойства используются в программе? 13

15 14 4. Каково назначение компонента Edit? С помощью какого свойства осуществляется доступ к его содержимому во время разработки и работы программы? 5. Каким образом можно назначить кнопке выполнение тех или иных действий? 6. Какими способами можно осуществить закрытие формы во время работы программы? 7. Каково назначение функции StrToFloat при обработке строковых значений?

16 2. УПРАВЛЯЮЩИЕ СТРУКТУРЫ C++ Любое выражение, завершающееся точкой с запятой, рассматривается в С++ как оператор. Например, a=b*c; // операция присваивания i++; // операция инкремента function(int x); // операция вызова функции Условие в языке программирования это выражение логического типа (boolean), которое может принимать одно из двух значений: «истина» (true) или «ложь» (false). Из простых условий при помощи логических операторов можно строить сложные условия. В качестве логических операторов используются: «логическое И» (&&), «логическое ИЛИ» ( ), «отрицание» (!) Реализация выбора Оператор ветвления Условный оператор позволяет проверить некоторое условие и в зависимости от результатов проверки выполнить ту или иную последовательность действий. Структура условного оператора имеет следующий вид: if (условие) // комментарий в программе < // команды, которые выполняются, если условие истинно >else < // команды, которые выполняются, если условие ложно >В качестве примера использования оператора IF рассмотрим программу вычисления стоимости телефонного разговора. Известно, что стоимость разговора по телефону в воскресные дни ниже, чем в будни. Интерфейс формы разрабатываемого приложения имеет следующий вид (рис. 2.1): Рис Диалоговое окно «Стоимость разговора» 15

17 Необходимо помнить, если день недели суббота или воскресенье, то стоимость уменьшается на величину скидки. Цена минуты разговора и величина скидки задаются в тексте программы как константы. Для ввода исходных значений (длительность разговора, номер дня недели) используются поля редактирования (компонент Edit), а для вывода результата и пояснительного текста метки (Label). Для выполнения вычислений и выхода с формы используются кнопки: обычная (Button) и событийная (BitBtn). В табл. 3 представлено описание компонентов формы приложения. Компонент Edit1 Компоненты формы приложения Назначение Поле ввода длительности разговора в минутах Таблица 3 Edit2 Label1, Label2 Label3 Button1 BitBtn1 Поле ввода номера дня недели Текстовая информация, служащая для ввода пояснительного текста о назначении полей ввода Текстовая информация, служащая для вывода результата вычисления стоимости разговора Кнопка, активизирующая процедуру вычисления стоимости разговора Кнопка, активизирующая процедуру, которая закреплена автоматически за данной событийной кнопкой Программа производит вычисления после нажатия на кнопку . В данной ситуации генерируется событие OnClick, обрабатывающееся функцией TForm1.Button1Click. Для перехода в программный код данного события необходимо произвести «двойной щелчок» по кнопке, после чего указатель будет установлен внутри соответствующей функции. Для кнопки BitBtn1 (вкладка Additional, компонент BitBtn) необходимо установить в Инспекторе объектов: свойство Kind, которое позволяет задать для данной (особой) кнопки уже существующую процедуру, например, закрытие формы через константу bkclose; свойство Caption, которому можно задать значение «Выход», поставив перед буквой «В» символ амперсанда (&); данный символ позволяет сделать символ, стоящий после него, «горячей клавишей». В листинге 2.1 приведен полный код файла u_lab2_1.cpp. В описательной части структуры программы объявлены и/или инициализированы глобальные переменные и константы, такие как Tim, Summa, Day и PAY, DISCOUNT соответственно. 16

18 Листинг 2.1. Вычисление стоимости телефонного разговора #include #pragma hdrstop #include u_lab2_1.h // #pragma package(smart_init) #pragma resource *.dfm TForm1 *Form1; // цена одной минуты разговора 0.45 рубля float PAY=0.45; // скидка 20% int DISCOUNT=20; // длительность разговора, стоимость разговора float Tim, Summa; // день недели int Day; // fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) < >// vo >Text); // получить день недели из текстового поля Day=StrToInt(Edit2->Text); // вычислить стоимость разговора Summa=PAY*Tim; // Если день недели суббота или воскресенье, // то уменьшить стоимость на величину скидки if ((Day==6) (Day==7)) < Summa=Summa*(100 DISCOUNT) / 100; >// Вывод результата вычисления в текстовое поле, // предварительно преобразовав вещественное // значение в строковое Label3->Caption= К оплате +FloatToStr(Summa)+ руб. ; > 17

19 В приведенном фрагменте описано и подключение различных стандартных модулей, включая и файл u_lab2_1.h. Файл с таким расширением получил название интерфейсного, так как в нем описывается (по умолчанию) интерфейс формы компоненты и их свойства Оператор выбора Оператор SWITCH является обобщением оператора IF и дает возможность выполнить одно из нескольких действий в зависимости от значения выражения. Формат оператора представляется следующим образом: switch (выражение) < case значение_1: <группа_команд_1; break>; case значении_2: <группа_команд_2; break>; case значение_n: <группа_команд_n; break>; default: <группа_команд; break>; > где от значения выражения зависит, какая группа команд будет выполняться; а значение_i представлено константами, разделенными запятыми. Приведем пример использования SWITCH: switch (n_day) < case 6: day= Суббота! ; break; case 7: day= Воскресенье! ; break; default: day= Рабочий день ; break; >В качестве примера использования оператора SWITCH/CASE рассмотрим программу, которая переводит вес из фунтов в килограммы, учитывая, что в разных странах фунт «весит» по-разному. В диалоговом окне программы, изображенном на рис. 2.2, для выбора страны используется список. Для оформления списка на форме используется компонент ListBox, значок которого располагается на вкладке Standard. В табл. 4 приведены свойства компонента ListBox. 18

20 Рис Диалоговое окно программы «Перевод веса» Свойство Name Items ItemIndex Font Свойства компонента ListBox Таблица 4 Определяет Имя компонента. В программе используется для доступа к свойствам компонента Элементы списка Номер выбранного элемента списка. Номер первого элемента списка равен нулю Шрифт, используемый для отображения элементов списка Свойство Items содержит элементы списка. Значения, выводимые в поле списка, могут быть сформированы во время создания формы приложения или динамически (во время работы программы). Для формирования списка строк во время создания формы приложения необходимо выделить размещенный на форме компонент ListBox, в окне Object Inspector выбрать свойство Items и «щелкнуть» на кнопке запуска Редактора списка строк (рис. 2.3). 19

21 Рис Окно Object Inspector В открывшемся диалоговом окне String List editor (редактор списка строк) необходимо набрать список, каждый элемент которого записывается в отдельной строке (рис. 2.4). Ввод каждого элемента списка должен заканчиваться нажатием клавиши . После ввода всех элементов списка следует нажать кнопку . 20 Рис Окно редактора списка строк Свойство ItemIndex характеризует номер выбранного элемента списка. Если ни один из элементов списка не выбран, то его значение равно 1. В табл. 5 описаны компоненты формы приложения.

22 ListBox1 Edit1 Компонент Label1, Label2, Label3 Label4 Button1 BitBtn1 Компоненты формы приложения Содержит Таблица 5 Список стран. Выбирается страна, для которой выполняется пересчет денежной единицы Поле ввода числового значения веса в фунтах Текстовая информация, служащая для вывода пояснительного текста о назначении полей ввода Текстовая информация, служащая для вывода результата пересчета денежной единицы Кнопка, служащая для активизации процедуры пересчета веса из фунтов в килограммы Кнопка, служащая для активизации процедуры, которая закреплена автоматически за данной событийной кнопкой Процедура пересчета денежной единицы, которая выполняется в результате нажатия кнопки , умножает вес в фунтах на коэффициент, равный весу в килограммах одного фунта. Значение коэффициента зависит от номера выбранного элемента списка, т. е. от страны. В листинге 2.2 приводятся две функции, которые обрабатывают два события: первое событие «срабатывает» при создании формы (метод FormCreate), а второе при нажатии на кнопку . Для перехода в программный код первого события необходимо сделать форму активной (в «Инспекторе объектов» текущим компонентом является форма), затем перейти на вкладку Events окна инспектора объектов и произвести «двойной щелчок» в зоне значения события OnCreate. После данного действия система переходит в программный код метода FormCreate. Эта процедура может быть использована для инициализации переменных программы, в том числе и для добавления элементов в список. В приведенном тексте программы закомментированный фрагмент описывает способ добавления элементов в компонент программным путем. Рекомендуется выполнить приведенный пример, а затем изменить программу так, чтобы в ней для заполнения списка использовалось событие OnCreate и метод ListBox1.Items.Add( ). 21

23 Листинг 2.2. Пересчет веса (из фунтов в килограммы) void fastcall TForm1::FormCreate(TObject *Sender) < // Данные команды не используются, так как значения списка // заданы инструментальным способом через свойства // компонента ListBox; в противном случае можно задать // программным путем, как описано ниже // ListBox1->Items->Add( Россия ); // ListBox1->Items->Add( Англия ); // ListBox1->Items->Add( Австрия ); // ListBox1->Items->Add( Германия ); // ListBox1->Items->Add( Дания ); // ListBox1->Items->Add( Исландия ); // ListBox1->Items->Add( Италия ); // ListBox1->Items->Add( Нидерланды ); // Установка первого элемента списка в качестве текущего // (индексация начинается с нуля) ListBox1->ItemIndex=0; > // void fastcall TForm1::Button1Click(TObject *Sender) < // объявление переменных, характеризующих количество фунтов, // количество килограммов, коэффициент веса float funt, kg, k; // установка коэффициента веса в зависимости от страны switch (ListBox1->ItemIndex) < case 0: k=0.4059; break; case 1: k= ; break; case 2: k= ; break; case 6: k= ; break; default: k=0.5; break; >// считывание из текстового поля количества фунтов funt=strtofloat(edit1->text); // вычисление кг kg=k*funt; // вывод в текстовое поле результата (вещественное число 22

24 //предварительно преобразовано в строковое значение Label3->Caption= Edit1->Text + фунт(а/ов) это + FloatToStrF(kg,ffFixed,6,3) + кг. ; > Функция FloatToStrF подробно описана в предыдущем пункте Реализация циклов Циклы реализуются в программе с использованием операторов: FOR, WHILE и DO WHILE Оператор цикла с известным количеством повторений Оператор FOR используется в том случае, если некоторую последовательность команд необходимо выполнить несколько раз, при этом число повторений заранее известно. Такой цикл называется циклом с известным количеством повторений. Формат оператора представляется следующим образом: for (инициализация; выражение; модификации) < группа_команд; >где инициализация задание некоторой переменной-счетчику начального значения, выражение запись, описывающая условие выполнения цикла, модификации операция, выполняющаяся после каждой итерации цикла. В качестве примера использования оператора FOR рассмотрим программу, которая вычисляет сумму первых 10 элементов ряда: 1+1/2+1/3+ (значение i-го элемента ряда связано с его номером формулой 1/i). Диалоговое окно программы (рис. 2.5) должно содержать, по крайней мере, три компонента: поле метки (Label1), командную кнопку (Button1) и событийную кнопку (BitBtn1). Рис Программа «Подсчет суммы ряда» 23

25 Вычисление суммы ряда и вывод результата выполняет процедура обработки события OnClick, текст которой приведен в листинге Листинг 2.3. Вычисление суммы ряда vo >Caption= Label1->Caption + Элемент = + FloatToStr(elem)+ char(13); > // вывод в текстовое поле результата, который предварительно // был переведен из вещественного значения в строковое Label1->Caption= Label1->Caption + \n \n Сумма ряда: + FloatToStr(summ); > В данном листинге рассматривается переход на новую строку двумя способами: 1) с помощью команды char(13); 2) с помощью кода \n, расположенном внутри строкового значения. Первый способ удобнее использовать при «склеивании» строковых значений, а второй в случае, если строка представляет собой единое целое и ее не нужно разбивать на части. Необходимо заметить, что код \n часто встречается в других языках программирования, например, в Прологе Организация цикла с предусловием Оператор WHILE используется в том случае, если некоторую последовательность команд надо выполнить несколько раз, причем необходимое число повторений во время разработки программы неизвестно и может быть определено только во время ее работы, т. е. в процессе

26 вычисления. Типовыми примерами использования цикла WHILE являются вычисления с заданной точностью, поиск в массиве или в файле. Формат оператора представляется следующим образом: while (условие) < группа_команд; >где условие это выражение логического типа, определяющее условие выполнения цикла. Группа команд будет повторяться, пока условие истинно. В качестве примера использования оператора WHILE рассмотрим программу, которая вычисляет значение числа π с точностью, задаваемой пользователем во время работы программы. В основе алгоритма вычисления лежит тот факт, что сумма ряда приближается к значению π/4 при достаточно большом количестве членов ряда ( 1) n+ 1 * (2n 1) Вид диалогового окна программы во время ее работы приведен на рис Пользователь вводит точность вычисления в поле ввода (Edit1). После нажатия командной кнопки (Button1) программа вычисляет значение числа π и выводит результат в поле метки (Label2). Кнопкой (BitBtn1) закрывается форма. Рис Диалоговое окно программы Вычисление ПИ Как и в предыдущих примерах, основную работу в задаче выполняет процедура обработки события OnClick, текст которой приведен в листинге

27 26 Листинг 2.4. Процедура вычисления числа π vo >Text); //задание начального значения для элемента elem=t+1; // пока выполняется условие, будет выполняться и // последовательность действий while (elem >= t) < // вычисление очередного элемента итерации elem = 1/(2*n-1); // преобразование вещественного числа N в целое число NN nn = FormatFloat( 0,n).ToInt(); // если число четное, то выполняется вычитание; в // противном случае сложение if (nn%2==0) < pi-=elem; >else < pi+=elem; >// переход на следующую итерацию n++; > // получение истинного значения числа π pi = pi*4; // вывод в текстовое поле результата, который // предварительно преобразован из вещественного значения // в строковое Label2->Caption= ПИ равно + FloatToStr(pi)+ char(13) + Просуммировано + FloatToStr(n)+ членов ряда ; >

28 В программном коде приводится команда nn = FormatFloat( 0,n).ToInt(); результатом выполнения которой является присвоение переменной nn целого числа. Метод FormatFloat класса AnsiString позволяет представить числовое (вещественное) значение в определенном формате, при этом возвращаемое значение представляется как строковое AnsiString. Синтаксис данного метода следующий: FormatFloat (формат, числовое_значение) В качестве формата в данном методе записан «0»; это значит, что при преобразовании все цифры, включая и 0, будут сохранены на своих позициях. Метод ToInt() относится к классу AnsiString и используется в случае, если необходимо преобразовать строковое значение в целое число. Запись двух методов через символ «точка» означает, что система последовательно реализует первый метод, а затем второй Организация цикла с постусловием Оператор DO-WHILE, как и оператор WHILE, используется в том случае, если необходимо организовать цикл, при этом необходимое число повторений во время разработки программы неизвестно и может быть определено только во время работы программы. Формат оператора представляется следующим образом: do < // группа команд; >while (условие); где условие это выражение логического типа, определяющее условие выполнения цикла. Приведем пример записи оператора DO-WHILE: str = ; do < str = str + IntToStr(i) + ; i:=i+1; >while (i 29 Оператор безусловного перехода GOTO Формат оператора представляется следующим образом: goto метка; где метка это идентификатор, находящийся перед фрагментом программы, которая должна быть выполнена после оператора GOTO. Метка не описывается в каком-либо разделе программы. В тексте программы метка ставится перед последовательностью команд, которые должны быть выполнены после оператора GOTO. После метки ставится двоеточие. В качестве примера рассмотрим программу, которая проверяет, является ли число, введенное пользователем, простым (делящимся только на единицу и само на себя). Проверить, является ли число N простым, можно делением числа N на два, на три и т. д. до N и проверкой остатка после каждого деления. Форма приложения «Простое число» изображена на рис Рис Форма приложения «Простое число» В табл. 6 перечислены компоненты формы приложения. Компонент Edit1 Label1 Label2 Button1 BitBtn1 Компоненты формы приложения Поле ввода исходного числа Назначение Таблица 6 Текстовая информация, служащая для ввода пояснительного текста о назначении поля ввода Текстовая информация, служащая для вывода результата проверки Кнопка, активизирующая процедуру проверки числа Кнопка, служащая для активизации процедуры, которая закреплена автоматически за данной событийной кнопкой

30 В программе используется функция ShowMessage, которая позволяет вывести указанное сообщение в информационное окно. Текст программы приведен в листинге 2.5. Листинг 2.5. Процедура проверки простого числа vo >text); // если введенное число равно 1, то программа прекращает // работать if (n Text= ; // переход на метку bye goto bye; > // задание начального значения делителю d=2; // выполняется последовательность команд, пока выполняется // условие do < // если деление по модулю d не равно 0, то делитель // увеличивается на 1; как только делимое и делитель // становятся равными, значит система достигла ситуации: // нет делителей для числа n r=n%d; if (r!=0) d++; >while (r!=0); Label2->Caption=Edit1->Text; if (d==n) < Label2->Caption=Label2->Caption+ — простое число. ; > else < Label2->Caption=Label2->Caption+ — обычное число. ;> // пустая метка, которая не требует никаких действий bye:; > 29

31 В литературе по программированию можно встретить суждения о недопустимости применения оператора GOTO, поскольку это приводит к запутанности программ. Однако с категоричностью таких утверждений согласиться нельзя. В некоторых случаях использование оператора GOTO вполне оправдано. В данной ситуации можно использовать условие, но оператор GOTO является простейшим решением для данной задачи. Вопросы для самоконтроля 1. Каков принцип работы условного оператора if? 2. Какой оператор позволяет выполнить одно из нескольких действий в зависимости от результата вычисления выражения? 3. Каким образом работает оператор цикла while? 4. В чем различие операторов do while и while? 5. Каким образом осуществляется описание и использование меток в программах? 6. Каково назначение компонента ListBox? Какие характеристики этого компонента определяют свойства Name, Items, ItemIndex? 7. При возникновении каких событий происходит вызов процедур FormCreate, Button1Click? 30

32 3. ПРИНЦИПЫ И ПРИЁМЫ СОЗДАНИЯ ПРОГРАММЫ, УПРАВЛЯЕМОЙ СОБЫТИЯМИ Принципы и приемы создания программы, управляемой событиями, можно рассмотреть на примере разработки контрольного теста по информатике. Программа будет иметь графический интерфейс, включающий в себя меню команд и диалоговые окна: с информацией об авторе теста; инструкцией по использованию; вопросами и результатом тестирования Разработка главной формы «Тест по информатике» При создании пустого проекта (приложения) система создает по умолчанию форму, которая является главной. В случае изменения статуса формы, например, сделать главной форму-заставку, пользователь может воспользоваться командой Project Options Main Form. После создания формы «Тест по информатике» необходимо оформить на ней пункты меню с использованием компонента MainMenu. Для этого необходимо выполнить следующие действия: 1. Выбрать пиктограмму MainMenu, расположенную на стандартной палитре компонентов, и установить компонент MainMenu на форме щелчком мыши. 2. Расположить появившийся на форме компонент в одном из ее верхних углов и произвести «двойной щелчок» по пиктограмме. При этом на экране появится окно с заголовком Form1.Mainmenu1. а) б) Рис Команды пунктов меню «Тест» и «Помощь» 3. В Инспекторе объектов в свойстве Caption ввести значение первого элемента меню «Тест», которое запишется в синем прямоугольнике, расположенном в левом верхнем углу полосы меню (рис. 3.1а). 31

33 4. Нажатием клавиши перейти к записи первой команды вертикально спускающегося меню. 5. В свойстве Caption ввести значение «Тестирование» и нажать . 6. Аналогично для следующих команд пункта «Тест» создать команды «Результат» и «Выход». 7. Создать следующий элемент меню «Помощь» (рис. 3.1б). Для этого активизировать мышью прямоугольник, находящийся справа от команды меню «Тест», а затем свойству Caption задать значение «Помощь». 8. Создать подменю пункта «Помощь», введя команды «Инструкция» и «О программе». 9. Сохранить файл модуля Unit1.cpp под именем Mainform.cpp, а файл проекта Project1.bpr под именем Test.bpr в каталоге пользователя. Разрабатываемое приложение состоит из главной формы, в которую встроено меню. Команды «О программе» и «Инструкция» будут вызывать дополнительные формы в виде информационных окон. Готовые шаблоны для них могут быть выбраны из диалогового окна New Items, которое вызывается последовательностью команд File New Other 3.2. Создание окон «О программе», «Инструкция» Создание окна «О программе» основано на форме AboutBox и подключено к главной форме Mainform. Создание такой формы осуществляется командой меню File New Other. которая вызывает диалоговое окно New Items. В разделе Form необходимо выбрать форму About Box. На экране появится стандартное окно Aboutbox (рис. 3.2), содержащее следующие элементы: графический рисунок, который вставляется в форму с помощью кнопки Image из палитры компонентов Additional; текстовые компоненты (Label); кнопку . 32 Рис Окно «О программе»

34 Работа с графическим объектом формы «О программе» заключается в следующем: 1. Активизировать компонент Image (рисунок) щелчком мыши. Растянуть границы компонента до размеров вставляемого графического объекта. 2. Задать свойству Stretch (масштабирование) компонента Image значение True. Рисунок «подстроится» под размеры рамки. 3. В «Инспекторе объектов» в свойстве Picture щелкнуть по многоточию. Появится окно редактора рисунка Picture Editor (рис. 3.3). 4. В окне редактора выполнить команду Load. Появится окно Load Picture. 5. Выбрать файл по желанию и нажать . Выбранный рисунок будет добавлен на форму в выделенную рамку. Рис Окно редактора рисунка 6. Удалить с формы текстовые компоненты Version и Comments. 7. Для компонентов Product Name и Copyright в «Инспекторе объектов» установить для свойства AutoSize значение false (это свойство устанавливает ширину Label по длине вводимой строки). Свойству Alignment установить значение tacenter для размещения текста по центру компонента. Свойству WordWrap установить значение true. 8. Для компонента Product Name в свойстве Caption записать значение «Тест по информатике». Для компонента Copyright в свойстве Caption записать значение «Copyright by» с указанием своей фамилии. 9. Самостоятельно задать компоненту Label необходимые размеры. Установить цвет фона, размер, вид и цвет шрифта. 10. Сохранить созданный модуль. Для этого нажать кнопку (сохранить файл проекта) в панели инструментов; в окне сохранения модулей ввести about.cpp, при этом проект и остальные модули сохраняться автоматически. Для подключения программного модуля формы «О программе» к главной программе «Тест по информатике» необходимо выполнить следующие действия: 33

35 1. Сделать текущим окно главной формы «Тест по информатике». 2. Открыть меню «Помощь» и щелкнуть мышью на команде «О программе». При этом откроется окно «Редактор кода программы» с процедурой обработки щелчка мыши на команде меню «О программе». 3. Подключить about.h. Для этого надо перейти в начало кода и ниже #include mainform.h подключить директиву #include about.h. 4. Вернуться в место мигания курсора, ввести команду AboutBox->ShowModal(); Эта команда при выполнении программы будет выводить на экран окно «О программе». Аналогичным способом разрабатывается форма «Инструкция». Ее создание основывается на форме Tabbed Pages и подключении его к главной программе (рис. 3.4). 34 Рис Окно инструкции Для решения данной задачи необходимо выполнить следующие действия: 1. Открыть диалоговое окно New Items командой File New Other. и в разделе Form выбрать форму Tabbed pages. 2. В свойстве Caption установить значение «Инструкция». В многостраничном диалоговом окне каждая страница вызывается «щелчком» мыши на ее закладке. В первоначальном виде окно Tabbed pages имеет три страницы с закладками. Количество закладок можно изменять. Закладкам можно присвоить другие имена: например, названия «Страница 1», «Страница 2» и «Страница 3» соответственно. 3. Активизировать TabSheet1 из списка объектов в окне инспектора объектов. 4. Задать свойству Caption значение «О тесте». 5. По желанию можно удалить остальные страницы. Для этого надо активизировать ненужную страницу, нажать по ней правой кнопкой мыши и выбрать команду Delete Page.

36 6. Заполнить страницу текстом инструкции. Для этого необходимо на форму разместить компонент многострочного текста, выбрав в палитре компонентов Standard элемент управления Memo «двойным щелчком» мыши. Растянуть до нужных размеров и в свойстве Lines в появившемся окне ввести текст инструкции. 7. Установить цвет и шрифт для текста. 8. Удалить с формы кнопки и . 9. Сохранить данный модуль под именем instruct.cpp. 10. Открыть окно Редактор кода главной программы с процедурой обработки «щелчка» мыши на команде меню «Инструкция». 11. Подключить директиву #include instruct.h. 12. Вернуться в место мигания курсора, ввести команду PagesDlg->ShowModal(); Эта команда при выполнении программы будет выводить на экран окно «Инструкция». 13. Проверить работоспособность команды «Инструкция» Разработка формы «Тестирование» На основе той же формы Tabbed pages создадим диалоговое окно с вопросами теста. Для этого необходимо выполнить следующие действия: 1. Создать форму аналогично предыдущему примеру. 2. Удалить на ней кнопки и . 3. Задать заголовок и идентификатор объекту формы: свойству Caption присвоить значение «Тестирование». 4. Добавить четыре страницы к трем существующим. Для этого вызвать контекстное меню заголовка страницы и в всплывающем списке выбрать команду New Page (новая страница). 5. Присвоить каждой вкладке страничного блока названия «Вопрос 1», «Вопрос 2» и т. д. На каждой странице нужно разместить вопрос и варианты ответов. Текст вопроса будет располагаться на цветной панели в рамке. Для этого можно воспользоваться компонентами Panel и Label (рис. 3.5). 6. Активизировать страницу для первого вопроса. 7. На странице разместить компонент в виде панели. Для этого из палитры компонентов Standard добавить на первую страницу компонент Panel и «растянуть» его мышью до необходимых размеров. 8. В Инспекторе объектов свойству Color задать любой цвет панели. 9. Установить рамку для панели. Для этого свойству Bevelinner (внутренняя фаска) присвоить значение Lowered (опущенная), а свойству Bevelouter (внешняя фаска) значение Raised (поднятая). 35

37 10. На готовую панель добавить компонент Label, «растянуть» его на всю панель. Для центрирования текста свойству Autosize установить значение false, а свойству Alignment tacenter. 11. Присвоить свойству Caption текущей страницы значение «Специальное устройство, способное передавать по обычной телефонной линии цифровые сигналы, это». 12. Установить цвет, вид и размер шрифта. На диалоговой странице разместить несколько вариантов ответа, среди которых тестируемый должен будет выбрать правильный ответ. Для альтернативного выбора в ряду элементов в палитре Standard существует компонент RadioGroup, который объединяет несколько радиокнопок (зависимых переключателей). 13. Добавить на форму «Тестирование» на страницу первого вопроса компонент RadioGroup и в его свойстве Caption задать заголовок «Варианты ответов». 36 Рис Окно «Тестирование» 14. В свойстве Items (элементы) «двойным щелчком» вызвать окно String List Editor («Редактор списка строк»). 15. В открывшемся редакторе в первой строке ввести фразу «Сканер», во второй строке «Модем», в третьей «Принтер» и «щелкнуть» по кнопке . Каждый вариант ответа будет размещен в панели компонента RadioGroup напротив соответствующей радиокнопки. 16. Скопировать на вторую страницу диалога готовую панель с первой страницы. Для этого на первой странице выделить панель «щелчком» мыши и выполнить команду Copy из меню Edit. В ActivePage выбрать вкладку «Вопрос 2», активизировать мышью внутреннюю панель TabSheet2 («щелчок» мышью в центре страницы) и выполнить команду Paste из меню Edit. Изменить текст вопроса и варианты ответов.

38 17. Аналогично оформить остальные вопросы и ответы. 18. Сохранить созданный модуль формы «Тестирование» под именем testir. 19. Открыть окно редактора кода главной программы с процедурой обработки «щелчка» мыши на команде меню «Тестирование». 20. Подключить директиву #include testir.h. 21. Вернуться в место мигания курсора, ввести команду PagesDlg1->ShowModal(); Эта команда при выполнении программы будет выводить на экран окно «Тестирование» Разработка формы «Результат» и завершение проекта Для решения данной задачи необходимо создать форму «Результат» (рис. 3.6), используя шаблон формы Standard Dialog из раздела Dialogs. На данной форме выводится результат в компонент Label. Однако перед открытием данной формы должны быть произведены вычисления, т. е. подсчет результатов. Рис Окно «Результат» В листинге 3.1 приводится программный код основного модуля, который обрабатывает форму, на которой находится меню программы. Листинг 3.1. Программа «Тестирование» #include #pragma hdrstop #include mainform.h #include about.h #include instruct.h #include testir.h // интерфейсный файл формы тестирования #include result.h // интерфейсный файл формы результата 37

39 // #pragma package(smart_init) #pragma resource *.dfm TForm1 *Form1; // fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) < >// void fastcall TForm1::Button1Click(TObject *Sender) < Form1->Close(); > // void fastcall TForm1::N7Click(TObject *Sender) < AboutBox->ShowModal(); > // void fastcall TForm1::N6Click(TObject *Sender) < PagesDlg->ShowModal(); > // void fastcall TForm1::N2Click(TObject *Sender) < PagesDlg1->ShowModal(); > // vo >RadioGroup1->ItemIndex==1) ball++; if (PagesDlg1->RadioGroup2->ItemIndex==0) ball++; if (PagesDlg1->RadioGroup3->ItemIndex==1) ball++; if (PagesDlg1->RadioGroup4->ItemIndex==0) ball++; if (PagesDlg1->RadioGroup5->ItemIndex==2) ball++; if (PagesDlg1->RadioGroup6->ItemIndex==1) ball++; if (PagesDlg1->RadioGroup7->ItemIndex==0) ball++; OKBottomDlg->Label1->Caption= Ваш результат: + IntToStr(ball); 38

40 OKBottomDlg->ShowModal(); > // void fastcall TForm1::N4Click(TObject *Sender) < Form1->Close(); > В результате тестирования за каждый правильный ответ начисляется 1 балл, и общая сумма баллов (максимум 7 баллов) должна выводится на форму «Результат». В программе результаты тестирования суммируются в переменной ball при условии, если пользователь выбрал правильный ответ («правильную» кнопку). В программе верный ответ обрабатывается через порядковый номер (индекс) кнопки в группе. Так, например, в первом вопросе правильным является третий ответ, значит, индекс радиокнопки 2. В программном коде строка if (PagesDlg1->RadioGroup1->ItemIndex==1) ball++; позволяет увеличить значение ball в случае правильного ответа. В ином случае эта команда не сработает. В программной строке OKBottomDlg->Label1->Caption= Ваш результат: + IntToStr(ball); свойству Caption компонента Label1, установленного в форме «Результат», присваивается значение Ваш результат: и число набранных баллов, преобразованных в строковое значение. Функция IntToStr(Ball) переводит целое число, находящееся в переменной ball, в формат строки. Команда OKBottomDlg->ShowModal(); демонстрирует форму «Результат». Вопросы для самоконтроля 1. Какой компонент используется для создания на форме командного меню? 2. Каким образом осуществляется подключение модуля к главной программе? 3. С какой целью используется компонент Memo и как осуществляется в него ввод текста? 4. С какой целью используется компонент RadioGroup? С помощью какого свойства задаются его элементы? 5. Какой метод позволяет вывести форму на экран; закрыть форму? 39

41 40 4. СИМВОЛЫ И СТРОКИ 4.1. Символы В среде C++Builder присутствует символьный тип данных, характеризующийся ключевым словом char. Значением переменной символьного типа char может быть любой отображаемый на экране символ: буква русского или латинского алфавитов, цифра или знак препинания. Символьный тип представляется одиночным символом, заключенным в апострофы. Переменная символьного типа должна быть объявлена в разделе объявления переменных. Синтаксис объявления символьной переменной: _сhar идентификатор; где идентификатор имя переменной символьного типа; char ключевое слово обозначения символьного типа. Например, char symb1; char symb2 = r ; где symb1, symb2 идентификаторы переменных символьного типа; первый пример объявление переменной, а второй пример инициализация переменной. При записи текста программы вместо символа можно указать его код. Так, например, часто используемый при записи сообщений символ новая строка записывается как char(13) Массивы символов В среде C++Builder присутствует символьный тип данных, но отсутствует специальный строковый тип. Строка рассматривается как массив символьных значений char, оканчивающийся нулевым символом \0. Обращение к строке осуществляется через указатель на первый символ строки, то есть строка является в данной среде указателем. Строка может быть объявлена либо как массив символов, либо как переменная типа char*. Каждое их двух приведенных ниже эквивалентных объявлений _сhar w[] = строка ; _char *ww = строка ; присваивает строковой переменной начальное значение «строка». Доступ к отдельным символам переменной осуществляется по индексам. Так, например, обращение w[3] к слову «компьютер» будет относиться к символу «п», так как индексы в строках начинаются с нуля.

42 Для обработки строк имеется ряд библиотечных функций (работающих именно с массивами символов типа char), некоторые из которых используются наиболее часто: 1) функция strcat (строка1, строка2) конкатенация (склеивание) строковых значений; 2) функция strcpy (строка1, строка2) копирование одной строки в другую (возвращает строковое значение строка1); 3) функция strlen (строка) определение длины строки (возвращает целое число); 4) функция strstr (строка1, строка2) поиск в строке заданной подстроки (возвращает NULL или число позицию, с которой строка2 в первый раз входит в строку1); 5) функция strcmp (строка1, строка2) сравнение двух строк (возвращает значение 0 при строка1>cтрока2; 6) функция AnsiStrLower (строка) приведение символов строки к нижнему регистру; 7) функция AnsiStrUpper (строка) приведение символов строки к верхнему регистру. Пример. Разработать программу замены в предложении заданной комбинации символов на другую комбинацию. Рис Окно демонстрации строковых значений типа char* Для данной задачи создается форма с несколькими метками, которые используются для комментариев. Сама фраза, действие и результат выводится в текстовые метки после нажатия на кнопку . Программный код оформлен в методе, описанном для события нажатия на кнопку (листинг 4.1). 41

43 42 Листинг 4.1. Обработка строк типа char* vo >Caption=word1; // конкатенация строк для второй метки Label2->Caption = strcat( Нужно найти и увеличить,word2); St = strstr(word1, word2); // 1 // если значение St true if (St) // 2 < *St=0; // 3 St +=strlen(word2); // 4 Label3->Caption = strcat(strcat(strcpy(s,word1),s1),st); // 5 > else Label3->Caption= Текст не найден! ; > Необходимо заметить, что команда St = strstr(word1, word2); записана в программе только для того, чтобы выяснить наличие ненулевого значения; в противном случае система выведет сообщение о том, что текст не найден. Далее в условной конструкции эта переменная обнуляется для дальнейшей работы с фрагментами строк. Рассмотрим, каким образом осуществляется замена одного текста на другой (по комментариям 1-5 программного кода) с помощью функций, обрабатывающих тип char*. В исходном виде массив word1 представлен как: Е, х, а, л,, Г, р, е, к, а,, ч, е, р, е, з,, р, е, к, у. \0 После выполнения функции (1) указатель St будет указывать на восьмой символ букву е. Командой (3) с использованием указателя (*) на это место (8-й символ) заносится символ конца строки \0.

44 После этого исходная строка выглядит следующим образом: Е, х, а, л,, Г, р, \0, к, а,, ч, е, р, е, з,, р, е, к, у. \0 Функция (4) увеличивает St на длину строки «ек» (на два символа) и начинает указывать на символ а (последняя буква слова «Грека»). Подробно рассмотрим команду (5). Функцией strcpy(s,word1) в строку S заносится исходная фраза, но до первого символа конца \0, то есть Е, х, а, л,, Г, р, \0. Функция strcat(strcpy(s,word1),s1) объединяет описанную выше фразу с символами «ЕК», после чего получается фраза: Е, х, а, л,, Г, р, Е, К, \0. Так как в строке St указатель стоит на букве а, то и в состав этой переменной входит уже оставшаяся часть исходной фразы: а,, ч, е, р, е, з,, р, е, к, у. \0 После функции strcat(strcat(strcpy(s,word1),s1),st) происходит объединение двух последних последовательностей символов в фразу: Е, х, а, л,, Г, р, Е, К, а,, ч, е, р, е, з,, р, е, к, у. \ Тип срок AnsiString Тип строк AnsiString реализован в C++Builder как класс, объявленный в файле vcl/dstring.h. Эти строки с нулевым символом в конце. Для класса AnsiString определены такие операции как операции отношения:!=, , >=, 45 // Результат n=4 2) метод Delete (позиция, число_символов) удаляет из текущей строки Str указанное Число_символов с заданной Позиции. Пример: AnsiString Str = program ; AnsiString q; q = Str.Delete(2,4); // Результат q= 3) метод FloatToStrF (число, формат, длина, количество_после_запятой) преобразует значение Числа, используя указанный Формат, в число определенной Длины и Количества знаков после запятой. Пример: AnsiString s; float a= ; s = FloatToStrF (a, fffixed, 7, 3); // Результат s = В качестве второго параметра данная функция использует следующие форматы: fffixed формат с фиксированной точкой вида -ddd.ddd. основной числовой формат (в том виде, как определено ffgeneral значение переменной). ffexponent научный формат вида -d.ddd E+dddd. ffnumber числовой формат вида -d,ddd, ddd.ddd. денежный формат, при котором число преобразуется ffcurrency в строку с указанием в ней денежной суммы. 4) метод Insert (строка, позиция) вставляет Строку в текущую строку Str, начиная с указанной Позиции. Пример: AnsiString oldstr = котер ; AnsiString newstr = мпью ; AnsiString res; res = oldstr.insert (newstr, 3); // Результат res= компьютер 5) метод IsEmpty () возвращает значение true, если строка пустая. Пример: AnsiString s = ; AnsiString ss = rows ; bool a, aa; a = s.isempty(); aa = ss.isempty(); if (a == true) 44

46 < Label5->Caption = true ; > else < Label5->Caption = false ; > if (aa) < Label6->Caption = true ; > else < Label6->Caption = false ; > Необходимо заметить, что выражения условия (a==true) и (a) эквивалентны; 6) метод Length () возвращает целое число, характеризующее количество символов в строке; 7) метод Pos (строка) возвращает позицию первого символа первого вхождения Строки в текущую строку Str. В отличие от метода AnsiPos не поддерживает многобайтные символы; 8) метод SetLength (количество) сокращает текущую строку до указанного Количества символов (в длину). Пример: AnsiString Str1= модернизация ; AnsiString res; res = Str1.SetLength(6); // Результат res= модерн 9) метод StringOfChar (символ, количество) возвращает строку, в которой Символ повторяется указанное Количество раз. Например, AnsiString s=ansistring:: StringOfChar ( a, 10); Данная команда позволяет инициализировать переменную s типа AnsiString длиною в 10 символов «а». При этом не вводится новая переменная, к которой можно применить метод StringOfChar, а используется чисто объектно-ориентированный подход: сначала записывается класс, затем через два «:» записывается метод данного класса. Необходимо также учесть (как и в С++), что переменная объявлена именно через метод-конструктор, который совпадает по названию с именем класса (причем всегда). Для перевода из строковых значений в числовые также используются методы ToDouble () и ToInt (), которые переводят строку в вещественное и целое числа соответственно. Методы Trim (), TrimLeft () и TrimRight () позволяют удалять лишние пробелы в строках: все пробелы, слева от строки и справа от строки соответственно. Для приведения букв к верхнему или нижнему регистрам используются методы UpperCase () и LowerCase () соответственно. 45

47 Рассмотрим пример, в котором производятся: 1) вычисление длины предложения (в словах); 2) вставка слова в указанное место предложения (рис. 4.2). Рис Окно программы «Демонстрация типа AnsiString» В листинге 4.2 приводится фрагмент программного кода, в котором описываются обработки событий кнопок . Листинг 4.2. Демонстрация типа AnsiString // объявление глобальных переменных AnsiString fraza, fraza1, fraza2, fraza3, fr, oldw, neww; int pr = 0; int pos; // vo >Text; fraza1 = fraza.trimright(); fraza2 = fraza1.trimleft(); // если строка пустая, то выводится соответствующее // сообщение; в противном случае «вырезается» каждый // символ из фразы и по количеству пробелов вычисляется // количество слов в предложении if (fraza2!= ) 46

48 < >else < for (int i=0; i Caption=pr+1; ShowMessage( Строка пустая! ); Label3->Caption=0; > > // vo >Text).TrimRight()).TrimLeft(); // считывание пропущенного слова (нового) и слова, после // которого пропущенное слово располагается (старого) oldw=edit3->text; neww=edit2->text; // поиск позиции, с которой начинается старое слово pos=fraza3.ansipos(oldw); // вставка дополнительного пробела после старого слова fr=fraza3.insert(, pos+oldw.length()+1); // вставка нового слова Edit4->Text=fr.Insert(neww, pos+oldw.length()+1); > Необходимо заметить, что приведенные функции являются основными и в сочетании друг с другом позволяют программисту обрабатывать строковые значения, полученные из различных компонентов Примеры использования строковых значений Рассмотрим несколько примеров на использование строк и символов. Пример 1. Продолжим решение задачи, демонстрация которой 47

49 представлена на рис. 4.1, добавив на форму компоненты для обработки строковых значений, описанных через класс AnsiString (рис. 4.3). 48 Рис Окно задачи «Примеры использования типов char и AnsiString» В листинге 4.3 представлен программный код события нажатия на вторую кнопку окна «Примеры использования char и AnsiString». Листинг 4.3. Обработка строк типа AnsiString vo >Caption=word_01; Label5->Caption= Нужно найти и уменьшить +word_02; // определение переменной i, хранящей позицию первого // вхождения строки word_02 в строку word_01 int i=word_01.pos(word_02); // если значение i true if (i) < // конкатенация различных частей фразы Label6->Caption=word_01.SubString(1,i-1)+ S_01 + word_01.substring(i+word_02.length(),255); > else Label6->Caption= Текст не найден! ; > Пример 2. Разработать программу, выполняющую следующие операции: 1) конкатенация; 2) перевод к нижнему и верхнему регистрам; 3) нахождение длины строки (рис. 4.4).

50 Рис Окно программы «Работа со строками» В данном примере используется только одна переменная типа AnsiString, которая связана со строкой типа char* операцией конкатенации +. В остальных случаях рассматривается работа с типом char*. Листинг 4.4. Работа со строками vo >Caption= title + txt1; Label2->Caption=strcat(txt1, изация ); // пример 2 при использовании переменной txt, объявленной // как массив символов, конкатенация не происходит // генерируется ошибка // Label3->Caption= title + txt; // Label4->Caption=strcat(txt, изация ); // пример 3 верхний и нижний регистры Label3->Caption= AnsiStrLower(txt1); Label4->Caption= AnsiStrUpper(txt1); // пример 4 длина строки Label5->Caption= Длина слова Маршрут + IntToStr(strlen(txt)); > Пример 3. Вывести на форму таблицу кодировки букв русского алфавита. 49

51 Основную работу выполняет процедура обработки события OnActivate, которая формирует и выводит в поле метки (Label1) таблицу. Событие OnActivate происходит при активизации формы приложения, и поэтому метод TForm1.FormActivate выполняется автоматически после появления формы на экране. Текст метода приведен в листинге 4.4, а диалоговое окно программы на рис Рис Окно «Таблица символов» Листинг 4.5. Таблица символов vo >

52 > Label1->Caption=st; > Форма рассматриваемого приложения содержит только один компонент поле метки (Label1). Для того чтобы колонки таблицы имели одинаковую ширину, свойству Label1.Font.Name следует присвоить имя шрифта, у которого все символы имеют одинаковую ширину, например, Courier New Cyr. Вопросы для самоконтроля 1. Как осуществляется описание переменных строкового и символьного типов? 2. Как получить значение кода требуемого символа? 3. Какое отношение каждый символ имеет к таблице кодов? Какой символ характеризуется кодом #13? 4. В какой ситуации осуществляется вызов процедуры FormActivate? 5. Каков синтаксис и назначение функций Length, Pos, Copy, Delete? 51

53 5. ТИПОВЫЕ ДЕЙСТВИЯ С МАССИВАМИ ДАННЫХ Массив это структура данных, которую можно рассматривать как набор переменных одинакового типа, имеющих общее имя. Массивы удобно использовать для хранения однородной по своей природе информации, например, таблиц, коэффициентов уравнений, матриц Объявление массива С массивами осуществляются следующие действия: 1) Объявление, заключающееся в указании имени массива, типа значений, а также при необходимости размера (длины) массива: тип имя_массива []; тип имя_массива [размер]; Например, massiv[3]. 2) Инициализация, позволяющяя задать каждому элементу массива конкретное значение описанного типа. При этом необходимо помнить, что нумерация индексов в массивах начинается с нуля. Например, massiv[0]=34; massiv[1]=78; massiv[2]=65; Отсюда видно, что при индексе, равном 3, будет переполнение массива, а это допускать нельзя. Таким образом, при работе с индексами массива необходимо использовать число, на 1 меньшее, чем объявлено в размере массива. Также можно определить массив, объединив объявление и инициализацию: AnsiString Str[]=< один, два, три >; 3) Обращение к элементам массива через имя массива и индекс. Для заполнения или считывания элементов массива наиболее часто используется цикл с известным количеством повторений. for (i=0; i 54 5.2. Вывод элементов массива на экран Рассмотрим программу, выводящую значения всех элементов массива в диалоговое окно. Предварительно необходимо организовать одномерный массив team, элементами которого будут названия команд участниц футбольного чемпионата. Рис Окно «Формирование массива» Обработка массива выполняется через нажатие кнопки , после чего генерируется событие onclick (листинг 5.1). Листинг 5.1. Программный код формирования массива vo >

55 st = st + IntToStr(i) + + team[i] + char(13); > ShowMessage(st); > Из программного кода видно, что для вывода информации в диалоговое окно используется функция ShowMessage(сообщение), в качестве параметра которой используется строковое значение Ввод элементов массива Под вводом элементов массива понимается получение от пользователя во время работы программы значений элементов массива. Рассмотрим два варианта организации ввода массива: 1) с использованием поля редактирования (компонента Edit); 2) с использованием поля Memo Использование компонента EDIT Диалоговое окно программы, позволяющее вводить элементы массива с клавиатуры, может выглядеть как на рис Рис Диалоговое окно программы «Ввод и вывод элементов массива» После «щелчка» на кнопке программа выполнит следующие действия: 1) выделит из введенной строки первую подстроку с числом (например, «45»); 2) преобразует ее в число; 3) присвоит полученное значение первому элементу массива; 4) выделит каждое последующее значение строки (расположенное между пробелами) и осуществит с ним действия п. 2 и п. 3. Для демонстрации работы программы необходимо создать диалоговое окно, разместив на нем три компонента: метку (Label1), поле ввода (Edit1) и командную кнопку (Button1).

56 Процедура обработки события OnClick для командной кнопки может выглядеть следующим образом (листинг 5.2): Листинг 5.2. Формирование элементов массива из строки vo >text; for (i=0; i 57 56 > else < res=st; >st2=st.substring(p+1,st.length()-p); return res; > Для того чтобы из полученной в качестве аргумента строки выделить n-ю подстроку (элемент массива), функция GetSub сначала удаляет в цикле for предшествующие ей n-1 подстроки, затем находит пробел, который отмечает конец нужной подстроки, выделяет ее и возвращает в качестве значения функции через неявную локальную переменную result. Описание (текст) этой функции следует поместить в описательную часть модуля до всех остальных методов Использование компонента Memo Для ввода символьного массива, занимающего несколько строк, целесообразнее использовать компонент Memo, который позволяет вводить несколько строк текста (в отличие от Edit). В табл. 7 приведены свойства компонента Memo. Свойство Name Lines Height Width Text Font Свойства компонента Memo Таблица 7 Определяет Идентификатор компонента. В программе используется для доступа к свойствам компонента Текст, находящийся в строках поля Memo Высоту поля Ширину поля Текст, находящийся в поле ввода-редактирования Шрифт, используемый для отображения вводимого текста При использовании компонента Memo ввод каждого элемента массива должен заканчиваться нажатием клавиши . Доступ к находящейся в поле Memo строке текста можно получить при помощи свойства Lines, указав в квадратных скобках номер нужной строки (строки нумеруются с 0).

58 На рис. 5.3 представлен интерфейс диалогового окна для ввода элементов массива с клавиатуры. Обработка данных будет происходить после нажатия клавиши . Рис Диалоговое окно приложения «Ввод массива» Приведенный ниже листинг программного кода обработки события нажатия кнопки демонстрирует использование компонента Memo для ввода строкового массива. Листинг 5.4. Обработка элементов списка vo >memo1->lines->count; if (n==0) < ShowMessage( Исходные данные не введены! ); >if (n>size) < ShowMessage ( Количество введенных строк \n превышает размер массива. ); n=size; >for (i=0; i Memo1->Lines->Strings[i]; > if (n>0) 57

59 > < >st= Введенный массив: \n\n ; for (i=0; i откроется диалоговое окно Pr_memo (рис. 5.3), в которое будут выведены значения элементов массива, полученные из Memo-поля. Вопросы для самоконтроля 1. Каким образом осуществляется объявление массива в программе? 2. Как осуществляется доступ к элементу массива? 3. Опишите принцип организации ввода элементов массива с помощью компонента Edit. 4. Какой раздел содержит текст функций и методов, определенных программистом? 5. Что определяют свойства Lines и Text компонента Memo? 6. С помощью какого метода можно определить количество строк в компоненте Memo? 7. Каково содержание раздела interface при наличии в модуле функций и процедур, определенных программистом? 58

60 6. МНОГОМЕРНЫЕ МАССИВЫ Исходные данные для решения многих задач удобно представляются в табличной форме. В программе для хранения и обработки таких табличных данных используют многомерные массивы. Если при описании массива задано два индекса, массив называется двумерным, если N индексов N-мерным. Пример описания двумерного массива целых чисел, состоящего из 3-х колонок и 4-х строк: int massiv2 [3][4]; Чтобы получить доступ к отдельному элементу многомерного массива, нужно указать значение каждого индекса, например: massiv[2][3]. В качестве примера рассмотрим программу, выполняющую обработку результатов спортивных соревнований олимпиады. Исходные данные для обработки представлены в табл. 8. Таблица 8 Таблица спортивных соревнований олимпиады Страна Количество медалей золотые серебряные бронзовые Австрия Германия Италия Канада Нидерланды Норвегия Россия США Финляндия Швейцария Япония Программа вычисляет общее количество медалей, завоеванных представителями каждой страны, и соответствующее количество очков (баллов), которое вычисляется по следующему правилу: за каждую золотую медаль команда получает 7 очков, за серебряную 6, за бронзовую 5 очков. Затем программа должна выполнить сортировку таблицы по убыванию количества набранных очков. 59

61 Вид диалогового окна программы представлен на рис Рис Диалоговое окно программы «Итоги олимпиады» В форме приложения появился новый компонент StringGrid (строковая таблица), значок которого находится на вкладке Additional палитры компонентов. В следующей таблице приведены значения свойств компонента StringGrid, используемого программой обработки результатов олимпиады для ввода исходных данных и вывода результатов (табл. 9). Обозначение Описание свойств компонента StringGrid Свойство Таблица 9 Значение Name Идентификатор компонента Tab1 ColCount Число колонок таблицы 6 RowCount Число строк таблицы 12 FixedCols FixedRows Число зафиксированных слева колонок таблицы. Зафиксированные колонки выделяются цветом и при горизонтальной прокрутке таблицы остаются на месте Число зафиксированных сверху строк таблицы. Зафиксированные строки выделяются цветом и при вертикальной прокрутке таблицы остаются на месте 0 1

62 Обозначение Options.goEditing Свойство Признак допустимости редактирования содержимого ячеек таблицы Значение TRUE DefaultColWidth Ширина колонок таблицы 68 DefaultRowHeight Высота строк таблицы 16 GridLineWidth Ширина линий, ограничивающих ячейки таблицы 1 Ячейки первой зафиксированной строки таблицы используются в качестве заголовков ее колонок. Во время создания формы приложения установить значения элементов массива Cells нельзя, так как элементы массива доступны только во время работы программы. Поэтому значения элементов массива Cells, соответствующих первой строке и первой колонке таблицы, устанавливает процедура обработки события OnActivate (листинг 6.1), которое происходит во время активизации формы приложения. Листинг 6.1. Формирование массива void fastcall TForm1::FormActivate(TObject *Sender) < Tab1->Cells[0][0]= Страна ; Tab1->Cells[1][0]= Золотых ; Tab1->Cells[2][0]= Серебряных ; Tab1->Cells[3][0]= Бронзовых ; Tab1->Cells[4][0]= Всего ; Tab1->Cells[5][0]= Баллов ; Tab1->Cells[0][1]= Австрия ; Tab1->Cells[0][2]= Германия ; Tab1->Cells[0][3]= Италия ; Tab1->Cells[0][4]= Канада ; Tab1->Cells[0][5]= Нидерланды ; Tab1->Cells[0][6]= Норвегия ; Tab1->Cells[0][7]= Россия ; Tab1->Cells[0][8]= США ; Tab1->Cells[0][9]= Финляндия ; Tab1->Cells[0][10]= Швейцария ; Tab1->Cells[0][11]= Япония ; > Продолжение табл. 9 Программа обработки исходной таблицы, текст которой приведен ниже, запускается при щелчке на командной кнопке . 61

63 Листинг 6.2. Подсчет итогов vo >rowcount; r++) < s=0; for (c=1; c Cells[c][r]!= ) s=s+strtoint(tab1->cells[c][r]); else Tab1->Cells[c][r]= 0 ; p = 7*StrToInt(Tab1->Cells[1][r])+6*StrToInt(Tab1->Cells[2][r])+ 5*StrToInt(Tab1->Cells[3][r]); Tab1->Cells[4][r]=IntToStr(s); Tab1->Cells[5][r]=IntToStr(p); > > //сортировка массива for (r=1; r rowcount-1; r++) < m=r; for (i=r; i rowcount-1; i++) if (StrToInt(Tab1->Cells[5][i]) > StrToInt(Tab1->Cells[5][m])) m=i; if (r!=m) for (c=0; c cells[c][r]; Tab1->Cells[c][r]=Tab1->Cells[c][m]; Tab1->Cells[c][m]=buf[c]; 62

64 > > > Сначала для каждой страны программа вычисляет общее количество медалей и соответствующее ему количество очков. Затем выполняет сортировку таблицы по убыванию количества набранных очков. Во время сортировки для обмена строк таблицы используется одномерный строковый массив buf, индекс которого, как и индекс строки таблицы меняется от 0 до 5. Такой прием позволяет наиболее просто выполнить копирование замещаемой строки в буфер и замещение строки содержимым буфера. Вопросы для самоконтроля 1. Каким образом осуществляется объявление двумерного массива? 2. Как описывается доступ к элементам двумерного массива? 3. Для чего предназначен компонент StringGrid? 4. С помощью каких свойств устанавливается число строк и столбцов компонента StringGrid? 5. Как можно реализовать заполнение компонента StringGrid программным путем? 63

65 7. СОЗДАНИЕ ОДНОТАБЛИЧНОЙ БАЗЫ ДАННЫХ Организация связи с базами данных в C++Builder Borland C++Builder не относится к системам управления базами данных (СУБД), т. е. не является специализированной средой, работающей только с объектами баз данных (БД). Система, разработанная фирмой Borland, является универсальной и работает с различными объектами, включая и БД. Чтобы пользователь мог разрабатывать приложения баз данных, необходимо воспользоваться специальным механизмом доступа к объектам данного типа. Borland Database Engine (BDE) процессор баз данных фирмы Borland. BDE служит посредником между приложением в C++Builder и базами данных, которые могут быть разработаны в любой БД, с которой среда работает. Приложение C++Builder никогда не обращается непосредственно к базе данных, а только к механизму BDE, сообщая ему псевдоним базы данных и необходимые таблицы в ней. BDE реализован в виде динамически присоединяемых библиотек DLL, которые снабжены API (Application Program Interface интерфейс прикладных программ), названным IDAPI (Integrated Database Application Program Interface). Это список процедур и функций для работы с базами данных, которым и пользуются приложения. Механизм BDE по псевдониму находит подходящий для указанной базы данных драйвер. BDE поддерживает естественный доступ к таким базам данных, как Microsoft Access, FoxPro, Paradox и dbase. Если собственного драйвера нужной СУБД в BDE нет, то используется драйвер ODBC. ODBC (Open Database Connectivity) динамическая библиотека, аналогичная по функциям BDE, но разработанная фирмой Microsoft. Работа через ODBC осуществляется несколько медленнее, чем через собственные драйверы СУБД, включенные в BDE, но благодаря связи с ODBC масштабируемость C++Builder существенно увеличилась, и сейчас из C++Builder можно работать с любой значительной СУБД. BDE поддерживает стандартизованный язык запросов SQL (Structured Query Language), позволяющий обмениваться данными с SQL-серверами, такими, как Sybase, Microsoft SQL, Oracle, Interbase. Эта возможность используется особенно широко при работе на платформе клиент/сервер. Работа с БД начинается с программы Database Desktop, которая позволяет загрузить программу по созданию и редактированию таблиц. Обычно вызов Database Desktop включен в главное меню C++Builder в раздел Tools. Если это не сделано, то полезно включить его туда с помощью команды Tools / Configure Tools.

66 7.2. Типы данных в среде C++Builder 6.0 В среде C++Builder 6.0 используются следующие типы данных (табл. 10). п/п 1. Alpha Тип данных Описание типов данных Обозначение Строковый (текстовый) 2. Number Числовой 3. $ (Money) Денежный 4. Short 5. Long Integer Короткий целый Длинный целый 7. Date Датовый 8. Time Тип «Время» (Timestamp) 10. Memo Примечание Назначение Таблица 10 Содержит любые печатаемые ASCII-символы; размер строки от 1 до 255 символов Числа в диапазоне от до с 15 значащими разрядами. Числовые значения, сопровождаемые денежным символом. Числа в диапазоне от до Числа в диапазоне от до Дата, представленная в следующем формате: (например, ) Время, представленное в следующем формате: 00:00:00 (например, 12:10:34 часы: минуты: секунды) Дата и время, одновременно представленные в следующем формате: 00:00:00, (например, 12:09:23, ). Между временем и датой задается запятая и пробел Поле, хранящее текст неограниченной длины. Сам текст примечания хранится в отдельном файле с расширением.mb (имя файла такое же, как и имя таблицы). Принимаемые значения: от 1 до 240 (число первых символов, хранящихся в таблице) 65

67 п/п Тип данных Обозначение 12. Graphic Графический 13. OLE OLE-объект 14. Logical Логический (Autoincrement) Продолжение табл. 10 Назначение Изображения из файлов в форматах.bmp,.pcx,.tif,.gif или.eps. Database Desktop преобразует их в формат.bmp Данные типа OLE-изображения, звуки, документы. Database Desktop не поддерживает поля этого типа Принимает только одно их двух значений: false или true (первый символ) Автоматически увеличивающееся на 1 длинное целое. Только Инкремент (автоматическийсей полей в оставшихся записях для чтения. При удалении запи- не изменяются Необходимо заметить, что просмотр полей типа «Примечание», «Графический», OLE-объект возможен только в Paradox или в приложениях C++Builder Создание новой таблицы с помощью Database Desktop Для создания новой таблицы (впервые) необходимо выполнить следующие действия: 1. Создать новый проект командой File / New / Application, если новый проект не открылся автоматически после загрузки системы программирования C++Builder. 2. Вызвать программу Database Desktop командой Tools / Database Desktop, после чего на экране появится окно для работы с таблицами (рис. 7.1). В состав панели инструментов входят три пиктограммы: Open Table открытие таблицы; Open Query открытие запроса; Open SQL File открытие SQL-файла. 3. Выполнить команду File / New / Table. 4. В появившемся окне выбрать таблицу типа Paradox 7.0. Нажать . 66

68 Рис Окно Database Desktop 5. В новом окне ввести названия поля (Field Name), типы полей (Type) и размеры полей (Size) в символах. Через контекстное меню можно открыть список типов данных и выбрать необходимый тип или ввести букву или символ, закрепленный по умолчанию за тем или иным типом данных (рис. 7.2). Рис Окно структуры таблицы с демонстрацией возможных типов данных 6. После ввода всех данных по полям установить некоторые свойства таблицы. Для этого необходимо активизировать пункт Validity Checks в комбинированном списке Table Properties. Данный пункт позволяет проверить правильность вводимых значений. 67

69 Рис Окно ввода структуры таблицы 7. Нажать кнопку , в открывшемся окне в поле Alias выбрать псевдоним WORK и сохранить таблицу под именем student.db. Рис Окно сохранения таблицы Возможна ситуация, когда таблица не сохраняется. В данном случае необходимо проверить типы полей, их размеры (для строковых значений), а также индексы таблиц. Для добавления записей в таблицу необходимо открыть таблицу командой File/Open/Table, а затем активизировать режим редактирования данных таблицы пиктограммой Edit Data. 68

проверить правильность введенного значения. Если в прямоугольной области появляется фраза «Value is valid», то введенное значение введено правильно. 5. Для сохранения маски необходимо нажать кнопку . В результате этого появится небольшое диалоговое окно «Save Picture». В нем необходимо ввести название маски (например, Phone), и зафиксировать операцию. 69

72 пользователя (USER NAME), режим открытия БД (OPEN MODE), размер КЭШа схем (SCHEMA CACHE SIZE), драйвер языка (LANGDRIVER), режим обработки запросов SQL (SQLQRYMODE), доступ к QBE и SQL (SQLPASSTHRU), пароль (PASSWORD). Рис Фрагмент окна Рис Окно Alias Manager для псевдонима IBLocal Для создания нового псевдонима используется кнопка ; для сохранения кнопка ; для удаления области кнопка . Наиболее удобным средством для работы с псевдонимами является BDE Administrator. Для создания нового псевдонима необходимо выполнить следующие действия: 1. Свернуть окно C++Builder 6.0 и закрыть программу Database Desktop. 2. В группе программ среды C++Builder 6.0 (через кнопку «Пуск») запустить программу BDE Administrator (рис. 7.8). 71

73 Рис Окно BDE Administrator В левой части окна расположен список всех псевдонимов (областей). «Двойной щелчок» по области позволяет отразить в правой части окна всю информацию о псевдониме. 3. Отключить пиктограмму Open or Close (в противном случае команда Object/New будет недоступна). 4. Выполнить команду Object/New. 5. В открывшемся окне выбрать драйвер для нового псевдонима (рис. 7.9); по умолчанию это STANDARD для БД Paradox: Рис Окно задания драйвера 6. В открывшемся окне BDE Administrator (рис. 7.10) в левой части окна ввести имя псевдонима aliasdb, а в правой части окна установить следующие параметры: тип драйвера STANDARD; драйвер для Paradox; путь к базе данных устанавливается через кнопку обзора; параметр ENABLE BCD определяет возможность транслирования числовых полей в значения с плавающей запятой или в коды BCD. Если задать значение true, то поля DECIMAL и NUMERIC преобразуются в коды BCD. 7. Сохранить созданный псевдоним командой Object/Save As с тем же именем aliasdb. 8. Закрыть BDE Administrator. 72

74 Рис Окно отображения данных о псевдонимах Работа с SQL Explorer производится аналогично работе с программой BDE Administrator (окно организовано по тем же принципам). Для сохранения уже существующей таблицы student в новой области необходимо выполнить следующие действия: 1. Открыть Database Desktop. 2. Открыть таблицу student.db из области WORK. 3. Перейти в структуру таблицы и нажать кнопку . 4. Сохранить таблицу в новой области под псевдонимом aliasdb. 5. Закрыть таблицу и проверить наличие ее в области aliasdb любым известным способом. Вопросы для самоконтроля 1. Каким образом организуется работа с базой данных в среде Borland C++Builder? 2. Какие механизмы доступа к данным используются в среде Borland C++Builder? В чем отличие их организации? 3. Каким образом построена работа с базой данных драйвера ODBC? 4. Какие типы данных имеют фиксированную длину? Охарактеризовать. 5. Что такое псевдоним? 6. Охарактеризовать последовательность создания таблицы. 7. Каким образом осуществляется установка минимального и максимального значений по умолчанию? 8. Каким образом задается псевдоним базы данных? 9. С какой целью используется маска при задании строковых полей? 10. Каким образом осуществляется ввод данных в таблицу? 11. Каким образом отредактировать структуру и записи таблицы? 73

75 8. ВИЗУАЛЬНЫЕ КОМПОНЕНТЫ ДЛЯ РАБОТЫ С БАЗОЙ ДАННЫХ 8.1. Компоненты формы, работающие с базой данных Среда C++Builder 6.0 имеет множество компонентов, которые позволяют организовать доступ к базам данных. Эти компоненты расположены на страницах Data Access (доступ к данным) и Data Control (управление данными). Каждое приложение, работающее с базами данных, должно иметь определенный набор компонентов формы. Компоненты наборы данных (data set) непосредственно связаны с таблицей (базой данных). К таким компонентам относятся Table, Query, StoredProc. Компонент источника данных (data source) необходим для связи между набором данных и визуальными компонентами формы DataSource. Компоненты визуализации и управления данными, такие как DBGrid, DBText, DBEdit и другие. Настройка каждого компонента имеет свое значение и должна быть произведена в определенном порядке (насколько это возможно). Рис Последовательность создания и настройки компонентов приложения На рис. 8.1 приведена схема последовательности настройки каждого из компонентов формы Разработка формы просмотра данных таблицы Для разработки простого приложения (рис. 8.2), которое позволяет просмотреть содержимое таблицы BOOK.db, необходимо выполнить следующие действия: 1. Установить на форму следующие компоненты: Table со страницы BDE панели компонентов (компонент виден только в режиме редактирования); DataSource со страницы Data Access (компонент виден только в режиме редактирования);

76 DBGrid со страницы Data Control (компонент виден в любом режиме и представляет собой таблицу-сетку). Рис Форма просмотра данных таблицы 2. Установить на форме метку компонент Label со страницы Standard и задать ей свойство Caption: «Просмотр таблицы STUDENT. db». 3. Выделить метку как объект и установить традиционным для Windows способом данную метку посередине формы в верхней ее части (как заголовок). 4. Сохранить изменения в проекте. 5. Запустить проект на выполнение и убедиться, что форма будет иметь следующий вид (рис. 8.3): Рис Окно приложения в рабочем режиме Как видно из рисунка, видимыми являются компоненты Label и DBGrid. Компоненты Table и DataSource видимы только при разработке приложения (в режиме редактирования). 6. Вернуться в режим разработки проекта. 7. Установить в указанном порядке (рис. 8.4) следующие свойства для установленных компонентов: 75

77 Рис Последовательность задания свойств для компонентов DataSource, Table и DBGrid В компоненте DataSource оформляется ссылка на компонент таблицы; в данном случае идентификатор таблицы (свойство Name) представлен как Table1. В компоненте DBGrid также оформлена ссылка на компонент связи между таблицей и компонентом Table; это элемент формы DataSource, имеющий идентификатор DataSource1 (свойство Name). Безусловно, что идентификаторы компонентов (свойства Name) могут быть изменены. 8. Проверить, что после активизации таблицы (установки свойства Active в положение true) в компоненте DBGrid1 должны появиться записи таблицы student.db. После задания параметров для описанных компонентов можно запускать приложение на выполнение Использование навигатора для работы с данными Существует множество других компонентов формы, которые позволяют передвигаться по записям, просматривать отдельную запись, а также многое другое. Для движения по записям в системе C++Builder существует компонент, который содержит совокупность кнопок для работы с отдельными записями навигатор, представленный компонентом DBNavigator со страницы Data Controls. Для добавления навигатора (рис. 8.5) в существующий проект необходимо выполнить следующие действия: 1. Установить на форме компонент DBNavigator со страницы Data Controls панели компонентов. 2. Активизировать навигатор и установить для него свойство DataSource, значение которого равно DataSource1 (идентификатор компонента DataSource). 3. Вернуться в режим редактирования проекта. 4. Активизировать компонент навигатора. 76

78 Рис Описание кнопок навигатора 5. В инспекторе объектов найти свойство Hints и нажать кнопку обзора (с тремя точками). После чего на экране появится окно «String List Editor» со списком названий кнопок навигатора. Свойство Hints компонента DBNavigator представлено некоторым списком, поэтому в инспекторе объектов присутствует фраза (TStrings). 6. Заменить все английские названия кнопок на русские названия, используя рис Рис Список названий кнопок навигатора 7. Для активизации заданных подсказок установить значение свойства ShowHint true. 8. Сохранить проект и запустить на выполнение. 9. Проверить работу подсказок подведением указателя мыши к любой кнопке навигатора (рис. 8.7). Рис Демонстрация работы подсказок кнопок навигатора 77

79 10. Добавить на форму несколько компонентов DBEdit со страницы Data Controls. Например, для просмотра значений полей «Фамилия», «Имя», «Дата рождения» и «Группа». 11. Добавить на форму столько же компонентов Label для подписи полей. Свойство Caption позволит задать названия компоненту-метке (рис. 8.7). 12. Задать для каждого компонента DBEdit свойства: свойство DataSource значение DataSource1 (для доступа к таблице student.db); свойство DataField значение Fam для фамилии; значение Nam для имени; значение Data_rog для даты рождения; значение Gruppa для группы. 13. Убедиться в том, что данные текущей записи отображены в полях DBEdit (рис. 8.8). Это связано с тем, что текущей записью в таблице является первая запись, а текстовые поля привязаны к таблице. Рис Вид формы в режиме разработки проекта 14. Сохранить проект и запустить на выполнение. Просмотр данных в загруженном приложении позволяет наблюдать следующее: значения полей типа OLE и Memo не просматриваются; они представлены названиями типов полей (рис. 8.9). 78 Рис Фрагмент просмотра данных в компоненте DBGrid

80 Как видно из рисунка, поля таких типов не просматриваются ни в Database Desktop, ни в компоненте DBGrid. Работа с графическими данными и полями примечаний возможна в режиме просмотра конкретной записи Установка подписей полей в компоненте DBGrid Как видно на рис. 8.9, в компоненте DBGrid каждый столбец имеет имя, характеризующее название поля. Безусловно, что названия полей не должны быть на латинском языке. Для изменения заголовков полей в компоненте DBGrid необходимо выполнить следующие действия: 1. Открыть проект (или создать), в котором все настройки для просмотра данных в DBGrid будут выполнены. 2. Произвести «двойной щелчок» на компоненте Table (рис. 8.10а). 3. Вызвать контекстное меню открывшегося окна «Редактор полей» Form1->Table1. 4. Выполнить команду Add All Fields. В результате чего в текущем окне появится список всех полей таблицы student.db (рис. 8.10б). а) б) Рис Окно Редактора полей 5. Выделив поле Nomer, убедиться в том, что «Инспектор объектов», содержащий свойства объектов, изменился в зависимости от текущего объекта. 6. Изменить значение свойства DisplayLabel на значение «Номер». 79

81 7. Изменить для всех полей «Редактор полей» заголовки согласно информации, которую несет каждый из столбцов таблицы. 8. Сохранить проект и запустить на выполнение (рис.8. 11). Рис Окно приложения Вопросы для самоконтроля 1. Какие визуальные компоненты используются для просмотра и обработки данных из таблицы? 2. Чем отличается компонент Button от компонента BitBtn? 3. Какие свойства необходимо установить для источника данных для просмотра информации из таблицы? 4. Каково условие просмотра таблицы в компоненте DBGrid? 5. Каково назначение навигатора? Какие кнопки он имеет? 6. Некоторые кнопки навигатора работают всегда, а некоторые при определенных обстоятельствах не функционируют. При каких условиях и какие кнопки работают от случая к случаю? 7. Каким образом установить заголовки таблицы на русском языке? 80

82 9. СОЗДАНИЕ МНОГОТАБЛИЧНОЙ БАЗЫ ДАННЫХ 9.1. Установка индексов для связывания таблиц В теории баз данных существуют различные типы связей, устанавливаемые между двумя таблицами. В настоящее время различают три вида связей, которые задаются между родительской и дочерней таблицами: 1) «один-к-одному» только одной записи родительской таблицы соответствует одна запись дочерней таблицы; 2) «один-ко-многим» только одной записи родительской таблицы соответствует одна или более записей дочерней таблицы; 3) «много-ко-многим» одной записи родительской таблицы соответствует одна или более записей дочерней таблицы, и наоборот. Допускается, что в родительской таблице могут находиться записи, которые не связаны с дочерней таблицей (в дочерней таблице отсутствуют записи для связи с родительской). Кроме того, в настоящее время связь «много-к-одному» потеряла актуальность, хотя в некоторых СУБД направление связи имеет большое значение для обработки данных и их просмотра. Рассмотрим две таблицы из базы данных ДЕКАНАТ: student.db и ozenka.db, которые связаны отношением 1:М. Данное отношение объясняется тем, что у каждого студента за время учебы должно быть большое количество оценок по различным зачетам и экзаменам. Таблица ОЦЕНКА представлена в прил. 1. Для связи таблиц воспользуемся следующим рисунком (рис. 9.1). Рис Описание индексов таблиц СТУДЕНТ и ОЦЕНКА Для этого необходимо в программе Database Desktop выполнить следующие действия: 1. Создать еще одну таблицу ozenka.db согласно прил Ввести несколько записей с учетом значений поля Nomer таблицы СТУДЕНТ. 81

83 3. Открыть таблицу student.db и перейти в структуру таблицы. 4. В столбце Key поля Nomer нажать пробел для установки в нем звездочки (первичный ключ). 5. В поле Table properties выбрать пункт Secondary Indexes. 6. Через кнопку открыть окно Define Secondary Index. 7. Кнопкой «Стрелка вправо» перевести в правый список поле Nomer; установить опцию «Unique» для первичного индекса (рис. 9.2а). 8. После нажатия кнопки в открывшемся окне сохранить индекс под именем nmrs (рис. 9.2б). а) б) Рис Установка индексов таблицы По умолчанию данные в поле индекса сортируются по возрастанию (Ascending); при необходимости изменения направления сортировки используется флажок Descending. 9. Сохранив все изменения в структуре таблицы, выйти из структуры таблиц. В случае, если индекс не устанавливается, необходимо проверить значения в поле, по которому создается индекс; возможно, что в этом поле существуют повторяющиеся значения, а этого не должно быть. 10. Открыть таблицу ozenka.db (она была создана и заполнена в начале задания). 11. Пиктограммой войти в структуру таблицы ozenka.db. 12. Активизировать свойство таблицы Secondary Indexes. 13. Кнопкой перейти в окно создания индекса. 14. Создать вторичный (не уникальный) индекс nmro по полю Nomer (рис. 9.3). 82

84 Рис Фрагмент окна структуры таблицы Для работы с индексами используются следующие кнопки: для создания нового индекса; для модификации уже существующего индекса; для удаления выделенного индекса. 15. Выйти из структуры таблицы ozenka.db, сохранив все изменения. На рис. 9.4 приведен фрагмент окна структуры таблицы ОЦЕН- КА. В представленном списке находятся два индекса (не уникальных). Второй индекс predmo предназначен для связи с таблицей ПРЕДМЕТ (см. прил. 1). Рис Фрагмент структуры таблицы со списком индексов После установки индексов начинается организация многотабличных баз данных. 83

85 9.2. Разработка формы просмотра данных двух таблиц Как известно, для просмотра записей из одной таблицы достаточно использовать компонент DBGrid или несколько компонентов DBEdit, которые настроены на определенную таблицу. Для просмотра двух таблиц (с отношением 1:М) необходимо воспользоваться и компонентами DBEdit для отображения данных из родительской таблицы, и компонентом DBGrid для демонстрации записей из дочерней таблицы. 84 Рис Форма просмотра двух таблиц Для создания формы просмотра данных двух таблиц (рис. 9.5) необходимо выполнить следующие действия: 1. Создать новый проект и сохранить пустой проект на диске и задать форме название «Работа с двумя связанными таблицами». 2. Добавить на форму метку Label и задать ей заголовок «Просмотр таблиц student.db и ozenka.db». 3. Добавить на форму две пары компонентов Table и DataSource. Пусть компоненты Table1 и DataSource1 описывают родительскую таблицу student.db, а компоненты Table2 и DataSource2 дочернюю таблицу ozenka.db. 4. Открыть «Редактор полей» («двойной щелчок» на компоненте Table1) первой таблицы и «перетащить» из «Редактора полей» необходимые поля на форму.

86 Необходимо заметить, что «перетаскивание» полей позволяет автоматически настроить их на соответствующую таблицу и соответствующие поля. При этом на форме появится само поле и комментарий в виде метки. Достаточно изменить свойство Caption у метки и расположить текстовые компоненты надлежащим образом. 5. Добавить на форму компонент DBNavigator и настроить его на родительскую таблицу. 6. Добавить на форму компонент DBGrid и настроить его на отображение данных второй (дочерней) таблицы. 7. Настроить все компоненты формы соответствующим образом с учетом родительской и дочерней таблиц. 8. Сохранить изменения и запустить проект на выполнение. 9. Убедиться в том, что связь между таблицами не наблюдается, то есть навигатор перемещается по записям первой таблицы, а данные второй таблицы не изменяются, и табличный указатель находится на одной и той же записи (рис. 9.6). Рис Приложение без связи таблиц Из рис. 9.6 видно, что связи между таблицами нет, так как в нижней части формы должны отображаться данные, равные номеру студента, то есть Вернуться в режим редактирования проекта. 11. У компонентов Table11 и Table2 значение свойства Active изменить на значение False. 85

87 Если пользователю необходимо изменить данные в таблице, которая активна на форме, то произойдет сбой программы-проекта. Обязательно нужно дезактивировать таблицу, предназначенную для работы на форме, а потом производить с ней различные изменения в Database Desktop. В противном случае, система будет извещать пользователя о том, что таблица в использовании (use). 12. Активизировать компонент Table2 и установить свойство MasterSource в значение DataSource Для свойства MasterFields активизировать кнопку обзора (рис. 9.7). Рис Уставновка связи между таблицами 14. Выбрать из списка Available Indexes индекс nmro таблицы ОЦЕНКА. 15. В списке Detail Fields (поля дочерней таблицы) выбрать поле Nomer. 16. Выбрать в мастер-таблице (родительской) поле Nomer. 17. После нажатия кнопки в поле Joined Fields появится запись: Nomer >Nomer Это значит, что две таблицы связались по полю Nomer. 18. Активизировать компоненты Table1 и Table2 значение свойства Active должно быть true. Необходимо убедиться в работе двух таблиц: при переходе на другую запись родительской таблицы в компоненте DBGrid отражаются только те записи дочерней таблицы, которые соответствуют в текущий момент записи родительской таблицы. 86

88 Вопросы для самоконтроля 1. Какие типы отношений существуют для связи таблиц? Охарактеризовать их. 2. Что представляет собой первичный ключ? 3. Какие особенности характеризуют вторичный индекс по отношению к первичному? 4. Как задается первичный индекс? 5. Как устанавливается связь между таблицами на форме просмотра двух взаимосвязанных таблиц? 6. Ситуация: таблица не открывается, выдается ошибка об использовании таблицы. Охарактеризовать ситуацию и ее разрешение. 87

89 10. ДОПОЛНИТЕЛЬНЫЕ ВОЗМОЖНОСТИ ПО РАБОТЕ С БАЗАМИ ДАННЫХ Ввод данных в поля типа OLE и Memo Как уже говорилось ранее, просмотреть информацию из полей OLE и Memo невозможно ни в программе Database Desktop, ни в компоненте Grid. Это возможно в ситуации, когда данные из таблицы просматриваются по одной записи. Данный режим необходим для того, чтобы ввести нужную информацию в таблицу. Предположим, что все графические файлы (фотографии) студентов существуют на диске в определенном каталоге. Для ввода в указанные поля данных необходимо произвести следующие действия: 1. Установить на форме компоненты Table, DataSource и DBNavigator. 2. Настроить все компоненты на таблицу СТУДЕНТ; свойство Active компонента Table должно быть false. 3. Произвести «двойной щелчок» на компоненте Table и из «Редактора полей» «перетащить» необходимые поля на форму (рис. 10.1). 88 Рис Рабочий режим приложения

90 Необходимо заметить, что все поля, которые были установлены на форме «перетаскиванием», автоматически настраиваются на конкретную таблицу согласно компонентам Table и DataSource. 4. Активизировать таблицу (свойство Active) и запустить на выполнение приложение. 5. Используя навигатор, остановиться на записи, в которой нет графического файла в поле Photo. 6. Свернуть приложение и обратиться к редактору просмотра графических файлов. 7. В буфер обмена скопировать графический файл (можно воспользоваться комбинацией клавиш ). 8. Вернуться к приложению и в программном режиме произвести «щелчок» на компоненте DBImage1. Компонент активизируется. 9. Командой вставки вставить графическое изображение в активное окно компонента DBImage Аналогичным образом вставить фотографии для всех необходимых студентов. Необходимо заметить, что при просмотре записей через компонент DBGrid наличие данных в полях типа DBImage и Memo характеризуется прописными буквами. Рис Программный режим приложения Ввод данных в поле Memo осуществляется также в программном режиме при условии, что данное поле не заблокировано для ввода данных. 89

91 10.2. Вычисляемые поля. Ниспадающий список Иногда при просмотре данных из каких-либо таблиц необходимо иметь дополнительные столбцы, которые не существуют в таблицах, а рассчитываются при работе приложения. Поля, которые создаются в рабочем порядке на основе уже имеющихся данных, получили название вычисляемых полей (calculated fields). Рассмотрим пример создания нового поля «Возраст» при выполнении проекта «Просмотр таблицы СТУДЕНТ». Для выполнения данного задания необходимо выполнить следующие действия: 1. Установить на форме компоненты Table, DataSource, DBGr > название поля должно появиться в списке полей. Если система вывела диалоговое окно с предупреждением, то, вероятно, пользователь забыл дезактивировать таблицу.

92 8. Перейти на вкладку Events «Инспектора объектов» при активизации компонента Table1. 9. В событии OnCalcFields произвести «щелчок» мыши. 10. В открывшемся окне программного кода проекта в добавленную функцию Table1CalcFields ввести код (листинг 10.1): Листинг Фрагмент приложения по обработке вычисляемого поля vo >asstring; //вырезка из дня рождения s четырех последних символов года рождения s1=s.substring(7,4); //преобразование года рождения в целое число d d=strtoint(s1); //установка в поле таблицы (в каждой записи) значения возраста // ТекущийГод ГодРождения Table1Vozr->Value = Year-d; > В программном коде данные о дате рождения считываются не из поля Data_rog, а из поля Table1Data_rog, идентификатор которого автоматически создается системой именно для программирования. Идентификатор Table1Vozr также был задан автоматически при создании нового поля (область Component). Идентификатор Year инициирован далее. 11. Активизировать форму и войти в программный код события OnCreate. 12. Ввести в программный код данного события команду по считыванию текущей даты: Date().DecodeDate(&Year, &Month, &Day); В данной команде используется стандартная функция Date(), которая возвращает значение текущей даты, например, в формате Метод DecodeDate позволяет распределить по переменным Year, Month и Day значения из текущей даты. 13. Для использования переменных Year, Month, Day необходимо объявить их глобальными в начале программного модуля.cpp: unsigned short Year, Month, Day; 91

93 14. При необходимости в программный код события OnCreate добавить активизацию таблицы, а в программный код события OnDestroy формы добавить дезактивацию таблицы. 15. Сохранить проект и запустить на выполнение (рис. 10.4): Рис Окно с вычисляемым полем «Возраст» Из рис видно, что при вводе данных часто повторяется одна и та же информация, например группа. Для упрощения работы с такими данными можно использовать так называемые ниспадающие списки. Необходимо помнить, что информация о группах в данной задаче не представлена в виде справочника, т. е. отдельной таблицы. Рассмотрим создание списка групп. Для этого необходимо выполнить следующие действия: 1. После открытия проекта просмотра данных таблицы СТУ- ДЕНТ необходимо дезактивировать таблицу. 2. Войти в «Редактор столбцов» компонента DBGrid «двойным щелчком» мыши (рис. 10.5а). 92 а) б) Рис Окно Редактора Столбцов компонента DBGrid

94 3. Через контекстное меню добавить все поля командой Add All Fields. 4. Активизировать поле Gruppa в «Редакторе столбцов» (рис. 10.5б). 5. Установить свойство ButtonStyle = cbsauto (разрешение на возможность появления ниспадающего списка при вводе и/или редактировании данных). 6. Произвести «двойной щелчок» на свойстве PickList, в результате чего открывается окно String List Editor. 7. Ввести список групп. После сохранения проекта можно проверить работу списка групп (рис. 10.6). Рис Использование ниспадающего списка ввода данных Необходимо заметить, что ниспадающие списки используются в ситуациях, когда невыгодно использовать новую таблицу. Например, если по группам, кроме названий, нет никаких данных, то созданная отдельная таблица будет содержать всего два поля: поле первичного ключа и название группы. Кроме того, сам список не является большим. Иная ситуация складывается, когда речь идет о специальности. В данном случае есть смысл вывести информацию о специальностях в отдельную таблицу и ввести такие данные, как: код специальности (для связи с другими таблицами); название специальности; шифр специальности; головной вуз; ФИО председателя УМО (учебно-методического объединения) и т. п. 93

95 В данной системе специальность оформлена в таблице СТУДЕНТ для простоты работы с данными. Как говорилось ранее, в представенной задаче используется упрощенный вариант базы данных (наименьшее количество таблиц) Использование маски ввода При создании таблицы в программе Database Desktop использовалась маска ввода для поля Телефон. Для удобства ввода данных по какому-либо шаблону можно также использовать специальные компоненты, предназначенные для формы, MaskEdit и DBEdit (через «Редактор полей»). Компонент MaskEdit является самостоятельным компонентом в отличие от DBEdit, который отражает данные конкретного поля. Свойство EditMask всех компонентов использует следующие шаблоны маски (табл. 11). Символ! Символы шаблона маски Описание символа шаблона маски Таблица 11 Наличие символа замена недостающих символов пробелами; отсутствие пробелы размещаются в конце строки > Все следующие за ним символы записываются в верхнем регистре (пока не сменится регистр) Анализ регистра не производится \ L l A a C c Используется для того, чтобы различать обычные символы или специальные. Так, например, комбинация символов \> означает, что это не шаблон маски, а обычный символ «больше». Другими словами, данный символ блокирует признак шаблонности для идущего за ним символа Только буква Буква или ничего Только буква или цифра Буква, цифра или ничего Любой символ Любой символ или ничего 94

96 Символ Описание символа шаблона маски 0 Только цифра 9 Цифра или ничего # Цифра, +, или ничего : Разделитель для времени / Разделитель для даты _ Автоматическая вставка пробела Продолжение табл. 11 Компонент MaskEdit расположен на вкладке Additional, и для него достаточно вызвать редактор маски через свойство EditMask. Для создания шаблона маски текстового поля таблицы необходимо выполнить следующие действия: 1. Установить на форме все необходимые компоненты и настроить их на просмотр какой-либо таблицы, например, КЛИЕНТ. 2. Вызвать «Редактор полей» и добавить в него все поля текущей таблицы. 3. Активизировать необходимое поле и через свойство EditMask вызвать окно Input Mask Editor (рис. 10.8). 4. Воспользовавшись правым списком, выбрать за основу какуюлибо маску, например, маску даты. 5. В поле Input Mask отредактировать маску или ввести собственный вариант. 6. В поле Character for Blanks автоматически появляется символ для заполнения, который вводится в третье поле маски. 7. В поле Test Input ввести пример даты (рис. 10.8). 8. Нажав кнопку , перейти к форме проекта. Рис Окно ввода шаблона маски 95

97 На рис приведен интерфейс формы просмотра данных таблицы КЛИЕНТ. В данном примере специально подобраны поля, для которых необходимо в «хорошей» программе определить маски ввода данных. 96 Рис Приложение с примерами масок Как видно из рисунка, при вводе данных и/или редактировании маска ввода автоматически появляется в необходимом поле (если она для него определена). В правой части формы приведена панель с масками, которые определены для полей, находящихся в левой части формы. Разработка приложений затрагивает одни и те же данные. В связи с этим возникает потребность в создании некоторого архива масок для других приложений. Это возможно с помощью создания файла с расширением dem. Этот файл должен иметь в каждой строке через разделитель три блока данных: название маски пример вводимые символы маска Создание двух первых масок (согласно вышеописанному проекту) заключается в следующих шагах: 1. Создать текстовый (через блокнот) файл. 2. Ввести информацию о масках в следующем формате: Телефон с кодом города \(0009\)_ ;1;* Номер автомобиля A837FF63 >L-000-LL-00;1;* 3. Сохранить файл под любым именем с расширением.dem в каталоге..\borland\cbuilder\bin.

98 Рис Окно Input Mask Editor 4. Проверить работу файла масок, загрузив его кнопкой окна Input Mask Editor. Как уже говорилось, наличие масок в текстовых полях (при вводе и/или редактировании) позволяет пользователю чувствовать себя спокойно в вопросе правильного ввода данных. Это подсказка и помощь для пользователя инфрмационной системы Дополнительные возможности просмотра данных В различных приложениях бывают ситуации, когда необходимо вывести ту или иную информацию по требованию. Например, в предыдущем приложении существует кнопка в правой нижней части формы (рис. 10.2), которая дополнительно открывает окно с характеристикой и фотографией (для подтверждения). Несмотря на то, что данные берутся из одной таблицы, сложность данной задачи заключается в том, что нужно передать информацию на другую форму (рис ). Рис Приложение с передачей данных на другую форму 97

99 Для создания второй формы, отображающей необходимую информацию из той же таблицы, нужно выполнить следующие действия: 1. Создать новую форму, например, под именем Form2 (с учетом того, что главная форма имеет идентификатор Form1). 2. Расположить на форме компоненты DBMemo и DBImage традиционным образом (но не «перетаскиванием»). 3. Выполнить команду File/Include Unit Hdr, что позволит второй форме видеть необходимую информацию с первой формы. Активной должна быть именно вторая форма. 4. Организовать на первой форме, например, кнопку для вызова второй формы с указанием команды: Form2->Show(); 5. Необходимо заметить, что вторая форма может быть невидима для первой, поэтому нужно в программном модуле первой формы подключить заголовочный файл второй формы: #include un_db_2_2.h ; 6. Активизировать вторую форму и установить следующие свойства: для компонента DBMemo DataSource = Form1->DataSource1 DataField = Haract для компонента DBImage DataSource = Form1->DataSource1 DataField = Photo Рассмотрим второй пример вывода данных из одной таблицы, используя компонент DBCtrlGrid (рис ). Рис Приложение с компонентом DBCtrlGrid 98

100 Необходимо заметить, что компонент DBCtrlGr >

101 5. После активизации таблицы на форме появятся соответствующие значения компонентов DBText и DBEdit (соответствующие данным первой записи таблицы). Рассмотрим третий пример вывода данных (рис ). В просмотре данных будут участвовать две таблицы: СТУДЕНТ и ОЦЕНКА; для вывода информации о предмете будет использована третья таблица ПРЕДМЕТ (с учетом связи между таблицами ПРЕДМЕТ и ОЦЕНКА). Последняя из трех таблиц необходима для того, чтобы получать полную информацию об оценках. Рис Окно просмотра данных таблиц СТУДЕНТ, ОЦЕНКА и ПРЕДМЕТ Реализуем сначала первый этап проекта: просмотр данных из двух таблиц с использованием компонентов DBCtrlGrid для первой таблицы и DBGrid для второй. Для создания данной части проекта необходимо выполнить следующие действия: 1. Создать новый проект, сохранив на диске все нужные файлы; запустить на выполнение программу DataBase Desktop и загрузить таблицу student.db. 2. Создать для таблицы СТУДЕНТ еще один индекс (не уникальный и составной) по полям Группа и Фамилия, сохранив индекс под именем grupfam (на рис в нижней части формы записаны невидимые метки, напоминающие о необходимых индексах). Индекс grupfam необходим таблице не для связи (для этого уже существует индекс nmrs), а для сортировки данных при просмотре. Вторая таблица ОЦЕНКА использует индекс nmro, который используется для связи с таблицей СТУДЕНТ (индекс связи nmrs). 3. Вернуться в рабочий режим проекта. 4. Установить на форме компоненты Table и DataSource (для первой таблицы с индексом 1 Table1 и DataSource1, для второй таблицы с индексом 2 и т. д.). 5. Каждый компонент DataSource настроить на соответствующую таблицу Table. 100

102 Рис Интерфейс формы просмотра нескольких таблиц 6. Для компонента Table1 установить свойства: DatabaseName = aliasdb, TableName = student, IndexName = grupfam. 7. Установить на форме компонент DBCtrlGr >

103 Описание опций окна New Field Таблица 12 Опция окна Name Component Type 102 Описание опции Название нового поля Что сделать? Ввести идентификатор поля, например, Prep. Он будет отражаться в списке «Редактор полей» Название поля Идентификатор Table2Prep. Данное название задается автоматически и исполь- для программированизуется в программировании Тип данных поля Из списка выбрать тип данных String (строковый тип) Size Размер поля Ввести длину поля, например, 30 Field Type Key Fields Dataset Lookup Key Result Field Вид создания нового поля Из предложенных переключателей выбрать Lookup для задания параметров нового поля Поле связи Из списка выбрать индекс дочерней таблицы Kod_predm (таблица ОЦЕНКА), первой таблицы, предназначенной для (ПРЕДМЕТ). Именно в дочерней таб- по которому она связана с родительской отображения лице будет отображаться информация данных из родительской Вторая таблица с полем связи К л ю ч е в о е поле второй таблицы, необходимое для связи с первой таблицей Из списка выбрать родительскую таблицу ПРЕДМЕТ (Table3) Из списка выбрать индекс Kod_predm родительской таблицы (ПРЕДМЕТ) для связи с дочерней таблицей (ОЦЕНКА) Из списка выбрать поле Predmet, которое Просматриваемое поле вто- ПРЕДМЕТ в таблицу ОЦЕНКА для про- будет добавлено из родительской таблицы рой таблицы смотра взаимосвязанных данных ПРЕД- МЕТ + ОЦЕНКА Система дает подсказки для выбора данных в поле Lookup definition.

104 Рис Окно New Field Рис Окно Редактора Полей таблицы Table2 Необходимо заметить, что такой подход вывод данных из двух взаимосвязанных таблиц позволяет просматривать содержимое двух таблиц в одном компоненте DBGrid, без использования дополнительных элементов DBEdit. 103

105 10.5. Диалоговые окна Очень часто в приложениях используются диалоговые окна для вывода различного рода информации, например, сообщений об ошибке, сообщений-подтверждений и т. п. Для этого используются различные функции вызова диалоговых окон. Рассмотрим их. 1. Функция ShowMessage (Msg). Сообщение Msg типа AnsiString. 2. Функция ShowMessageFmt (Msg, Param, ParamSize), где Msg сообщение типа AnsiString, Param массив параметров, ParamSize размер этого массива параметров. Для передачи массива в функцию используется макрос OPENARRAY. Эта функция описана в стандартном файле sysdefs.h. Макрос обеспечивает передачу в функцию открытого массива, содержащего до 19 элементов. В программном коде события кнопки введено (рис ): ShowMessage ( Это сообщение в простом окне! ); В программном коде события кнопки введено: short a=5; short b=7; ShowMessageFmt( Задано%d параметров из%d, OPENARRAY(TVarRec, (a,b))); 104 а) б) Рис Пример вывода диалоговых окон 3. Функция MessageDlg предназначена для задания вопроса и получения на него ответа. Формат данной функции следующий: MessageDlg (Msg, DlgType, Buttons, HelpCtx), где Msg сообщение, DlgType тип диалогового окна (константа), Buttons перечисление необходимых кнопок (константы), HelpCtx экран контекстной справки при нажатии клавиши .

106 В табл. 13 приведены константы типов диалоговых окон: Таблица 13 Константы типов диалоговых окон Значение _mtconfirmation _mtinformation _mterror _mtwarning _mtcustom Описание Окно подтверждения, содержащее вопросительный знак (рис а) Информационное окно, содержащее символ i (рис б) Окно ошибок, содержащее красный стоп-сигнал (рис а) Окно замечаний, содержащее желтый восклицательный знак (рис б) Заказное окно без рисунка, имеющее заголовок проекта (рис ) Параметр Buttons представляет собой некое множество, в которое необходимо включать различного вида кнопки. Возможные значения видов кнопок приведены в табл. 14. Таблица 14 Значения видов кнопок Значение кнопки mbyes mbno mbok mbcancel mbhelp mbabort mbretry mbignore mball Описание Кнопка с надписью Yes Кнопка с надписью No Кнопка с надписью OK Кнопка с надписью Cancel Кнопка с надписью Help Кнопка с надписью Abort Кнопка с надписью Retry Кнопка с надписью Ignore Кнопка с надписью All Необходимые кнопки заносятся в Buttons операцией 107 _mbyesnocancel сочетание кнопок «Yes», «No» и «Cancel»; _mbokcancel сочетание кнопок «Ok» и «Cancel»; _mbabortretryignore сочетание кнопок «Abort», «Retry» и «Ignore». Параметр HelpCtx определяет экран контекстной справки, соответствующей данному диалоговому окну. Этот экран справки будет появляться каждый раз, когда пользователь нажмет клавишу . Если в приложении справка не планируется, то этот параметр должен равняться нулю. Функция MessageDlg возвращает одно из значений нажатий кнопок: _mrnone _mrabort _mryes _mrok _mrretry _mrno _mrcancel _mrignore _mrall 106 а) б) Рис Диалоговые окна при завершении приложения Для вывода таких окон используется следующий фрагмент приложения: vo >

108 а) б) Рис Демонстрация окна-ошибки и окна-предупреждения Окно с заголовком проекта можно вывести следующим образом: void fastcall TForm1::BtnCustClick(TObject *Sender) < switch ( MessageDlg ( Занести запись в базу данных?, mtcustom, mbyesnocancel, 0)) < case mryes: Table1->Post(); break; case mrno: Table1->Cancel(); break; case mrcancel: Close(); > > Рис Окно, определенное пользователем 4. Функция TApplication->MessageBox. Основным недостатком ранее рассмотренных функций является отсутствие русификации диалоговых окон и невозможность указать текст заголовка окна. Эти недостатки устраняет функция TApplication- >MessageBox. Формат данной функции следующий: MessageBox (Text, Caption, Flags), где Text текст сообщения, которое может превышать 355 символов, Caption текст заголовка окна, Flags множество флажков, определяющих вид и поведение диалогового окна. 107

109 Рассмотрим значения различных параметров данной функции. В табл. 15 приведены флажки для кнопок и иконок диалогового окна. Таблица 15 Кнопки Флажки кнопок и пиктограмм в диалоговом окне Флажок Описание MB_ABORTRETRYIGNORE MB_OK MB_OKCANCEL MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL Пиктограммы MB_ICONWARNING MB_ICONINFORMATION MB_ICONQUESTION MB_ICONSTOP, MB_ICONERROR Кнопки Abort (Стоп), Retry (Повтор) и Ignore (Пропустить) Кнопка Ok Кнопки Ok и Cancel (Отмена) Кнопки Retry (Повтор) и Cancel (Отмена) Кнопки Yes (Да) и No (Нет) Кнопки Yes (Да), No (Нет) и Cancel (Отмена) Восклицательный знак (замечание, предупреждение) Буква i в круге (подтверждение) Знак вопроса (ожидание ответа) Знак креста на красном круге (запрет, ошибка) Данная функция также возвращает одно из значений нажатий кнопок (табл. 16). Таблица 16 Константы кнопок Значение Численное значение Пояснение IDABORT 3 Выбрана кнопка Abort (Стоп) IDCANCEL 2 Выбрана кнопка Cancel (отмена) и нажата клавиша Esc IDIGNORE 5 Выбрана кнопка Ignore (Пропустить) IDNO 7 Выбрана кнопка No (Нет) IDOK 1 Выбрана кнопка Ok IDRETRY 4 Выбрана кнопка Retry (Повтор) IDYES 6 Выбрана кнопка Yes (Да) 108

110 Рассмотрим пример, в котором запрашивается подтверждение на завершение работы приложения, а затем (при положительном ответе) выводится диалоговое окно информационного характера о завершении программы (рис ). if (Application->MessageBox( Вы хотите завершить приложение?, Подтверждение на завершение, MB_YESNOCANCEL + MB_ICONQUESTION)==IDYES) < Application->MessageBox( Работа закончена!, Завершение приложения, MB_OK + MB_ICONINFORMATION); Close(); > Рис Диалоговые окна подтверждения и информационного характера 5. Функция InputBox. Диалоговое окно, создаваемое с помощью данной функции, используется для ввода каких-либо данных. Функция возвращает вводимое значение, которое можно использовать затем в приложении для обработки (рис б). Формат функции: InputBox (Caption, Prompt, Default), где Caption заголовок окна, Prompt комментарий для ввода данных, Default строка, которую функция возвращает в случае, если пользователь отказался от нажатия на кнопку . а) б) с) Рис Поэтапная реализация приложения 109

111 Следующий фрагмент позволяет организовать диалоговое окно для ввода данных: AnsiString Name= InputBox ( Пожалуйста, представьтесь, Введите Ваше имя, Неизвестный ); Label1->Caption = Name; 6. Функция InputQuery. В отличие от предыдущей функция InputQuery возвращает значение только в случае положительного ответа. Это значит, что пользователь всегда будет знать, положительный или отрицательный ответ был дан. Если при разработке приложения такой момент обязательно нужно проследить, то есть смысл выбрать функцию InputQuery, в противном случае можно воспользоваться предыдущей функцией InputBox. Формат функции: InputQuery (Caption, Prompt, &Value), где Caption и Prompt характеризуют те же параметры, что и в функции InputBox, Value строка редактирования текстового поля в диалоговом окне. Например, следующий фрагмент программного кода позволяет при положительном ответе вывести приветствие с именем пользователя, а при отрицательном приветствие незнакомца. AnsiString Name=»Неизвестный»; if (! InputQuery («Представьтесь», «Введите Ваше имя», Name)) ShowMessageBox (); else ShowMessageBox («Здравствуйте,» + Name + «!»); 110 Вопросы для самоконтроля 1. Чем отличается работа с полями типа OLE и Memo от работы с другими полями таблицы? 2. Как вводятся в таблицу значения полей типа OLE и Memo? 3. Что такое вычисляемое поле? 4. Каким образом создается вычисляемое поле? Описать последовательность действий. 5. С какой целью используется ниспадающий список в режиме просмотра таблицы? 6. Каким образом создается ниспадающий список? 7. Что такое маска ввода? 8. С какими компонентами формы связана маска ввода? 9. Какие шаблоны используются при создании маски ввода? 10. Каким образом можно передать данные с одной формы на другую (в случае просмотра данных из одной таблицы)?

112 11. Какие дополнительные компоненты системы могут быть использованы для просмотра данных и их поиска? 12. Как можно просмотреть данные из трех взаимосвязанных таблиц? 13. Какие возможные ситуации могут быть связаны с окном New Field? Пояснить, какие типы новых полей можно создавать. 14. Какие виды диалоговых окон можно использовать для диалога с пользователем? 15. Какие функции используются для вывода диалоговых окон? 16. Каким образом формируется функция вывода окна сообщения MessageDlg в зависимости от ситуации? 111

113 11. РЕАЛИЗАЦИЯ ОСНОВНЫХ ФУНКЦИЙ ПРИЛОЖЕНИЯ Разработка пользовательского навигатора Использование системного навигатора упрощает осуществление многих функций при работе с базами данных. Однако знание различных команд, способствующих разработке приложений, необходимо для создания более сложных функций. Рассмотрим пример формы (рис. 11.1), которая позволяет: осуществлять переход по записям через собственный навигатор данных таблицы; выполнить через системный навигатор операции манипулирования данными; поиск данных по фамилии и вычисление среднего арифметического всех оценок студента. Необходимо заметить, что в качестве примера взята таблица СТУ- ДЕНТ, являющаяся результирующей таблицей, то есть объединяющей информацию различных таблиц. Использование связей в данном примере не предусмотрено; основным моментом в данном примере является использование программного кода для обработки информации таблицы. 112 Рис Форма проекта по работе с БД «Студент»

114 Для реализации данной формы необходимо выполнить следующие действия: 1. Создать таблицу СТУДЕНТ с использованием Database Desktop. 2. На главной форме расположить компоненты Table, DataSource, DBGrid, DBNavigator и настроить их соответствующим образом. 3. Проверить работу проекта. 4. Активизировать компонент DBNavigator1 и раскрыть «щелчком» групповое свойство VisibleButtons. 5. Для идентификаторов nbfirst, nbprior, nbnext, nblast установить значение false (в результате чего на форме видимы будут только шесть кнопок). 6. Добавить на форму четыре кнопки и задать им соответствующие названия: , , , . Данный навигатор представим как пользовательский. 7. Войти в программный код кнопки и ввести следующий фрагмент программы: // если табличный указатель в текущий момент не находится // на первой записи if (Table1->Bof! = true) < // перевести табличный указатель на первую запись Table1->First(); > Метод Bof (Begin Of File) проверяет начало таблицы, а метод Eof (End Of File) конец таблицы. Метод First() осуществляет переход табличного указателя на первую запись таблицы; Next() на следующую запись; Prior() на предыдущую запись; Last() на последнюю запись. 8. Используя описанные выше методы, аналогичным способом оформить программные коды всех кнопок пользовательского навигатора. 9. Для установки русских названий столбцов необходимо использовать Редактор полей. 10. Проверить изменения в окне Object TreeView; в результате обращения к «Редактору полей» в окне появятся имена полей, которые можно использовать при обращениях к записям таблиц в программном коде (рис. 11.2). Идентификаторы, представленные на рисунке и установленные по умолчанию, позволяют в дальнейшем разработчику обращаться к ним для обработки полей таблиц. 113

115 Рис Окно Object TreeView Поиск данных в проекте Необходимо заметить, что для поиска данных в приложениях, работающих на основе баз данных, используются специальные средства, например, язык запросов SQL. В данной работе используются средства системы Borland C++Builder и языка С++. Для поиска данных используется два подхода: просмотр всех записей для поиска данных согласно критерию; поиск и остановка на конкретной записи, которая удовлетворяет условию. Рассмотрим первый вариант. На рис приведена форма с кнопкой, которая позволяет вычислить среднее арифметическое всех оценок конкретного студента. При этом просматривается вся таблица (пока не конец файла). Листинг Программный код кнопки «Расчет средней оценки» // инициализация переменной, характеризующая среднее арифметическое // всех оценок float soz=0; // инициализация счетчика количества оценок int n=0; // установка табличного указателя на первую запись таблицы Table1->First();

116 // условие пока не конец файла while (Table1->Eof!=true) < // условие если значение поля текущей записи равно значению // текстового поля if (Table1FAM->Value==Edit1->Text) < // инкремент счетчика количества оценок n++; // увеличение суммы на значение новой оценки soz=soz+table1ozenka->value; > // переход на следующую запись Table1->Next(); > // условие, контролирующее более одной записи if (n>1) < soz=soz/n; Label2->Caption= Средняя оценка студента = +FloatToStrF(soz, ffgeneral,3,1); > // условие, контролирующее одну запись if (n==1) < Label2->Caption= У студента одна оценка! ; > // условие, проверяющее отсутствие записи в таблице if (n==0) < Label2->Caption= Такого студента нет! ; > // переход на первую запись Table1->First(); Второй вариант Существует несколько методик поиска записей, которые можно назвать SetKey, FindKey, Lookup. 1. Оператор SetKey. Таблица предварительно должна быть индексирована по тому полю, по которому будет проводиться поиск. Затем таблица устанавливается в состояние поиска dssetкеу с помощью метода SеtКеу. В состоянии 115

117 dssetkey набор данных воспринимает последующий оператор как задание ключа поиска. Поэтому после задания данного состояния устанавливается требуемое значение ключа поиска по интересующему полю. В заключение методом GotoKey курсор переводится на запись, в которой значение указанного поля равно ключу. Если таких записей несколько, то курсор переводится на первую из них. Если cоответствующая запись не находится, то метод GotoKey возвращает false. Для полей типа строк лучше использовать не метод GotoKey, а метод GotoNearest. Этот метод перемещает курсор на первую запись, значение поля в которой максимально близко к ключу. То есть он сработает и тогда, когда совпадение не полное. Метод GotoNearest можно применять и к цифровым полям. В этом случае он переместит курсор на первую запись, значение поля в которой больше или равно заданному значению ключа. Например, на форме в текстовое поле вводится фамилия; необходимо найти данную фамилию в таблице; в случае отсутствия фамилии в базе на экран выводится информационное сообщение. Table1->IndexFieldNames = Fam ; Table1->SetKey(); Table1->FieldByName( Fam )->AsString = EdFam->Text; if (!Table1->GotoKey()) ShowMessage ( Запись не найдена ); Первый оператор подключает индекс, созданный по полю Fam. Второй оператор переводит набор данных в состояние dssetkey. Третьей командой задается ключ поиска, который равен считанному из текстового поля EdFam значению. При этом считываемое значение воспринимается системой как строковое (AsString). Четвертый оператор осуществляет переход к соответствующей записи или сообщает об отсутствии такой записи. Поиск фамилии можно осуществить и следующим фрагментом программного кода: Table1->IndexFieldNames = Fam ; Table1->SetKey(); Table1->FieldByName( Fam )->AsString = EdFam->Text; Table1->GotoNearest(); Даже если точно такой фамилии не найдется, курсор перейдет на наиболее похожую (совпадающую по первым символам). 2. Оператор FindKey. Методика поиска FindKey еще богаче по своим возможностям. В этой методике таблица также должна быть проиндексирована по тем ключевым полям, по которым осуществляется поиск. Функция FindKey определена следующим образом: bool fastcall FindKey (const System::TVarRec *KeyValues, const int KeyValues_Size); 116

118 Параметр KeyValues представляет собой открытый массив: разделяемый запятыми список значений полей, по которым индексирован набор данных, в той последовательности, в которой они входят в индекс. При этом не обязательно перечислять все поля достаточно перечислить первое или несколько первых. Параметр KeyValues_Size определяет индекс последнего поля в массиве, участвующего в поиске. Поскольку индексы начинаются с 0, то KeyValues_Size на единицу меньше количества полей, участвующих в поиске. Вместо FindKey для полей строкового типа можно использовать аналогичный метод FindNearest, обеспечивающий переход к наиболее совпадающей строке, если полного совпадения не получено. Объявление и параметры этого метода те же, что и в методе FindKey. Метод FindNearest можно применять и к цифровым полям. В этом случае он переместит курсор на первую запись, значение полей в которой больше или равны заданным значениям ключей. Метод Lookup определен следующим образом: System:: Variant fastcall Lookup ( const System::AnsiString KeyFields, const System::Variant &KeyValues, const System::AnsiString ResultFields); Например, если необходимо найти запись, относящуюся к сотруднику, фамилия которого указана в текстовом поле EdFam, и вывести в поле EdNam имя сотрудника, то эти операции можно осуществить следующим образом: EdNam->Text = Table1->Lookup( Fam, EdFam->Text, Nam ); Метод Lookup не изменяет положения курсора. Он только возвращает значения указанных полей. Они могут использоваться любым способом. В частности, они могут использоваться вместо параметра KeyValues в другом операторе Lookup или Locate. Это открывает широкие возможности формирования сложных запросов по нескольким таблицам. Рассмотрим еще один пример, который позволяет осуществлять поиск данных при работе с двумя таблицами ПРЕПОДАВАТЕЛЬ и ПРЕДМЕТ (рис. 11.3). Данный проект позволяет выбрать из комбинированного списка фамилию преподавателя, а затем получить список предметов, которые он преподает. Трудность разработки данного проекта заключается в том, что при указании источника данных для комбинированного списка данный список автоматически не устанавливается, как обычно это наблюдается в специализированных системах (СУБД). Необходимо прибегнуть к некоторой хитрости для того, чтобы создать список преподавателей (из таблицы ПРЕ- ПОДАВАТЕЛЬ), а затем привязать его ко второй таблице (ПРЕДМЕТ). 117

119 Рис Просмотр данных по фамилии Прежде чем приступить к разработке данного приложения, необходимо описать некоторые моменты. На рис расположено два набора компонентов для таблиц. Компонент DBGrid относится только ко второй таблице, компоненты DBEdit к первой. По интерфейсу формы видно, что в нижней части формы расположены текстовые поля для того, чтобы проверить работу выбора элемента комбинированного списка. 118 Рис Форма приложения в режиме редактора

120 Для разработки приложения необходимо выполнить следующие действия: 1. Создать новый проект и установить соответствующие компоненты (рис.11.4). 2. Настроить компоненты Table1, DataSource1 на таблицу ПРЕ- ПОДАВАТЕЛЬ, Table2, DataSource2, DBGrid на таблицу ПРЕДМЕТ. 3. «Перетащить» компоненты DBEdit из «Редактора полей» таблицы ПРЕПОДАВАТЕЛЬ. 4. Активизировать форму и войти в программный код события OnCreate во вкладке Events. 5. Ввести программный код, учитывая некоторые особенности собственного приложения: Листинг Добавление в комбинированный список значений // активизировать таблицу ПРЕПОДАВАТЕЛЬ Table1->Active=true; // перейти на первую запись Table1->First(); // очистить список фамилий ComboBox1->Clear(); // пока не конец файла таблицы while (!Table1->Eof) < // добавить в комбинированный список строковое значение, взятое // из текущей записи поля Фамилия Table1Famil ComboBox1->Items->Add(Table1Famil->AsString); // перейти на следующую запись Table1->Next(); > // установить активным первый элемент списка (индекс 0) ComboBox1->ItemIndex=0; // перейти на первую запись Table1->First(); // активизировать вторую таблицу Table2->Active=true; Необходимо заметить, что введенный программный код позволяет ввести в любой список данные из конкретного поля. 6. Активизировать компонент ComboBox и вызвать программный код события OnChange на вкладке Events. 7. Ввести, учитывая некоторые особенности собственного приложения, следующий код: 119

121 120 Листинг Установка связей между таблицами // установить для дочерней таблицы поле связи из родительской таблицы Table2->MasterFields= Kod_prep ; // установить для дочерней таблицы собственное поле связи Table2->IndexFieldNames= Kod_pp ; // установить поле, по которому существует индекс для поиска Table1->IndexFieldNames= Famil ; // найти согласно элементу списка нужное значение (см. 4.5) Table1->FindNearest(&TVarRec(ComboBox1->Text),0); // передать источник данных компоненту-просмотрщику DBEdit1->DataSource=DataSource1; // передать фокус, который позволит активизировать и обновить компонент DBGrid1->SetFocus(); Таким образом, можно организовать просмотр данных из нескольких таблиц Фильтрация данных Фильтрация процесс отбора в оперативной памяти данных таблиц согласно определенному критерию. Необходимо заметить, что сама таблица и его содержимое не изменяется; изменения происходят в оперативной памяти, то есть во временной таблице, куда загружается на временное пользование база данных. Предполагается, что с отфильтрованными записями можно производить какие-либо действия, а потом вновь возвращать базу данных к исходному состоянию. Такая ситуация складывается в случаях, когда не нужно изменять таблицу, не нужно создавать лишние файлы (возможно, огромного объема), а просто для удобства выбрать некоторые записи и поработать с ними некоторое время (просто попользоваться данными). Следующие три рисунка (рис ) показывают определенное состояние таблицы СТУДЕНТ: рис отображение всех данных (разные группы различных специальностей); рис отображение данных по конкретной группе; рис отображение данных конкретной специальности. Прежде чем рассмотреть программный код приложения, необходимо пояснить, какие компоненты формы расположены на ней.

122 Настройка таблицы на компоненты Table, DataSource и DBGrid не раз рассматривалась в различных параграфах. Поэтому рассмотрим интерфейс нижней части формы. Рис Окно приложения «Фильтрация записей» Необходимо заметить, что в нижней части формы расположены следующие компоненты, установленные с вкладки Standard: RadioGroup (группа зависимых переключателей); ListBox (список); Memo (многострочное текстовое поле); ComboBox (раскрывающийся или комбинированный список). Компонент Memo является недоступным для редактирования, так как носит только ознакомительный характер для пунктов соседнего списка. Свойство Lines содержит список пунктов; свойство Enabled (доступность) находится в состоянии false (недоступен). Свойство Items (также как и свойство Lines компонента Memo) компонента ListBox содержит список шифров специальностей. Компонент ComboBox должен заполняться элементами при наступлении события выбора пункта шифра специальности в компоненте ListBox. Первоначально можно установить для комбинированного списка свойства недоступности. Это связано с тем, что пользователь случайно может выбирать группу, а ее, к сожалению, нет в списке, так как список формируется после выбора шифра специальности. Очень часто при разработке приложений возникают ситуации, когда необходимо «заблокировать» действие, которое пользователь может 121

123 произвести. Это обычно связано с тем, что пользователь не знает последовательности наступления тех или иных событий, и может нарушить порядок действий. В связи с этим есть смысл делать недоступными те или иные компоненты, пока они не станут «нужными». Фильтрация может производиться по группе, если последняя установлена, или по специальности, если та выбрана. В данной программе не предусмотрен анализ выбора группы или специальности, хотя при разработке «правильного» приложения такой момент необходимо учитывать обязательно. Рассмотрим фрагмент программного кода события выбора специальности. Для этого активизируется компонент LIstBox, и на вкладке Events осуществляется переход в программный код события OnClick: 122 Листинг Формирование списка // очистка списка, необходимая каждый раз при выборе специальности ComboBox1->Clear(); // если считанный по индексу пункт (как строковое значение) списка равен if (ListBox1->Items->Strings[ListBox1->ItemIndex] == ) < // добавить в список элемент как очередной пункт списка ComboBox1->Items->Add( ПИ-101 ); ComboBox1->Items->Add( ПИ-201 ); ComboBox1->Items->Add( ПИ-202 ); ComboBox1->Items->Add( ПИ-301 ); ComboBox1->Items->Add( ПИ-302 ); ComboBox1->Items->Add( ПИ-303 ); > // в этом месте должны быть условия для заполнения списка другими // значениями групп. // установка активного элемента списка (первый элемент всегда имеет // индекс 0) ComboBox1->ItemIndex=0; // установка доступности списка (после выбора шифра специальности) ComboBox1->Enabled=true; Таким образом, после выбора шифра специальности (в обычном списке ListBox) в комбинированном списке появляется список групп согласно специальности. Следующий шаг связан с описанием программного кода события выбора переключателя.

124 Необходимо заметить, что для фильтрации необходимо подключать индексы, созданные по полям, которые служат основой для критерия. Так, например, для фильтрации по группе необходимо создать индекс Группа+Фамилия, а для фильтрации по специальности Специальность+Фамилия. Второе поле в обеих фильтрациях необходимо для простоты работы с фамилиями, то есть сначала сортировка происходит по группе (специальности), а затем по фамилии. Допустим, что существуют (созданные в Database Desktop) индексы grupfam и spezfam. Рассмотрим фрагмент программного кода выбора переключателя. Для этого активизируется компонент RadioGroup и на вкладке Events осуществляется переход по событию OnClick: Листинг Обработка переключателей // активизация индекса grupfam Table1->IndexName= grupfam ; // если выбран первый переключатель (его индекс 0) if (RadioGroup1->ItemIndex==0) // признак таблицы не фильтрованная Table1->Filtered=false; else < // если выбран третий переключатель (его индекс 2) if (RadioGroup1->ItemIndex==2) < // активизация индекса spezfam Table1->IndexName= spezfam ; // формирование предложения-критерия Table1->Filter= Spez= + ListBox1->Items->Strings[ListBox1->ItemIndex]+ ; > // если выбран второй переключатель (его индекс 1) else < // формирование предложения-критерия Table1->Filter= Gruppa= +ComboBox1->Text+ ; > // признак таблицы фильтрованная Table1->Filtered=true; > 123

125 Далее приведены интерфейсы фильтрации по группе и по специальности. Рис Фильтрация по группе ПИ-302 специальности Рис Фильтрация по специальности «Математика» Последним шагом в данном приложении является разработка кнопки «Обновить». Данная кнопка необходима для того, чтобы обновить данные в таблице после выбора специальности или группы. Поэтому в программном коде события нажатия кнопки необходимо сделать ссылку (или вызвать) на функцию выбора переключателей. Например, выбор переключателей осуществляется через функцию, описанную как void fastcall TForm1::RadioGroup1Click(TObject *Sender)

126 Чтобы вызвать данную функцию для очередного выполнения, необходимо записать имя функции и ее параметры, то есть RadioGroup1C lick(sender) Добавление данных Добавление записей в базу данных является одной из основных функций приложения, обрабатывающего информацию структурированных данных. Системный анализ задачи предполагает различные варианты добавления данных: 1. Добавление новых студентов. 2. Добавление новых преподавателей. 3. Добавление новых дисциплин. 4. Добавление оценок студентов после каждой сессии. Реализация данных функций позволяет проследить последовательность действий разработчика. Предполагается, что в приложении на главной форме существует меню, которое позволяет вызвать форму добавления, удаления и просмотра данных. Допустим, что форма добавления данных вызывается аналогичным способом и является лишь частью проекта. Из предложенных вариантов добавления данных первая пара функций реализуется так же одинаково, как и вторая пара функций. Рассмотрим первую и третью функции добавления данных (рис. 11.8, прил. 2). Рис Страница добавления новых студентов 125

127 Как видно из рис. 11.8, форма добавления данных содержит компонент RadioGroup, который позволяет активизировать одну из четырех вкладок (страниц) компонента PageControl, имеющий в своем составе любое количество страниц TabSheet. В верхней части формы находится компонент DBGrid, отражающий данные тех таблиц, с которыми пользователь в настоящее время работает. Поэтому необходимо программным путем организовать активизацию таблиц в определенные моменты времени. На форме располагаются четыре набора компонентов для обработки таблиц базы данных (СТУДЕНТ, ОЦЕНКА, ПРЕДМЕТ, ПРЕПОДА- ВАТЕЛЬ). Необходимо заметить, что для первой функции добавления достаточно работать только с таблицей СТУДЕНТ, для второй функции с таблицей ПРЕПОДАВАТЕЛЬ, для третьей функции с таблицами ПРЕПОДАВАТЕЛЬ и ПРЕДМЕТ, для четвертой с таблицами СТУДЕНТ, ПРЕДМЕТ и ОЦЕНКА. Чтобы не усложнять обработку данных, необходимо заметить, что все пары компонентов настроены на соответствующие таблицы, но без связей между ними. Кроме того, достаточно сложно добавить фотографию в таблицу уже известным способом. Поэтому есть смысл фотографию добавить после того, как запись введена в таблицу, т. е. в режиме редактирования, а не добавления. Последний вариант наиболее прост и удобен. I. Разработка первой функции добавление нового студента Особенность обработки: при открытии страницы (выбор переключателя) должны быть установлены какие-либо параметры для работы данной вкладки. Так, например, код студента должен формироваться автоматически, увеличиваясь на 1 (при открытии страницы); формирование даты должно осуществляться каждый раз после выбора дня, месяца и года; кнопка «Добавить в базу данных» должна добавлять запись в таблицу СТУДЕНТ и автоматически обновлять компонент DBGrid. Ход работы: 1. На новую форму добавить компонент PageControl. 2. Выполнить команду New Page из контекстного меню компонента PageControl. 3. Активизировать первую страницу «щелчком» мыши. При этом проверить, чтобы в «Инспекторе объектов» была указана именно первая страница, например, TabSheet1. 4. Через свойство Caption задать странице название согласно рис Аналогичным способом задать необходимое число страниц с заголовками. 126

128 5. Установить на области страницы необходимые компоненты Label, Edit, ComboBox, Button, Memo, DBImage, EditMask (для телефона). 6. Установить для каждого компонента страницы свойства согласно интерфейсу. Свойство TabOrder позволяет установить для компонента порядок передачи фокуса. Индекс 0 должен быть у текстового поля фамилии; затем по порядку устанавливается индекс для имени, отчества, домашнего адреса и т. п. Задать фиксированные списки для компонентов ComboBox через свойство Items (день: 1-31; месяц: 1-12; год: ; группа; специальность). Для компонента EditMask описать свойство MaskEdit. 7. Активизировать компонент RadioGroup и описать программный код события OnClick: Необходимо заметить, что в программном коде описывается поиск наибольшего значения среди кодов студентов, и найденное число увеличивается на 1. Таким образом, автоматически определяется код для нового студента, что очень важно, так как это поле Nomer не допускает повторяющихся значений. По нему существует первичный ключ (индекс). Листинг Ввод неповторяющихся значений в ключевое поле // если выбран первый переключатель if (RadioGroup1->ItemIndex==0) < // задать источник данных для компонента DBGrid из первой // таблицы СТУДЕНТ DBGrid1->DataSource=DataSource1; // инициализация максимума среди значений поля Nomer int max=0; // активизация и видимость первой страницы (индекс 0) PageControl1->ActivePageIndex=0; PageControl1->Visible=true; // установка табличного курсора на первую запись Table1->First(); // пока не конец файла таблицы while (!Table1->Eof) < // если max FieldByName( Nomer )->AsInteger) // то max=считанному значению текущей записи поля Nomer max = Table1->FieldByName( Nomer )->AsInteger; 127

129 > // переход на следующую запись Table1->Next(); > // получение нового значения, равное +1 Edit1->Text=max+1; // переход на первую запись Table1->First(); // передача фокуса текстовому полю фамилии Edit2->SetFocus(); 8. Активизировать компонент ComboBox, содержащий дни, и войти в программный код события OnChange. 9. Ввести следующий код: Листинг Обработка комбинированного списка vo >text; // считывание значения месяца str02=combobox4->text; // считывание значения года str03=combobox5->text; // конкатенация всех трех переменных str=str01+. +str02+. +str03; // присвоение текстовому полю результирующего значения Edit5->Text=str; > 10. Активизировать компонент ComboBox, содержащий месяцы, и в программном коде события OnChange, ввести следующую команду: ComboBox3Change(Sender); 11. Аналогичным образом ввести эту команду и для события OnChange компонента ComboBox, описывающего года. 12. Сохранить проект и проверить работу комбинированных списков. 13. Активизировать кнопку добавления и ввести программный код: 128

130 Листинг Добавление данных в таблицы // добавить новую запись в таблицу СТУДЕНТ, при этом на ней // устанавливает табличный курсор (особенности работы // с базами данных) Table1->Insert(); // добавить в текущую данные из различных полей, преобразовав //в целое число значение для поля Nomer, в дату значение для поля // Data_rog Table1->FieldByName( Nomer )->AsInteger=StrToInt(Edit1->Text); Table1->FieldByName( Fam )->AsString = Edit2->Text; Table1->FieldByName( Nam )->AsString = Edit3->Text; Table1->FieldByName( Otch )->AsString = Edit4->Text; Table1->FieldByName( Data_rog )->AsDateTime = StrToDate(Edit5->Text); Table1->FieldByName( Adres )->AsString = Edit6->Text; Table1->FieldByName( Phone )->AsString = MaskEdit1->Text; Table1->FieldByName( Gruppa )->AsString = ComboBox1->Text; Table1->FieldByName( Spez )->AsString = ComboBox2->Text; // сохранить все изменения в таблице Table1->Post(); 14. Сохранить проект и проверить работу первого переключателя. II. Разработка третьей функции добавление новой дисциплины. Особенность обработки: при открытии страницы (выбор переключателя) должны быть установлены какие-либо параметры для работы данной вкладки. Так, например, код новой специальности должен формироваться автоматически, увеличиваясь на 1 (при открытии страницы); а фамилии преподавателей должны быть загружены в комбинированный список из таблицы ПРЕПОДАВАТЕЛЬ; при открытии третьей страницы видимыми являются только данные для первого семестра обучения; если пользователь выбирает второй переключатель, то видимой становится и вторая область ввода; также дело обстоит и с третьей областью ввода; после выбора преподавателя необходимо обратиться к таблице ПРЕПОДАВАТЕЛЬ и считать код преподавателя (для ввода кода в таблицу ПРЕДМЕТ; код преподавателя внешний ключ); после выбора семестра в первом комбинированном списке автоматически должны появляться последующие номера семестров во втором и третьем семестрах; 129

131 кнопка «Добавить в базу данных» должна добавлять запись в таблицу ПРЕДМЕТ и автоматически обновлять компонент DBGrid. Рис Страница добавления новых дисциплин Ход работы: 1. Активизировать третью страницу «щелчком» мыши. При этом проверить, чтобы в «Инспекторе объектов» указана именно первая страница, например, TabSheet3. 2. Установить на странице, согласно интерфейсу, необходимые компоненты: Label, Edit (код дисциплины и ее ввод, отображение кода преподавателя), RadioGroup (количество семестров), ComboBox (номера семестров и список фамилий преподавателей), Button и CheckBox (флажки для зачетов и экзаменов). 3. Установить для некоторых компонентов необходимые свойства: для комбинированных списков семестров числа 1 9, для переключателей активным первый элемент (индекс 0), заголовки меток. 4. Активизировать группу переключателей в верхней части формы (варианты добавления) и вновь войти в программный код события OnClick. 5. Добавить в программный код обработку третьего переключателя: 130

132 Листинг Обработка переключателей // если активизирован третий переключатель if (RadioGroup1->ItemIndex==2) < // задать источник данных для компонента DBGrid из третьей таблицы ПРЕДМЕТ DBGrid1->DataSource=DataSource3; // инициализация максимума среди значений поля Kod_predm int maxx=0; // активизация и видимость третьей страницы (индекс 2) PageControl1->ActivePageIndex=2; PageControl1->Visible=true; // установка табличного курсора на первую запись Table3->First(); // пока не конец файла таблицы while (!Table3->Eof) < // если maxx AsInteger) // то maxx=считанному значению текущей записи поля // Kod_predm maxx=table3->fieldbyname( Kod_predm )->AsInteger; // переход на следующую запись таблицы Table3->Next(); > // получение нового значения, равного +1 Edit9->Text=IntToStr(maxx+1); // переход на первую запись таблицы Table3->First(); // передача фокуса текстовому полю ввода дисциплины Edit8->SetFocus(); // данный фрагмент программы заполняет данными список // преподавателей // переход на первую запись таблицы Table4->First(); // пока не конец файла таблицы while (!Table4->Eof) < // добавление в список значения из поля фамилии Table1Famil ComboBox9->Items->Add(Table4Famil->AsString); 131

133 > // переход на следующую запись Table4->Next(); > // установка первого элемента ComboBox9->ItemIndex=0; // переход на первую запись Table4->First(); 6. Активизировать комбинированный список преподавателей и перейти в программный код события OnChange: Листинг Поиск данных 132 // объявление переменной целого типа int nm; // поиск указанной в комбинированном списке фамилии среди // значений поля Famil, а затем считывание значения поля Kod_predm nm = Table4->Lookup( Famil,ComboBox9->Text, Kod_prep ); // передача найденного кода после преобразования текстовому полю Edit10->Text = IntToStr(nm); 7. Установить для компонентов, характеризующих второй и третий семестры, свойство Visible в состояние false. 8. Активизировать компонент RadioGroup и в программном коде события OnClick ввести следующий код: // если активизирован первый переключатель (1 семестр), то первую // область (1 семестр) сделать видимой, а остальные невидимыми if (RadioGroup2->ItemIndex==0) < Label15->Visible=true; ComboBox6->Visible=true; CheckBox1->Visible=true; CheckBox2->Visible=true; Label16->Visible=false; ComboBox7->Visible=false; CheckBox3->Visible=false; CheckBox4->Visible=false; Label17->Visible=false; ComboBox8->Visible=false; CheckBox5->Visible=false; CheckBox6->Visible=false; >

134 // аналогичным образом обработать второй и третий переключатели Активизировать комбинированный список 1-го семестра и в программном коде события OnChange ввести следующий код: // объявление переменной целого типа int p; // считывание номера для первого семестра p=strtoint(combobox6->text); // установка последующих семестров ComboBox7->Text=IntToStr(p+1); ComboBox8->Text=IntToStr(p+2); Этот программный код необходим для того, чтобы после установки первого семестра автоматически установить последующие семестры, например, если первый 5 семестр, то последующие 6 и Активизировать кнопку и в программном коде события OnClick ввести следующий код: Листинг Обработка кнопок // если список первого семестра видим if (ComboBox6->Visible==true) < Table3->Insert(); Table3->FieldByName( Kod_predm )->AsInteger= StrToInt(Edit9->Text); Table3->FieldByName( Predmet )->AsString = Edit8->Text; Table3->FieldByName( Semestr )->AsInteger = StrToInt(ComboBox6->Text); Table3->FieldByName( Kod_pp )->AsInteger = StrToInt(Edit10->Text); if (CheckBox1->Checked==true) Table3->FieldByName( Zachet )->AsString = з ; if (CheckBox2->Checked==true) Table3->FieldByName( Ekzamen )->AsString = э ; Table3->Post(); > // если список второго семестра видим if (ComboBox7->Visible==true) < Edit9->Text=IntToStr(StrToInt(Edit9->Text)+1); Table3->Insert(); 133

135 134 Table3->FieldByName( Kod_predm )->AsInteger= StrToInt(Edit9->Text); Table3->FieldByName( Predmet )->AsString = Edit8->Text; Table3->FieldByName( Semestr )->AsInteger = StrToInt(ComboBox7->Text); Table3->FieldByName( Kod_pp )->AsInteger = StrToInt(Edit10->Text); if (CheckBox3->Checked==true) Table3->FieldByName( Zachet )->AsString = з ; if (CheckBox4->Checked==true) Table3->FieldByName( Ekzamen )->AsString = э ; Table3->Post(); > // если список третьего семестра видим if (ComboBox8->Visible==true) < Edit9->Text=IntToStr(StrToInt(Edit9->Text)+1); Table3->Insert(); Table3->FieldByName( Kod_predm )->AsInteger= StrToInt(Edit9->Text); Table3->FieldByName( Predmet )->AsString = Edit8->Text; Table3->FieldByName( Semestr )->AsInteger = StrToInt(ComboBox8->Text); Table3->FieldByName( Kod_pp )->AsInteger = StrToInt(Edit10->Text); if (CheckBox5->Checked==true) Table3->FieldByName( Zachet )->AsString = з ; if (CheckBox6->Checked==true) Table3->FieldByName( Ekzamen )->AsString = э ; Table3->Post(); > Необходимо заметить, что сложность в последнем программном коде заключалась в том, что даже в невидимом состоянии комбинированные списки семестров продолжали иметь значения. Поэтому в качестве критерия (условия) проверка на отсутствие значений была бы неправильной. В связи с этим есть смысл в качестве критерия использовать видимость и невидимость компонентов. Из программного кода видно, что он представлен тремя блоками, работающими на три переключателя. Добавление новой записи и ввод данных в конкретные поля не представляет проблем. Особенность заключается в том, что должен автоматически изменяться (увеличиваться)

136 код дисциплины, поэтому в начале каждого блока система обновляет код предмета в поле Edit Удаление данных Удаление данных также является одной из основных функций приложения. Удаление также предполагает несколько вариантов: удаление преподавателя (из таблицы ПРЕПОДАВАТЕЛЬ с изменением (а не удалением) кода преподавателя в таблице ПРЕДМЕТ); удаление студента в случае отчисления (из таблицы СТУДЕНТ с одновременным удалением оценок из таблицы ОЦЕНКА); удаление предметов (из таблицы ПРЕДМЕТ); перемещение из текущей базы группы студентов в таблицу-архив. Рассмотрим пример удаления студента (см. прил. 3) с преждевременным поиском его в базе данных. Необходимо заметить, что данные удаляются из обеих взаимосвязанных таблиц СТУДЕНТ и ОЦЕНКА (рис ). Особенности обработки: при активизации страницы «Удаление студента» комбинированный список «Выберите группу» должен быть заполнен элементами фиксированного списка; после выбора группы должен заполниться комбинированный список студентов из выбранной группы; после выбора конкретного студента информация о нем должна появляться в нижней части страницы; после нажатия кнопки текущая запись удаляется из таблицы СТУДЕНТ и связанной таблицы ОЦЕНКА. Рис Форма удаления данных 135

137 Ход работы: 1. Установить на форме компонент PageControl и через контекстное меню добавить новые страницы TabSheet. 2. Задать заголовки всем страницам. 3. Активизировать вторую страницу и установить на странице четыре набора компонентов для обработки таблиц (Table, DataSource). 4. Настроить каждый набор на соответствующую таблицу (пока без установки связей между ними). 5. Установить на странице необходимые компоненты: Label, DBEdit и DBImage («перетащить» из Редактора Полей таблицы СТУ- ДЕНТ), DBGrid (настроить на вторую таблицу ОЦЕНКА), Button. 6. Активизировать форму и войти в программный код создания формы OnCreate. 7. Ввести команды активизации таблиц: Table1->Activate = true; Table2->Activate = true; Table3->Activate = true; Table4->Activate = true; 8. Для события OnDestroy формы описать обратные действия дезактивировать таблицы. 9. Активизировать компонент Table2 (таблицу ОЦЕНКА). 10. Установить следующие свойства: // в качестве родительского источника таблица СТУДЕНТ MasterSource = DataSource1 // в качестве индекса родительской таблицы СТУДЕНТ поле Nomer MasterFields = Nomer // в качестве индекса дочерней таблицы ОЦЕНКА для связи // с таблицей СТУДЕНТ IndexName = NmrO 11. Сохранить проект и проверить работу компонентов DBGrid и DBEdit. 12. Вернуться в рабочий режим проекта. 13. Активизировать комбинированный список групп и установить свойство Items как список групп. 14. Войти в программный код события OnChange и ввести команды по выбору формированию списка студентов выбранной группы: // объявление переменной s String s; // очищение списка студентов ComboBox2->Clear(); // переход на первую запись иаблицы 136

138 Table1->First(); // пока не конец файла таблицы while (!Table1->Eof) < // если значение поля Gruppa текущей записи равно // выбранному элементу списка if (Table1->FieldByName( Gruppa )->AsString==ComboBox1->Text) < // присвоение переменной значения из поля Fam текущей //записи s= Table1->FieldByName( Fam )->AsString; // добавление в список студентов найденного значени // (студента) ComboBox2->Items->Add(s); > Table1->Next(); > Table1->First(); 15. Активизировать список студентов и в программном коде события OnChange ввести следующие команды: // задать в качестве индекса родительской таблицы поле Nomer // (для связи) Table2->MasterFields= Nomer ; // задать в качестве индекса дочерней таблицы поле Nomer (для связи) Table2->IndexFieldNames= Nomer ; // подключить индекс по полю Fam для дальнейшего поиска данных // по фамилии Table1->IndexFieldNames= Fam ; // нахождение по фамилии нужного значения (остановка //на конкретной записи) Table1->FindNearest(&TVarRec(ComboBox2->Text),0); // передача фокуса компоненту DBGrid с одновременным обновлением DBGrid1->SetFocus(); 16. Сохранить проект и проверить работу комбинированных списков. 17. Вернуться в рабочий режим. 18. Активизировать кнопку и войти в программный код данного компонента. 19. Ввести следующие команды: // удаление текущей записи (на чем стоит табличный курсор) // с одновременным переходом на следующую запись 137

139 Table1->Delete(); // при необходимости дезактивировать таблицы Table1->Active=false; Table2->Active=false; Предложенная последовательность действия позволяет корректно и правильно осуществить операцию удаления Программирование базы данных Помимо рассмотренных ранее методов модификации записей Table имеется ряд методов, позволяющих модифицировать таблицы и индексы. 1. Метод CreateTable. Метод создает новую таблицу, исходя из установок компонента Table, содержащихся в свойствах Fields или FieldDefs. Если таблица с именем, указанным в свойстве TableName уже имеется, она будет переписана. Применение этого метода позволяет, например, взять структуру существующей таблицы, как-то изменить ее, затем изменить свойство TableName, на имя новой таблицы и создать эту таблицу. 2. Метод DeleteTable. Метод уничтожает существующую таблицу, которая задана свойствами DatbaseName и TableName. Таблицу надо предварительно закрыть. 3. Метод RenameTable(s) Метод переименовывает существующую таблицу, присваивая ей новое имя, содержащееся в s. Одновременно переименовываются все сопутствующие таблице файлы. 4. Метод DeleteIndex(s) Удаляет вторичный индекс с именем s из таблицы. Следующий фрагмент программного кода позволяет создать таблицу с учетом того, что на форме существуют необходимые компоненты, которые пока еще не настроены ни на какую таблицу. Листинг Добавление данных (второй способ) // дезактивация таблицы Table1->Activate = false; // задание имени новой таблицы Table1->TableName = student.db ; // если такой таблицы в текущем каталоге не существует, значит, ее можно создать if (!Table->Exists) < // установить тип таблицы через константу системы

140 > Table1->TableType = ttparadox; // очистить список полей Table1->FieldDefs->Clear(); // создать указатель на объект описания поля // добавить в таблицу новое поле, определив его название, // тип и запрет на нулевые значения в этом поле TFieldDef *pnewdef = Table1->FieldDefs->AddFieldDef(); bnewdef->name = Nomer ; bnewdef->datatype = ftinteger; bnewdef->required = true; // добавить в таблицу следующее поле pnewdef = Table1->FieldDefs->AddFieldDef(); bnewdef->name = Fam ; bnewdef->datatype = ftstring; bnewdef->size = 20; bnewdef->required = true; // добавить в таблицу следующее поле pnewdef = Table1->FieldDefs->AddFieldDef(); bnewdef->name = Data_rog ; bnewdef->datatype = ftdate; // добавить в таблицу следующее поле pnewdef = Table1->FieldDefs->AddFieldDef(); bnewdef->name = Family ; bnewdef->datatype = ftboolean; // очистить указатель Table1->IndexDefs->Clear(); // добавить для первого поля первичный индекс Table1->IndexDefs->Add(, Nomer, TIndexOptions() CreateTable(); // открыть таблицу для работы Table1->Open(); // вставить новую запись и заполнить ее записью Table1->Insert(); Table1->FieldByName( Nomer )->AsInteger = 100; Table1->FieldByName( Fam )->AsString = Иванов ; Table1->FieldByName( Data_rog )->AsDate = 02/09/1986 ; Table1->FieldByName( Family )->AsBoolean = false; // сохранить введенные изменения Table1->Post(); 139

141 Для работы с полями типа Memo необходимо воспользоваться методом Modified (например, Form1->Memo1->Modified = false;), чтобы разрешить пользователю изменять содержимое примечания. Обработка поля типа DBImage также происходит через использование булевого компонента. Необходимо, чтобы компонент DBImage = false. Вопросы для самоконтроля 1. Какие операторы используются для перехода с одной записи на другую? Какое отношение к переходу имеет проверка начала или конца файла? 2. Какие способы поиска в таблице существуют? Перечислите их и охарактеризуйте. 3. В чем особенность поиска данных метода Lookup? 4. Каким образом настраивается комбинированный список и компонент Grid для просмотра данных? Необходимо заметить, что выборка должна осуществляться после выбора элемента в ниспадающем списке. 5. Какое событие описывается выбором элемента в комбинированном списке? 6. Что такое фильтрация данных? 7. Каким образом осуществляется фильтрация данных программным путем? 8. Какое отношение фильтрация имеет к поиску данных? 9. Как осуществляется добавление данных программным путем? 10. Какое основное условие необходимо соблюдать при вводе данных в ключевые поля? 11. Как осуществляется удаление данных программным путем? 12. Каким образом возможна работа с несколькими таблицами одновременно? Каково условие их совместного существования? 140

142 12. РАЗРАБОТКА ЗАПРОСОВ К БАЗЕ ДАННЫХ Введение в язык SQL Язык SQL (Structured Query Language язык структурированных запросов) был создан в конце 70-х годов и получил через некоторое время широкое распространение. Он позволяет формировать весьма сложные запросы к базам данных. Запрос это вопрос к базе данных, возвращающий запись или множество записей, удовлетворяющих вопросу. К сожалению, SQL в настоящее время недостаточно стандартизован. Существует стандарт SQL ANSI, но существует и множество диалектов, с которыми работают различные системы. Например, Sybase SQL Server и Microsoft SQL используют синтаксис, существенно отличающийся от стандарта ANSI. InterBase, Oracle и многие другие серверы в основном придерживаются стандарта ANSI, но каждый разработчик вносит в него и свои усовершенствования. Дальнейшее изложение будет основываться на диалекте, принятом в локальном сервере БД InterBase. C++Builder позволяет приложению при помощи запросов SQL использовать данные: таблиц Paradox и dbase используется синтаксис локального SQL; локального сервера InterBase полностью поддерживается соответствующий синтаксис; удаленных серверов SQL через драйверы SQL Links. Общие правила синтаксиса SQL очень просты. Язык SQL не чувствителен к регистру. Если используется программа из нескольких операторов SQL, то в конце каждого оператора ставится точка с запятой «;». Впрочем, если вы используете всего один оператор, то точка с запятой в конце необязательна. Комментарий может писаться и в стиле С: /* */, а в некоторых системах и в стиле Pascal: < >Оператор выбора SELECT Оператор SELECT необходим для выборки данных из одной или нескольких таблиц. Рассмотрим формат данной команды: 1 SELECT список_имен_полей 2 FROM список_имен_таблиц 3 WHERE связь_между_таблицами условие_отбора 4 ORDER BY список_имен_полей 5 GROUP BY список_имен_полей; 141

143 Представленный формат команды SELECT для одной таблицы можно перевести так: 1 ВЫБРАТЬ поле1, поле2, поле3, 2 ИЗ таблицы1 3 ПРИ УСЛОВИИ, ЧТО поле1=значение1 [ AND OR поле2=значение2 ] 4 [ ОТСОРТИРОВАВ ПО полю3 [ASC DESC] ] 5 [ СГРУППИРОВАВ ПО полю2 ] Необходимо заметить, что фрагменты 3, 4 и 5, оформленные в квадратных скобках, не являются обязательными. Если в запросе не задается условие и при выводе не указывается какое-либо выражение, то система выводит все записи. В случае, если необходимо использовать для вывода данных все поля таблицы, то достаточно использовать символ *. В опции WHERE используются следующие операции отношения: = Равно > Больше >= Больше или равно 144 фигурировать или поля (в том числе и вычисляемые), или совокупные характеристики, но не могут фигурировать и те, и другие (без указания на группирование данных). Другими словами, оператор SELECT может возвращать или множество значений, или суммарные характеристики, но не может возвращать их совокупность, так как это несовместимо. Смешение в одном операторе полей и совокупных характеристик возможно, если использовать группировку записей, задаваемую ключевыми словами GROUP BY. При группировании записей с помощью GROUP BY можно вводить условия отбора записей с помощью ключевого слова HAVING. Необходимо заметить, что не все базы данных поддерживают ключевое слово HAVING. Если с БД InterBase проблем с данной опцией нет, то БД Paradox не работает с этим словом. Иногда возникают ситуации, когда использование запроса стандартного вида не дает нужных результатов. Для этого нужно воспользоваться так называемыми вложенными запросами. Это значит, что в качестве источника данных (условий) используется результат запроса. Формат вложенного запроса может выглядеть так: подзапрос как конкретное значение: SELECT FROM WHERE поле знак_отношения (SELECT ) подзапрос как список конкретных значений: SELECT FROM WHERE поле IN (SELECT ) При работе в условии WHERE с множеством записей можно использовать ключевые слова: ANY и ALL. ALL означает, что условие выполняется для всех записей, а ANY хотя бы для одной записи. До сих пор речь шла о запросах из одной таблицы. Рассмотрим формат запроса для вывода информации из двух и более взаимосвязанных таблиц: 1 ВЫБРАТЬ поле1, поле2, поле3, 2 ИЗ таблицы1, таблицы2, 3 ПРИ УСЛОВИИ ЧТО ( таблица1.поле1=таблица2.поле2 [, ] ) AND ( таблица1.поле1=значение1 [ AND\OR таблица2. поле2=значение2 ] ) 4 [ ОТСОРТИРОВАВ ПО полю3 [ASC DESC] ] 5 [ СГРУППИРОВАВ ПО полю2 ] Необходимо заметить, что при связи таблиц опция WHERE начинает выполнять и вторую функцию (помимо условия) установка связи между таблицами по конкретным полям. Поля, как известно, должны 143

145 быть одного и того же типа, длины, а также иметь одинаковые идентификаторы для простоты работы. Для работы с таблицами иногда используют так называемые псевдонимы, которые пользователь сам назначает. Однако эти псевдонимы обязательно необходимо указать вместе с таблицами. Это удобно использовать в случае, если названия таблиц слишком длинные, а также, если возникают запросы, которые без псевдонима не решишь (см. далее пример 21). Рассмотрим несколько примеров запросов. 1. Выбрать из таблицы СТУДЕНТ всех студентов по всем полям. SELECT * FROM student 2. Выбрать из таблицы СТУДЕНТ всех студентов; при этом вывести информацию о фамилии, имени и группе. SELECT fam, nam, gruppa FROM student 3. Вывести всех преподавателей кафедры Информатики и ВТ; достаточно вывести фамилию, имя, отчество и кафедру. SELECT famil, kafedra FROM prepodav WHERE kafedra= Информатика и ВТ Для вывода новых данных, например, как в случае создания нового поля, необходимо использовать опцию AS. 4. Вывести фамилии студентов с указанием возраста. Предположим, что в таблице существует поле Year. В запросе создается новое поле Vozr, которое вычисляется через текущий год и год рождения студента. SELECT fam, (2005-Year) AS Vozr FROM prepodav 5. Вывести всех студентов, фамилии которых начинаются с «М». Символ «%» означает любое количество любых символов. SELECT fam FROM prepodav WHERE fam LIKE М% Если в качестве критерия задать fam LIKE %ван%, то результатом запроса будут и фамилии, которые включают символы «ван» в состав фамилии. Примером будут «Иванов», «Иванников», «Иванова» и «Ванюшкина». 6. Вывести всех преподавателей, родившихся в период с 1 января 1965 года по 31 декабря 1989 года. 144

146 SELECT famil, kafedra FROM prepodav WHERE Dat_rog BETWEEN AND Вывести всех студентов, родившихся в 1985 и 1987 годах. Предположительно, что в таблице существует поле Year. SELECT famil, kafedra FROM prepodav WHERE Year IN (1985, 1987) 8. Вывести списки студентов по группам. Предполагается, что список каждой группы будет представлен в алфавитном порядке фамилий. SELECT fam, nam, otch, gruppa FROM student ORDER BY gruppa, fam Необходимо заметить, что сортировка сначала происходит по группе, а затем по фамилии. Если нарушить последовательность, то список будет представлен алфавитным порядком фамилий; и в каждой группе одинаковых фамилий отсортируется группа. Последний вариант не подходит для описанного задания. 9. Вывести списки студентов в обратном алфавитном порядке. SELECT fam, nam, otch FROM student ORDER BY fam DECS Опция сортировки имеет подопцию, которая характеризует направление сортировки: ASC (Ascending возрастание), DESC (Descending убывание). В представленном примере результирующий запрос будет содержать фамилии в обратном алфавитном порядке. 10. Вывести на экран общее количество записей таблицы СТУДЕНТ. SELECT count(*) FROM student 11. Вывести на экран количество записей, удовлетворяющих условию: коды студентов от 100 до 130. SELECT count(*) FROM student WHERE Nomer BETWEEN 100 AND Вывести на экран дату рождения самого младшего и самого старшего студентов группы ПИ

147 SELECT min(data_rog), max(data_rog) FROM student WHERE gruppa= ПИ Вывести на экран информацию о количестве студентов в каждой группе. SELECT gruppa, count(*) FROM student GROUP BY gruppa 14. Вывести на экран информацию о количестве студентов в каждой группе, кроме групп ПИ-101 и ПИ-102. SELECT gruppa, count(*) FROM student GROUP BY gruppa HAVING gruppa<> ПИ-101 OR gruppa!= ПИ Вывести на экран фамилию и дату рождения самого старшего в группе ПИ-201. SELECT fam, data_rog FROM student WHERE Data_rog = ( SELECT max(data_rog) FROM student WHERE gruppa= ПИ-201 ) Вложенный запрос возвращает лишь одно значение максимальную дату среди всех дат поля Data_rog в записях, где gruppa= ПИ-201. Поэтому для главного запроса вложенный запрос становится лишь конкретным значением. 16. Допустим, что существует таблица НАГРАДА, в которой находятся фамилии студентов, награжденных за различные достижения. В отдел кадров необходимо предоставить по данным студентам всю информацию из таблицы СТУДЕНТ. SELECT fam, nam, otch, gruppa, FROM student WHERE Fam IN (SELECT fam FROM nagrada) 17. Вывести студентов из таблицы СТУДЕНТ, которые не старше любого студента в таблице СТУДЕНТ01. SELECT * FROM student WHERE Data_rog >= ALL (SELECT Data_rog01 FROM student01) 146

148 18. Вывести преподавателей таблицы ПРЕПОДАВАТЕЛЬ, которые моложе хотя бы одного сотрудника в таблице ПРЕПОДАВАТЕЛЬ01. SELECT * FROM student WHERE Data_rog > ANY (SELECT Data_rog01 FROM prepodav01) 19. Вывести информацию о сессиях (экзаменационных оценках) студентов группы ПИ-303. SELECT fam, nam, gruppa, ozenka, data_ekz FROM student, ozenka WHERE (student.nomer=ozenka.nomer) AND (gruppa= ПИ-303 ) В некоторых системах описание полей сопровождается именем таблицы как при указании связи между объектами. Если в двух таблицах есть одинаковые поля (по имени), то обязательно необходимо указывать таблицу, в которой это поле находится. 20. Вывести данные из двух таблиц (с использованием псевдонимов) по семейным студентам. SELECT S.*, O.* FROM student S, ozenka O WHERE (S.nomer=O.nomer) AND (S.family=true) 21. Вывести студентов, обучающихся в одной группе. SELECT p1.fam, p1.gruppa, p2.fam, p2.gruppa FROM student p1, student p2 WHERE (p1.gruppa=p2.gruppa) AND (p1.fam!=p2.fam) AND (p1.fam

149 Как видно, в запросе используется одна таблица, которая рассматривается под двумя псевдонимами. Это необходимо для того, чтобы выполнить задание. При этом ставятся следующие условия: первое для проверки равенства группы; второе для того, что студент при поиске не стал сам себе одногруппником; третье для удаления дублирования данных, так как система будет выдавать по две записи на каждую пару одногруппников Операции с записями Для работы с записями таблицы используются три оператора: INSERT вставка записи в таблицу; UPDATE модификация записи таблицы; DELETE удаление текущей записи таблицы. Формат оператора вставки записи: INSERT INTO таблица [(поле1, поле2, поле3, )] VALUES (значение1, значение2, значение3, ) Если запись добавляется в таблицу не по всем полям, то необходимо указывать список полей, а в опции VALUES значения полей указывать в том же порядке. Если запись добавляется полностью (по всем полям), то перечисление полей после названия таблицы необязательно. Пример. Добавить в таблицу СТУДЕНТ запись по некоторым полям. INSERT INTO student (nomer, fam, nam, gruppa, data_rog, family) VALUES (200, Петрова, Мария, ПИ-101, , false) Необходимо иметь в виду, что поля, в которые пользователь не вводит сразу значений, должны иметь разрешение на наличие в них «пустых» значений. Если необходимо ввести несколько записей, то можно воспользоваться подзапросом, например, INSERT INTO student (SELECT * FROM nagrada) Необходимо заметить, что при добавлении из одной таблицы в другую полных записей (или из запроса), нужно строго следить за тем, чтобы обе таблицы имели одинаковую структуру. Формат оператора изменения записи: UPDATE таблица SET поле1=значение1, поле2=значение2 [, ] WHERE условие

150 Пример 1. Изменить у всех студентов сумму стипендий согласно индексации 15%. Предполагается, что в таблице СТУДЕНТ существует поле стипендии stipend. UPDATE student SET stipend=stipend*1.15 Пример 2. Изменить студентке Петровой из группы ПИ-301 фамилию на Морозову в связи с документом о заключении брака. UPDATE student SET fam= Морозова WHERE fam= Петрова AND gruppa= ПИ-301 Формат оператора удаления записи: DELETE FROM таблица [ WHERE условие ] Если необходимо удалить все записи, то условие в операторе не задается. Пример 1. Удалить все записи в таблице СТУДЕНТ. DELETE FROM student Пример 2.Удалить в таблице СТУДЕНТ всех выпускников (возможно, что критерий не совсем корректен). DELETE FROM student WHERE gruppa= ПИ-501 OR gruppa= ПИ-502 OR gruppa= Пи Операции с таблицами и индексами Для работы с таблицами используют следующие операторы: CREATE TABLE создание таблицы; DROP TABLE удаление таблицы; ALTER TABLE изменение таблицы. Формат оператора создания таблицы: CREATE TABLE имя_таблицы ( имя_поля1 тип_поля [(размер)], имя_поля2 тип_поля [(размер)] [, ] ) 149

151 Размер указывается только для полей строковых и некоторых других типов. После объявления некоторых полей могут включаться слова PRIMARY KEY, что указывает на то, что данное поле входит в первичный ключ. Кроме того, после объявления некоторых полей можно вставлять слова NOT NULL, означающие, что значение этого поля обязательно должно быть задано в каждой записи. Пример. Создать таблицу СТУДЕНТ с полями, в которых не разрешаются «пустые» значения. CREATE TABLE student ( nomer INTEGER NOT NULL PRIMARY KEY, fam char(20) NOT NULL, nam char(15) NOT NULL, data_rog date NOT NULL, gruppa NOT NULL ) Формат оператора изменения таблицы: ALTER TABLE имя_таблицы [DROP поле1, поле2, ] [ADD поле1 тип_поля [(размер)], ] Опция ADD используется для добавления поля, а опция DROP для удаления поля. Пример. Добавить в структуру таблицы СТУДЕНТ новое поле «Домашний адрес» и удалить поле «Группа». ALTER TABLE student DROP gruppa, ADD Adres char(40) Формат оператора удаления таблицы: DROP TABLE имя_таблицы Пример. Удалить таблицу СТУДЕНТ. DROP TABLE student Обычно создание структуры таблицы сопровождается созданием и индексов таблицы. Формат оператора создания индекса: CREATE INDEX имя_индекса ON имя_таблицы поле1, поле2, поле3, 150

152 Пример 1. Создать индекс nmrs по полю Nomer таблицы СТУДЕНТ. CREATE INDEX nmrs ON student Nomer Пример 2. Создать индекс grupfam по полям группа + фамилия. CREATE INDEX grupfam ON student gruppa, fam Для удаления индекса используется команда DROP INDEX: DROP INDEX student.grupfam Если таблица многократно изменяется и в нее вносится много новых записей, индексы могут оказаться разбалансированы и их эффективность при выполнении запросов уменьшается. В этом случае полезно проводить повторное создание и балансировку индекса последовательным применением операторов деактивации и активации: ALTER INDEX nmrs DEACTIVATE ALTER INDEX nmrs ACTIVATE Компонент Query Для выполнения запроса в приложениях используется компонент Query со страницы BDE. Однако необходимо заметить, что в серверных приложениях целесообразнее использовать компонент Query, а при работе с локальными базами данных компонент Table. Рассмотрим использование компонента Query в приложении просмотра данных. Для этого необходимо выполнить следующие действия: 1. Установить на форме компоненты Query1, DataSource1 и DBGrid1. 2. Активизировать компонент Query1 и установить свойство DatabaseName, значение которого равно псевдониму таблицы aliasdb. 3. Активизировать компонент DatabaseName1 и установить свойство DataSet, равное Query1. 4. Активизировать компонент DBGrid1 и установить значение DataSource1 в свойстве DataSource. 5. Активизировать компонент Query1 и войти в редактор списка запроса свойства SQL. 6. В открывшемся окне String List Editor ввести SQL-команду: SELECT p1.fam, p1.gruppa, p2.fam, p2.gruppa FROM student p1, student p2 151

153 152 WHERE (p1.gruppa=p2.gruppa) AND (p1.fam!=p2.fam) AND (p1.fam

Active=false; Query3->Active=false; // установить в качестве источника данных результаты запроса 1 DataSource1->DataSet=Query1; // активировать запрос 1 Query1->Active=true; // передать управление компоненту-просмотрщику таблиц для // активизации последнего DBGrid1->SetFocus();

154 Рис Рабочий режим приложения 6. Аналогичным образом оформить программные коды для двух оставшихся кнопок, учитывая то, что в определенный момент активным должен быть только один компонент Query. 7. Сохранить проект и проверить его работу (рис. 12.3). Рис Результат запроса 153

155 12.6. Динамические запросы Все запросы SQL, которые до сих пор рассматривались это так называемые статические запросы. В них фиксировано все: имена таблиц, поля, константы в выражениях и т. п. Но помимо таких статических запросов SQL допускает и динамические запросы, использующие параметры. Причем параметры можно применять вместо имен таблиц, имен полей и их значений. Значения этих параметров передаются извне и тем самым, не изменяя текст самого запроса, можно менять возвращаемый им результат. Параметры задаются в запросе с двоеточием, предшествующим имени параметра: : имя_параметра Например, если в запросе SELECT элемент WHERE записан в виде: WHERE Data_rog

156 3. Установить при необходимости следующие свойства: DataType (тип данных), Name (идентификатор), ParamType (тип параметра используется при обращении к процедурам, хранимым на сервере), Precision (количество знаков после запятой), Size (размер), Value (значение параметра по умолчанию), Type (тип значения Value по умолчанию), используя рис. 12.5а. а) б) Рис Свойства параметров sgrup и bsem Необходимо заметить, что для типа данных используется константа, о которой было упоминание в предыдущей работе, когда создавалась таблица. Поэтому в этом свойстве (представленном списком) можно более подробно ознакомиться с константами типов данных. 4. Аналогичным способом установить свойства и для параметра bsem (рис. 12.5б). 5. Активизировать компонент Query через свойство Active = true. 6. Сохранить проект и проверить его работу (рис. 12.6). Рис Результат запроса с параметрами 155

157 Программный доступ к параметрам во время выполнения приложения осуществляется аналогично доступу к полям набора данных. Свойство Params является указателем на массив параметров типа TParam, к элементам которого можно обращаться по индексу через его свойство Items[Word Index]. Последовательность, в которой располагаются параметры в массиве, определяется последовательностью их упоминания в запросе SQL. Значения параметров, как и значения полей, определяются такими свойствами объектов-параметров, как Value, AsString, AsInteger и т. п. Например, оператор for (int I=0; I Params->Count; I++) if (Query1->Params->Items[I]->IsNull && Query1->Params->Items[I]->DataType ==ftinteger) Query1->Params->Items[I]->AsInteger = 1; задаст значение «-1» всем целым параметрам, которым до этого не было присвоено значение, В нем использовано свойство Count число параметров, свойство isnull, равное true, если параметру не задано никакое значение, свойство DataType, указывающее тип параметра, и свойство AsInteger, дающее доступ к значению параметра как к целому числу. Другой пример: операторы Query1->Params->Items[0]->AsString = ПИ-201 ; Query1->Params->Items[1]->AsBoolean= true; задают значения первому (индекс 0) и второму (индекс 1) параметрам компонента Query1, в свойстве SQL. которого записан приведенный ранее оператор Select с параметрами:sgrup и:bsem. Поскольку в этом операторе параметр:sgrup упоминается первым, то его индекс равен 0. Кроме свойства Items, у Params есть еще одно свойство ParamValues. Оно представляет собой массив значений параметров типа Variant. В качестве индекса в это свойство передается имя параметра или несколько имен, разделяемых точками с запятой. Например, операторы Query1->Params->ParamValues[ sgrup ] = ПИ-3% ; Query1->Params-> ParamValues[ bsem ]= true; задают те же значения параметрам, что и приведенные выше. Преимуществом является то, что при записи этих операторов не надо помнить индексы параметров. Другим преимуществом свойства ParamValues является возможность задать значения сразу нескольким параметрам. Например: Variant par[] = < ПИ-3%, true>; Query1->Params->ParamValues[ sgrup; bsem ] = VarArrayOf (par,1); Другой способ обращения к параметрам, при котором не надо помнить их индексы использование метода ParamByName компонента Query. Например, операторы 156

158 Query1->ParamByName( sgrup )->AsString = ПИ-3% ; Query1-> ParamByName( bsem )->AsBoolean = true; задают параметрам с именами sgrup и bsem те же значения, что и приведенные ранее операторы. Следует оговориться, что задание нового значения параметру само по себе еще не обеспечивает влияния на возвращаемый из запроса результат. Надо повторно выполнить данный запрос, чтобы ощутить изменения Связывание таблиц Большинство свойств Query аналогичны свойствам Table. Программный доступ к этим полям осуществляется так же, как в Table, с помощью свойства Fields (например, Query1->Fields[0]) или методом FieldByName (например, Query1->FieldByName( Gruppa )). Можно также создавать объекты полей с помощью «Редактора полей», вызываемого двойным щелчком на Query или из меню, всплывающего при щелчке на Query правой кнопкой мыши. В этом случае доступ к объекту поля можно осуществлять также и по его имени (например, Query1Gruppa). Для доступа к значениям полей используются те же их свойства Value, AsString, AsInteger и т. п., что и в Table. Точно так же, как в Table, можно осуществлять навигацию по набору данных, устанавливать фильтры, ограничивать вводимые значения полей, кэшировать изменения. Из свойств, отличных от Table, остановимся на свойстве DataSource. Это свойство позволяет строить приложения, содержащие связанные друг с другом таблицы. Рассмотрим пример использования запроса к двум взаимосвязанным таблицам. Для этого необходимо выполнить следующие действия: 1. Создать новое приложение. 2. Установить на форме два набора компонентов Query, DataSource и DBGr >

159 Рис Вид формы в режиме редактора 6. Аналогичным способом установить свойства второго набора компонентов и задать запрос для второй таблицы: SELECT * FROM ozenka 7. Сохранить проект и проверить работу приложения, убедившись в том, что оба набора компонентов работают самостоятельно, но не в связи друг с другом. 8. Вернуться в рабочий режим проекта. 9. Дезактивировать компоненты Query. 10. Активизировать свойство SQL запроса Query2 и дополнить его связью таблиц: SELECT * FROM ozenka WHERE (Nomer=:Nomer) 11. Изменить для компонента Query2 свойство DataSource=DataSource1 (то есть достаточно изменить источник данных для дочернего запроса). 12. Активировать компоненты Query. 13. Сохранить проект и проверить его работу (рис. 12.7). 158 Рис Результат запроса

160 К основным методам Query можно отнести методы открытия и закрытия соединения с базой данных. Метод Close закрывает соединение с базой данных, а метод Open открывает соединение. Если запрос заранее не задан, а должен быть сформирован в течение работы программы, то можно запрос в виде SQL-предложения задать переменной, например, ssql. Тогда фрагмент программы, открывающий и выполняющий запрос, будет выглядеть следующим образом: // очистить SQL-предложение Query1->SQL->Clear(); // добавить из переменной ssql SQL-предложение Query1->SQL->Add(ssql); // открыть SQL-предложение Query1->Open(); // запустить на выполнение SQL-предложение Query1->ExecSQL(); Вопросы для самоконтроля 1. Каково назначение языка SQL? 2. С какой целью используется оператор SELECT? 3. Каков формат команды SELECT при работе с одной и более таблицами? Пояснить. 4. Что такое функции агрегации? 5. Что такое псевдоним таблицы? Как он задается? 6. Какие операторы используются для работы с записями? Перечислить и охарактеризовать. 7. Какие операторы используются для работы с таблицами? Перечислить и охарактеризовать. 8. Какой из визуальных компонентов работает с запросами на форме? Какие свойства данного компонента необходимо устанавливать для его настройки? 9. Что может служить источником данных для компонента Query? 10. Каким подходом к работе похожи компоненты Query и Table? 11. Что такое динамические запросы? Дать определение. 12. В чем особенность задания динамического запроса? Привести пример. 13. Как задаются значения параметров в запросе? 14. Каким образом происходит связывание таблиц в запросе (при выводе информации)? 15. Привести примеры использования команды SELECT. 159

161 13. СОЗДАНИЕ ОТЧЁТОВ Компонент QuickRep Для создания отчётов в C++Builder включена система QuickReport. Компоненты этой системы размещены на странице QReport палитры компонентов. QuickReport использует генератор отчетов, состоящих из множества полос. Полоса (band) это область отчета или раздел, содержащий некоторый текст, изображения, графики, диаграммы и т. п. Полоса является контейнером для других компонентов, вносящих в отчет информацию или графику. Если полоса и размещенные на ней компоненты связаны с базой данных, то содержание этой полосы печатается столько раз, сколько соответствующих записей имеется в источнике данных. Таким образом, достаточно расположить компоненты, связанные с данными, на полосе, а печатаемые значения и их количество будут автоматически управляться базой данных. Как в компонентах, связанных с данными, вы можете задавать головную и вспомогательную таблицы, так и между полосами можно задавать аналогичные связи. Таким образом, все возможности, реализуемые в приложениях, реализуются с тем же успехом и в отчетах. Основным компонентом, на котором строится весь отчет, является QuickRep. Он предоставляет ряд возможностей по управлению создаваемым отчетом, включая формирование заголовка, полос, шрифтов, установок принтера и др. Этот компонент является визуальным и после его соединения с базой данных может использоваться как контейнер полос, составляющих отчёт. Компонент QuickRep имеет ряд свойств, определяющих характеристики печати отчёта: PrinterSetting задает число копий отчета и диапазон печатаемых страниц; задает размер страницы PaperSize (можно установить заказной Page размер Custom и определить длину и ширину страницы свойствами Length и Width), ее ориентацию и поля; определяет, надо ли печатать верхний колонтитул первой Options страницы (FirstPageHeader) и нижний колонтитул последней (LastPageFooter); задает единицу измерения размеров страницы, полей и т. п.: Units миллиметры, дюймы, пикселы и т. д.; Zoom масштаб печати в процентах; ReportTitle заголовок окна предварительного просмотра.

162 Свойство DataSet определяет набор данных, к которому подключается отчет. Этим набором может являться компонент типа TTable, TQuery и т. п. Компонент QuickRep имеет два основных метода: Preview предварительный просмотр, и Print печать. Предварительный просмотр и даже печать отчета можно осуществлять и в процессе проектирования. Для этого надо щелкнуть правой кнопкой мыши на компоненте QuickRep и из всплывшего меню выбрать команду Preview. Перед вами откроется окно предварительного просмотра, в котором, в частности, имеется кнопка печати. Компоненты QRLabel, QRMemo, QRRichText, QRShape, QRImage, размещаемые на полосах отчета, являются аналогами обычных компонентов Label, Memo, RichEdit, Shape, Image. Основной особенностью соответствующих компонентов QuickReport является их способность печататься в тех полосах отчета, в которых они размещены. Компоненты имеют два свойства, отсутствующих в обычных компонентах: Frame и Size. Свойство Frame имеет ряд подсвойств, определяющих рамку вокруг компонента: Color цвет, Style стиль, Width ширина, DrawBottom, DrawLeft, DrawRight, DrawTop определяют наличие рамки соответственно внизу, слева, справа и вверху компонента. Свойство Size имеет подсвойства, определяющие размер и место размещения компонента при печати. Все определяется в единицах измерения, заданных свойством Units компонента QuickRep. Некоторые компоненты имеют свойство AlignToBand выравнивание в полосе. Если это свойство установить в true, то компонент будет выровнен по краю полосы, заданному свойством Alignment: taleftjustify влево, tacenter по центру, tarightjustify вправо. При установке полос отчета используется свойство Bands, которое в своем составе имеет несколько полос. Чтобы та или иная полоса была доступна в отчете, необходимо установить значение true напротив соответствующей полосы: HasTitle HasDetail HasPageHeader HasPageFooter HasColumnHeader имеется полоса заголовка отчета, которая печатается один раз в начале отчета; имеется полоса детализации, которая печатается столько раз, сколько записей в нее передается; имеется верхний колонтитул (заголовок) на каждой странице отчета; имеется нижний колонтитул на каждой странице отчета; имеется заголовок печатаемой таблицы. 161

163 Компонент QRSysData используется для того, чтобы устанавливать какие-либо системные параметры, например, дату, время номер страницы и т. п. qrsdate qrsdatetime qrsdetailcount qrsdetailno qrspagenumber qrsreporttitle qrstime текущая дата; текущие дата и время; число записей в базе данных; текущий номер записи в базе данных; номер текущей страницы; заголовок отчета; текущее время. Если необходимо установить вычисляемое поле, то используется компонент QRExpr Разработка простых отчётов Рассмотрим разработку нескольких отчетов, начиная с простого и заканчивая более сложными (с использованием нескольких таблиц). Пример 1. Создать отчет список всех студентов. Для реализации данной задачи необходимо выполнить следующие действия: 1. Создать новый проект. 2. Установить на форме со страницы QReport компонент QuickRep. При этом компонент приобретет по умолчанию размеры, характерные для листа формата А4. В случае, если размеры листа (по умолчанию) не устраивают пользователя, то можно произвести «двойной щелчок» на области компонента QuickRep. В результате чего появится окно Report Settings. В данном окне можно установить различные параметры отчета. Список Paper Size позволяет установить различные размеры отчета. 3. Установить на форме компоненты Table и DataSource. 4. Настроить компоненты таблицы и источника на соответствующую таблицу СТУДЕНТ. 5. Активизировать компонент QuickRep и раскрыть свойство Bands. 6. Установить в значение true полосы HasTitle, HasColumnHeader, HasDetail (рис. 13.1). 162

164 Рис Полосы отчета Эти полосы будут добавлены именно в указанном порядке, хотя добавлять их можно в любой последовательности. Данный порядок объясняется просто: заголовок для всего отчета, затем идет «шапка» таблицы в области заголовков столбцов, а завершается простой отчет (без каких-либо итоговых данных) списком данных. Кроме того, необходимо понять следующее (это характерно для всех отчетов в различных системах): область «детализации» (Detail) содержит только названия полей или выражений (с полями), а при просмотре (выводе) эти поля повторяются столько раз, сколько выводится записей. Единожды установив поле, пользователь получает столько значений этого поля, сколько записей соответствует условию вывода. 7. При необходимости изменить размеры областей полос. 8. Установить в полосе заголовка (первой полосе) компонент QRLabel и задать ему заголовок «СПИСОК». 9. Аналогично установить метку «студентов специальности ». 10. Используя свойство Font, установить необходимые параметры. 11. Вызвать контекстное меню отчета и командой Preview просмотреть отчет. Убедиться в том, что заголовок в отчете присутствует. 12. Используя компонент QRShape, во второй полоске нарисовать графы для заголовков полей. 13. Установить во второй полоске (в графах) заголовки полей компонентами QRLabel. 14. В области Detail установить компоненты QRDBText под заголовками. 15. Активизировать первый компонент QRDBText1 и установить для него следующие свойства: DataSet = Table1; DataField = Fam. После чего компонент в области отчета приобретет имя поля. 16. Аналогичным способом настроить остальные поля (рис. 13.2). 163

165 Рис Рабочий режим отчёта 17. Активизировать таблицу. 18. Выделить область компонента отчета QuickRep и установить для него свойство DataSet = Table1. Необходимо заметить, что активизация таблицы является недостаточным условием демонстрации отчета. Обязательно нужно установить свойство DataSet = источник. Это может быть и таблица, и запрос. Результат отчета приведен в сокращенном виде (рис. 13.3). Рис Фрагмент демонстрации отчёта Рассмотрим еще один отчёт. Пример 2. Вывести список первокурсников специальности (рис. 13.4). 164

166 Рис Отчёт список первокурсников Разработка его отличается от первого отчёта тем, что в качестве источника используется не таблица, а запрос. Необходимо для запроса Query задать SQL-предложение: SELECT fam, nam, gruppa, adres FROM student WHERE gruppa= ПИ-101 OR gruppa= ПИ-102 В полосе Title установить компонент QRSysData, после чего в свойстве Data выбрать значение qrsdate (даты). Указание источника для компонента QuickRep обязательно: DataSet = Query Разработка отчётов по взаимосвязанным таблицам До сих пор рассматривались отчеты, которые выводились по одной таблице. Работа с двумя и более таблицами заключается в том, что необходимо не просто настроить таблицы на определенные компоненты, а установить связь между таблицами. Пример. Вывести отчет по преподавателям с указанием предметов преподавания (рис. 13.5). 165

167 166 Рис Отчёт по двум таблицам Для реализации данного отчёта необходимо выполнить следующие действия: 1. Установить на форму два набора компонентов для настройки на таблицу ПРЕПОДАВАТЕЛЬ и ПРЕДМЕТ. 2. Установить связь между таблицами традиционным способом, при этом таблицы не активировать. 3. Установить на форме компонент QuickRep (с идентификатором QuickRep1). 4. В свойстве Bands установить свойства: HasTitle = true. 5. В области заголовка установить компоненты QRLabel и задать две строки заголовка: «СПИСОК» и «преподавателей». 6. Добавить в отчет область QRSubDetail (с идентификатором QRSubDetail1). 7. Установить для данной области свойство DataSet = Table1. 8. Установить в области детализации компоненты QRLabel (название «Преподаватель») и QRDBText. 9. Активизировать компонент QRDBText и установить для него свойства: DataSet = Table1, DataField = famil. 10. Активизировать таблицу Table1 и проверить работу отчета. Убедиться в том, что в отчете присутствует список преподавателей.

168 11. Дезактивировать таблицу ПРЕПОДАВАТЕЛЬ. 12. Добавить в отчет еще один компонент QRSubDetail (с идентификатором QRSubDetail2) и установить свойство DataSet = Table Установить во второй области детализации компоненты QRDBText для отображения полей предмета и семестра из таблицы ПРЕДМЕТ (Table2). 14. Добавить в отчет комментарии по кафедре и семестру (рис. 13.6). 15. Сохранить проект и проверить работу отчета. Убедиться в том, что отчет не совсем корректно отображает данные; это связано с тем, что в отчете не указана связь между областями (хотя связь между таблицами установлена). Рис Рабочий режим отчёта 16. Вернуться в рабочий режим проекта. 17. Активизировать вторую область детализации (QRSubDetail2) и войти в свойство Master. 18. Установить значение QRSubDetail1 в свойстве Master. Это означает, что первая область будет родительской для второй (дочерней) области. 19. Активизировать все таблицы. Необходимо заметить, что две области детализации рассматриваются как родительская и дочерняя области; при этом первая область организует внешний цикл для фамилий преподавателей первой таблицы, а вторая область внутренний цикл для предметов, которые представлены во второй таблице. Отношение между таблицами ПРЕ- ПОДАВАТЕЛЬ и ПРЕДМЕТ «один-ко-многим». Следующий пример не связан с двумя таблицами, но он использует прием, описанный выше. Пример 3. Вывод списков студентов по группам. На рис приведен отчёт, который обрабатывает только одну таблицу, но списки выводит по группам. Если бы группы и фамилии 167

169 находились в разных таблицах, то пришлось бы воспользоваться последовательностью действий, описанных в последующем пункте. В данной задаче необходимо прибегнуть к небольшой хитрости. 168 Рис Отчёт по студентам специальности Для реализации задачи необходимо выполнить следующие действия: 1. Установить на форме два набора компонентов: первый набор Query1, DataSource1 и второй набор Table1, DataSource2. 2. Настроить первый набор на запрос, который выводит только список групп: SELECT gruppa FROM student GROUP BY gruppa Необходимо обратить внимание на то, что, если не воспользоваться в запросе группировкой, то результат запроса будет содержать столько значений групп, сколько записей в таблице СТУДЕНТ. Использование группировки позволяет выводить каждое значение только один раз. 3. Настроить второй набор на таблицу Table1 (СТУДЕНТ). Учитывая то, что результат запроса представляет собой временную таблицу, можно установить связь между результатом запроса как родительской таблицей и таблицей СТУДЕНТ как дочерней, используя для связи поле gruppa.

170 4. Активизировать компонент Table1 и установить для него свойство MasterSource = DataSource1. 5. Активизировать свойство MasterFields и войти в окно установки связей между таблицами (рис. 13.8). Рис Окно установки связи между таблицами 6. Выбрать индексы поля для связи из запроса (Gruppa) и из таблицы СТУДЕНТ (gruppa), то есть установить связь Query1.Gruppa = Table1. gruppa. 7. Установить на форме компонент QuickRep и добавить в отчёт компоненты согласно рис. 13.9: полоску Title и полоски QRSubDetail1 и QRSubDetail2. Рис Рабочий режим отчёта 8. Установить для каждой области детализации свойство DataSet. Для первой запрос, для второй таблицу. 169

171 9. В первой области установить комментарий и поле gruppa из запроса. 10. Во второй области установить поля fam, nam, otch, gruppa из таблицы для вывода данных. Необходимо помнить, что связи между запросом и таблицей недостаточно для отображения нужных данных в отчёте. Нужно установить связь и между областями детализации. 11. Активизировать вторую область детализации и установить свойство Master со значением QRSubDetail1, которое характеризует первую область детализации. 12. Активизировать запрос и таблицу. Представленная последовательность операций позволяет разработать отчёт по двум таблицам с учётом вложенности (группировки) данных. Вопросы для самоконтроля 1. Для какой цели разрабатываются отчёты в приложениях? 2. Какой компонент системы используется для разработки отчёта? 3. Что представляет собой область отчёта в конструкторе (в режиме разработки)? 4. Какие вспомогательные компоненты системы используются для организации и/или оформления отчёта? 5. Какие свойства компонента QuickRep необходимо задать для разработки отчёта? 6. Что представляет собой «простой» отчёт? Охарактеризуйте. 7. Что представляет собой отчёт по взаимосвязанным таблицам? Охарактеризовать. 8. Каким образом осуществляется группировка в отчётах? Для какой цели эта группировка используется? 170

172 ЛАБОРАТОРНЫЕ РАБОТЫ Лабораторная работа 1 Создание простейшего приложения Теоретический материал: п. 1. Варианты 1. Разработать и реализовать программу для нахождения скорости животных, если известно, что путь в 60 км заяц-русак пробегает за 1 ч, а волк за 1 ч 20 мин. Данные вводятся с клавиатуры. 2. Разработать и реализовать программу для нахождения времени полета ракеты, если известно, что ракета со скоростью 8 км/с отлетела от Земли на расстояние 480 км. Какое время потребуется на преодоление такого же расстояния самолету ИЛ 18, если его скорость 0,18 км/с? 3. Разработать и реализовать программу для определения объема пирамиды, если известно, что ее высота равна 12 см, основание имеет вид прямоугольника со сторонами 8,3 см и 4 см. 4. Разработать и реализовать программу для определения массы и объема куба, если известно, что ребро равно 23,1 см, а плотность вещества, из которого он сделан, 2700 кг/м Разработать и реализовать программу для определения объема и площади полной поверхности прямоугольного параллелепипеда, если известно, что измерения параллелепипеда равны 12,4 см, 6 см, 20 см. 6. Разработать и реализовать программу для вычисления массы шара и куба, если известно, что радиус и ребро равны 0,5 м, плотность вещества 2700 кг/м 3? 7. Разработать и реализовать программу для нахождения времени, через которое будет услышан выстрел охотника, если известно, что расстояние до него составляет 2 км. Скорость звука 3 м/с. 8. Разработать и реализовать программу для определения объема конуса и цилиндра, если известно, что их высота равна 14,75 см, а радиус основания 8,5 см. 9. Разработать и реализовать программу для нахождения объема цилиндра, если известно, что его масса равна 2 кг, а плотность вещества 19,3 кг/м 3. Чему равен объем при той же массе, но с плотностью вещества 10,5 кг/м 3? 10. Разработать и реализовать программу для определения плотности вещества, из которого сделан брусок. Известно, что длина точильного бруска равна 30 см, ширина 5 см и толщина 2 см. Масса бруска 1,2 кг. 171

173 172 Теоретический материал: п. 2. Лабораторная работа 2 Управляющие структуры С++ Задание А 1. Компонент ListBox содержит фамилии писателей. Составить программу, позволяющую узнать, в каком жанре работает выбранный писатель. 2. Составить программу, которая при выборе в компоненте ListBox названия месяца, выводит количество дней в выбранном месяце. 3. Компонент ListBox содержит наименование валют. Составить программу, пересчитывающую введенную сумму (в рублях) в выбранную валюту. 4. Компонент ListBox содержит наименование имеющихся в продаже моделей принтеров. Составить программу, выводящую на экран тип выбранного принтера. 5. Компонент ListBox содержит названия правильных многоугольников. Составить программу, вычисляющую площадь выбранного многоугольника по введенной длине стороны. 6. Компонент ListBox содержит названия математических функций. Составить программу, вычисляющую значение функции для введенного аргумента. 7. Компонент ListBox содержит названия стран. Составить программу, выводящую на экран наименование национальной валюты для выбранной страны. 8. Компонент ListBox содержит фамилии художников. Составить программу, позволяющую узнать, в каком жанре работает выбранный художник. 9. Компонент ListBox содержит названия стран. Составить программу, позволяющую узнать государственный язык выбранной страны. 10. Составить программу, которая при выборе в компоненте ListBox названия месяца, выводит соответствующее месяцу время года: «зима», «весна», «лето», «осень». Задание B Составить программу вычисления суммы ряда. Значение аргумента и точность вводить с клавиатуры. Вывод результата должен осуществляться с помощью кнопки в компонент Label. Вывести на экран количество просуммированных членов ряда. 2 3 x x x 1. e = 1+ x ! 3!

174 (x 1) 2. ln(x) = (x 1) 2 2 (x 1) x x x cos(x) = ! 4! 6! x x x ln(1 x) = x x x x sin(x) = x ! 5! 7! x x x arctg(x) = x x x e + e x x x = ! 4! 6! x x x ln(1 + x) = x x x e e x x x = ! 5! 7! x x x 10. e 2 = 1+ x ! 3! 4! 3 (x 1) Задание C Разработать программу решения задачи с выводом результата в компонент Label. 1. В интервале от a до b найти все простые числа. Значения a и b вводить с клавиатуры. 2. Найдите все трехзначные числа, сумма цифр которых равна заданному числу. Число вводить с клавиатуры. 3. Число Армстронга это такое число из k цифр, для которого сумма k-х степеней его цифр равна самому числу. Например, 153 = Найти все числа Армстронга из двух и трех цифр. 4. Найти все трехзначные натуральные числа, в записи которых есть одинаковые цифры. 5. Счастливым будем считать такое число из шести цифр, в котором сумма левых трех цифр равна сумме правых трех цифр. Например, 173

175 457961: = Найти все счастливые билеты и подсчитать их количество (номера билетов от 0 до ). Если в числе меньше шести цифр, то недостающие начальные цифры считаются нулями. 6. Дано натуральное число n. Среди чисел 1,, n (n 99) найти все такие, запись которых совпадает с последними цифрами записи их квадрата (например, 62 = 36, 252 = 625). Значение n вводить с клавиатуры. 7. Найти наименьшее общее кратное двух заданных чисел. Числа вводить с клавиатуры. 8. Найти все совершенные числа в интервале от a до b. Совершенным называется такое натуральное число, которое равно сумме всех своих делителей, за исключением самого числа, например, 28 = Значения a и b вводить с клавиатуры. 9. Разбить заданное число на 2 слагаемых всеми различными способами. Разбиения, отличающиеся лишь порядком слагаемых, разными не считать. Число вводить с клавиатуры. 10. Получить все трехзначные натуральные числа, в записи которых нет двух одинаковых цифр. 174

176 Лабораторная работа 3 Разработка MDI-приложений Теоретический материал: п. 3. Создать тестовую программу по заданной тематике, которая будет включать в себя меню команд и диалоговые окна: с информацией об авторе теста, инструкцией по использованию программы, вопросами и результатом тестирования: по литературе; биологии; химии; русскому языку; геометрии; географии; истории; психологии; физике; художественной культуре. Примечания. 1. Предполагается, что проект должен содержать заставку, выполненную в отдельной форме. 2. Добавить в проект диалоговое окно, запрашивающее фамилию и имя тестируемого, чтобы эти данные учитывались при выводе результата. 3. Некоторые вопросы теста должны содержать рисунки. 4. Предусмотреть переключение страниц с помощью командной кнопки. 175

177 Лабораторная работа 4 Символы и строки Теоретический материал: п. 4. Составить программу обработки строковых величин. Исходные данные для обработки должны вводиться с клавиатуры в объект Edit. Обработка должна осуществляться по «щелчку» командной кнопки. Для вывода результатов использовать объект Label или окно сообщений. Задание А 1. Выяснить, является ли данное слово перевертышем. 2. Выяснить, все ли буквы слова X, стоящие на четных местах, различны. 3. Разработать программу обращения слова. 4. Задан список группы студентов с тремя оценками. Фамилии от оценок и оценки друг от друга отделены символом «*». Напечатать список фамилий и средний балл каждого студента на отдельных строках. 5. Определить, какие символы и сколько раз встречаются в тексте. 6. Определить символ, чаще всего встречающийся в слове X. 7. Убрать из слова X повторяющиеся буквы. 8. На какую букву начинается больше слов в тексте Y (между словами может быть несколько пробелов). 9. Составить программу, вычеркивающую из слова X те гласные, что встречаются дважды. 10. Напечатать самое длинное слово из текста (между словами может быть несколько пробелов). Задание В 1. Составить программу подсчета гласных букв слова X, что используются при написании слова Z. 2. Составить программу, вычеркивающую из слова X те буквы слова Y, что используются при написании слова Z. 3. Составить программу, отыскивающую гласную, чаще всего встречающуюся в слове X. 4. Составить программу, выясняющую, все ли буквы слова X, стоящие на нечетных местах, различны. 5. Составить программу, подсчитывающую, сколько различных согласных слова X употребляется в написании X более одного раза. 6. Составить программу, вычеркивающую из слова X и Y те буквы, что одновременно используются при написании каждого из этих слов. 7. Составить программу, вычеркивающую из слова Y те согласные, которые используются в слове Z. 176

178 8. Составить программу, проверяющую, можно ли из букв, входящих в слово X, составить слово Y (буквы можно переставлять и каждую букву можно использовать ровно два раза.) 9. Составить программу, отыскивающую согласную, встречающуюся в слове X реже всего. 10. Составить программу, подсчитывающую, сколько различных гласных слова X употребляется в написании Y более одного раза. 177

179 Лабораторная работа 5 Массивы Теоретический материал: пп. 5, 6. Задание А I) Создать диалоговое окно, содержащее компоненты для ввода числового и символьного одномерных массивов, состоящих из 12 элементов каждый (по одному из вариантов): 1. Список учеников класса и их оценки по математике. 2. Список товаров на складе и цены на каждый товар. 3. Расписание авиарейсов. 4. Меню ресторана. 5. Учебный план (наименование изучаемых дисциплин и количество часов). 6. Годовой план по выпуску продукции (процентное выполнение по каждому месяцу). 7. Список студентов группы и их возраст. 8. Реклама туристического агентства (маршруты и цены). 9. Результаты спортивных соревнований. 10. Учет пропущенных занятий (список фамилий студентов и количество пропусков). II) Написать функцию, позволяющую вывести эти массивы в окно сообщения (окно может выглядеть в соответствии с рисунком, расположенным ниже). III) Добавить на форму командную кнопку и разработать процедуру обработки события OnClick этой кнопки, выполняющую сортировку по возрастанию или убыванию элементов числового массива и соответственно переставляющую элементы символьного массива. 178

180 Задание В Разработать программу обработки одномерного массива, использующую модуль функций программиста для ввода элементов (по варианту задания). 1. Создать программу, которая считывает положительное вещественное число Аns, вводит 20 вещественных чисел в одномерный массив, а затем выбирает из них то, которое по абсолютной величине ближе всего к значению Ans. 2. Создать программу, которая вводит 20 вещественных чисел в одномерный массив, подсчитывает среднее арифметическое этих элементов и выбирает элемент, абсолютная величина которого ближе всего к значению среднего арифметического. 3. Создать программу, которая считывает 30 вещественных чисел в два одномерных массива (по 15 в каждый), а затем формирует из них два новых массива с положительными и отрицательными элементами. 4. Создать программу, которая вводит 20 вещественных чисел в одномерный массив, а затем вычисляет так называемую моду этого массива, т. е. число, встречающееся наиболее часто. 5. Создать программу, которая вводит 30 целых чисел в два одномерных массива (по 15 в каждый), а затем подсчитывает, сколько в этих массивах одинаковых элементов, и выводит на экран их значения. 6. Создать программу, которая считывает целое число Аns, вводит 19 целых чисел в одномерный массив, а затем добавляет это число в массив, если оно там отсутствует. 7. Создать программу, которая вводит 20 вещественных чисел в одномерный массив, а затем выполняет циклический сдвиг элементов массива на один элемент (т. е. последний элемент становится первым, первый вторым, второй третьим и т. д.). 8. Создать программу, которая считывает целое число Аns, вводит 20 целых чисел в одномерный массив, а затем удаляет из массива элемент, равный по абсолютному значению Ans (если такой элемент в массиве есть). 9. Создать программу, которая вводит 20 целых чисел в одномерный массив и вычисляет сумму элементов, имеющих нечетные значения и встречающиеся в этом массиве более 2-х раз. 10. Создать программу, которая вводит 20 вещественных чисел в одномерный массив и вычисляет произведение неповторяющихся элементов. Задание С Составить программу обработки двумерного массива. Для вывода двумерного массива использовать компонент StringGrid. Ввод исходных данных в таблицу осуществить с помощью процедуры обработки события OnActivate. Обработка данных массива и выдача результатов должны осуществляться по щелчку командной кнопки. 179

181 1. На олимпиаде по информатике участникам были предложены для решения 5 задач. Каждая из них оценивалась по пятибалльной системе. Составить программу, использующую двумерный массив и выводящую список участников олимпиады в порядке убывания баллов. 2. В соревнованиях по прыжкам в длину принимает участие 12 спортсменов. Каждый из них имеет 3 попытки. Составить программу, использующую двумерный массив и определяющую лучшую попытку каждого спортсмена. Программа также должна выводить список участников соревнований в порядке занятых мест. 3. Результаты соревнований фигуристов по одному из видов многоборья представлены оценками судей в баллах (от 0 до 6). Места участников распределяются по сумме баллов, которые каждый участник получил у всех судей. Составить программу, использующую двумерный массив и выводящую список участников соревнований в порядке занятых мест. 4. Информация об урожае зерновых по районам для 8 областей (в каждой области 5 районов) представлена в таблице. Составить программу, использующую двумерный массив и определяющую среднюю урожайность по каждой области. Результаты должны быть представлены в порядке возрастания урожайности. 5. Для каждой участницы кросса в таблицу были введены следующие данные: фамилия, город, время старта и время финиша. Составить программу, использующую двумерный массив и выводящую список участниц в порядке возрастания времени забега. 6. Каждый абитуриент при поступлении в институт сдал 4 экзамена, оценивавшихся по пятибалльной системе. Для поступления необходимо было набрать 16 баллов. Составить программу, использующую двумерный массив и выводящую список абитуриентов в порядке убывания проходного балла, причем около каждой фамилии должна стоять отметка «зачислен», «не зачислен». 7. В некоторой компании ведется учет данных, регистрирующих количество часов, отработанных служащими (12 человек) в течение недели. Запись о каждом служащем содержит фамилию, почасовую ставку и семь чисел, представляющих продолжительность работы в каждый из семи дней недели. Составить программу, использующую двумерный массив и находящую суммарное число часов, отработанных каждым служащим за неделю, а также размер зарплаты (произведение отработанного времени на почасовую ставку). Результаты вывести в порядке возрастания заработной платы. 8. Для формирования сборной команды по хоккею предварительно выбрано 16 игроков. На основании протоколов игр (всего 6 игр) составлена таблица, в которой содержится штрафное время каждого 180

182 игрока по каждой игре (штрафное время может составлять 2, 5 или 10 мин). Составить программу, использующую двумерный массив и выводящую список кандидатов в сборную в порядке возрастания суммарного штрафного времени. 9. В некоторой торговой компании ведется учет данных, регистрирующих продажи 8 видов товаров за каждый месяц года. Запись о каждом товаре содержит название, цену за единицу товара и 12 чисел, представляющих количество товаров, проданных в каждом месяце. Составить программу, использующую двумерный массив и находящую суммарное количество товаров по каждому наименованию, проданных за год, а также их общую стоимость (произведение количества проданных за год товаров на цену за единицу товара). Результаты вывести в алфавитном порядке наименований товара. 10. Фамилии абитуриентов и их оценки после сдачи двух экзаменов при поступлении в институт представлены в виде таблицы. Исключив из этого списка фамилии абитуриентов, получивших неудовлетворительную оценку на втором экзамене, напечатать список абитуриентов в порядке убывания их суммы баллов. 181

183 Лабораторная работа 6 Создание приложения обработки однотабличной базы данных Теоретический материал: пп. 7, 8. Задание А 1. Открыв программу «BDE Administrator», создать собственный псевдоним (область) для собственных баз данных. 2. Согласно варианту задания разработать базу данных (не менее 4-х таблиц). 3. Выбрать одну из основных таблиц и реализовать ее средствами DataBase Desktop (создать структуру таблицы, описать каждое поле и заполнить таблицу записями). Ввести в таблицу не менее 5 записей. Примечания. 1. При разработке таблиц обратить внимание на поля, для которых необходимо создать маски ввода. 2. Необходимо, чтобы в базе данных (хотя бы в одном экземпляре) были поля типа OLE, Memo и Logical. Варианты заданий 1. Железнодорожная касса 2. Аптечный склад 3. Фирма недвижимости 4. Школьный администратор 5. Касса Аэрофлота 6. Библиотека 7. Касса магазина 8. Деканат 9. Кадры (сотрудники) 10. Архив 11. Станция техобслуживания 12. Паспортный стол 13. Видеотека 14. Музыкальная коллекция 15. Спортивная секция Задание В Разработать форму просмотра информации из однотабличной базы данных. 182

184 Лабораторная работа 7 Разработка многотабличной базы данных Теоретический материал: пп. 9, 10. Задание А Разработать многотабличную базу данных согласно варианту задания. Таблиц должно быть не менее 3-х. Задание В 1. Изучить теоретический материал и проанализировать области приложения, в которых можно использовать возможности, описанные в данном пункте. 2. Разработать формы просмотра данных согласно заданию. 3. Дополнить уже существующую структуру приложения дополнительными элементами: a) добавить графические изображения в таблицы; b) выполнить просмотр данных с использованием дополнительного окна («вывести» редко используемую информацию на дополнительную форму просмотра); c) добавить в формы просмотра ниспадающие списки для удобства и легкости ввода данных; d) добавить в просмотр вычисляемое поле; e) добавить на формы необходимые маски ввода; f) реализовать форму просмотра трех таблиц через компонент DBCtrlGrid; g) добавить при необходимости различные виды диалоговых окон. 4. Этап реализации согласно разработанным и измененным блокам информационной системы реализовать формы просмотра, выполнив все условия задания (условия а-g). 183

185 Лабораторная работа 8 Реализация основных функций приложения Теоретический материал: п. 11. Задания 1. Изучить теоретический материал и проанализировать области приложения, в которых можно использовать возможности, описанные в данном пункте. 2. Разработать формы добавления, удаления и модификации согласно заданию. 3. Разработать функцию, которая является основной линией приложения (например, продажа, покупка, сдача, выдача и т. п.). 4. Дополнить уже существующую структуру приложения дополнительными элементами формами, выполняющими основные функции: добавление, удаление, модификация и поиск (который может быть включен в описанные процедуры). 5. Согласно разработанным и измененным блокам информационной системы реализовать формы добавления, удаления и модификации, выполнив все условия задания. 184

186 Лабораторная работа 9 Разработка запросов приложения Теоретический материал: п. 12. Разработать и реализовать несколько запросов к вариативной базе данных (с учетом специфики создаваемого приложения). 1. Определить, какая функция будущего приложения может быть разработана через многофункциональной запрос, а затем реализовать ее. Например, разработана форма поиска данных. На данной форме присутствуют поля для ввода большого количества критериев. Пользователь вводит критерий (или критерии) только в определенные (а не во все!) поля. В данной ситуации целесообразно разработать запросы, которые будут выполняться, например, от нажатия на кнопку или переключатель (или другой компонент формы). Запрос должен обрабатывать как данные из одной таблицы, так и данные из двух таблиц. 2. Разработать и реализовать два запроса с использованием агрегированных функций. 3. Разработать и реализовать запросы по использованию даты, сравнения строковых значений, а также использования списка значений (отношения BETWEEN, IN). 4. Разработать и реализовать два динамических запроса согласно вариативному заданию. Замечание. Все разрабатываемые запросы обязательно должны соответствовать основной функции будущего приложения. Система не должна содержать операции, которые не дают существенных результатов. 185

187 Лабораторная работа 10 Разработка отчётов приложения Теоретический материал: п. 13. Разработать несколько отчётов по вариативной базе данных, предварительно определив, какие виды отчётов необходимы для приложения. 1. Разработать и реализовать простой отчёт (из одной таблицы). 2. Разработать и реализовать отчёт из двух взаимосвязанных таблиц. Разработать и реализовать отчёт с использованием группировки. 186

188 Библиографический список 1. Borland C++Builder 6. [Электронный ресурс]. interface.ru/borland/cb5main.htm 2. Архангельский, А.Я. C++Builder 6 : справ. пособие. Кн. 1. Язык С++ / А.Я. Архангельский. М. : Бином-Пресс, с. 3. Архангельский, А.Я. C++Builder 6 : справ. пособие. Кн. 2. Классы и компоненты / А.Я. Архангельский. М. : Бином-Пресс, с. 4. Архангельский, А.Я. Приемы программирования в Delphi / А.Я. Архангельский. 2-е изд., перераб. и доп. М. : Бином-Пресс, с. 5. Архангельский, А.Я. Программирование в C++Builder 6 / А.Я. Архангельский. М. : Изд-во БИНОМ, с. 6. Боровский, А.Н. C++ и C++Builder : самоучитель / А.Н. Боровский. СПб. : Питер, с. 7. Дворжецкий, А.В. SQL: Structured Query Language : руководство пользователя / А.В. Дворжецкий. М. : Познавательная книга плюс, с. 8. Ермолаев, В. C++Builder: Книга рецептов / В. Ермолаев, Т. Сорока. М. : КУДИЦ-ОБРАЗ, с. 9. Павловская, Т.А. С/С++. Программирование на языке высокого уровня / Т.А. Павловская. СПб. : Питер, с. 10. Пахомов, Б.И. Interbase и C++Builder на примерах / Б.И. Пахомов. СПб. : БХВ-Петербург, с. 11. Холингворт, Д. Borland C++Builder 6 : руководство разработчика / Д. Холингворт [и др.]; пер. с англ. М. : Изд. дом «Вильямс», с. 12. Элджер, Д. С++: библиотека программиста / Д. Элджер. СПб. : Питер, с. 187

189 Приложение 1 Описание базы данных «Деканат» Структура базы данных «Деканат» 188 Спецификация таблицы student.db Комментарий Имя поля Тип поля (длина) п/п 1. Nomer (S) Short Уникальный номер студента 2. Fam (A) Alpha (20) Фамилия студента 3. Nam (A) Alpha (15) Имя студента 4. Otch (A) Alpha (30) Отчество студента 5. Data_rog (D) Date Дата рождения студента 6. Adres (A) Alpha (50) Домашний адрес студента 7. Phone (A) Alpha (8) Домашний телефон (формат ) 8. Photo (O) OLE Фотография студента (ввод данных в это поле возможно только при работе с приложением в C++Builder) 9. Gruppa (A) Alpha (6) Номер группы (формат АА-000) 10. Spez (A) Alpha (6) Номер специальности (формат ) 11. Prim (M) Memo (240) Примечание дополнительная информация (ввод данных в это поле возможно только при работе с приложением в C++Builder) 12. Haract (M) Memo (240) Примечание характеристика (ввод данных в это поле возможно только при работе с приложением в C++Builder) 13. Family (L) Logical Наличие семьи у студента («да» наличие семьи, «нет» семья отсутствует)

190 Спецификация таблицы ozenka.db п/п Имя поля Тип поля (длина) 1. Nomer (S) Short Комментарий Уникальный номер студента необходим для связи с родительской таблицей СТУДЕНТ 2. Kod_predm (S) Short 3. Dat_ekz (D) Date Дата экзамена 4. Ozenka (S) Short 5. Zachet (S) Short Код предмета, необходимый для связи с таблицей ПРЕДМЕТ Оценка за экзамен; необходимо установить минимальное значение 2, максимальное значение 5, значение по умолчанию 2 Зачет обозначается цифрой 0 или 1. Необходимо также установить минимальное значение (0), максимальное значение (1) и значение по умолчанию (0) п/п Спецификация таблицы predmet.db Имя поля Тип поля (длина) Комментарий 1. Kod_predm (S) Short Уникальный номер, характеризующий предмет необходим для связи с таблицей ОЦЕНКА 2. Predmet (A) Alpha (50) Название дисциплины 3. Semestr (S) Short Номер семестра. Ограничение от 1 до 9 4. Zachet (A) Alpha (1) Наличие зачета: 1 есть, 0 нет 5. Ekzamen (A) Alpha (1) Наличие экзамена: 1 есть, 0 нет 6. Kod_pp (S) Short Код преподавателя необходим для связи с родительской таблицей ПРЕПОДАВАТЕЛЬ Спецификация таблицы prepodav.db п/п Имя поля Тип поля (длина) Комментарий 1. Kod_prep (S) Short Уникальный номер, характеризующий предмет необходим для связи с таблицей ПРЕДМЕТ 2. Famil (A) Alpha (20) Фамилия преподавателя с инициалами 3. Kafedra (A) Alpha (30) Название кафедры 189

191 Форма «Добавление данных» в конструктуре форм Вкладка «Добавление новых студентов» Приложение 2 Вкладка «Добавление новых дисциплин» 190

192 Форма «Удаление данных» в конструктуре форм Приложение 3 191

193 Приложение 4 Описание некоторых пиктограмм палитры компонентов Вкладка Пиктограммы Обозначение Описание Standard Label Текстовая информация Standard Edit Однострочное поле для ввода данных Standard Button Кнопка Standard Standard ListBox MainMenu Список с возможностью выбора нескольких элементов Компонент меню, позволяющий оформить подпункт меню с закреплением за ним конкретного действия Standard Memo Многостраничное поле ввода Standard Panel Панель-контейнер Standard RadioGroup Группа радиокнопок для выбора Additional Image Графический компонент Additional BitBtn Кнопка, за которой автоматически закреплена та или иная функция 192

Среда визуального программирования Borland C++Builder

C++Builder (си-плас-плас-Билдер, си-Билдер) — программный продукт, инструмент быстрой разработки приложений (RAD), интегрированная среда программирования (IDE), система, используемая программистами для разработки программного обеспечения на языке C++.

Изначально разрабатывался компанией Borland Software, а затем её подразделением CodeGear, ныне принадлежащем компании Embarcadero Technologies.

C++Builder объединяет в себе комплекс объектных библиотек (STL, VCL, CLX, MFC и др.), компилятор, отладчик, редактор кода и многие другие компоненты. Цикл разработки аналогичен Delphi. Большинство компонентов, разработанных в Delphi, можно использовать и в C++Builder без модификации, но обратное утверждение не верно.

C++Builder содержит инструменты, которые при помощи drag-and-drop действительно делают разработку визуальной, упрощает программирование благодаря встроенному WYSIWYG-редактору интерфейса и пр.

Следуя пионерской традиции нисходящего визуального стиля программирования Delphi на Объектном Паскале, корпорация Borland выпускает на рынок систем быстрой разработки приложений RAD (Rapid Application Development) мощную систему под названием C++ Builder на языке C++.

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

Система содержит Библиотеку из более 100 повторно используемых визуальных компонент, которые перетаскиваются мышью на форму и сразу становятся элементами управления прототипа вашей программы. Помимо известных элементов управления Windows (кнопки, линейки прокрутки, поля редактирования, простые и комбинированные списки и т.д.) Библиотека содержит новые компоненты поддержки диалогов, обслуживания баз данных и многие другие

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

Опытным C++ программистам понравится синтаксис и структура кода разрабатываемых на C++Builder программ, хотя его графическое обрамление заметно отличается от традиционных оболочек систем разработки. Благодаря графическим средствам интегрированной среды C++Builder, новички смогут быстрее освоить стиль объектно-ориентированного программирования на C++, чем при использовании традиционного программно-текстового интерфейса других систем.

C++Builder поддерживает основные принципы объектно-ориентированного программирования — инкапсуляцию, полиморфизм и множественное наследование, а также нововведенные спецификации и ключевые слова в стандарте языка.

Язык C++

C++Builder обеспечивает высокое быстродействие при компиляции и сборке 32-разрядных приложений для современных операционных систем Windows 95 и Windows NT, включая OLE взаимодействие клиент-сервер. Система даже отображает время, затраченное на основные этапы построения программ. Результирующие программы хорошо оптимизированы по скорости исполнения и затратам памяти. Хотя отладочный режим низкого уровня полностью интегрирован в среду C++Builder, к отладке также пришлось привыкать. Дизайнер форм. Инспектор объектов и другие средства остаются доступными во время работы программы, поэтому вносить изменения можно в процессе отладки.

C++Builder поставляется в трех вариантах: Standard (стандартный). Professional (для профессионалов разработчиков, ориентированных на сетевую архитектуру) и Client/Server Suite (для разработки систем в архитектуре клиент/сервер). Последние два варианта дополняют стандартный исходными текстами визуальных компонент, разномасштабным словарем данных, новыми функциями языка запросов SQL для баз данных, пакетом поддержки систем Internet, службой мониторинга программ, а также рядом других средств.

Эксперименты с тестовыми программами в рамках стандартного варианта легли в основу материала, излагаемого здесь. Испытывая систему, я переложил на C++ Builder несколько приложений, ранее написанных на Borland C++ версии 4.5. Благодаря визуальным компонентам, из программ исчезла «кодовая шелуха» обработки сообщений Windows и ресурсных файлов, и остался только содержательный код. Пользовательский интерфейс приложений приобрел законченный профессиональный облик.

Хотя C++ Builder представляется весьма надежной системой, корпорации еще предстоит опровергнуть расхожее утверждение, что в каждой отлаженной программе (в том числе и в коммерческой) есть по меньшей мере одна ошибка. Видимо, именно этим стремлением объясняется излишняя, на мой взгляд, поспешность с рекламированием «улучшенной и расширенной» версии Borland C++ версии 5.02.

Поддержка баз данных

C++ Builder поддерживает связь с различными базами данных 3-х видов:

dBASE и Paradox: Sybase, Oracle, InterBase и Informix; Excel, Access, FoxPro и Btrieve. Механизм BDE (Borland Database Engine) придает обслуживанию связей с базами данных удивительную простоту и прозрачность. Проводник Database Explorer позволяет изображать связи и объекты баз данных графически. Используя компоненты баз данных, я построил электронную записную книжку по таблице dBASE за полчаса работы на компьютере. Наследование готовых форм и их «подгонка» под специфические требования заметно сокращают временные затраты на решение подобных задач.

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

Благодаря средствам управления проектами, двусторонней интеграции приложения и синхронизации между средствами визуального и текстового редактирования, а также встроенному отладчику (с ассемблерным окном прокрутки, пошаговым исполнением, точками останова, трассировкой и т.п.) — C++ Builder корпорации Borland предоставляет собой впечатляющую среду разработки, которая, видимо, выдержит конкурентную борьбу с такими модными продуктами как Microsoft Developer Studio.

Самоучитель C++ Builder, Культин Н.Б., 2004

Самоучитель C++ Builder, Культин Н.Б., 2004.

Книга является руководством по программированию в среде Borland C++ Builder. В ней рассматривается весь процесс разработки программы — от компоновки диалогового окна и написания функций обработки событий до отладки и создания справочной системы при помощи программы Microsoft HTML Help Workshop и установочного CD-ROM в InstallShield Express, разбираются вопросы работы с графикой, мультимедиа и базами данных, приведено описание процесса создания анимации в Macromedia Flash 5. Прилагаемый к книге компакт-диск содержит проекты, приведенные в издании в качестве примеров.
Для начинающих программистов.

Редактор кода.
Во время набора текста программы редактор кода автоматически выделяет элементы программы: полужирным шрифтом — ключевые слова языка программирования (if, else, int, float и др.), курсивом — комментарии. Это делает текст программы более выразительным, что облегчает восприятие структуры программы.

В процессе разработки программы часто возникает необходимость переключения между окном редактора кода и окном формы. Сделать это можно при помощи командной кнопки Toggle Form/Unit, которая находится на панели инструментов View (рис. 2.20), или нажав клавишу . На панели инструментов View находятся командные кнопки View Unit и View Form, используя которые можно выбрать нужный модуль или форму в случае, если проект состоит из нескольких модулей или форм.

Содержание
Предисловие
C++ Builder — что это?
Об этой книге
ЧАСТЬ I. СРЕДА РАЗРАБОТКИ C++ BUILDER
Глава 1. Начало работы
Глава 2. Первый проект
Форма
Компоненты
Событие и функция обработки события
Редактор кода
Система подсказок
Навигатор классов
Шаблоны кода
Справочная система
Сохранение проекта
Компиляция
Ошибки
Предупреждения и подсказки
Компоновка
Запуск программы
Ошибки времени выполнения
Внесение изменений
Настройка приложения
Название программы
Значок приложения
Перенос приложения на другой компьютер
Структура простого проекта
ЧАСТЬ II. ПРАКТИКУМ ПРОГРАММИРОВАНИЯ
Глава 3. Графика
Холст
Карандаш и кисть
Графические примитивы
Линия
Ломаная линия
Прямоугольник
Многоугольник
Окружность и эллипс
Дуга
Сектор
Текст
Точка
Иллюстрации
Битовые образы
Мультипликация
Метод базовой точки
Использование битовых образов
Загрузка битового образа из ресурса программы
Создание файла ресурсов
Подключение файла ресурсов
Глава 4. Мультимедиа
Компонент Animate
Компонент Media Player.
Воспроизведение звука
Просмотр видеороликов
Создание анимации
Глава 5. Базы данных
База данных и СУБД
Локальные и удаленные базы данных
Структура базы данных
Псевдоним
Компоненты доступа и манипулирования данными
Создание базы данных
Доступ к базе данных
Отображение данных
Манипулирование данными
Выбор информации из базы данных
Перенос программы управления базой данных на другой компьютер
Глава 6. Компонент программиста
Выбор базового класса
Создание модуля компонента
Тестирование компонента
Установка компонента
Ресурсы компонента
Установка
Проверка компонента Настройка палитры компонентов
Глава 7. Консольное приложение
Ввод/вывод
Функция printf
Функция scanf
Создание консольного приложения
Глава 8. Справочная система
Создание справочной системы при помощи Microsoft Help Workshop
Подготовка справочной информации
Проект справочной системы
Вывод справочной информации
HTML Help Workshop
Подготовка справочной информации
Использование Microsoft Word
Использование HTML Help Workshop
Создание файла справки
Компиляция
Вывод справочной информации
Глава 9. Создание установочного диска
Программа InstallShield Express
Новый проект
Структура
Выбор устанавливаемых компонентов
Конфигурирование системы пользователя
Настройка диалогов
Системные требования
Создание образа установочной дискеты
Глава 10. Примеры программ
Система проверки знаний
Требования к программе
Файл теста
Форма приложения
Отображение иллюстрации
Доступ к файлу теста
Текст программы
Игра «Сапер»
Правила игры и представление данных
Форма приложения
Игровое поле
Начало игры
Игра
Справочная информация
Информация о программе
Текст программы
Очистка диска
Приложение 1. C++ Builder — краткий справочник
Компоненты
Форма
Label
Edit
Button
Memo
Radio Button
Check Box
ListBox
Combo Box
StringGrid
Image
Timer
Animate Media Player
Speed Button
Up Down
Table
Query
Data Source
DВEdit, DВMemo, DBText
DВGrid
DBNavigator
Графика
Canvas
Pen
Brush
Функции
Функции ввода и вывода
Математические функции
Функции преобразования
Функции манипулирования датами и временем
События
Исключения
Приложение 2. Содержимое компакт-диска
Рекомендуемая литература
Предметный указатель.

Бесплатно скачать электронную книгу в удобном формате, смотреть и читать:
Скачать книгу Самоучитель C++ Builder, Культин Н.Б., 2004 — fileskachat.com, быстрое и бесплатное скачивание.

Скачать pdf
Ниже можно купить эту книгу по лучшей цене со скидкой с доставкой по всей России. Купить эту книгу

Изучаем компоненты borland c builder

Не удалось найти товары, содержащие все слова. Показаны товары, содержащие «borland c builder«

Цена: 967.00 руб.

Описание Эта книга будет изготовлена в соответствии с Вашим заказом по технологии Print-on-Demand. Данная книга посвящена изложению вопросов совместного использования богатой библиотеки визуальных компонент Borland C++ Builder и возможностей языка C++ с мощными . Категория Книги :: Печать книг на заказ :: Информатика и информационные технологии Автор Подкур М.П. Серия — Издательство ДМК Пресс Год 2006 На складе +

Цена: 385.00 руб.

Категория Книги :: Техника. Медицина :: Информатика. Компьютеры :: Прикладные программы :: Научное ПО Автор Смоленцев Н. К. ISBN 978-5-94074-729-1 Издательство ДМК Год 2012 На складе +

Цена: 2999
Цена: 792.00 руб.

Категория Книги :: Разное Автор Смоленцев Н Издательство ДМК Пресс Год 2011 Описание УДЛ На складе +

Илон Маск рекомендует:  AssignFile - Процедура Delphi
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL