На главную   На главную   Форумы Новости Документация Скачать Купить  
Регистрация  
Система Allegro
Oб Allegro Характеристики Пример конфигурации Документация База ошибок Развитие
Версия для печати К списку книг Вернуться к оглавлению Предыдущий параграф Следующий параграф
Поиск по книге

Глава 5. СОЗДАЕМ ОКОННЫЙ ИНТЕРФЕЙС «ПОСТУПЛЕНИЯ НА СКЛАД»

Полный листинг проекта «Поступление на склад»

unit stock_in;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, ComCtrls, Menus,DCMenuEditor,DBGridA, DBGrids, IBCustomDataSet,
  IBDatabase, DB,StdCtrls, DBCtrls,ActnList,AlgCtrls,IBQuery,xlReport;
type
  TStockInForm = class(TForm)
    TopPanel: TPanel;
    dbgDetail: TDBGridA;
    Splitter1: TSplitter;
    dbgGoods: TDBGrid;
    qryMaster: TIBDataSet;
    qryDetail: TIBDataSet;
    traCurrent: TIBTransaction;
    dsrMaster: TDataSource;
    dsrDetail: TDataSource;
    qryDetailID1: TIntegerField;
    qryDetailN1: TIntegerField;
    qryDetailGOODS1: TIntegerField;
    qryDetailITEM_NAME1: TIBStringField;
    qryDetailQUANTITY1: TIntegerField;
    qryDetailPRICE_L1: TIBBCDField;
    qryDetailPRICE_L_WO_VAT1: TIBBCDField;
    qryDetailPRICE_R1: TIBBCDField;
    qryDetailPRICE_R_WO_VAT1: TIBBCDField;
    qryDetailAMOUNT_L1: TIBBCDField;
    qryDetailAMOUNT_R1: TIBBCDField;
    qryDetailAMOUNT_S1: TIBBCDField;
    qryMasterID1: TIntegerField;
    qryMasterDIR_ID1: TIntegerField;
    qryMasterDOC_DATE1: TDateField;
    qryMasterDOC_KIND1: TIntegerField;
    qryMasterDOC_NO1: TIBStringField;
    qryMasterENTRY_DATE1: TDateField;
    qryMasterHAS_ENTRY1: TSmallintField;
    qryMasterSTOCK_ACC1: TIntegerField;
    qryMasterLAYER_ID1: TIntegerField;
    qryMasterLAYER_NAME1: TIBStringField;
    qryMasterVAT_RATE1: TIBBCDField;
    qryMasterACC_ID1: TIntegerField;
    qryMasterCONTRAGENT1: TIntegerField;
    qryMasterCONTRAGENT_NAME1: TIBStringField;
    qryMasterCALC_MODE1: TIntegerField;
    qryMasterTOTAL_L1: TIBBCDField;
    qryMasterTOTAL_R1: TIBBCDField;
    qryMasterTOTAL_S1: TIBBCDField;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    DBText1: TDBText;
    DBText2: TDBText;
    DBText3: TDBText;
    DBText4: TDBText;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    DBText5: TDBText;
    DBText6: TDBText;
    DBText7: TDBText;
    DBText8: TDBText;
    qryMasterSTOCK_ACC_NAME1: TIBStringField;
    qryMasterCREDIT_ACC_NAME1: TIBStringField;
    PopupMenu1: TPopupMenu;
    ImageList1: TImageList;
    qryMasterEXCH_RATE_L1: TFloatField;
    qryMasterEXCH_RATE_S1: TFloatField;
    Timer1: TTimer;
    ActionList1: TActionList;
    actHeader: TAction;
    actSave: TAction;
    actReport: TAction;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    DBNavigator1: TDBNavigator;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    qryDetailNUM1: TIntegerField;
    RefDialog1: TRefDialog;
    qryGoods: TIBQuery;
    qryGoodsOBJECT_ID1: TIntegerField;
    qryGoodsSHORT_NAME1: TIBStringField;
    dsrGoods: TDataSource;
    qryTotals: TIBQuery;
    xlReport1: TxlReport;
    procedure FormCreate(Sender: TObject);
    procedure actHeaderExecute(Sender: TObject);
    procedure actSaveExecute(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure qryMasterAfterPost(DataSet: TDataSet);
    procedure Timer1Timer(Sender: TObject);
    procedure qryDetailAfterInsert(DataSet: TDataSet);
    procedure qryDetailCalcFields(DataSet: TDataSet);
    procedure qryDetailAfterDelete(DataSet: TDataSet);
    procedure dbgDetailEditButtonClick(Sender: TObject);
    procedure dsrDetailDataChange(Sender: TObject; Field: TField);
    procedure qryDetailBeforePost(DataSet: TDataSet);
    procedure dsrMasterDataChange(Sender: TObject; Field: TField);
    procedure dbgDetailSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
    procedure dbgDetailKeyPress(Sender: TObject; var Key: Char);
    procedure dbgGoodsDblClick(Sender: TObject);
    procedure dbgGoodsKeyPress(Sender: TObject; var Key: Char);
    procedure actReportExecute(Sender: TObject);
    procedure xlReport1Progress(Report: TxlReport; const Position, Max: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  StockInForm: TStockInForm;
implementation
uses
  stock_in_header;
{$R *.DFM}
var
  Modified: boolean;
  LastValue: string;
procedure TStockInForm.FormCreate(Sender: TObject);
begin
  traCurrent.StartTransaction; //стартовать транзакцию
  Modified := False;
  actSave.Enabled := Modified;
  qryMaster.ParamByName('ID').AsInteger := RunContext.Documents[0].doc_id;
  qryMaster.Open;
  if RunContext.Documents[0].doc_id <=0 then
  begin
    qryMaster.Insert; {Начальные значения полей нового документа}
    qryMaster.FieldByName('DIR_ID').AsInteger := RunContext.dir_id;
    qryMaster.FieldByName('DOC_KIND').AsInteger := 0;
    qryMaster.FieldByName('CALC_MODE').AsInteger := 1;
    qryMaster.FieldByName('DOC_DATE').AsDateTime := Date;
    qryMaster.FieldByName('HAS_ENTRY').AsInteger := 1;
    qryMaster.FieldByName('ENTRY_DATE').AsDateTime := Date;
    qryMaster.FieldByName('VAT_RATE').AsCurrency := 20;
    qryMaster.FieldByName('TOTAL_L').AsCurrency := 0;
    qryMaster.FieldByName('TOTAL_S').AsCurrency := 0;
    qryMaster.FieldByName('TOTAL_R').AsCurrency := 0;
    qryMaster.FieldByName('CONTRAGENT').AsInteger := 0;
    qryMaster.FieldByName('STOCK_ACC').AsInteger := 1007; //Главный склад
    qryMaster.FieldByName('ACC_ID').AsInteger := 1012; //Поставщики
    if StockInHeaderForm.ShowModal <> mrOK then
      Timer1.Enabled := True;
  end;
  if Timer1.Enabled then
    exit;
  self.Caption := NameOfDocument('STOCK_IN', qryMaster.FieldByName('ID').AsInteger,
      traCurrent); //устанавливаем новый заголовок формы
qryDetail.ParamByName('ID').AsInteger := RunContext.Documents[0].doc_id;
  qryDetail.Open;
end;
procedure TStockInForm.actHeaderExecute(Sender: TObject);
begin
   if StockInHeaderForm.ShowModal = mrOK then
      self.Caption := NameOfDocument('STOCK_IN', qryMaster.FieldByName('ID').AsInteger,
         traCurrent); //устанавливаем новый заголовок формы
end;
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;
  actSave.Enabled := Modified;
  RefreshExplorer; //пересветить "Проводник по документам"
  RefreshBalance;  //пересветить "Баланс"
end;
procedure TStockInForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if Modified then
  case MessageDlg(
      'Сохранить изменения в документе ?', mtConfirmation,
      mkSet(mbYes, mbNo, mbCancel), 0) of
  mrYes: actSaveExecute(nil); //вызов обработчика OnExecute команды actSave
  mrCancel: Canclose := False;
  end;
end;
procedure TStockInForm.qryMasterAfterPost(DataSet: TDataSet);
begin
  Modified := True;
  actSave.Enabled := Modified;
end;
procedure TStockInForm.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  Modified := False;
  actSave.Enabled := Modified;
  Self.Close;
end;
var
  lock_insert: boolean;
procedure TStockInForm.qryDetailAfterInsert(DataSet: TDataSet);
begin
  if not lock_insert then
  begin
    lock_insert := True;
    qryDetail.Cancel; //отменяем режим вставки
    qryDetail.Append; //вставляем в конец набора
    LastValue := '';
    dbgDetail.SelectedField := qryDetail.FieldByName('ITEM_NAME');
                     //перемещаем фокус ввода в поле наименования
  end;
  lock_insert := False;
end;
procedure TStockInForm.qryDetailCalcFields(DataSet: TDataSet);
begin
  with DataSet do
    FieldByName('NUM').AsInteger := RecNo;
end;
procedure TStockInForm.qryDetailAfterDelete(DataSet: TDataSet);
begin
  Modified := True;
  DataSet.Close;
  DataSet.Open;
  actSave.Enabled := Modified;
end;
procedure TStockInForm.dbgDetailEditButtonClick(Sender: TObject);
begin
  with RefDialog1 do
  if Execute then //вызываем диалог на экран и проверяем, был ли выбран товар
  begin
    qryDetail.Edit; //переводим набор данных в режим редактирования
    {присваиваем значение ID товара полю GOODS набора}
    qryDetail.FieldByName('GOODS').AsInteger := Object_ID;
    {присваиваем значение краткое наименование товара полю ITEM_NAME набора}
    qryDetail.FieldByName('ITEM_NAME').AsString :=
                  NameOfRefObject(Object_ID, 'SHORT_NAME');
    {перемещаем фокус ввода в сетке в поле "Количество"}
    dbgDetail.SelectedField := qryDetail.FieldByName('QUANTITY');
  end;
end;
procedure TStockInForm.dsrDetailDataChange(Sender: TObject; Field: TField);
begin
  if (Field <> nil) and
     ((Field.FieldName = 'PRICE_L') or
      (Field.FieldName = 'PRICE_L_WO_VAT') or
      (Field.FieldName = 'QUANTITY'))then
  with qryDetail do
  begin
    {Если режим расчета сумм на основе цен с НДС
    и изменено поле "Цена с НДС"  или "Количество"}
    if ((Field.FieldName = 'PRICE_L')  or (Field.FieldName = 'QUANTITY')) and
       (qryMaster.FieldByName('CALC_MODE').AsInteger = 1) then
    begin
      FieldByName('AMOUNT_L').AsCurrency :=
        FieldByName('PRICE_L').AsCurrency *
        FieldByName('QUANTITY').AsInteger;
      FieldByName('PRICE_L_WO_VAT').AsCurrency :=
          round(FieldByName('PRICE_L').AsCurrency * 1000 * 100/
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
      FieldByName('PRICE_R').AsCurrency :=
          FieldByName('PRICE_L').AsCurrency *
          qryMaster.FieldByName('EXCH_RATE_L').AsCurrency;
      FieldByName('PRICE_R_WO_VAT').AsCurrency :=
          round(FieldByName('PRICE_R').AsCurrency * 1000 * 100/
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
      FieldByName('AMOUNT_R').AsCurrency :=
          round(FieldByName('PRICE_R').AsCurrency *
          FieldByName('QUANTITY').AsInteger);
    end
    else
    {Если режим расчета сумм на основе цен без НДС и
    изменено поле "Цена без НДС" или "Количество"}
    if ((Field.FieldName = 'PRICE_L_WO_VAT')   or (Field.FieldName = 'QUANTITY')) and
       (qryMaster.FieldByName('CALC_MODE').AsInteger = 0) then
    begin
      FieldByName('AMOUNT_L').AsCurrency :=
        round(FieldByName('PRICE_L_WO_VAT').AsCurrency * 10 *
          FieldByName('QUANTITY').AsInteger *
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
      FieldByName('PRICE_L').AsCurrency :=
        round(FieldByName('PRICE_L_WO_VAT').AsCurrency * 10 *
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
      FieldByName('PRICE_R_WO_VAT').AsCurrency :=
          FieldByName('PRICE_L_WO_VAT').AsCurrency *
          qryMaster.FieldByName('EXCH_RATE_L').AsCurrency;;
      FieldByName('PRICE_R').AsCurrency :=
          round(FieldByName('PRICE_R_WO_VAT').AsCurrency * 10 *
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
      FieldByName('AMOUNT_R').AsCurrency :=
          round(FieldByName('PRICE_R_WO_VAT').AsCurrency * 10 *
          FieldByName('QUANTITY').AsInteger *
          (qryMaster.FieldByName('VAT_RATE').AsCurrency + 100))/1000;
    end;
    {Расчет суммы в долларах}
    FieldByName('AMOUNT_S').AsCurrency :=
             FieldByName('AMOUNT_L').AsCurrency *
             qryMaster.FieldByName('EXCH_RATE_L').AsCurrency/
             qryMaster.FieldByName('EXCH_RATE_S').Ascurrency;
  end;
end;
procedure TStockInForm.qryDetailBeforePost(DataSet: TDataSet);
begin
  qryDetail.FieldByName('ID').AsInteger := qryMaster.FieldByName('ID').AsInteger;
end;
procedure TStockInForm.dsrMasterDataChange(Sender: TObject; Field: TField);
begin
  {устанавливаем видимость колонок цены, в зависимости от режима расчета сумм}
  dbgDetail.Columns[3].Visible := qryMaster.FieldByName('CALC_MODE').AsInteger=1;
  dbgDetail.Columns[4].Visible := not dbgDetail.Columns[3].Visible;
end;
{Поиск по нажатию любой клавиши в сетке позиций}
procedure TStockInForm.dbgDetailSetEditText(Sender: TObject; ACol, ARow: Integer;
     const Value: String);
var
  s: string;
begin
  if Value = LastValue then
    exit; //защита от повторного поиска по тем же признакам
  if dbgDetail.SelectedField <> qryDetail.FieldByName('ITEM_NAME') then
    exit; //ограничение поиска нажатием клавиш в поле "Наименование"
  LastValue := Value;
  {Конструирование запроса из строки признаков, разделенных пробелами}
  s := 'SELECT O1.OBJECT_ID, O1.SHORT_NAME'#13+
       'FROM GOODS G, OBJECT_NAMES O1'#13+
       'WHERE G.ID = O1.OBJECT_ID AND O1.OBJECT_ID <> 0';
  if Value <> '' then
    s:=Format('%s AND'#13'%s',[s, StrToVarcharFilter('O1.SHORT_NAME','',Value)]);
  ResetCurrentTime; //сброс счетчика времени
  {включение светодиода в статусной строке Allegro}
  StatusBarDisplay(clLime,0,0,0,'','','');
  with qryGoods do
  begin
    Close;
    SQL.Text := s;
    Open; //открытие запроса
  end;
  {отображение в статусной строке времени, затраченного на поиск}
  StatusBarDisplay(clBlack,0,0,0,GetCurrentTimeStr,'','');
end;
{Нажатие клавиш Enter в списке позиций}
procedure TStockInForm.dbgDetailKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = 13) and not qryGoods.IsEmpty then
    dbgGoods.SetFocus; //Перемещение фокуса ввода в нижний список
end;
{Копирование позиции из нижнего списка товаров двойным щелчком мыши}
procedure TStockInForm.dbgGoodsDblClick(Sender: TObject);
begin
  qryDetail.Edit; {Присвоение значений полям позиции}
  qryDetail.FieldByName('GOODS').AsInteger :=
     qryGoods.FieldByName('OBJECT_ID').AsInteger;
  qryDetail.FieldByName('ITEM_NAME').AsString :=
     qryGoods.FieldByName('SHORT_NAME').AsString;
  LastValue := qryDetail.FieldByName('ITEM_NAME').AsString;
  dbgDetail.SelectedField := qryDetail.FieldByName('QUANTITY');
  dbgDetail.SetFocus; //Возвращение фокуса ввода в сетку позиций
end;
procedure TStockInForm.dbgGoodsKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = 13 then
    dbgGoodsDblClick(nil) // Выбор и добавление товара в сетку позиций на Enter
  else if Key = 27 then
    dbgDetail.SetFocus; //Простое возвращение фокуса ввода в сетку позиций на Esc
end;
procedure TStockInForm.actReportExecute(Sender: TObject);
begin
  XLReport1.Report;
end;
{Отображение прогресса в статусной строке}
procedure TStockInForm.xlReport1Progress(Report: TxlReport; const Position, Max: Integer);
begin
  if Position = 0 then
    StatusBarDisplay(clBlack, Position, 0, Max, '', '', '')
  else
    StatusBarDisplay(clLime, Position, 0, Max, '', 'Экспорт в Excel...', '');
end;
end.
unit stock_in_header;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls,RxDBComb, AlgCtrls, RXDBCtrl, DBCtrls,RxLookup,IBQuery, DB;
type
  TStockInHeaderForm = class(TForm)
    ButtonPanel: TPanel;
    btnOK: TButton;
    btnCancel: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    cbxDOC_KIND: TRxDBComboBox;
    edDOC_DATE: TDBDateEdit;
    cbxSTOC_ACC: TRxDBLookupCombo;
    edDOC_NO: TDBEdit;
    aedACC_ID: TDBAccountEdit;
    edVAT_RATE: TDBEdit;
    refCONTRAGENT: TDBRefEdit;
    edEXCH_RATE_S: TDBEdit;
    cbxLAYER_ID: TDBLayerComboBox;
    edEXCH_RATE_L: TDBEdit;
    edENTRY_DATE: TDBDateEdit;
    cbHAS_ENTRY: TDBCheckBox;
    rgCALC_MODE: TDBRadioGroup;
    qryStocks: TIBQuery;
    dsrStocks: TDataSource;
    procedure FormShow(Sender: TObject);
    procedure btnOKClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  StockInHeaderForm: TStockInHeaderForm;
implementation
uses
  stock_in;
{$R *.DFM}
procedure TStockInHeaderForm.FormShow(Sender: TObject);
begin
  qryStocks.Open;
end;
procedure TStockInHeaderForm.btnOKClick(Sender: TObject);
begin
  with StockInForm.qryMaster do
  if InSet(State, MkSet(dsEdit, dsInsert)) then
  begin
    Post;
    RunContext.Documents[0].doc_id := FieldByName('ID').AsInteger;
  end;
  self.ModalResult := mrOK;
end;
procedure TStockInHeaderForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  with StockInForm.qryMaster do
  if InSet(State, MkSet(dsEdit, dsInsert)) then
    Cancel;
end;
end.


Пример создания склада в Allegro Наверх