Глава 5. СОЗДАЕМ ОКОННЫЙ ИНТЕРФЕЙС «ПОСТУПЛЕНИЯ НА СКЛАД»
Реализуем перепроведение документа «Поступление на склад».
Для того чтобы документ перепровелся, достаточно вызвать процедуру MakeEntries
. В эту процедуру нужно передать всего два параметра:
название главной таблицы документа и указатель на компонент транзакции.
После перепроведения документа и подтверждения транзакции желательно всегда еще вызывать
процедуру ReafreshBalance, которая освежит баланс компании, если окно
баланса присутствует на экране.
Добавим вызов этих двух процедур (они выделены жирным шрифтом
) в обработчик OnExecute команды actSave:
procedure TStockInForm.actSaveExecute(Sender: TObject);
begin
MakeEntries('STOCK_IN', qryMaster.FieldByName('ID').AsInteger, traCurrent);
traCurrent.CommitRetaining; //подтвердить транзакцию
Modified := False;
RefreshExplorer; //пересветить "Проводник по документам"
RefreshBalance; //пересветить "Баланс"
end;
Запустим проект, вызовем окно «Баланс» через меню
Бухгалтерия /Баланс, выберем в балансе слой USD.
Вызовем на передний план окно документа через меню Окно/
Поступление на склад и отодвинем его так, чтобы были
видны суммы в окне «Баланс» на счетах Товарных
запасов. Теперь изменим что-то в цифрах документа
и сохраним. Сумма на счете товарных запасов в балансе
должна измениться:
Нам осталось реализовать перерасчет сумм в главной таблице документа STOCK
_IN. Это суммы в полях TOTAL_L
, TOTAL_S и TOTAL_R. В
принципе без этих полей можно было бы обойтись, но
иногда удобно иметь поля сумм в главной таблице, например
, в данном случае мы используем одну из этих сумм
для отображения «сумм» документов «Поступление на склад
» в «Проводнике по документам». Также удобно иметь
сумму документа при поиске по сумме и для ускорения некоторых
отчетов.
Мы сделаем расчет сумм в момент сохранения документа.
Добавим к форме StockInForm еще один компонент IBQuery с палитры
InterBase.
Установим его свойство:
Transaction = traCurrent
DataSource = dsrMaster
Name = qryTotals
Дважды щелкнем на свойстве SQL и впишем такой запрос:
SELECT SUM(AMOUNT_L), SUM(AMOUNT_R), SUM(AMOUNT_S)
FROM STOCK_IN_ITEM
WHERE ID = :ID
А в обработчик события OnExecute команды actSave добавим ряд строк
, которые выделены здесь жирным шрифтом:
procedure TStockInForm.actSaveExecute(Sender: TObject);
begin
qryTotals.Open;
qryMaster.Edit;
qryMaster.FieldByName('TOTAL_L').AsCurrency := qryTotals.Fields[0].AsCurrency;
qryMaster.FieldByName('TOTAL_R').AsCurrency := qryTotals.Fields[1].AsCurrency;
qryMaster.FieldByName('TOTAL_S').AsCurrency := qryTotals.Fields[2].AsCurrency;
qryMaster.Post;
qryTotals.Close;
MakeEntries('STOCK_IN', qryMaster.FieldByName('ID').AsInteger, traCurrent);
traCurrent.CommitRetaining; //подтвердить транзакцию
Modified := False;
RefreshExplorer; //пересветить "Проводник по документам"
RefreshBalance; //пересветить "Баланс"
end;
Здесь мы обращаемся к полям компонента запроса qryTotals по их
индексам. А к полям компонента qryMaster – по именам
. Оба этих способа можно использовать. Способ обращения по
имени предпочтительнее, когда мы хотим, чтобы у программы
был более читабельный текст.
Дабавим еще маленький штрих – ограничение на минимальный размер формы
на экране. Для этого в Инспекторе объектов для формы
StockInForm в свойстве Constraints зададим:
MinHeight = 500
MinWidth = 650
Запустим проект, изменим какую-нибудь цену и нажмем
кнопку сохранения. Обратим внимание, что сумма документа,
отображаемая на верхней панели, изменилась. Теперь она всегда
становится равна сумме позиций после сохранения документа. Попробуем уменьшить
размер окна. Мы видим, что наши ограничения на
минимальный размер окна тоже работают.
Еще один штрих, которого не хватает – возможности видеть
, был ли изменен документ и нуждается ли он в
сохранении. Наиболее элегантный способ этого отображения – управлять свойством
Enabled кнопки «сохранить».
Найдем с помощью поиска Ctrl+F все места в
тесте модуля stock_in, в которых происходит присвоение
переменной Modified значения True или False.
Вставим после каждого такого присвоения строку:
actSave.Enabled := Modified;
В принципе, можно вообще отказаться от использования переменной Modified
и использовать вместо нее свойство Enabled, но мы так
не поступим: это может сделать текст нашей программы менее
понятным. Запустим проект и убедимся, что кнопка с
дискетой неактивна. Внесем какое-нибудь изменение и убедимся
в том, что кнопка стала активной.
|