// Copyright (c) 1993-2005 "Компания БЭСТ". Все права сохраняются.
#DEFINE PLOCAL LOCAL
#DEFINE SLOCAL LOCAL
#translate Bs_KeyNo(<cTag>) => IF(<cTag>==NIL,OrdKeyNo(),OrdKeyNo(<cTag>))
#translate Bs_KeyNo() => OrdKeyNo()


/***********************************

    SetScope(cScope,xScope,xScope1,aOrder) - задание ключевого интервального фильтра

    SetScope() - отмена

    cScope      - выражение для ключевой фильтрации в виде символьной строки
                для вычисления (путем макроподстановки) значения ключа при
                фильтрации

    xScope      - значение ключа для ключевой фильтрации, т.е.
                уставливается фильтр &(cScope)==xScope для ключа или
                значение нижней границы ключа,если xScope1!=NIL

    xScope1     - значение верхней границы ключа,если xScope1!=NIL,
                то устанавливается фильтр на интервал: xScope...xScope1

    aOrder      - массив ордеров на которые распространяется SetScope
                  NIL -  Все
                  {'TAG_NNDOC'} - первый и т.д.

    lAdd        - если .T., то осуществляется добавление к текущему SetScope()
                  используется для установки различных граничных условий
                  по различным tag'ам

       ТЕПЕРЬ ВОЗМОЖНО УСТАНОВКА РАЗЛИЧНЫХ УСЛОВИЙ ДЛЯ РАЗНЫХ ТЭГОВ
                С НОРМАЛЬНЫМ ВОССТАНОВЛЕНИЕМ И ОЧИСТКОЙ !!

  При применении ключевой фильтрации следует следить, чтобы при любом tag'е
  который может выбрать пользователь, выражение cScope являлось
  старшей частью ключа.

*************************/


STATIC aScope:={}

//--------------------------------------------------------------------------//
FUNCTION SetScope( cScope, xScope, xScope1, aOrder, lAdd )
//--------------------------------------------------------------------------//
PLOCAL nArea := SELECT(), j, cTag := OrdName()
PLOCAL oldScope := IF( LEN(aScope) >= nArea, aScope[nArea], NIL )
PLOCAL aNewScope
IF nArea > 0
   IF nArea > LEN( aScope )
     ASIZE( aScope, nArea )
   ENDIF
   aNewScope :=IF(cScope==NIL,NIL,IF(VALTYPE(cScope)=='A',(ASIZE(cScope,6),IF(cScope[6] = NIL,cScope[6] :=IF(lAdd != NIL.AND.lAdd.AND.ValType(oldScope) = "A",oldScope,0),NIL),cScope),{ cScope, xScope, xScope1, .F. ,aOrder,IF(lAdd != NIL.AND.lAdd.AND.ValType(oldScope) = "A",oldScope,0)} ) )
   IF ValType( aNewScope ) == 'A'
     cScope  := aNewScope[ 1 ]
     xScope  := aNewScope[ 2 ]
     xScope1 := aNewScope[ 3 ]
     aOrder  := aNewScope[ 5 ]
     IF ValType(aNewScope[ 6 ]) = 'A'
       SetScope(aNewScope[ 6 ],,,,.T.)
     ENDIF
   ELSE
     cScope := xScope := xScope1 := NIL
   ENDIF
   aScope[ nArea ] := aNewScope

   IF ValType( aOrder ) <> 'A'
      // замена этого цикла лежит в _hrdd.prg
      aOrder := ORDList(xScope)
/****
         j := 1
         aOrder := {}
         DO WHILE !EMPTY( OrdName(j) )
           IF xScope = NIL .OR. ValType( xScope ) == ValType( &(OrdKey( j ))  )
             AADD( aOrder, OrdName(j) )
           ENDIF
           j++
         ENDDO
*****/
   ENDIF

   FOR j := 1 TO LEN( aOrder )
       // Поставим на все НУЖНЫЕ теги
       OrdSetFocus( aOrder[j] )

     IF  cScope == NIL // НЕТ SCOPE
           OrdScope( 0,)
           OrdScope( 1,)
     ELSE
         IF xScope <> NIL
            OrdScope( 0, xScope )
         ELSE
            OrdScope( 0, NIL )
         ENDIF

         IF xScope1 <> NIL
            OrdScope( 1, xScope1 )
         ELSEIF xScope <> NIL
                OrdScope( 1, xScope )
         ELSE
            OrdScope( 1, NIL )
         ENDIF
     ENDIF
   NEXT
   OrdSetFocus( cTag )
