Ввести на основании

Готовые скрипты, модули расширений, динамические библиотеки и вспомогательные утилиты.
Аватара пользователя
Владимир
Администратор
Сообщения: 600
Зарегистрирован: 10 фев 2018, 18:27
Откуда: Белгород
Контактная информация:

Ввести на основании

Сообщение Владимир » 05 сен 2019, 11:43

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


Изображение Изображение

Параметры и опции:

Ввести на основании - имя документа создаваемого на основании текущей записи (может быть указана текущая форма).

Заполнить поля:
  • Поле текущей формы - выбор поля предназначенного для копирования в поле формы назначения.
  • (или) Выражение - выражение, вычисляемое в контексте формы-источника. Может использоваться вместо Поля текущей формы совместно с функциями выражений. Имеет приоритет перед Полем текущей формы (если указано выражение - выбранное Поле текущей формы игнорируется)
  • Поле формы назначения - выбор поля в форме назначения для помещения в него значения Поля текущей формы или результата Выражения.
Копировать данные таблиц:
  • Табл.-источник - выбор таблицы текущей формы.
  • Поле - выбор полей текущей формы для копирования в таблицу назначения.
  • Табл. назначения - выбор таблицы формы назначения.
  • Поле - выбор полей формы назначения
Вычислить выражение в форме назначения - заполненное выражение будет вычислено в контексте формы назначения.

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

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

