Глава 5. СОЗДАЕМ ОКОННЫЙ ИНТЕРФЕЙС «ПОСТУПЛЕНИЯ НА СКЛАД»
Добавляем окно редактирования шапки. SQL-запрос для выпадающего списка
Закроем все окна и перейдем в режим «Дизайнер».
Добавим в проект еще одну форму с помощью Файл/
Новая форма.
Эта форма нам понадобится для редактирования шапки документа. Изменим
свойство Name формы c Form1 на StockInHeaderForm, а в
свойство Caption впишем ’Шапка документа’ . Сохраним модуль под именем
stock_in_header.pas. Добавим компонент
Panel с палитры Standard, установим в Инспекторе объектов его
свойство Align в состояние alBottom. Панель прижмется к нижнему
краю окна. Разместим на этой панели два компонента Button
с палитры Standard.
Изменим свойства Caption кнопок Button1 и Button2 на Сохранить и
Отмена, а в свойстве Caption панели сотрем текст,
чтобы не отображать ее заголовок вообще. Присвоим значения еще
некоторым свойствам:
Button1
Name = btnOK
Caption = OK
Button2
Name = btnCancel
Caption = Отмена
ModalResult = mrCancel
Cancel = True
Panel1
Name = ButtonPanel
BevelOuter = bvNone (уберем фаску)
Caption = ‘’
Значение ModalResult = mrCancel у второй кнопки означает, что
при нажатии кнопки форма закроется, если она находилась в
так называемом модальном режиме отображения. Свойство Cancel = True
той же кнопки означает, что нажатие клавиши Escape на
клавиатуре будет восприниматься так же, как если бы пользователь
нажал эту кнопку.
Для того чтобы форма StockInFormHeader отображалась как диалог (с
фиксированным размером) и в центре экрана, выберем ее
и установим еще два ее свойства:
BorderStyle = bsDialog
Position = poScreenCenter
Для того чтобы программный модуль добавленной формы проекта «видел
» переменные модуля главной формы, нужно, чтобы в
секции uses раздела implementation было указано имя модуля главной формы
. Это объявление можно вписать вручную, а можно и
с помощью меню Файл/Использовать объект. То же
самое нужно сделать в модуле главной формы stock_in
по отношению к модулю stock_in_header.
Теперь нужно организовать вызов формы для редактирования шапки из главной
формы проекта. Вызов формы в модальном режиме (в
режиме диалога) осуществляется с помощью метода ShowModal этой формы
. Для того чтобы вызвать этот метод нам понадобится кнопка
или какой-то другой орган управления, который пользователь
мог бы использовать. Удобно для решения подобных задач использовать
компонент ActionList с палитры Standard. Этот компонент позволяет составить
список всех команд, которые могут понадобиться пользователю, а
затем подключить к этим командам разные органы управления. Например
, создав команду «Шапка…» можно подключить к ней
кнопку, пункт контекстного меню и назначить горячую клавишу.
Тогда пользователь сможет вызывать эту команду тем способом, который
ему покажется более удобным. Централизованный список команд ActionList позволяет
назначить каждой команде обработчик, заголовок, подсказку, пиктограмму
и горячую клавишу.
Выберем главную форму StockInForm. Добавим к ней компоненты:
ActionList (палитра Standard)
PopupMenu (палитра Standard)
ImageList (палитра Win32).
Дважды щелкнем на компоненте ImageList1 мышью. В появившемся редакторе
добавим в список три картинки размером 16x16 пиксель. Первая
картинка (с индексом 0) будет изображать пиктограмму шапки
документа, вторая – дискету, третья – символ Excel
. Нажмем OK.
Компонент ImageList позволяет хранить список картинок одинакового размера и затем
обращаться к ним по их индексу, который начинается с
нуля. Размеры картинок определяются его свойствами Width и Height
. Назначим компонентам ActionList1 и PopupMenu1 значение свойства Images =
ImageList1 в Инспекторе объектов. Дважды щелкнем на компоненте ActionList1
. Появится редактор списка команд.
Добавим три команды (TAction). В Инспекторе объектов назначим
им свойства:
Caption |
Шапка… |
ImageIndex |
0 |
Hint |
Шапка |
Name |
actHeader |
Caption |
Сохранить |
ImageIndex |
1 |
Hint |
Сохранить |
Name |
actSave |
ShortCut |
Ctrl+S |
Caption |
Отчет |
ImageIndex |
2 |
Hint |
Отчет |
Name |
actReport |
Закроем редактор списка команд.
Дважды щелкнем на компоненте PopupMenu1 мышью. Появится редактор пунктов
меню. Добавим в меню три пункта клавишей Insert.
Последовательно выбирая пункты меню, присвоим их свойствам Action созданные
только что нами команды:
actHeader
actSave
actReport
Закроем редактор меню.
Дважды щелкнем на компоненте ActionList1. В появившемся редакторе списка
команд выберем команду «Шапка» (actHeader) и
создадим ей обработчик события OnExecute.
Добавим в обработчике следующее выражение:
procedure TStockInForm.actHeaderExecute(Sender: TObject);
begin
if StockInHeaderForm.ShowModal = mrOK then
self.Caption := NameOfDocument('STOCK_IN', qryMaster.FieldByName('ID').AsInteger,
traCurrent); //устанавливаем новый заголовок формы
end;
В обработчик OnCreate формы также добавим:
self.Caption := NameOfDocument('STOCK_IN', qryMaster.FieldByName('ID').AsInteger,
traCurrent); //устанавливаем новый заголовок формы
Здесь мы присваиваем заголовок форме. Функция NameOfDocument возвращает наименование
документа в соответствии с теми правилами форматирования, которые для
него заданы.
Переключимся на форму клавишей F12 и в Инспекторе объектов присвоим
свойству PopupMenu формы StockInForm компонент PopupMenu1. Теперь у формы
есть контекстное меню. Запустим проект (F9) и
щелкнем правой кнопкой мыши на форме. Появится контекстное меню
. Остается выбрать пункт «Шапка» и вызвать окно
редактирования шапки. Окно вызвалось модально. Пока оно не
закрыто, невозможно активизировать какое-либо другое окно программы
. Закроем окно, нажав кнопку Cancel или клавишу Escape
. Закроем окно документа и перейдем к добавлению компонентов на
форму «шапки».
Для «массового» добавления компонента какого-то определенного
класса нужно выбрать этот компонент на палитре, нажав клавишу
Shift и щелкнув на компоненте мышью. Компонент выделится синим
цветом на палитре. После этого достаточно щелкать мышью на
форме и компонент будет добавляться многократно. Поступим так с
компонентом Label с палитры Standard, нам нужно добавить его
8 раз на форму.
Для того чтобы отменить режим «массового» добавления компонента
щелкнем на палитре на самом левом значке со стрелкой.
Добавим 11 компонентов Label. Заменим свойство Caption добавленных нами
компонентов на: Вид документа, Дата документа, Склад
, Номер документа, Кредитуемый счет, Ставка НДС,
Поставщик, Курс USD, Валюта документа, Курс валюты
документа, Дата поступления на склад.
Добавим компоненты управления данными и назначим им свойства в Инспекторе
объектов.
Поле «Вид документа»: компонент RxDBComboBox (палитра RX
DBAware)
DataSource = StockInForm.dsrMaster
DataField = DOC_KIND
EnableValues = True
Name = cbxDOC_KIND
Style = csDropDownList
Items = Поступление от поставщика
Приобретение
Ввод начальных остатков
Values = 0
1
2
при заполнении свойств Items и Values в Инспекторе объектов вызывается
редактор многостроковых текстовых данных типа TStrings:
Поле «Дата документа»: компонент DBDateEdit (палитра RX
DBAware)
DataSource = StockInForm.dsrMaster
DataField = DOC_DATE
Name = edDOC_DATE
Поле «Склад»: компонент RxDBLookupCombo (палитра RX DBAware
)
DataSource = StockInForm.dsrMaster
DataField = STOCK_ACC
Name = cbxSTOCK_ACC
Поле «Номер документа»: компонент DBEdit (палитра Data
Controls)
DataSource = StockInForm.dsrMaster
DataField = DOC_NO
Name = edDOC_NO
Поле «Кредитуемый счет»: компонент DBAccountEdit (палитра Allegro
)
DataSource = StockInForm.dsrMaster
DataField = ACC_ID
Name = aedACC_ID
Transaction = StockInForm.traCurrent
Поле «Ставка НДС»: компонент DBEdit (палитра Data
Controls)
DataSource = StockInForm.dsrMaster
DataField = VAT_RATE
Name = edVAT_RATE
Поле «Поставщик»: компонент DBRefEdit (палитра Allegro)
ClassTableName = CONTRAGENT
DataSource = StockInForm.dsrMaster
DataField = CONTRAGENT
Name = refCONTRAGENT
Transaction = StockInForm.traCurrent
Поле «Курс USD»: компонент DBEdit (палитра Data
Controls)
DataSource = StockInForm.dsrMaster
DataField = EXCH_RATE_S
Name = edEXCH_RATE_S
Поле «Валюта документа»: компонент DBLayerComboBox (палитра Allegro
)
DataSource = StockInForm.dsrMaster
DataField = LAYER_ID
Name = cbxLAYER_ID
Transaction = StockInForm.traCurrent
Поле «Курс валюты документа»: компонент DBEdit (палитра
Data Controls)
DataSource = StockInForm.dsrMaster
DataField = EXCH_RATE_L
Name = edEXCH_RATE_L
Поле «Дата поступления на склад»: компонент DBDateEdit (
палитра RX DBAware)
DataSource = StockInForm.dsrMaster
DataField = ENTRY_DATE
Name = edENTRY_DATE
Добавим еще 2 компонента:
Поле «Товар поступил на склад»: компонент DBCheckBox (
палитра Data Controls)
Caption = Товар поступил на склад
DataSource = StockInForm.dsrMaster
DataField = HAS_ENTRY
Name = cbHAS_ENTRY
Поле «Расчет сумм»: компонент DBRadioGroup (палитра Data
Controls)
Caption = Расчет сумм
DataSource = StockInForm.dsrMaster
DataField = CALC_MODE
Name = rgCALC_MODE
Items = От цены без НДС
От цены с НДС
Values = 0
1
Сохраним все изменения.
Можно запустить проект и вызвать окно «шапки» с
помощью контекстного меню, чтобы убедиться, что все поля
документа (кроме поля «Склад») отображаются правильно.
Не пытайтесь редактировать поля. У нас еще не введены
необходимые для этого тексты SQL-запросов. Проверьте,
как перемещается фокус ввода между компонентами окна «шапки»
по нажатию клавиши Tab. Если Вам не нравится порядок
перехода, то нужно вернуться в режим дизайна, выбрать
форму шапки и вызвать пункт меню Правка/Порядок перехода
. Появится диалог, в котором можно поменять порядок перехода
между экранными объектами.
Остановим проект, если он запущен и вернемся в режим
дизайна.
Для того чтобы организовать выпадающий список складов, добавим на
форму 1 компонент IBQuery и 1 компонент DataSource (палитра
InterBase) .
Установим свойства компонента DataSource:
DataSet = qryStocks
Name = dsrStocks
Установим свойства компонента IBQuery:
Transaction = StockInForm.traCurrent
Name = qryStocks
Теперь нам нужно вписать в свойство SQL компонента IBQuery текст
SQL-запроса, который возвратил бы нам все имеющиеся
в конфигурации склады. Для того, чтобы поэкспериментировать с
запросами, «растянем» главное окно программы (кнопка
Растянуть Главное Окно) и вызовем окно ISQL через меню
Инструменты/Интерактивный SQL. Наберем такую команду:
select acc_id, parent_id, name
from acc
Нажмем Ctrl + Enter. Мы обратились к системной таблице
счетов ACC и запросили внутренние ID счетов, внутренние ID
их родителей и имена счетов. Найдем в полученном наборе
счета складов. Мы видим, что они имеют PARENT
_ID = 1005. Это ID регистра «Товары
».
Изменим текст запроса так, чтобы он нам возвращал все
счета, непосредственно входящие в регистр «Товары»:
select acc_id, name
from acc where parent_id = 1005
Нажмем Ctrl+Enter и убедимся, что это тот
список складов, что нам нужен. После выполнения запроса
текст запроса исчезает из верхнего окна. Поэтому вернемся на
шаг назад (Ctrl+P) в окне ISQL
, для того, чтобы скопировать текст запроса в буфер
обмена Windows. Выделим текст запроса и скопируем его в
буфер обмена (Ctrl+C). Сожмем Главное окно
с помощью кнопки Сжать Главное Окно. Выберем компонент qryStocks
и в Инспекторе объектов щелкнем дважды на его свойстве SQL
.
Вставим текст запроса из буфера обмена (Ctrl+V
) и нажмем OK.
Нам остается привязать управляющий элемент поля «Склад» к
запросу так, чтобы он получал из запроса значения для
выпадающего списка. Сделаем это, установив свойства компонента cbxSTOC
_ACC именно в той последовательности, как здесь перечислено
:
LookupSource = dsrStocks
LookupField = ACC_ID
LookupDisplay = NAME
Для того чтобы запрос открылся при показе формы на экране
, создадим обработчик события OnShow формы и впишем в него
такую команду:
qryStocks.Open;
Теперь запустим проект (F9).
Закроем все окна и выйдем из режима «Дизайнер».
|