ENDIF
RETURN( oldScope )

FUNCTION GetScope()
PLOCAL nArea:=SELECT()
RETURN IF( LEN(aScope) >= nArea, aScope[nArea], NIL )

FUNCTION ScopeBlock(cOrder) //Возвращает условие Scope в виде блока кода
RETURN &("{||"+BlockScope(@cOrder)+"}")

FUNCTION ScopeMacro(cOrder) //Возвращает условие Scope в виде символьной строки
RETURN BlockScope(@cOrder)
//-------------------------------------------------------------------------//
            STATIC FUNCTION BlockScope(cOrder,aTScope,cScope)
//-------------------------------------------------------------------------//
PLOCAL nArea:=SELECT()
PLOCAL lYes:=!(LEN(aScope)<nArea.OR.aScope[nArea]==NIL)
IF(ValType(cOrder) = "C",NIL,cOrder := ORDNAME())
IF lYes
  IF aTScope = NIL
    aTScope := aScope[nArea]
  ENDIF
  IF aTScope[5] = NIL .OR. ASCAN(aTScope[5],{|cSOrder| UPPER(cSOrder) == UPPER(cOrder) }) != 0
    IF aTScope[3] = NIL
      cScope := aScope[nArea,1]+"="+LockStrF(aScope[nArea,2],'Полный')
    ELSE
      cScope := aScope[nArea,1]+">="+LockStrF(aScope[nArea,2],'Полный')
      cScope += ".AND."+aScope[nArea,1]+"<="+LockStrF(aScope[nArea,3],'Полный')
    ENDIF
    IF ValType(aTScope[6]) = "A"
      BlockScope(@cOrder,aTScope[6],@cScope)
    ENDIF
    RETURN (cScope)
  ELSEIF ValType(aTScope[6]) = "A"
    BlockScope(@cOrder,aTScope[6],@cScope)
  ENDIF
ENDIF
RETURN '.T.'

FUNCTION dCloseArea()
PLOCAL nArea:=SELECT()
DBCLOSEAREA()
IF LEN(aScope) >= nArea .AND. aScope[nArea] <> NIL
   aScope[nArea] := NIL
ENDIF
RETURN(NIL)

FUNCTION dCloseAll()
  LOCAL bError := ErrorBlock( {|oError| BREAK(oError) } )
  BEGIN SEQUENCE
    aScope:={}
    DBCLOSEALL()
  END SEQUENCE
  ErrorBlock( bError )
RETURN(NIL)
//--------------------------------------------------------------------------//
                       FUNCTION dIndexKey(n)
//--------------------------------------------------------------------------//
PLOCAL cRet := IndexKey(n)
IF RIGHT(cRet,5) == '+"  "'
  RETURN LEFT(cRet,LEN(cRet)-5)
ENDIF
RETURN cRet
//--------------------------------------------------------------------------//
                       FUNCTION dOrdKey(cOrderName,cBagName)
//--------------------------------------------------------------------------//
PLOCAL cRet := ORDKEY(cOrderName,cBagName)
IF RIGHT(cRet,5) == '+"  "'
  RETURN LEFT(cRet,LEN(cRet)-5)
ENDIF
RETURN cRet
//-----------------------------------------------------------------------------//
FUNCTION ScopeCount(cTag)
//-----------------------------------------------------------------------------//
// Возвращет кол-во записей входящих в SCOPE
PLOCAL nRec := RECNO()
PLOCAL nCount
If IndexOrd() == 0
 nCount := LastRec()
Else
 IF cTag != NIL
   cTag := ORDSETFOCUS(cTag)
 ENDIF
 dbGoBottom()
 nCount := Bs_KeyNo(cTag)
 dbGoTop()
 nCount -= Bs_KeyNo(cTag)-1
 IF cTag != NIL
   cTag := ORDSETFOCUS(cTag)
 ENDIF
 dbGoTo(nRec)
EndIf
RETURN nCount
//--------------------------------------------------------------------------//
                        FUNCTION _Bs_Tags()
//--------------------------------------------------------------------------//
// Возвращает список teg
PLOCAL j := 1
PLOCAL aOrder := {}
DO WHILE !EMPTY( OrdName(j) )
  AADD( aOrder, OrdName(j) )
  j++
ENDDO
RETURN aOrder