Код: Выделить всё

    {@module
    author=Develop-Soft [ https://forum.develop-soft.ru ]
    version=2.0
    description=Типовые учетные операции
    Действия:
    1. Ввести на основании - действие кнопки. Создает новый документ на основании
    текущего, заполняет поля и копирует данные таблиц (поддерживается 2 таблицы).

    Изменения:
    v 1 от 05.09.2019 - выход первой версии
    v 1.1 от 13.09.2019 - добавлен параметр "Цикличный ввод"
    v 2.0 от 15.09.2019
    - В "заполнить поля" добавлено поле ввода выражения (вычисляется в форме-источнике).
    - Добавлено неограниченное количество копируемых таблиц
    - Добавлено поле ввода выражения для вычисления в форме назначения.
    ...
    @}

    {@action
    ID=7AE392AD-BA54-431D-A85B-3C47D9322DAF
    Target=button
    OrigName=EnterOnBasis
    Name=Ввести на основании
    Group=Типовые учетные операции
    UI=<ui>
    <form name="dest_frm" caption="Ввести на основании:" required="1"/>
    <grid name="_fldgrid" caption="Заполнить поля">
        <field name="src_fld" caption="Поле текущей формы"
        filter="text;number;date;time;object;checkbox,counter"/>
       <expr name="expr" caption="(или) Выражение" />
        <field name="dest_fld" caption="Поле назначения" source="dest_frm"
        filter="text;number;date;time;object;checkbox"/>
      </grid>
        <divider caption="Копировать данные таблиц:"/>
     <grid name="fields2" caption="">
      <childform name="_src2" caption="Табл.-источник" />
      <field name="destfield2" caption="Поле" source="_src2"
        filter="text;number;date;time;object;checkbox" required="1"/>
      <childform name="_dest2" caption="Табл. назначения" source="dest_frm" />
        <field name="srcfield2" caption="Поле" source="_dest2"
        filter="text;number;date;time;object;checkbox" required="1"/>
      </grid>
      <expr name="DstFmExpr" caption="Вычислить выражение в форме назначения:" source="dest_frm"/>
      <divider caption="Дополнительно:"/>
      <text name="_FName" Caption="Собственный заголовок окна">
      <checkbox name="circle" caption="Цикличный ввод на основании">
      <divider/>
    </ui>
    Description=
    <b>Ввести на основании - действие кнопки.<br>Создает новый документ на основании
    текущего, заполняет поля и копирует данные подчиненных форм (таблиц)</b><br><br><br>
    <b>Параметры и опции:</b><br><br>
    <b>Ввести на основании</b> - имя документа создаваемого на основании текущей
    записи (может быть указана текущая форма).
    <br><br>
    <b>Заполнить поля:</b><br><br>
    <ul>
    <li><b>Поле текущей формы</b> - выбор поля предназначенного для копирования в
    поле формы назначения.</li>
    <li><b>(или) Выражение</b> - выражение, вычисляемое в контексте формы-источника.
     Может использоваться вместо Поля текущей формы совместно с функциями выражений.
      Имеет приоритет перед Полем текущей формы (если указано выражение - выбранное
      Поле текущей формы игнорируется)</li>
    <li><b>Поле формы назначения</b> - выбор поля в форме назначения для помещения
    в него значения Поля текущей формы или результата Выражения.</li>
    </ul><br><br>
    <b>Копировать данные таблиц:</b> <br><br>
    <ul>
    <li><b>Табл.-источник</b> - выбор таблицы текущей формы.</li>
    <li><b>Поле</b> - выбор полей текущей формы для копирования в таблицу
    назначения.</li>
    <li><b>Табл. назначения</b> - выбор таблицы формы назначения.</li>
    <li><b>Поле</b> - выбор полей формы назначения</li>
    </ul><br><br>
    <b>Вычислить выражение в форме назначения</b> - заполненное выражение будет
    вычислено в контексте формы назначения.<br><br>
    <b>Собственный заголовок окна</b> - опция позволяет установить собственный
    заголовок для окна документа вводимого на основании.<br><br>
    <b>Цикличный ввод на основании</b> - при установке флага инициируется добавление
     документа по принципу "один за другим" после сохранения предыдущего.
     При нажатии "Отмена" или закрытии формы крестиком - цикл добавления записей
     прекращается.
    @}

    var Old_DstFmEWOS:TNotifyEvent;
        CustomFormName:string;


procedure FillTable(DstFm: TdxForm; SourceTable, DestTable: String; TablesFields: TVariantArray2d);
var
  SrcTbl, DestTbl: TdxForm;
  i: Integer;
  src, dest: String;
begin
  if (SourceTable = '') or (DestTable = '') or (Length(TablesFields) = 0)
  then Exit;
  SrcTbl := Self.Forms[SourceTable];
  DestTbl := DstFm.Forms[DestTable];
  try
    SrcTbl.DisableControls;
    DestTbl.DisableControls;
    SrcTbl.MoveFirst;
    while not SrcTbl.EOF do
    begin
      DestTbl.Append;
      for i := 0 to Length(TablesFields) - 1 do
      begin
        src := TablesFields[i][0];
        dest := TablesFields[i][1];
        DestTbl[dest] := SrcTbl[src];
      end;
      DestTbl.Post;
      SrcTbl.MoveNext;
    end;
  except
  //  debug(ExceptionParam);
  finally
    DestTbl.MoveFirst;
    DestTbl.EnableControls;
    SrcTbl.EnableControls;
  end;
end;

    procedure DstFmEWOS(Sender: TObject);
    var Ew:TEditWindow;
        S:string;
    begin
    if Old_DstFmEWOS<>nil then Old_DstFmEWOS(Sender);
    Ew := TEditWindow(Sender);
    if Trim(CustomFormName)<>'' then
    S := CustomFormName else
    S:= Ew.Form.FormCaption;
    Ew.Top:=Ew.Top+30;
    Ew.Left:=Ew.Left+30;
    Ew.Caption:= S + ' (Ввод на основании)';
    end;

    function EnterOnBasis(
        DestForm:string;
        Fields, Tables: TVariantArray2d;
        DstFmExpr,
        FName:string;
        CirceCreate:integer
        ):integer;
    var
      DstFm: TdxForm;
      i,j, RecId: Integer;
      dest, expr, src: String;
      ExprResult:variant;
      ModalResult:integer;
      SL,SL2, SL3:TStringList;
      ST,STF,DT,DTF:string;
      TablesFields: TVariantArray2d;

    begin
      result:=0;
      if (Self.State=dsInsert) then
      begin
      MsgBox('Ввести на основании: ошибка!',
      'Для корректного "ввода на основании" необходимо предварительно сохранить запись');
      exit;
      end;
      if Self.State <> dsEdit then
      if MessageDlg('Ввести на основании: "'+DestForm+'"',
      'Необходимо перевести текущую запись в режим редактирования.'+#10#10+'Продолжить?',
      mtConfirmation,[mbYes,mbCancel]) <> mrYes then
      exit;
      try
        if Self.State = dsEdit then
        if EvalExpr('MODIFIEDREC',Self)=1 then
        begin
          if MessageDlg('Ввести на основании: "'+DestForm+'"',
          'Текущая запись изменилась и будет сохранена.'+#10#10+'Продолжить?',
          mtConfirmation,[mbYes,mbCancel]) = mrYes then
            Self.Post
              else
            exit;
        end;
        Self.Edit;
        CustomFormName := FName;
        DstFm := TdxForm.Create(DestForm);
        DstFm.OpenRecord(0);
        DstFm.Append;

        for i := 0 to Length(Fields) - 1 do
        begin
          src := Fields[i][0];
          expr := Fields[i][1];
          dest := Fields[i][2];
          try
            ExprResult := EvalExpr(expr,Self);
            DstFm[dest] := ExprResult;
          except
          end;
        if ExprResult=null then
          try
            DstFm[dest] := Self[src];
          except
            Continue;
          end;
        end;


SL:=TStringList.Create;

for i := 0 to Length(Tables) - 1 do
begin
  ST := Tables[i][0];
  STF:= Tables[i][1];
  DT:= Tables[i][2];
  DTF:= Tables[i][3];
  SL.Values[ST+'*'+DT]:=SL.Values[ST+'*'+DT]+#13#10+STF+'/'+DTF;
end;

for i:=0 to SL.Count-1 do
begin
  SL2:=TStringList.Create;
  SplitStr(SL.Names[i],'*',SL2);
  ST:=SL2[0];
  DT:=SL2[1];
  SL2.Free;
  SL2:=TStringList.Create;
  SL2.Text:=trim(SL.Values[SL.Names[i]]);
  SetArrayLength(TablesFields,SL2.Count);
  for j:=0 to SL2.Count-1 do
  begin
    SL3:=TStringList.Create;
    SplitStr(SL2[j],'/',SL3);
    SetArrayLength(TablesFields[j],2);
    TablesFields[j][0]:=SL3[0]
    TablesFields[j][1]:=SL3[1]
    SL3.Free;
  end;
  FillTable(DstFm, ST, DT, TablesFields);
  SetArrayLength(TablesFields,0);
  SL2.Free;
end;
SL.Free;

        try
          EvalExpr(DstFmExpr,DstFm);
        except
        end;
        Old_DstFmEWOS:=DstFm.EditWindow.OnShow;
        DstFm.EditWindow.OnShow:=@DstFmEWOS;
        DstFm.EditWindow.ShowModal;
        if DstFm.EditWindow.ModalResult = mrOk then
        begin
          DstFm.Post;
          if DstFm.Id = Self.Id then
            begin
              RecId:=Self.Recid;
              Self.Refresh;
              Self.GotoRecord(RecId);
              Self.Edit;
            end
          else
            begin
            for i:=0 to MainWindow.Pages.PageCount-1 do
              begin
                if MainWindow.FormViews[i].Form.id = DstFm.Id then
                MainWindow.FormViews[i].Form.Refresh;
              end;
            end;
        result := 1;
        end
        else
        begin
        DstFm.Cancel;
        result := 0;
        end;
      finally
        if DstFm<>nil then
        begin
          ModalResult:=DstFm.EditWindow.ModalResult;
          DstFm.Free;
          DstFm:=nil;
        end;
        CustomFormName := '';
        if (ModalResult=mrOk) and (CirceCreate=1) then
          EnterOnBasis(
          DestForm,
          Fields, Tables,
          DstFmExpr,
          FName,
          CirceCreate
          );
        ModalResult:=0;
      end;
    end;

Скачать:
Ввести на основании v2.0b.epas
(10.44 КБ) 4 скачивания
Ввести на основании v1.1.epas
(8.97 КБ) 1 скачивание
Предыдущие версииПоказать
Ввести на основании v1.0.epas
(7.92 КБ) 36 скачиваний

Демо

Похожие расширения: "Заполнить по"


Поддержка проекта

Теги:

Аватара пользователя
Владимир
Администратор
Сообщения: 600
Зарегистрирован: 10 фев 2018, 18:27
Откуда: Белгород
Контактная информация:

Ввести на основании

Сообщение Владимир » 13 сен 2019, 18:22

Обновление:
v1.1 - добавлен "Цикличный ввод". (подробности в шапке).

Добавлены примеры в демобазе:
- Создание нескольких документов вводов на основании в одной кнопке.
- Вариант выставления счета клиенту (из формы справочника "Клиенты")
- Ввод на основании с условием (если не пустая таблица товаров в документе-основании).
- Цикличный ввод товара.

Аватара пользователя
Владимир
Администратор
Сообщения: 600
Зарегистрирован: 10 фев 2018, 18:27
Откуда: Белгород
Контактная информация:

Ввести на основании

Сообщение Владимир » 15 сен 2019, 22:06

Обновление:
v1.1:
  • Исправлены некоторые ошибки.
v2.0 beta:
(Версия несовместима со старыми модулями. Требуется повторная установка и настройка.)
  • В "заполнить поля" добавлено поле ввода выражения (вычисляется в форме-источнике).
  • Добавлено неограниченное количество копируемых таблиц
  • Добавлено поле ввода выражения для вычисления в форме назначения.
  • Добавлен вывод результата (1 - если запись "документа на основании" была сохранена и 0 - не сохранена)
Изображение

Быстрый ответ

Смайлики
:-) ;-) :-( :-[ :-D :-P O_O :bye: :good: :help: :lol: :ok: :pardon: :sorry: :yes:
Ещё смайлики…
Загрузить изображение
 
   
Ответить