DBPush

 *  Функция: DBPush([<cAlias>], [<xOrder>], [<cFilter>],;
 *                  [<aScope>], [<aRelations>], [<LAdd>], [<nRecNo>], [<lNoStek>])
 *
 *  Назначение: Сохраняет все текущие физические "элементы состояния" рабочей
 *              области, такие как: алиас, текущий тег, текущий фильтр, Scope,
 *              реляции, номер записи, анализируя, были ли они установлены
 *              каждый в отдельности и устанавливает новые если заданы
 *              соответствующие параметры. Если какой-либо параметр не задан
 *              то значение соответствующего "элемента состояния" остается
 *              прежним. Если необходимо снять текущие фильтр, Scope или
 *              реляции то вместо соответствующего параметра надо передать
 *              любое пустое значение кроме NIL: ("", {}, 0, .F.).
 *              Все параметры опциональны.
 *
 *  Параметры:
 *
 *      <cAlias> - новый алиас (символьная строка).
 *
 *      <xOrder> - номер или имя нового тэга (число или символьная строка).
 *
 *     <cFilter> - новое выражение фильтра (символьная строка).
 *
 *      <aScope> - массив из двух, трех или четырех элементов соответствующих
 *                 параметрам функции SetScope(), структура:
 *
 *                 {<cScope>, <xScope>, [<xScope1>], [<aOrder>]} .
 *
 *  <aRelations> - новые реляции в виде массива подмассивов из двух элементов,
 *                 подмассивов может быть несколько, структура:
 *
 *                 { {<xLinkArea>, <cLinkExpr>},... }
 *
 *                 где:
 *                      <xLinkArea> - номер или алиас рабочей области для
 *                                    реляции (число или символьная строка).
 *                      <cLinkExpr> - выражение реляции (символьная строка);
 *                 Возможен вариант когда этот параметр строка используемая
 *                 для реляции.
 *        <LAdd> - если задан то реляции добавляются к существующим.
 *                 Этот параметр для совмещения со складским модулем
 *                 может быть алиасом связной таблицы.
 *      <nRecNo> - новый номер записи (число).
 *     <lNoStek> - не сохраняется в стек DBStatus, а сбрасывается в массив.
 */

 FUNCTION DBPush( cAlias, xOrder, cFilter, aScope, aRelations, LAdd, nRecNo, lNoStek )
   LOCAL IsNoAli     := Y_Nil( cAlias ),;
         IsNoOrd     := Y_Nil( xOrder ),;
         IsNoFil     := Y_Nil( cFilter ),;
         IsNoScp     := Y_Nil( aScope ),;
         IsNoRel     := Y_Nil( aRelations ).OR. (VALTYPE(aRelations)=="A".AND.LEN(aRelations)==0) ,;
         IsNoRec     := Y_Nil( nRecNo ),;
         IsNoStk     := Y_Nil( lNoStek )
   LOCAL aOldStat
   LOCAL IsAnotherAlias
   LOCAL xT
   LOCAL nLen
   LOCAL i := 1
   IF !IsNoScp.AND.LEN(aScope)>4.AND.VALTYPE(aScope[4])="L".AND.VALTYPE(aScope[5])="A"
     aScope[4]:=aScope[5] //titov - когда приходит из запомненного aScope
   ENDIF
   aOldStat :=  DBSave()
   IF EMPTY(lNoStek)
     IsAnotherAlias := !IF( IsNoAli, IsNoAli, aOldStat[1] == UPPER(cAlias) )
     // 9 .F. если незадан алиас или оно не совпадает с текущим
     AADD( aOldStat, IsAnotherAlias)
     AADD( DBStatus, aOldStat)
     // Если заданный алиас не совпадает с текущим то сохраняем текущий и заданный
     IF( !IsAnotherAlias, NIL, ( DBSelectArea( cAlias ), DBPush()) )
       IF( IsNoRel, NIL,;
          ( xT := { EMPTY(aRelations), Y_Type(aRelations, "A"), EMPTY(LAdd), Y_Type(aRelations, "C") .AND. Y_Type(LAdd, "C") },;
          IF( !( xT[1] .OR. ( xT[2] .AND. xT[3] ) .OR. xT[4]), NIL, DBClearRelation());
          );
          )
         IF( IsNoFil, NIL, DBClearFilter())
           IF( IsNoScp, NIL, SetScope())
             IF( IsNoOrd, NIL, OrdSetFocus(xOrder))
               IF( IsNoScp, NIL,;
                  IF( EMPTY(aScope), NIL,;
                  IF( !( Y_Type( aScope, "A") .AND. ( nLen := LEN( aScope ) ) > 1), NIL,;
                  SetScope( aScope[1],;
                  aScope[2],;
                  IF( nLen < 3,;
                  NIL,;
                  aScope[3];
                  ),;
                  IF( nLen < 4,;
                  NIL,;
                  aScope[4];
                  ),,IF(!IsNoOrd,.T.,NIL);
                  );
                  );
                  );
                  )
                 IF( IsNoFil, NIL, IF( EMPTY(cFilter), NIL, DBSETFILTER( &("{||" + cFilter + "}"), cFilter)))
                   IF( IsNoRel, NIL,;
                      IF( xT[1] .OR. !xT[2],;
                      IF( !xT[1] .AND. xT[4],;
                      DBSetRelation( LAdd, &("{|| "+aRelations+"}"), aRelations ),;
                      NIL;
                      ),;
                      AEVAL( aRelations,;
                      {|x, i| DBSetRelation(x[1], &("{||" + x[2] + "}"), x[2])};
                      );
                      );
                      )
                     IF( PCOUNT() == 0, NIL, IF( IsNoRec, DBGOTOP(), DBGOTO(nRecNo) ) )
                     ENDIF
                     RETURN IF( IsNoStk, NIL, aOldStat )