// Copyright (c) 1993-2005 "Компания БЭСТ". Все права сохраняются.
//

#include "inkey.ch"
#include "fileio.ch"
#include "s_public.ch"
#include "my.ch"
#include "achoice.ch" 

#include "excel.ch"

MEMVAR aDisp1,lHardHead,lHardKart,PrivateFormat

#define COMPILE(cExpr) &('{||'+cExpr+'}')

#define DOS_MODE nSelectMode==1
#define WIN_MODE nSelectMode==2
#define EXCEL_MODE (nSelectMode==3.OR.nSelectMode==4)
#define EXCEL_DRILL nSelectMode==4
#define WORD_MODE nSelectMode==5
#define XML_MODE nSelectMode==6
#define OOC_MODE nSelectMode==7
#define OOW_MODE nSelectMode==8
#define EXCEL_OOC_MODE (nSelectMode==3.OR.nSelectMode==4.OR.nSelectMode==7)


STATIC nHeadColor := 15, nItogoColor := 37

#define FTELL(handle)  fseek(handle, 0, FS_RELATIVE)
STATIC sYesSyn := 'Да '                 // пеpеменная для вывода лог. .T.
STATIC sNoSyn  := 'Hет'                 // пеpеменная для вывода лог. .F.

STATIC nFields, nGroup := 0, aTotal, nNum := 0, nUnit, nStrWid := 0, aTotVal, aTotLine,aTotSheet,aGroupLine,aGroupSheet,aTotFields, aTotFields0, aBlockPicture
STATIC nDone            := 0, nDoneExcel:=0 ,xDif      // strings written
STATIC lRunPlugInsPrint := .F.
STATIC aFieldsName, aColWidth, aPicture, aPict0, aFieldsTot, aGroup, lIsNum := .F., lIsIndicator := .F., aRazdel
STATIC bStFormat        := { || "" }
STATIC lSayHead, cPreHKey
STATIC sFormat0, sFormat, oApp, oAS, aResultCol := {}
STATIC nSelectMode := 0, nSelectFont := 8, cExcelFont := "Courier New",cSelectOrient:=" ",cListSep, cDecSep, lIsRus, cBuffer := "", nLineBuffer := 1           //nFields0
STATIC aRepHead         := {}, aRepHead1 := {}, nStage := 0, lKart := .F., lSpaceDelim := .F., lProcessFooter := .F.    //HARBOUR
STATIC cPublicFile, oDataPacket, oFields, oRowData, aRes
STATIC oStyleBold, oStyleNorm, oStyleBreak

/*   TotRep()
* RETURN: Kол-во строк записанных в файл или -1 если запись неудачна
* PARAMS:
* CHAR    aTotHdr       - Заголовок отчета (массив стpок)
* CHAR    aFieldsName[] - Массив имен переменных    /обязат./
* CHAR    aFieldsHead[] - Массив заголовков         /обязат./
* CHAR    cFormat       - Формат вывода инфоpмации /обязат./
*   должен соответствовать пpедыдущему паpаметpу aFieldsHead[]
* ВНИМАНИЕ! В cFormat могут присутствовать фрагменты (Titov - 11.03.95):
* │RRRRRRRRRRRRRRRRR│ - формат формир.автоматически под основную валюту (CURR_MAIN)
* │SSSSSSSSSSSSSSSSS│ - то же самое,только с разделительными запятыми
* │VVVVVVVVVVVVVVVVV│ - формат формир.автоматически под валюту строки базы Valuta->Accuracy
* │WWWWWWWWWWWWWWWWW│ - то же самое,только с разделительными запятыми
* │QQQQQQQQQQQQQQQQQ│ - формат формир.автоматически под кол-во десят.знаков FIELD->Kol_
* │KKKKKKKKKKKKKKKKK│ - формат формир.автоматически под кол-во десят.знаков FIELD->Kol1_
* │HHHHHHHHHHHHHHHHH│ - формат получаемый выполнением блока кода выставленого
*                       функцией SetRepFormat(блок кода возвращающий формат),
*                       в блок кода передается номер выводимой колонки и ее ширина
*                       и PICTURE по умолчанию
* NUMERIC aFieldTot[]   - Массив номеров числовых элементов из aFieldsName,
*   суммы котоpых показать в итогах
*   Итоги pассчитываются для всех числовых полей и помещаются в aTotal[]
* aGroup[]     - Массив описания групп, i-ая группа задается параметрами:
* aGroup[i][1] - Имя группового поля /обязат./
* aGroup[i][2] - Заголовок группы (может быть блоком кода,возвр.заголовок,или массивом из номеров колонок)
*                Если блок кода, то первым параметром ему передается
*                блок кода при выполнении которого на любой записи
*                базы мы можем получить признак вхождения записи
*                в текущую группу. Можно использовать для определения
*                наличия в группе более одной записи (для отказа от вывода
*                заголовка можно вернуть пустую строку) .
*                Если массив, то в качестве заголовка будут отображены значения 
*                соответствующих полей
* aGroup[i][3] - Подпись для итого по группе (может быть блоком кода,возвр.заголовок)
*                Если блок кода то ему передается
*                первый параметр : массив итоговых сумм
*                второй параметр : логическая переменная по ссылке
*                                  если ее выставить в .T., то ничего печататься в
*                                  подписе не будет (надо выводить все в блоке кода
*                                  посредством Str2File("") без указания дескриптора)
*                третий параметр :кол-во записей в группе
* aGroup[i][4] - Номер первой переменной для подсчета итого по группе
*        ...
* aGroup[i][n] - Номер n-3-ой переменной для подсчета итого по группе
* bFooter      - CodeBlock for the Footer, первый переданный параметр aTotal (суммы итого)
* cFile        - Имя файла, куда напpавить отчет
* lIsNum       - Нумеровать строки (.F.) ?
* lIsPage      - Нумеровать страницы (.F.) ?
* lIsIndicator - Показывать индикатоp хода пpоцесса (.F.) ?
* nVolume      - Пpедп. pазмеp отчета (в записях) (100% для индикатоpа)
* lContinue    - Дописать в конец существующего файла (.F.)
* aBlockPicture- Массив блоков кода возвращающих значение aFieldsName[]
*                Вывод минуя формат
* cDif         - выражение из полей, если в подряд идущих строках имеет одинаковое
                 значение, то строки не выводятся (подавляются)
* bPostBlock   - блок кода, выполняющийся после каждой выдаче строки. В нем
*                можно использовать переменную m->nKolStr1Zap: количество
*                реально сформированных строк документа (на 1 строку файла)
* bPreBlock    - блок кода выполняемый перед кажой выдачей строки
*                ему передается номер повтора для текущей записи,
*                если возвращает массив, то формирование строки
*                для текущей записи произойдет заданое число раз
*                (в первом элементе массива хранится число повторов)
* bFor         - блок кода, FOR условие
* bWhile       - блок кода, WHILE условие
* bSortKey     - блок кода, возвращающий ключ для сортировки
* bItog        - блок кода возвращающий признак участия суммы в итоге
*                ему передается номер колонки и
*                номер группы (0 - общий итог)
* lSpace       - .T. то считать разделителем в cFormat пробел и "│"
* bSkip        - блок кода для выполненения skip по базе
* bSayHead     - Блок вывода заголовка по ключу bKeyHead, если не выводить
*                то должен вернуть NIL, выполняется только при смене ключа.
*                Получает параметры текущего ключа, и предидущего.
* bKeyHead     - Блок ключа заголовка. ({|| UPPER(Grup)})
* bGHeader     - Выполняется после вывода заголовка группы // V@
* lLineEnd     - Выводить закрывающую линию или пользовательская // V@
* nSelectMode0 - Режим, если задан, то дополнительного запроса нет
***/

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function TotRep()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION TotRep( aTotHdr, a1FName, a1FieldsHead, c1Format, a1FTot, ;
                    a1Grup, bFooter, cFile, IsNum, lIsPage, IsIndicator, ;
                    nVolume, lContinue, a1BPicture, cDif, bPostBlock, bPreBlock, bFor, bWhile, ;
                    bSortKey, bItog, lSpace, bSkip, bSayHead, bKeyHead, bGHeader, lLineEnd, nSelectMode0 )

LOCAL nArea         := SELECT(), aStru := {}, cTypeVal, nDec, nLen, oRange      //HARBOUR
LOCAL i, j, k, n, cString, cColumn, nWindow := WSELECT()
LOCAL lSuccess      := .T., cTFormat, lNoRestBag := .F.
LOCAL cOrdKey       := "EVAL(_bSortKey)", bAddkey, cPreBag, nPreOrder, cTempIndex, nPreRec
LOCAL aFName        := ACLONE( a1FName )
LOCAL aFieldsHead   := ACLONE( a1FieldsHead )
LOCAL aFieldsHead1  := {}               //дополнительные строки заголовка
LOCAL cFormat       := c1Format
LOCAL aFTot         := ACLONE( a1FTot )
LOCAL aGrup         := ACLONE( a1Grup )
LOCAL aBPicture     := ACLONE( a1BPicture ), cPict
LOCAL cCreateFields, bLastHandler
LOCAL nDone0,nDone0Excel,nRecno
LOCAL aVal0, aVal, aKol0, aKol, aFormul
   //altd()

PRIVATE _bSortKey := bSortKey

   lSpaceDelim := VALTYPE( lSpace ) = "L" .AND. lSpace

   lKart := ( ( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart ) ) //.OR. lContinue != NIL )

   sFormat := sFormat0 := cFormat
   //nFields0:=LEN(aFName)
   IF( VALTYPE( aBPicture ) <> 'A', aBPicture := ARRAY( LEN( aFName ) ), )

   lIsNum := IsNum
   lIsNum := IIF( lIsNum == NIL, .F., lIsNum )

   aTotFields0 := {}
   IF VALTYPE( aGrup ) = "A" .AND. LEN( aGrup ) > 0
      FOR i := 1 TO LEN( aGrup )
         AADD( aTotFields0, {} )
         FOR j := 4 TO LEN( aGrup[ i ] )
            AADD( aTotFields0[ i ], aGrup[ i , j ] )
         NEXT
      NEXT
   ENDIF
   IF nSelectMode0 != NIL
      nSelectMode := nSelectMode0
   ELSEIF ( lContinue == NIL .OR. !lContinue ) .AND. ;
               ! Correct( @aFName, @aFieldsHead, @aFieldsHead1, @aFtot, @aGrup, @abPicture, "Standard", lContinue )
      ClearTotRepStatic()
      RETURN 0
   ENDIF

   nSelectMode0 := nSelectMode          //для возврата по ссылке

   cFormat := sFormat

   lLineEnd := IF( lLineEnd == NIL, .T., lLineEnd )         // V@

   lSayHead    := VALTYPE( bSayHead ) == "B" .AND. VALTYPE( bKeyHead ) == "B"
   cPreHKey    := NIL
   aFieldsName := aFName
   aFieldsTot  := aFTot
   aGroup      := aGrup

   lIsIndicator := IsIndicator
   aPicture     := {}                   // массив шаблонов для каждой колонки
   aColWidth    := {}                   // шиpина каждой колонки
   aRazdel      := {}                   // массив разделителей колонок

   lIsPage := IIF( lIsPage == NIL, .F., lIsPage )

   IF( VALTYPE( bFor ) = "B", NIL, bFor := { || .T. } )
   IF( VALTYPE( bWhile ) = "B", NIL, bWhile := { || .T. } )
   IF( VALTYPE( bPreBlock ) = "B", NIL, bPreBlock := { || .T. } )
   IF( VALTYPE( bPostBlock ) = "B", NIL, bPostBlock := { || .T. } )
   IF( VALTYPE( bSkip ) = "B", NIL, bSkip := { || DBSKIP() } )

   aBlockPicture := aBPicture

   RunPlugIns( "ОТЧЕТ", "ВХОД", cFile )

   nNum  := 0

   IF ( lContinue == NIL .OR. !lContinue )
      nDone := 0
      nDoneExcel:=0
   ENDIF

   PRIVATE nIndicator  // номеp индикатоpа

   WSELECT( 0 )

   IF EXCEL_MODE
      IF ( lContinue == NIL .OR. !lContinue ) .AND. !CreateExcel()
         RETURN 0
      ENDIF
   ELSEIF WORD_MODE
      IF ( lContinue == NIL .OR. !lContinue ) .AND. !CreateWord()
         RETURN 0
      ENDIF
   ELSEIF OOW_MODE
      IF ( lContinue == NIL .OR. !lContinue ) .AND. !CreateOOW()
         RETURN 0
      ENDIF
   ELSEIF XML_MODE 
      IF ( lContinue == NIL .OR. !lContinue ) .AND. !CreateXML(cFile)
         RETURN 0
      ENDIF
   ELSE
      cFile := GetFileName( cFile, lContinue )
   ENDIF

   IF lIsIndicator
      nIndicator := Proces_ini( nVolume, 14, 9, 'Формирование отчета ', 60 )
   ELSE
      Busy( .T., 'Формирование отчета ' )
   ENDIF

   DBCOMMITALL()

   IF bSortKey != NIL
      // Сортировка
      cTempIndex := TEMPFILE( _TMP_DIR, "CDX" )
      nPreOrder  := ORDNUMBER()
      nPreRec    := RECNO()
      FERASE( cTempIndex )

#ifndef AXS
      IF !EMPTY( ORDBAGNAME() ) .AND. Bs_IsTmp( ORDBAGNAME() )
         lNoRestBag := .T.
         cTempIndex := _TMP_DIR + ORDBAGNAME()
      ELSE
#endif
         cPreBag := Bs_PathName() + IF( EMPTY( ORDBAGNAME() ), ORDBAGNAME( 1 ), ORDBAGNAME() )
#ifndef AXS
      ENDIF
#endif
#ifdef SIX
      INDEX ON &( cOrdKey ) TAG MY_REPORT OF( cTempIndex ) ADDITIVE EMPTY
      bAddKey := { || Sx_KeyAdd( "MY_REPORT" ) }
#else
#ifdef CDX
      INDEX ON &( cOrdKey ) TAG MY_REPORT TO ( cTempIndex ) ADDITIVE CUSTOM
      bAddKey := { || OrdKeyAdd( "MY_REPORT" ) }
#else
      INDEX ON &( cOrdKey ) TAG MY_REPORT OF( cTempIndex ) ADDITIVE EMPTY
      bAddKey := { || IF( Ax_RLock(), ( Ax_KeyAdd( "MY_REPORT" ), DBUNLOCK() ), NIL ) }
#endif
#endif
      ORDSETFOCUS( nPreOrder )
      DBGOTO( nPreRec )
      DBEVAL( bAddKey, bFor, bWhile )
      RE_OPEN_DBF
      ORDSETFOCUS( "MY_REPORT" )
      DBGOTOP()
   ENDIF
   nFields := LEN( aFieldsName )

   // Инициализация массивов aPicture,aRazdel и aColWidth
   aPicture  := ARRAY( nFields )
   aPict0    := ARRAY( nFields )
   aColWidth := ARRAY( nFields )
   aRazdel   := ARRAY( nFields )
   i         := 1
   cTFormat  := cFormat

   TokenInit( @cFormat, "│" + IF( lSpaceDelim, " ", "" ) )

   WHILE !TokenEnd() .AND. i <= nFields
      cColumn        := TokenNext( @cFormat )
      aColWidth[ i ] := LEN( cColumn )
      aPicture[ i ]  := aPict0[ i ] := TRIM( cColumn )
      // Делаем автоматические форматы
      cPict := LEFT( LTRIM( aPict0[ i ] ), 1 )
      DO CASE
      CASE cPict = 'R' .AND. TYPE( 'CURR_MAIN' ) == 'N'
         aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), m->CURR_MAIN )

      CASE cPict = 'V' .AND. SELECT( 'VALUTA' ) > 0
         aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), Valuta->Accuracy )

      CASE cPict = 'S' .AND. TYPE( 'CURR_MAIN' ) == 'N'
         aPicture[ i ] := SummaPic( m->CURR_MAIN, LEN( aPicture[ i ] ), .T. )
      CASE cPict = 'W' .AND. SELECT( 'VALUTA' ) > 0
         aPicture[ i ] := SummaPic( Valuta->Accuracy, LEN( aPicture[ i ] ), .T. )
      CASE cPict = 'Q' .AND. SELECT( 'MGrup' ) > 0
         aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), IF( EXCEL_MODE, 4, MGrup->Kol_ ) )
      CASE cPict = 'K' .AND. SELECT( 'MGrup' ) > 0
         aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), IF( EXCEL_MODE, 4, MGrup->Kol1_ ) )
      CASE cPict = 'H'
         // Изменение denom
         aPicture[ i ] := EVAL( bStFormat, i, LEN( aPicture[ i ] ), aPicture[ i ] )
      ENDCASE

      IF i < nFields
         aRazdel[ i ] := SUBSTR( cTFormat, ATTOKEN( cTFormat, "│" + IF( lSpaceDelim, " ", "" ), i + 1 ) - 1, 1 )
      ELSE
         aRazdel[ i ] := "│"
      ENDIF

      nLen := LEN( aPicture[ i ] )
      nDec := 0
      IF EXCEL_MODE
         oAS:columns( i ) :ColumnWidth := aColWidth[ i ] + 1
         oAS:columns( i ) :VerticalAlignment := xlTop
         IF EMPTY( TRIM( CHARREM( "-0123456789.,", aPicture[ i ] ) ) )          //число
            IF !aPicture[ i ] == "99999999"                 //очень похоже на дату
               IF cPict $ "QKH"
                  oAS:columns[ i ] :Rows:NumberFormat := REPLICATE( "#", LEN( aPicture[ i ] ) - 6 ) + "0" + cDecSep + "0000"
               ELSE
                  oAS:columns[ i ] :Rows:NumberFormat := GetNumExcelPict( aPicture[ i ] )
               ENDIF
               aPicture[ i ] := STRTRAN( aPicture[ i ], ',', "" )
            ENDIF
         ELSE
            oAS:columns[ i ] :Rows:NumberFormat = "@"
         ENDIF
      ENDIF

      i ++

   ENDDO

   // Определение ширины таблицы
   nStrWid  := IIF( lIsNum, 7, 0 ) + LEN( cFormat )
   cFormat  := NIL
   cTFormat := NIL

   IF DOS_MODE .OR. WIN_MODE
      IF ( nUnit := IF( lContinue != NIL .AND. lContinue .AND. FILE( cFile ), FOPEN( cFile, 2 ), FCREATE( cFile ) ) ) == - 1                //
         SayError( 'Ошибка создания файла ' + cFile )
         CLearTotRepStatic()
         RETURN - 1
      ENDIF
      FSEEK( nUnit, 0, 2 )              // выставляем указатель на конец файла

   ELSEIF EXCEL_DRILL .AND. EMPTY( aGroup )

      aGroup := {}
      IF bFooter != NIL
         AADD( aGroup, { aFieldsName[ 1 ], { 1 }, } )       //новая возможность - массив номеров полей в качестве заголовка
         IF !EMPTY( aFTot )
            FOR j := 1 TO LEN( aFTot )
               AADD( aGroup[ LEN( aGroup ) ], aFTot[ j ] )
            NEXT
         ENDIF
      ELSE

         //   Анализ структуры
         nRecNo := RECNO()
         j      := 0

         aVal  := ARRAY( MIN( nFields, 4 ) )
         aVal0 := ARRAY( MIN( nFields, 4 ) )
         aKol  := ARRAY( MIN( nFields, 4 ) )
         aKol0 := ARRAY( MIN( nFields, 4 ) )
         AFILL( aKol, 0 )
         AFILL( aKol0, 0 )

         nLen := 0
         GO TOP
         WHILE !EOF() .AND. EVAL( bWhile ) .AND. ++ nLen < 200
            FOR i := 1 TO LEN( aVal )
               aVal[ i ] := IF( VALTYPE( aBlockPicture[ i ] ) == 'B', EVAL( aBlockPicture[ i ] ), &( aFieldsName[ i ] ) )
               IF aVal0[ i ] != NIL .AND. aVal[ i ] == aVal0[ i ]
                  aKol[ i ] ++
               ELSE
                  aVal0[ i ] := aVal[ i ]
                  aKol0[ i ] := MAX( aKol0[ i ], aKol[ i ] )
                  FOR j := i TO LEN( aVal )
                     aKol[ j ] := 0
                  NEXT
               ENDIF
            NEXT
            SKIP
         ENDDO

         FOR i := 1 TO LEN( aKol0 )
            IF ( aKol0[ i ] := MAX( aKol0[ i ], aKol[ i ] ) ) > 3
               aVal := {}
               FOR j := 1 TO i
                  AADD( aVal, j )
               NEXT
               AADD( aGroup, { aFieldsName[ i ], aVal, } )  //новая возможность - массив номеров полей в качестве заголовка
               IF !EMPTY( aFTot )
                  FOR j := 1 TO LEN( aFTot )
                     AADD( aGroup[ LEN( aGroup ) ], aFTot[ j ] )
                  NEXT
               ENDIF
            ENDIF
         NEXT
         aTotFields0 := {}
         FOR i := 1 TO LEN( aGroup )
            AADD( aTotFields0, {} )
            FOR j := 4 TO LEN( aGroup[ i ] )
               AADD( aTotFields0[ i ], aGroup[ i , j ] )
            NEXT
         NEXT

         DBGOTO( nRecNo )
      ENDIF

   ELSEIF OOC_MODE
      altd()
      IF ( lContinue == NIL .OR. !lContinue ) .AND. !CreateOOC(IF(lKart,nStrWid+10,NIL))
         RETURN 0
      ENDIF
   ENDIF

   lRunPlugInsPrint := IsRunPlugIns( "ОТЧЕТ", "ФОРМИРОВАНИЕ" )

   BEGIN SEQUENCE


      // Bывoд нaзвания

      IF (DOS_MODE .OR. WIN_MODE).OR.(lKart.AND.EXCEL_OOC_MODE)

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .T.
            lHardKart := .T.
            i         := nStrWid
         ENDIF

         IF !lKart
            AEVAL( aTotHdr, { | x | Str2File( IF( EMPTY( LEFT( x, 3 ) ), PADC( ALLTRIM( x ), nStrWid ), PADR( x, nStrWid ) ) ) } )
         ELSE
            AEVAL( aTotHdr, { | x | Str2File( x ) } )
         ENDIF
         Str2File( '' )

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .F.
            lHardKart := .F.
            nStrWid   := i
         ENDIF

         // Bывoд зaгoлoвкa стpаниц
         AEVAL( aFieldsHead, { | x | Str2File( x ) } )
         //   IF !sFormat==sFormat0
         AEVAL( aFieldsHead1, { | x | Str2File( x ) } )     //дополнительные строки заголовка
         //   ENDIF

      ELSEIF EXCEL_OOC_MODE
         // Bывoд нaзвания

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .T.
            lHardKart := .T.
         ENDIF
//altd()

         ExcelHeader( aTotHdr )
         StrToExcel( '' )

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .F.
            lHardKart := .F.
         ENDIF

         // Bывoд зaгoлoвкa стpаниц
         AEVAL( aFieldsHead, { | x | HdrToExcel( x,.T. ) } )
         AEVAL( aFieldsHead1, { | x | Str2File( x ) } )     //дополнительные строки заголовка

      ELSEIF WORD_MODE

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .T.
            lHardKart := .T.
         ENDIF

         HdrToWord( aTotHdr, lContinue )
         StrToWord( '' )

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .F.
            lHardKart := .F.
         ENDIF

         HeadToWord( aFieldsHead, lContinue )
         AEVAL( aFieldsHead1, { | x | Str2File( x ) } )     //дополнительные строки заголовка

      ELSEIF OOW_MODE

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .T.
            lHardKart := .T.
         ENDIF

         HdrToOOW( aTotHdr, lContinue )
         StrToOOW( '' )

         IF TYPE( "lHardHead" ) = "L" .AND. lHardHead
            lKart     := .F.
            lHardKart := .F.
         ENDIF

         HeadToOOW( aFieldsHead, lContinue )
         AEVAL( aFieldsHead1, { | x | Str2File( x ) } )     //дополнительные строки заголовка
      ENDIF

      IF cDif != NIL
         xDif := &( cDif )
      ENDIF

      // инициализация массива сумм по числовым полям
      aTotal := ARRAY( nFields )
      AFILL( aTotal, 0 )
      nDone0 := nDone
      nDone0Excel := nDoneExcel

      nGroup     := IIF( aGroup == NIL, 0, LEN( aGroup ) )
      aTotVal    := {}
      aTotLine   := {}
      aTotSheet  := {}
      aGroupLine := {}
      aGroupSheet:= {}
      aTotFields := {}
      IF ( nGroup > 0 )
         FOR i := 1 TO nGroup
            AADD( aTotVal, ARRAY( nFields ) )
            AADD( aTotLine, { 0, 0 } )
            AADD( aTotSheet, { 0, 0 } )
            AADD( aGroupLine, { 0, 0 } )
            AADD( aGroupSheet, { 0, 0 } )
            AFILL( aTotVal[ i ], 0 )
            AADD( aTotFields, {} )
            FOR j := 4 TO LEN( aGroup[ i ] )
               IF VALTYPE( aGroup[ i, j ] ) = "N" .AND. aGroup[ i, j ] <= LEN( aPicture ) .AND. EMPTY( TRIM( CHARREM( "-0123456789.,", aPicture[ aGroup[ i, j ] ] ) ) )             //число
                  AADD( aTotFields[ i ], aGroup[ i , j ] )
               ENDIF
            NEXT
         NEXT
      ENDIF

altd()

      // Bывoд значений
      DO WHILE !EOF() .AND. EVAL( bWhile )
         PrintGroup( 1, cDif, @bPreBlock, @bPostBlock, @bFor, @bWhile, { || .T. }, @bItog, @bSkip, 0, bSayHead, bKeyHead, bGHeader )
      ENDDO

      IF lLineEnd .AND. ( DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE .OR.(lKart.AND.EXCEL_OOC_MODE))
         cString := IIF( lIsNum, "└─────┴", "└" )
         FOR i := 1 TO nFields
            cString += REPLICATE( '─', aColWidth[ i ] ) + IF( aRazdel[ i ] = " ", "─", "┴" )
         NEXT
         cString := STUFF( cString, LEN( cString ), 1, "┘" )
         Str2File( cString )
      ENDIF

      //ИТОГО

      IF ( DOS_MODE .OR. WIN_MODE .OR. EXCEL_OOC_MODE .OR. WORD_MODE .OR. OOW_MODE )
         IF ( aFieldsTot != NIL )
            IF EXCEL_MODE.AND.!lKart
               cString := ""
               aFormul := {}
               n       := 0
               FOR i := 1 TO nFields
                  IF ( j := ASCAN( aFieldsTot, i ) ) = 0 .OR. ;
                            ! EMPTY( TRIM( CHARREM( "-0123456789.,", aPicture[ i ] ) ) )            //не число
                     IF EMPTY( cString )
                        cString := "Итого"
                     ENDIF
                     cString += CHR( K_TAB )
                  ELSE
                     IF EMPTY( n )
                        n := i
                     ENDIF
                     AADD( aFormul, { i, nDone0Excel, nDoneExcel - 1,1,oAS:index} )
                     cString += STRTRAN(TRANSFORM( aTotal[ i ], aPicture[ i ] ),".",cDecSep) + CHR( K_TAB )
                  ENDIF
               NEXT
               IF n > 0
                  XXToExcel( cString, { 1, n - 1 }, aFormul, nHeadColor )
                  IncDone()
               ENDIF
            ELSEIF OOC_MODE.AND.!lKart
               cString := ARRAY(nFields)
               aFormul := {}
               n       := 0
               FOR i := 1 TO nFields
                  IF ( j := ASCAN( aFieldsTot, i ) ) = 0 .OR. ;
                            ! EMPTY( TRIM( CHARREM( "-0123456789.,", aPicture[ i ] ) ) )            //не число
                     IF EMPTY( cString[1] )
                        cString[1]:="Итого"
                     ENDIF
                  ELSE
                     IF EMPTY( n )
                        n := i
                     ENDIF
                     AADD( aFormul, { i, nDone0Excel, nDoneExcel,1,0} ) //oAS:index
                     cString[i]:=aTotal[i]
                  ENDIF
               NEXT
               IF n > 0
                  XXToExcel( cString, {1,n - 1},aFormul,nHeadColor )
                  IncDone()
               ENDIF   
            ELSE
               cString := IIF( lIsNum, "       ", " " )
               n       := 0
               FOR i := 1 TO nFields
                  IF ( ( j := ASCAN( aFieldsTot, i ) ) > 0 )
                     IF ( n = 0 )
                        n := LEN( cString )
                     ENDIF
                     IF EMPTY( aTotal[ i ] )
                        cString += SPACE( aColWidth[ i ] ) + " "
                     ELSE
                        cString += PADC( TRANSFORM( aTotal[ i ], ;
                                         ALLTRIM( aPicture[ i ] ) ), aColWidth[ i ], " " ) + " "
                     ENDIF
                  ELSE
                     cString += SPACE( aColWidth[ i ] + 1 )
                  ENDIF
               NEXT
               IF ( n > 0 )
                  cString := STUFF( cString, MAX( 2, n - 6 ), MIN( 6, n - 1 ), PADR( "ИТОГО:", ;
                                    MIN( 6, n - 1 ) ) )
                  Str2File( cString )
                  //        StrToExcel("Итого",,.T.,.T.,n-1,nHeadColor,,.T.)
               ENDIF
            ENDIF
         ENDIF

         // Bывoд подложий
         //altd()
         IF ( bFooter != NIL )
            lProcessFooter := .T.
            IF (TYPE( "lHardHead" ) = "L" .AND. lHardHead).OR.;
               (TYPE( "lHardKart" ) = "L" .AND. lHardKart)
               lHardKart:=.T.
               lKart:=.T.
               EVAL( bFooter,aTotal )
            ELSE
               EVAL( bFooter, Reconfigure( aTotal, LEN( a1FName ) ) )
            ENDIF
            lProcessFooter := .F.
         ENDIF
      ENDIF

      IF lContinue != NIL 
         IncDone()

      ENDIF


   RECOVER USING lSuccess
   END SEQUENCE
   IF !lSuccess
      nDone := - 1
      nDoneExcel:=-1
   ENDIF

   //altd()
   IF !EMPTY( nUnit )
      FCLOSE( nUnit )
   ENDIF
   IF lIsIndicator
      Proces_end( nIndicator )
   ELSE
      Busy( .F. )
   ENDIF

   IF bSortKey != NIL
      // Сброс сортировки
      IF lNoRestBag
         DELETE TAG MY_REPORT
      ELSE
         CLOSE INDEXES
         FERASE( cTempIndex )
         IF FILE( cPreBag )
            SET INDEX TO ( cPreBag )
            ORDSETFOCUS( nPreOrder )
         ENDIF
      ENDIF
   ENDIF




   RunPlugIns( "ОТЧЕТ", "ВЫХОД", cFile )

   WSELECT( nWindow )
   lRunPlugInsPrint := .F.

   WriteBuffer()

   //altd()


RETURN nDone

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Procedure ClearTotRepStatic()
*+
*+    Called from ( outrep_h.prg )   2 - function totrep()
*+                                   3 - function str2file()
*+                                   1 - static function createexcel()
*+                                   1 - static function createword()
*+                                   1 - function winview()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
PROCEDURE ClearTotRepStatic()

   WriteBuffer()
   nFields          := 0
   nDone            :=0
   nDoneExcel       :=0
   nGroup           := NIL
   aTotal           := NIL
   nNum             := 0
   nUnit            := NIL
   nStrWid          := 0
   aTotVal          := NIL
   aTotLine         := NIL
   aTotSheet        := NIL
   aGroupLine       := NIL
   aGroupSheet      := NIL
   aTotFields       := NIL
   aTotFields0      := NIL
   aBlockPicture    := NIL
   xDif             := NIL
   lRunPlugInsPrint := .F.
   aFieldsName      := NIL
   aColWidth        := NIL
   aPicture         := NIL
   aPict0           := NIL
   aFieldsTot       := NIL
   aGroup           := NIL
   lIsNum           := .F.
   lIsIndicator     := .F.
   aRazdel          := NIL
   bStFormat        := { || "" }
   lSayHead         := NIL
   cPreHKey         := NIL
   sFormat0         := NIL
   sFormat          := NIL
   oAS              := NIL
   oApp             := NIL
   oStyleBold       := NIL
   oStyleNorm       := NIL
   oStyleBreak      := NIL
   aResultCol       := {}
   //nFields0:=NIL
   cListSep    := NIL
   cDecSep     := NIL
   lIsRus      := NIL
   nSelectMode := 0
   aRepHead    := {}                    //для внешнего входа - заголовок отчета
   aRepHead1   := {}                    //для внешнего входа - заголовок таблицы
   nStage      := 0                     //для внешнего входа этап обработки
   lKart       := .F.                   //строгая карточка
   lSpaceDelim := .F.
   cPublicFile := NIL
   oDataPacket := NIL
   oFields     := NIL
   oRowData    := NIL
   aRes        := {}
   SetExcelFormat("")
   SetDefaultProp(,,,,.F.)
RETURN

//----------------------------------------------------------------------------//

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure PrintGroup()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - static procedure printgroup()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE PrintGroup( nGNum, cDif, bPreBlock, bPostBlock, bFor, bWhile, bCondition, ;
                                bItog, bSkip, nLine, bSayHead, bKeyHead, bGHeader )
   //----------------------------------------------------------------------------//
   //   MEMVAR nIndicator
LOCAL cb            // блок кода для хpанения макpокомпил. cCondition
   // обязательно LOCAL !!
LOCAL nCont         := 0, aCont := {}, aVal := {}
LOCAL i, j, n, cType, cFStr, cString, uVal, cItogo, nItogo, cTypeCond, cGrHeader, lNoFooter, cCondition := ""
LOCAL xRet, nPoz, nPreRec, nNewPreRec
LOCAL lItog         := VALTYPE( bItog ) = "B"
LOCAL lFor          := .F.
LOCAL nIncLine      := 0
LOCAL cCurHKey, cSayH, cRazd
LOCAL cc, nDec, nDone1
LOCAL bLastHandler, nSelH, aFormul
PRIVATE nKolStr1Zap

   IF ( nGroup > 0 )
      uVal       := &( aGroup[ nGNum, 1 ] )
      cCondition += aGroup[ nGNum, 1 ] + "=="
      cTypeCond  := VALTYPE( uVal )
      cGrHeader  := ""
      DO CASE
      CASE ( cTypeCond = "C" )
         cCondition += DopScobCond( TRANSFORM( uVal, "" ) )
      CASE ( cTypeCond = "D" )
         cCondition += "CTOD([" + LTRIM( TRANSFORM( uVal, "" ) ) + "])"
      CASE ( cTypeCond = "L" )
         cCondition += "." + LTRIM( TRANSFORM( uVal, "" ) ) + "."
      CASE ( cTypeCond = "N" )
         cCondition += LTRIM( TRANSFORM( uVal, "" ) )
      ENDCASE
      cb := COMPILE( cCondition )
   ELSE

      cb := { || .T. }
   ENDIF

   nPreRec := RECNO()

   DO WHILE EVAL( cb ) .AND. EVAL( bCondition ) .AND. !EOF() .AND. EVAL( bWhile )
      IF EVAL( bFor )
         IF ( nGroup == 0 .OR. nGNum == nGroup )
            nIncLine ++
         ENDIF
         IF !lFor
            IF nGroup > 0 .AND. aGroup[ nGNum , 2 ] != NIL
               cGrHeader := IF( VALTYPE( aGroup[ nGNum, 2 ] ) != 'B', aGroup[ nGNum, 2 ], ;
                                EVAL( aGroup[ nGNum , 2 ], cb ) )
            ENDIF
            IF !EMPTY( cGrHeader )
               IF VALTYPE( cGrHeader ) == "C"
                  IF EXCEL_OOC_MODE.AND.!lKart
                     StrToExcel( cGrHeader,, .F., .T.,, nHeadColor, xlCenter )
                  ELSEIF ( DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE )
                     Str2File( "│" + PADC( cGrHeader, nStrWid - 2, "." ) + "│" )
                  ENDIF

               ELSEIF VALTYPE( cGrHeader ) == "A"           //новая возможность:номера колонок
                  IF EXCEL_MODE.AND.!lKart
                     cString := ""
                     FOR i := 1 TO nFields
                        IF !i $ cGrHeader
                           cString += XXTOC( "", i )
                        ELSE
                           cString += XXTOC( IF( VALTYPE( aBlockPicture[ i ] ) == 'B', EVAL( aBlockPicture[ i ] ), &( aFieldsName[ i ] ) ), i ) + CHR( K_TAB )
                        ENDIF
                     NEXT
                     XXToExcel( cString,,, nItogoColor )
                     //nDone++
                     IncDone()
                  ELSEIF OOC_MODE.AND.!lKart
                     cString := ARRAY(nFields)
                     FOR i := 1 TO nFields
                        IF !i $ cGrHeader
                           cString[i]:=""
                        ELSE
                           cString[i]:=IF(VALTYPE(aBlockPicture[i])=='B',EVAL(aBlockPicture[i]), &(aFieldsName[i]))
                        ENDIF
                     NEXT
                     XXToExcel(cString,,,nItogoColor )
                     //nDone++
                     IncDone()
                  ELSE
                     cString := IIF( lIsNum, "│" + STR( ++ nNum, 5 ) + "│", "│" )
                     FOR i := 1 TO nFields
                        IF !i $ cGrHeader
                           cFStr := SPACE( aColWidth[ i ] ) + aRazdel[ i ]
                           LOOP
                        ENDIF
                        cString += XXTOC( IF( VALTYPE( aBlockPicture[ i ] ) == 'B', EVAL( aBlockPicture[ i ] ), &( aFieldsName[ i ] ) ), i ) + aRazdel[ i ]
                     NEXT
                     Str2File( cString )
                  ENDIF
               ENDIF
            ENDIF

            IF bGHeader != NIL .AND. VALTYPE( bGHeader ) == 'B'
               EVAL( bGHeader )
            ENDIF
            IF nGroup > 0 .AND. EXCEL_DRILL .AND. EMPTY( aGroupLine[ nGNum, 1 ] )
               aGroupLine[ nGNum, 1 ] := nDoneExcel
               aGroupSheet[ nGNum, 1 ] := oAS:Index
            ENDIF
         ENDIF
         lFor := .T.
         IF ( nGroup == 0 .OR. nGNum == nGroup )
            IF VALTYPE( xRet := EVAL( bPreBlock, 1 ) ) != "A"
               xRet := 1
            ELSE
               xRet := xRet[ 1 ]
            ENDIF
         ELSE
            xRet := 1
         ENDIF

         FOR nPoz := 1 TO xRet

            IF ( nGroup == 0 .OR. nGNum == nGroup ) .AND. nPoz != 1
               EVAL( bPreBlock, nPoz )
            ENDIF
            IF EXCEL_MODE.AND.!lKart
               cString := ""
               FOR i := 1 TO nFields
                  cString += CHR( K_TAB ) + XXTOC( ( uVal := IF( VALTYPE( aBlockPicture[ i ] ) == 'B', EVAL( aBlockPicture[ i ] ), &( aFieldsName[ i ] ) ) ), i )
                  IF VALTYPE( uVal ) = "N" .AND. ( nGroup == 0 .OR. nGNum == nGroup )
                     IF ( nGNum == nGroup )
                        FOR n := 1 TO nGroup
                           IF ( ( j := ASCAN( aTotFields[ n ], i ) ) > 0 )
                              IF !lItog .OR. EVAL( bItog, j, n )
                                 aTotVal[ n, j ] += uVal
                                 IF EMPTY( aTotLine[ n, 1 ] )
                                    aTotLine[ n, 1 ] := nDoneExcel
                                    aTotSheet[ n, 1 ] := oAS:Index
                                 ENDIF
                                 aTotLine[ n, 2 ] := MAX( aTotLine[ n, 2 ], nDoneExcel )
                                 aTotSheet[ n, 2 ] := oAS:Index
                              ENDIF
                           ENDIF
                        NEXT
                     ENDIF
                     IF !lItog .OR. EVAL( bItog, j, 0 )
                        aTotal[ i ] += uVal
                     ENDIF
                  ENDIF
               NEXT
            ELSEIF OOC_MODE.AND.!lKart
               cString := ARRAY(nFields)
               FOR i := 1 TO nFields
                  cString[i]:=uVal:=IF(VALTYPE(aBlockPicture[i])=='B',EVAL(aBlockPicture[i]), &(aFieldsName[i]))  
                  IF VALTYPE(uVal)=="N".AND.(nGroup==0.OR.nGNum==nGroup )
                     IF ( nGNum == nGroup )
                        FOR n := 1 TO nGroup
                           IF ( ( j := ASCAN( aTotFields[ n ], i ) ) > 0 )
                              IF !lItog .OR. EVAL( bItog, j, n )
                                 aTotVal[ n, j ] += uVal
                                 IF EMPTY( aTotLine[ n, 1 ] )
                                    aTotLine[ n, 1 ] := nDoneExcel
                                    aTotSheet[ n, 1 ] := 0 //oAS:Index!!!!!!!!!
                                 ENDIF
                                 aTotLine[n,2 ] := MAX( aTotLine[ n, 2 ], nDoneExcel+1)
                                 aTotSheet[n,2] := 0 ///oAS:Index!!!!!!!!!!!
                              ENDIF
                           ENDIF
                        NEXT
                     ENDIF
                     IF !lItog .OR. EVAL( bItog, j, 0 )
                        aTotal[ i ] += uVal
                     ENDIF
                  ENDIF
               NEXT
            ELSEIF DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE.OR.(EXCEL_OOC_MODE.AND.lKart)
               IF ( nCont != 0 )
                  nCont := 0
                  aCont := {}
                  aVal  := {}
               ENDIF

               // Первая строка группы

               cString := IIF( lIsNum, "│" + STR( ++ nNum, 5 ) + "│", "│" )
               FOR i := 1 TO nFields
                  uVal:=IF(VALTYPE(aBlockPicture[i])=='B',EVAL(aBlockPicture[i]),&(aFieldsName[i]))
                  cString += XXTOC(@uVal,i) + aRazdel[i]
                  cType   := VALTYPE( uVal )
                  IF cType = "N" .AND. ( nGroup == 0 .OR. nGNum == nGroup )
                     IF ( nGNum == nGroup )
                        FOR n := 1 TO nGroup
                           IF ( ( j := ASCAN( aTotFields[ n ], i ) ) > 0 )
                              IF !lItog .OR. EVAL( bItog, j, n )
                                 aTotVal[ n, j ] += uVal
                              ENDIF
                           ENDIF
                        NEXT
                     ENDIF
                     IF !lItog .OR. EVAL( bItog, j, 0 )
                        aTotal[ i ] += uVal
                     ENDIF
                  ELSEIF cType $ "CM"
                     IF ( ( n := MLCOUNT( TRIM( uVal ), LEN( LTRIM( aPicture[ i ] ) ), 1 ) ) > 1 )
                        AADD( aCont, i )
                        AADD( aVal, uVal )
                        nCont := MAX( nCont, -- n )
                     ENDIF
                  ENDIF
               NEXT
            ELSEIF XML_MODE
               WriteXmlRow()
            ENDIF

            IF ( nGroup == 0 .OR. nGNum == nGroup )
               IF lSayHead
                  cCurHKey := EVAL( bKeyHead )
                  cSayH    := IF( cCurHKey != cPreHKey, EVAL( bSayHead, cCurHKey, cPreHKey ), NIL )
                  IF !EMPTY( cSayH )
                     IF EXCEL_OOC_MODE.AND.!lKart
                        StrToExcel( cSayH,, .F., .T.,, nHeadColor, xlCenter )
                     ELSEIF ( DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE )
                        cRazd := IIF( lIsNum, "│" + STR( ++ nNum, 5 ) + "│", "│" )
                        Str2File( cRazd + PADC( cSayH, LEN( cString ) - LEN( cRazd ) - 1 ) + "│" )
                     ENDIF
                  ENDIF
               ENDIF
               IF EXCEL_OOC_MODE.AND.!lKart
                  XXTOEXCEL( cString )
                  //nDone++
                  IncDone()
               ELSEIF DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE .OR.(lKart.AND.EXCEL_OOC_MODE)
                  Str2File( cString )
               ENDIF
               m->nKolStr1Zap := nCont + 1
               EVAL( bPostBlock )
            ENDIF
            IF lIsIndicator .AND. TYPE( "nIndicator" ) == "N"
               Proces_update( m->nIndicator )
            ENDIF
            IF DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE.OR.(lKart.AND.EXCEL_OOC_MODE)
               // Строки продолжения, если есть
               FOR n := 1 TO nCont
                  cString := IIF( lIsNum, "│     │", "│" )
                  FOR i := 1 TO nFields
                     IF ( ( j := ASCAN( aCont, i ) ) > 0 )
                        uVal    := aVal[ j ]
                        cString += PADR( SPACE( COUNTLEFT( aPicture[ i ] ) ) + MEMOLINE( uVal, ;
                                         LEN( LTRIM( aPicture[ i ] ) ), n + 1 ), aColWidth[ i ] ) + aRazdel[ i ]
                     ELSE
                        cString += SPACE( aColWidth[ i ] ) + aRazdel[ i ]
                     ENDIF
                  NEXT
                  IF ( nGroup == 0 .OR. nGNum == nGroup )
                     Str2File( cString )
                  ENDIF
               NEXT
            ENDIF
            // Вглубь, в группы, если надо
            IF ( nGroup > nGNum )
               PrintGroup( nGNum + 1, cDif, @bPreBlock, @bPostBlock, @bFor, @bWhile, { || EVAL( cb ) .AND. EVAL( bCondition ) }, @bItog, @bSkip, @nIncLine, bSayHead, bKeyHead )
            ENDIF
         NEXT
      ENDIF

      IF nGroup <= nGNum
         nPreRec := RECNO()
         IF( lSayHead, cPreHKey := EVAL( bKeyHead ), )
         EVAL( bSkip )
         //nIncLine++
         IF cDif != NIL
            DBEVAL( { || NIL }, bFor, { || &( cDif ) == xDif .AND. EVAL( bWhile ) } )
            xDif := &( cDif )
         ENDIF
      ENDIF
   ENDDO
   IF ( nGroup > 0 )

      // Вывод Total - полей
      IF lFor
         IF LEN( aTotFields[ nGNum ] ) > 0
            IF EXCEL_MODE.AND.!lKart
               cString := ""
               aFormul := {}
               n       := 0
               IF EXCEL_DRILL .AND. VALTYPE( aGroup[ nGNum, 2 ] ) = "A"         //пишем итоги в строку заголовка
                  nDone1 := nDoneExcel
                  oApp:Sheets(aGroupSheet[ nGNum, 1 ]):Activate()
                  nDoneExcel := aGroupLine[ nGNum, 1 ] - 1      //выставляемся на заголовок
                  FOR i := 1 TO nFields
                     IF ( j := ASCAN( aTotFields[ nGNum ], i ) ) > 0
                        ToExcel( i, aTotVal[ nGNum, j ], aPicture[ i ], nItogoColor )
                        IF !(TYPE("lNoFormuls")="L".AND.m->lNoFormuls).AND.oAS:index=1
                           
                           oAs:Cells( nDoneExcel, i ) :Formula := ;
                                   OEMTOANSI( IF( lIsRus, "=ПРОМЕЖУТОЧНЫЕ.ИТОГИ(9" + cListSep, "=SUBTOTAL(9" + cListSep ) + GetRange( i,, aTotLine[ nGNum, 1 ], aTotLine[ nGNum, 2 ], aTotSheet[ nGNum, 1 ], aTotSheet[ nGNum, 2 ] ) + ")" )
                        ENDIF
                     ENDIF
                  NEXT
                  nDoneExcel := nDone1
                  oAS:Activate()
               ELSE
                  
                  FOR i := 1 TO nFields
                     IF ( j := ASCAN( aTotFields[ nGNum ], i ) ) = 0
                        IF EMPTY( cString )
                           cString := "Итого"
                        ENDIF
                        cString += CHR( K_TAB )
                     ELSE
                        IF EMPTY( n )
                           n := i
                        ENDIF
                        AADD( aFormul, { i, aTotLine[ nGNum, 1 ], aTotLine[ nGNum, 2 ],aTotSheet[ nGNum, 1 ], aTotSheet[ nGNum, 2 ] } )
                        cString +=STRTRAN(TRANSFORM( aTotVal[ nGNum, j ], aPicture[ i ] ),".",cDecSep) + CHR( K_TAB )
                     ENDIF
                  NEXT
                  IF n > 0
                     lNoFooter := .F.
                     IF aGroup[ nGNum , 3 ] != NIL
                        IF VALTYPE( aGroup[ nGNum , 3 ] ) = 'B'
                           nNewPreRec := RECNO()
                           DBGOTO( nPreRec )
                           cItogo := ALLTRIM( EVAL( aGroup[ nGNum, 3 ], ReconfigureTotVal( nGNum ), @lNoFooter, nIncLine ) ) + ":"
                           DBGOTO( nNewPreRec )
                        ELSE
                           cItogo := ALLTRIM( aGroup[ nGNum, 3 ] ) + ":"
                        ENDIF
                        cString := STRTRAN( cString, "Итого", cItogo )
                     ENDIF
                     IF EMPTY( lNoFooter )
                        XXToExcel( cString, { 1, n - 1 }, aFormul, nItogoColor )
                        //nDone++
                        IncDone()
                     ENDIF
                  ENDIF

               ENDIF
            ELSEIF OOC_MODE.AND.!lKart
               cString := ARRAY(nFields)
               aFormul := {}
               n       := 0
                  
               FOR i := 1 TO nFields
                  IF ( j := ASCAN( aTotFields[ nGNum ], i ) ) = 0
                     IF EMPTY( cString[1] )
                        cString[1]:="Итого"
                     ENDIF
                  ELSE
                     IF EMPTY( n )
                        n := i
                     ENDIF
                     AADD( aFormul, { i, aTotLine[ nGNum, 1 ], aTotLine[ nGNum, 2 ],aTotSheet[ nGNum, 1 ], aTotSheet[ nGNum, 2 ] } )
                     cString[i]:=aTotVal[ nGNum, j ]
                  ENDIF
               NEXT
               IF n > 0
                  lNoFooter := .F.
                  IF aGroup[ nGNum , 3 ] != NIL
                     IF VALTYPE( aGroup[ nGNum , 3 ] ) = 'B'
                        nNewPreRec := RECNO()
                        DBGOTO( nPreRec )
                        cItogo := ALLTRIM( EVAL( aGroup[ nGNum, 3 ], ReconfigureTotVal( nGNum ), @lNoFooter, nIncLine ) ) + ":"
                        DBGOTO( nNewPreRec )
                     ELSE
                        cItogo := ALLTRIM( aGroup[ nGNum, 3 ] ) + ":"
                     ENDIF
                     cString[1] := STRTRAN( cString[1], "Итого", cItogo )
                  ENDIF
                  IF EMPTY( lNoFooter )
                     XXToExcel( cString, { 1, n - 1 },aFormul,nItogoColor)
                     //nDone++
                     IncDone()
                  ENDIF
               ENDIF

            ELSEIF DOS_MODE .OR. WIN_MODE .OR. WORD_MODE .OR. OOW_MODE.OR.(lKart.AND.EXCEL_OOC_MODE)

               cString := IIF( lIsNum, "│      ", "│" )
               n       := 0
               FOR i := 1 TO nFields
                  IF ( ( j := ASCAN( aTotFields[ nGNum ], i ) ) > 0 )
                     n += IIF( n == 0, LEN( cString ), 0 )
                     IF EMPTY( aTotVal[ nGNum, j ] )
                        cString += SPACE( aColWidth[ i ] + 1 )
                     ELSE
                        cString += PADC( TRANSFORM( aTotVal[ nGNum, j ], ;
                                         LTRIM( aPicture[ i ] ) ), aColWidth[ i ] ) + " "
                     ENDIF
                  ELSE
                     cString += SPACE( aColWidth[ i ] + 1 )
                  ENDIF
               NEXT
               cString := STUFF( cString, LEN( cString ), 1, "│" )
               IF ( n > 0 )
                  lNoFooter := .F.
                  IF( aGroup[ nGNum , 3 ] == NIL )
                  cItogo := "Итого:"
                  nItogo := 6
               ELSEIF VALTYPE( aGroup[ nGNum , 3 ] ) = 'B'
                  nNewPreRec := RECNO()
                  DBGOTO( nPreRec )
                  cItogo := ALLTRIM( EVAL( aGroup[ nGNum, 3 ], ReconfigureTotVal( nGNum ), @lNoFooter, nIncLine ) ) + ":"
                  nItogo := LEN( cItogo )
                  DBGOTO( nNewPreRec )
               ELSE
                  cItogo := ALLTRIM( aGroup[ nGNum, 3 ] ) + ":"
                  nItogo := LEN( cItogo )
               ENDIF
               IF EMPTY( lNoFooter )
                  cString := STUFF( cString, MAX( 2, n - nItogo ), MIN( nItogo, n - 1 ), ;
                                    PADR( cItogo, MIN( nItogo, n - 1 ) ) )
                  Str2File( "│" + REPLICATE( ".", nStrWid - 2 ) + "│" )
                  Str2File( cString )
               ENDIF
            ENDIF
         ENDIF
         AEVAL( aTotVal[ nGNum ], { | x, j | aTotVal[ nGNum, j ] := 0 } )
         aTotLine[ nGNum ] := { 0, 0 }
         aTotSheet[ nGNum ] := { 0, 0 }

      ENDIF         //IF LEN(aTotFields[nGNum]) > 0
      IF EXCEL_DRILL.AND.!lKart
         aGroupLine[ nGNum, 2 ] := IF( VALTYPE( aGroup[ nGNum, 2 ] ) != "A" .AND. LEN( aTotFields[ nGNum ] ) > 0, nDoneExcel - 2, nDoneExcel - 1 )
         aGroupSheet[ nGNum, 2 ] := oAS:Index
         IF aGroupLine[ nGNum, 2 ] >= aGroupLine[ nGNum, 1 ]
            oAS:Range( GetRange( i,, aGroupLine[ nGNum, 1 ], aGroupLine[ nGNum, 2 ], aGroupSheet[ nGNum, 1 ], aGroupSheet[ nGNum, 2 ] ) ):Rows:Group()
         ENDIF
         aGroupLine[ nGNum ] := { 0, 0 }
         aGroupSheet[ nGNum ] := { 0, 0 }
      ENDIF
   ENDIF
   ENDIF
   nLine += nIncLine
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function DopScobCond()
*+
*+    Called from ( outrep_h.prg )   1 - static procedure printgroup()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION DopScobCond( cRet )

LOCAL cScob := IF( "[" $ cRet .OR. "]" $ cRet, "'", "[" )
RETURN ( cScob + cRet + IF( cScob == "[", "]", cScob ) )

/** NUMERIC Str2File() -> strings written if successful writing to nDev
*                         0 - otherwise
*  PURPOSE: Writes cString to nDev with ending CRLF and
*   updates nDone - written lines counter
*  PARAMS:  cString   - source string
*           [nDevice] - file handle
*  GLOBAL: nDone ( declared as STATIC in this module)
**/

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function Str2File()
*+
*+    Called from ( outrep_h.prg )  10 - function totrep()
*+                                   7 - static procedure printgroup()
*+                                   7 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION Str2File( cString, nDevice, NoFF, lHead, nSelectMode0 )

STATIC cc1      := "┐└├┼┘┌┴┬┼┤"
STATIC cc2      := "──││────││"

LOCAL aRepHead2 := {}, lRepair := .F.,oRange
LOCAL nKey, nStrings := 0, lInter := !EMPTY( nDevice ), i

   IF !DOS_MODE .AND. "{[0]}" $ cString
      RETURN 0
   ENDIF
   

   IF (( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart ).OR.lKart.OR.!EMPTY(SetExcelFormat())).AND.EXCEL_OOC_MODE 

         IF EMPTY(cString)
            cString:=SPACE(1)
         ENDIF
         IF EXCEL_MODE

            IF EMPTY(oApp)
               CreateExcel()
            ENDIF
            IF CHR(12)$cString
               oAS:Rows(nDoneExcel):PageBreak := xlPageBreakManual
            ELSEIF !EMPTY(SetExcelFormat())
            
               IF LEFT(SetExcelStyle(),3)=="TAB" //идем по таблице
                  IF EMPTY( TRIM( CHARREM( cc1+"─│.,:", cString ) ) ) //отсекаем ненужное
                     nDone--
                     nDoneExcel--
                  ELSE 
                     IF SetExcelStyle()=="TABHEAD" //заголовок таблицы
                        HdrToExcel(cString,,.T.)
                        nDone--
                        nDoneExcel--
                     ELSEIF SetExcelStyle()=="TABTOTAL" //итоговая строка
                        RepairForExcel(cString)
                     ELSE
                        RepairForExcel(cString)
                        IF SetExcelStyle()=="TAB1" //строка таблицы с разделителями
                           FOR i:=1 TO nFields
                           SetBorder(oAS:Cells(nDoneExcel,i),,1)
                           NEXT
                        ENDIF

                     ENDIF
                  ENDIF
               ELSE
                  Wvt_SetClipBoard(cString)
                  oAs:Cells(nDoneExcel, 1 ):Select()
                  oAS:Paste()
                  IF SetExcelStyle()=="HEAD" //заголовок в обычном тексте
                  ENDIF

               ENDIF
            ELSE
               Wvt_SetClipBoard(cString)
               oAs:Cells(nDoneExcel, 1 ):Select()
               oAS:Paste()
               IF SetExcelStyle()=="HEAD" //заголовок в обычном тексте
               ENDIF
            ENDIF
            IncDone()
         ELSEIF OOC_MODE
            IF EMPTY(oApp)
               CreateOOC(500)
            ENDIF
            IF CHR(12)$cString
               oApp:AddRow("",,,,.T.)
            ELSEIF !EMPTY(SetExcelFormat())
            
               IF LEFT(SetExcelStyle(),3)=="TAB" //идем по таблице
                  IF EMPTY( TRIM( CHARREM( cc1+"─│.,:", cString ) ) ) //отсекаем ненужное
                  ELSE 
                     IF SetExcelStyle()=="TABHEAD" //заголовок таблицы
                        HdrToExcel(cString,,.T.)
                     ELSEIF SetExcelStyle()=="TABTOTAL" //итоговая строка
                        RepairForExcel(cString)
                     ELSE
                        RepairForExcel(cString)
                     ENDIF
                  ENDIF
               ELSE
                  oApp:AddRow(cString)
                  IF SetExcelStyle()=="HEAD" //заголовок в обычном тексте
                  ENDIF

               ENDIF
            ELSE
               oApp:AddRow(cString)
               IF SetExcelStyle()=="HEAD" //заголовок в обычном тексте
               ENDIF
            ENDIF
            IncDone()
         ENDIF
      RETURN 1
   ENDIF

   IF lHead == NIL.AND.UPPER( m->LBL_BOSS2 ) $ UPPER( cString ) .OR. ;
       UPPER( LBL_SHEF2 ) $ UPPER( cString )
       lHead := .T.
   ENDIF

   IF nSelectMode0 != NIL               //вход снаружи уже с заданным режимом
      nSelectMode := nSelectMode0
   ELSEIF ( TYPE( "lFromMaker" ) = "L" .AND. m->lFromMaker ) .AND. !( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart )
      nSelectMode := 1
      lKart       := .T.
   ELSEIF aFieldsName == NIL .AND. nStage < 2               //Вошли извне
      IF nStage == 0
         IF ( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart )
            AADD( aRepHead, cString )
            lKart  := .T.
            nStage := 2
            IF !Correct()
               ClearTotRepStatic()
               BREAK .F.
            ENDIF
            IF EXCEL_MODE
               CreateExcel()
               AEVAL( aRepHead, { | x | Str2File( x ) } )
            ELSEIF OOC_MODE
               CreateOOC(LEN(aRepHead[1]))
               AEVAL( aRepHead, { | x | Str2File( x ) } )
            ELSEIF WORD_MODE
               CreateWord()
               AEVAL( aRepHead, { | x | StrToWord( x ) } )
            ELSEIF OOW_MODE
               CreateOOW()
               AEVAL( aRepHead, { | x | StrToOOW( x ) } )
            ELSE
               AEVAL( aRepHead, { | x | Str2File( x, nDevice, NoFF ) } )
            ENDIF
            RETURN 0
         ELSEIF "┌" $ cString .AND. "┬" $ cString           //втретили шапку
            nStage := 1
         ELSE
            AADD( aRepHead, cString )
            IF LEN( aRepHead ) > 10     // если после 10 строк заголовка нет шапки, значит это не отчет
               lKart  := .T.
               nStage := 2
               IF !Correct()
                  ClearTotRepStatic()
                  BREAK .F.
               ENDIF
               IF WORD_MODE
                  CreateWord()
                  AEVAL( aRepHead, { | x | StrToWord( x ) } )
               ELSEIF OOW_MODE
                  CreateOOW()
                  AEVAL( aRepHead, { | x | StrToOOW( x ) } )
               ELSE
                  AEVAL( aRepHead, { | x | Str2File( x, nDevice, NoFF ) } )
               ENDIF
            ENDIF
            RETURN 0
         ENDIF
      ENDIF
      IF nStage == 1                    // Идем по шапке таблицы
         IF LEN( aRepHead1 ) > 20 .OR. cString[ 1 ] = "└" .OR. ;
                 ( TYPE( "nHeadHeight" ) = "N" .AND. LEN( aRepHead1 ) >= m->nHeadHeight )
            nStage := 2
            IF !Correct(, @aRepHead1, @aRepHead2 )
               ClearTotRepStatic()
               BREAK .F.
            ENDIF
            IF DOS_MODE .OR. WIN_MODE
               AEVAL( aRepHead, { | x | Str2File( IF( EMPTY( LEFT( x, 3 ) ), PADC( ALLTRIM( x ), MAX( nStrWid, 70 ) ), PADR( x, MAX( nStrWid, 70 ) ) ), nDevice, NoFF, "Head" ) } )
               Str2File( '', nDevice, NoFF )
               AEVAL( aRepHead1, { | x | Str2File( x, nDevice, NoFF ) } )
               AEVAL( aRepHead2, { | x | Str2File( x, nDevice, NoFF ) } )
            ELSEIF WORD_MODE
               CreateWord()
               HdrToWord( aRepHead )
               StrToWord( '' )
               HeadToWord( aRepHead1 )
               AEVAL( aRepHead2, { | x | StrToWord( x ) } )
            ELSEIF OOW_MODE
               CreateOOW()
               HdrToOOW( aRepHead )
               StrToOOW( '' )
               HeadToOOW( aRepHead1 )
               AEVAL( aRepHead2, { | x | StrToOOW( x ) } )
            ELSEIF EXCEL_MODE
               CreateExcel()
               MakeFormatExcel()
               ExcelHeader( aRepHead )
               StrToExcel( '' )
               AEVAL( aRepHead1, { | x | HdrToExcel( x ) } )
               AEVAL( aRepHead2, { | x | Str2File( x, nDevice, NoFF ) } )       //дополнительные строки
            ELSEIF OOC_MODE
               CreateOOC()
               ExcelHeader( aRepHead )
               StrToExcel( '' )
               AEVAL( aRepHead1, { | x | HdrToExcel( x ) } )
               AEVAL( aRepHead2, { | x | Str2File( x, nDevice, NoFF ) } )       //дополнительные строки
            ENDIF

         ELSE
            AADD( aRepHead1, cString )

            RETURN 0
         ENDIF
      ENDIF
   ENDIF

   nDevice := IIF( nDevice == NIL, nUnit, nDevice )

   IF !EXCEL_OOC_MODE
      IF lKart
         nStrWid := MAX( nStrWid, LEN( cString ) )
      ENDIF

      IF sFormat0 != NIL .AND. sFormat != sFormat0 .AND. EMPTY(lHead).AND. LEN( cString ) > LEN( sFormat )             //не все колонки
         cString := RepairForTxt( cString )
         lRepair := .T.
      ENDIF
      IF NoFF = NIL
         cString := PADR( TRIM( cString ), IF(EMPTY(lHead), nStrWid, LEN( TRIM( cString ) ) ) ) + IF( DOS_MODE, CHR( 255 ), " " )          //пробел не убирать!!!
      ELSE
         cString := TRIM( LEFT( cString, IF(EMPTY(lHead), nStrWid, LEN( TRIM( cString ) ) ) ) )
      ENDIF

      IF WIN_MODE
         cString := CHARREPL( cc1, cString, cc2 )
         cString := HB_OEMTOANSI( cString )
      ENDIF
      nStrings := NUMAT( CHR( K_ENTER ) + CHR( K_CTRL_RET ), cString )
      IF lRunPlugInsPrint
         RunPlugIns( "ОТЧЕТ", "ФОРМИРОВАНИЕ", { | cString | FWRITE( nDevice, cString + CHR( K_ENTER ) + CHR( K_CTRL_RET ) ) }, cString )
      ELSEIF WORD_MODE
         StrToWord( cString, lRepair )
      ELSEIF OOW_MODE
         StrToOOW( cString, lRepair )
      ELSEIF XML_MODE
         //в XML отсюда не выводим
      ELSEIF nDevice!=NIL.AND.( LEN( cString ) + 2 > FWRITE( nDevice, cString + CHR( K_ENTER ) + CHR( K_CTRL_RET ) ) )
         SayError( 'Oшибкa зaпиcи в фaйл' )
         BREAK .F.
      ENDIF
   ELSE
      IF sFormat0 == NIL //.OR.( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart )
         StrToExcel( cString )
      ELSE
         RepairForExcel( cString )
      ENDIF
   ENDIF
   IncDone( ++ nStrings )

RETURN nStrings

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function Width()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION Width( nWidth )

   nStrWid := nWidth
RETURN ( NIL )

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetPict()
*+
*+    Called from ( outrep_h.prg )   4 - function totrep()
*+                                   3 - static function xxtoc()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetPict( nLen, nDec )

RETURN REPLICATE( '9', nLen - 1 - nDec ) + IF( nDec > 0, '.' + REPLICATE( '9', nDec ), '9' )
//----------------------------------------------------------------------------//

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function SetRepFormat()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION SetRepFormat( bFormat )

   //----------------------------------------------------------------------------//
   // Хранит блок текущего формата
LOCAL bOldFormat := bStFormat
   bStFormat := bFormat
RETURN bOldFormat

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function MyHandler()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION MyHandler()

   BREAK
RETURN NIL

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function ToExcel()
*+
*+    Called from ( outrep_h.prg )   1 - static procedure printgroup()
*+                                   1 - static procedure repairforexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION ToExcel( nCol, xVal, cPict, nColorIndex )

LOCAL cType := VALTYPE( xVal )
LOCAL oCell := oAS:Cells( nDoneExcel, nCol )
   //altd()
   WriteBuffer()
   IF cType = "C" .AND. ( "#0" $ cPict .OR. "9" $ cPict ) .AND. !"X" $ cPict
      xVal  := VAL( ALLTRIM(STRTRAN(xVal,cDecSep,".")) )
      cType := "N"
   ELSEIF cType = "D"
      cType := "C"
      xVal  := IF( EMPTY( xVal ), "", DTOC( xVal ) )
   ENDIF

   IF cType $ "C"
      oCell:NumberFormat := "@"
      IF LEN( TRIM( xVal ) ) > aColWidth[ nCol ]
         oCell:wraptext := .T.
      ENDIF
      oCell:Value := HB_OEMTOANSI( TRIM( xVal ) )

   ELSEIF cType = "N"
      IF !EMPTY( xVal )
//         IF "9"$cPict
//            oCell:NumberFormat:=GetNumExcelPict(cPict)
//         ENDIF
         oCell:Value := xVal
      ENDIF
   ENDIF
   IF nColorIndex != NIL
      SetBorder( oCell, nColorIndex, .T. )
   ENDIF

RETURN NIL

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure ExcelHeader()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE ExcelHeader( aHead )

LOCAL i, lBold := .T., nAlign, lItalic,cHead
   WriteBuffer()
altd()   
   FOR i := 1 TO LEN( aHead )
      cHead:=aHead[i]
      IF TYPE( "lHardHead" ) = "L" .AND. m->lHardHead
         IF i = 1
            lBold   := .T.
            lItalic := .T.
            nAlign  := xlCenter
         ELSE
            nAlign  := xlLeft
            lBold   := .F.
            lItalic := .F.
         ENDIF
      ELSE
         IF i = 1 .AND. "ПРЕДПРИЯТИЕ" $ UPPER( cHead )
//            cHead:=TRIM(cHead)+SPACE(2)+DTOC(DATE())+" "+TIME()
            lBold   := .F.
            lItalic := .T.
            nAlign  := NIL
         ELSEIF i==1.OR.PADC( ALLTRIM( cHead ), LEN( cHead ) ) == cHead .OR. EMPTY( LEFT( cHead, 10 ) )
            nAlign  := xlCenter
            lBold   := .F.
            lItalic := .F.
         ELSE
            nAlign  := NIL
            lBold   := .F.
            lItalic := .F.
         ENDIF
      ENDIF
      
      StrToExcel( IF( nAlign == xlCenter, ALLTRIM( cHead ), TRIM( cHead ) ),, lBold, lItalic,,, nAlign,, .T. )

   NEXT

RETURN




*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function HdrToExcel()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION HdrToExcel( cString,lTrim,NoKart )

STATIC cc1 := "┐└┴┬├─┼┘┌┤│:"
STATIC cc2 := "┼├┤"
STATIC cc3 := "│││"
LOCAL i, n, oCell, oRange, cc, i0 := 0, nLen0, n0, cccc

IF lKart.AND.EMPTY(NoKart)
   Str2File(cString)
ELSEIF EXCEL_MODE
   WriteBuffer()

   IF LEN( TRIM( cString ) ) = 0
      oRange              := oAS:Range( GetRange( 1, nFields ) )
      oRange:WrapText     := .F.
      oRange:MergeCells   := .T.
      oRange:NumberFormat := "@"
      //   nDone++
      IncDone()
   ELSEIF !EMPTY( TRIM( ( cccc := CHARREM( cc1, cString ) ) ) )
      cString := CHARREPL( cc2, cString, cc3 )

      IF !"│" $ cString
         oRange              := oAS:Range( GetRange( 1, nFields ) )
         oRange:WrapText     := .F.
         oRange:MergeCells   := .T.
         oRange:NumberFormat := "@"
         oRange:Value        := HB_OEMTOANSI( cString )
         oRange:font:bold    := .T.
      ELSE
         FOR i := 1 TO nFields + 1
            n := ATTOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), i )

            IF SUBSTR( cString, n - 1, 1 ) = "│" .OR. i == nFields + 1
               IF i0 > 0
                  
                  IF i0 == i - 1
                     //Cell
                     oCell          := oAS:Cells( nDoneExcel, i0 )
                     cc             := CHARREM( cc1, SUBSTR( cString, n0, nLen0 ) )
                     IF !EMPTY(lTrim)
                        cc:=ALLTRIM(cc)
                     ENDIF
                     oCell:wraptext := .F.
                     oCell:HorizontalAlignment := xlCenter
                     oCell:NumberFormat        := "@"
                     oCell:Formula             := HB_OEMTOANSI( cc )
                     SetBorder( oCell, nHeadColor, .T. )
                  ELSE
                     //Range
                     oRange            := oAS:Range( GetRange( i0, i - 1 ) )
                     oRange:WrapText   := .F.
                     oRange:MergeCells := .T.
                     cc                := CHARREM( cc1, SUBSTR( cString, n0, nLen0 ) )
                     IF !EMPTY(lTrim)
                       cc:=ALLTRIM(cc)
                     ENDIF
                     oRange:NumberFormat        := "@"
                     oRange:HorizontalAlignment := xlCenter
                     oRange:Formula             := HB_OEMTOANSI( TRIM(cc) )
                     SetBorder( oRange, nHeadColor, .T. )
                  ENDIF
               ENDIF
               i0    := i
               nLen0 := 0
               n0    := n
            ENDIF
            IF i <= nFields
               nLen0 += aColWidth[ i ] + 1
            ENDIF
         NEXT
      ENDIF
      //   nDone++
      IncDone()
   ENDIF
ELSE
   IF LEN( TRIM( cString ) ) = 0
      oApp:AddRow("",1)
      IncDone()
   ELSEIF !EMPTY( TRIM( ( cccc := CHARREM( cc1, cString ) ) ) )
      cString := CHARREPL( cc2, cString, cc3 )
      IF CHR(12)$cString
         oApp:AddRow("",,,,.T.)
      ELSEIF !"│" $ cString
         oApp:AddRow(cString,1)
      ELSE
         oApp:AddRow(,1)
         FOR i := 1 TO nFields + 1
            n := ATTOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), i )

            IF SUBSTR( cString, n - 1, 1 ) = "│" .OR. i == nFields + 1
               IF i0 > 0
                  
                  IF i0 == i - 1
                     
                     //Cell
                     cc:= CHARREM( cc1, SUBSTR( cString, n0, nLen0 ) )
                     IF !EMPTY(lTrim)
                        cc:=ALLTRIM(cc)
                     ENDIF
                     oApp:AddCell(cc)
                  ELSE
                     //Range
                     cc:= CHARREM( cc1, SUBSTR( cString, n0, nLen0 ) )
                     IF !EMPTY(lTrim)
                       cc:=ALLTRIM(cc)
                     ENDIF
                     oApp:AddCell(cc,i-i0)
                  ENDIF
               ENDIF
               i0    := i
               nLen0 := 0
               n0    := n
            ENDIF
            IF i <= nFields
               nLen0 += aColWidth[ i ] + 1
            ENDIF
         NEXT
      ENDIF
      //   nDone++
      IncDone()
   ENDIF
ENDIF

RETURN NIL

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function StrToExcel()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   2 - static procedure printgroup()
*+                                   2 - function str2file()
*+                                   1 - static procedure excelheader()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION StrToExcel( cString, cFont, lBold, lItalic, n, nColorIndex, nAlignment, lBorder, lWrap )

LOCAL cc1    := "┐└┴┬├─┼┘┌┤─"
LOCAL cc2    := SPACE( LEN( cc1 ) )
LOCAL oRange
IF n == NIL
   n:=nFields
ENDIF


IF OOC_MODE
   IF CHR(12)$cString
      oApp:AddRow("",,,,.T.)
   ELSE
      oApp:AddRow(cString,StyleType(nColorIndex,nAlignment),n)
   ENDIF
ELSE

   oRange := oAS:Range( GetRange( 1, IF( n == NIL, nFields, n ) ) )
   
   WriteBuffer()

   IF lBold == NIL
      lBold := .F.
   ENDIF
   IF lItalic == NIL
      lItalic := .F.
   ENDIF

   IF cFont != NIL
      oRange:font:Name := cFont
   ENDIF
   cString             := CHARREPL( cc1, cString, cc2 )
   oRange:font:bold    := lBold
   oRange:font:italic  := lItalic
   oRange:WrapText     := IF( lWrap == NIL, .F., lWrap )
   oRange:MergeCells   := .T.
   oRange:NumberFormat := "@"
   IF nAlignment != NIL
      oRange:HorizontalAlignment := nAlignment
   ENDIF
   oRange:Formula := HB_OEMTOANSI( cString )
   SetBorder( oRange, nColorIndex, lBorder )
   //nDone++
ENDIF
IncDone()
RETURN NIL

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure RepairForExcel()
*+
*+    Called from ( outrep_h.prg )   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE RepairForExcel( cString, nBorder )  
//nBorder - 1 - слева-справа ячейки  
//nBorder - 2 или .t.  - вокруг ячейки
LOCAL i, n, nLen := 0, i0 := 0, cc := "", n0 := 0, xVal, iNew, iNew0, j
LOCAL oRange, cType, cStr := ""
LOCAL cc1     := "┐└┴┬├─┼┘┌┤─│"
LOCAL cc2     := SPACE( LEN( cc1 ) )
LOCAL cToken, nNumToken := NUMTOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ) ), cToken1
LOCAL nDone0  := nDoneExcel,cPict
LOCAL lBorder := IsHead(cString)
LOCAL lBreak:=!EMPTY(cString).AND.CHR(12)$cString
   
   IF EMPTY( TRIM( CHARREM( cc1+".,:", cString ) ) )
      nDone --
      nDoneExcel --
      RETURN
   ELSEIF IsHead1(cString)
      HdrToExcel(cString)
      nDone--
      nDoneExcel--
      RETURN
   ENDIF
   IF lBreak.OR.(nDoneExcel>10.AND.;
     "Касса за "$cString.AND.;
     "Лист"$cString.AND.!"Лист    1"$cString)
      WriteBuffer()
      IF EXCEL_MODE
         oAS:Rows(nDoneExcel):PageBreak := xlPageBreakManual
      ELSE
         lBreak:=.T.
      ENDIF
   ENDIF
   IF !lProcessFooter.AND.(nNumToken=NUMTOKEN(cString,"│"+IF(lSpaceDelim," ","")))
      IF sFormat0!=NIL
         IF OOC_MODE
            cStr:=ARRAY(LEN(aResultCol))
         ENDIF
         FOR i := 1 TO LEN(aResultCol)
            n := ATTOKEN(sFormat0, "│"+IF(lSpaceDelim," ",""),aResultCol[i])
            cc := TRIM(SUBSTR(cString,n,aColWidth[i]))
            IF IsMyNumber(cc) //число
               cc := STRTRAN(ALLTRIM(cc),",","")
               IF OOC_MODE
                  cc:=VAL(cc)
               ELSE
                  cc := STRTRAN(cc,".",cDecSep)
               ENDIF
            ELSE 
               IF ".." $ cc
                  cc := STRTRAN(cc,"."," ")
               ENDIF
            ENDIF
            IF OOC_MODE
               cStr[i]:=cc
            ELSE
               cStr += CHR(K_TAB)+TRIM(cc)
            ENDIF
         NEXT
      ELSE
         cStr := STRTRAN( cString, "│" + IF( lSpaceDelim, " ", "" ), CHR( K_TAB ) )
         cStr := STRTRAN( cStr, ",", " " )
      ENDIF
      XXToExcel(cStr,,, IF( lBorder, nItogoColor, NIL ), IF(nBorder==NIL,lBorder,nBorder),lBreak )
      RETURN
   ENDIF

   WriteBuffer()

   //Разбираем в сответствии со старым форматом sFormat0
   //а пишем в соответствии с новым форматом sFormat (aResultCol)

   nLen := 0
   i0   := 0
   cc   := ""

   IF OOC_MODE
      oApp:AddRow(,StyleType(IF(lBorder,nItogoColor,NIL)),,,lBreak)
   ENDIF

   FOR i := 1 TO nNumToken + 1          //проверка на непустые числовые ячейки
      n      := ATTOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ), i )
      cToken := TOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ), i )

      IF ( iNew := ASCAN( aResultCol, i ) ) > 0

         cToken1 := SUBSTR( cString, n, LEN( cToken ) )
         //altd()
         IF ( "9" $ aPicture[ iNew ] .OR. "#0" $ aPicture[ iNew ] .OR. empty(aPicture[ iNew ]) ) .AND. ;
            !"X" $ aPicture[ iNew ] .AND. IsMyNumber(cToken1) 
            cString[ n - 1 ] := "│"
            IF LEN( cString ) < n + LEN( cToken )
               cString := PADR( cString, n + LEN( cToken ) )
            ENDIF
            cString[ n + LEN( cToken ) ] := "│"
         ENDIF
      ENDIF
   NEXT



   FOR i := 1 TO nNumToken + 1
      n      := ATTOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ), i )
      cToken := TOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ), i )
      IF SUBSTR( cString, n - 1, 1 ) == "│" .OR. n == 2 .OR. i == nNumToken + 1
         IF i0 > 0 .AND. ( iNew0 := ASCAN( aResultCol, i0 ) ) > 0               //позиция в новом формате
            IF i0 == i - 1              //одна ячейка
               IF n0 == 2 .AND. SUBSTR( cString, n0, 1 ) != "│"
                  n0 --
                  nLen ++
               ENDIF
               xVal := SUBSTR( cString, n0, nLen - 1 )
               cPict:=""
               IF ( EMPTY(aPicture[ iNew0 ]).OR. "9" $ aPicture[ iNew0 ] .OR. "#0" $ aPicture[ iNew0 ] .OR. ;
                    ( !EMPTY( aFieldsName ) .AND. !EMPTY( aFieldsName[ iNew0 ] ) .AND. VALTYPE( &( aFieldsName[ iNew0 ] ) ) == "N" ) ) .AND. ;
                    IsMyNumber(xVal)    //явно число
                  IF empty(aPicture[ iNew0 ])
                     //altd()
                     cPict := REPLICATE( "9", LEN( xVal ) )
                     IF "." $ xVal
                        cPict[ AT( ".", xVal ) ] := "."
                     ENDIF
                     IF EXCEL_MODE.AND.(EMPTY( oAS:columns[ iNew0 ] :Rows:NumberFormat ).OR.oAS:columns[ iNew0 ] :Rows:NumberFormat="@")
                        oAS:columns[ iNew0 ] :Rows:NumberFormat := GetNumExcelPict( cPict )
                     ENDIF
                  ENDIF
                  xVal := STRTRAN( xVal, ",", "" )
                  xVal := VAL( xVal)
               ELSE
                  IF ".." $ xVal
                     xVal := STRTRAN( xVal, ".", " " )
                  ENDIF
                  xVal := TRIM( CHARREPL( cc1, xVal, cc2 ) )
               ENDIF
               IF OOC_MODE
                  oApp:AddCell(xVal)
               ELSE
                  ToExcel( iNew0, xVal, IF(EMPTY(aPicture[iNew0]),cPict,aPicture[ iNew0 ]), IF( lBorder, nItogoColor, NIL ) )
               ENDIF
            ELSE
               j := i - 1
               WHILE ( iNew := ASCAN( aResultCol, j -- ) ) = 0 .AND. j > 0 
               ENDDO
               IF EXCEL_MODE
                  oRange            := oAS:Range( GetRange( iNew0, iNew ) )
                  oRange:MergeCells := .T.
               ENDIF
               IF n0 == 2 .AND. SUBSTR( cString, n0, 1 ) != "│"
                  n0 --
                  nLen ++
               ENDIF
               xVal := SUBSTR( cString,n0,nLen )
               IF ".." $ xVal
                  xVal := STRTRAN( xVal, ".", " " )
               ENDIF
               xVal := CHARREPL( STRTRAN(cc1,".",","),xVal,cc2 )
               IF PADC(xVal,LEN(xVal))==xVal
                  xVal:=TRIM(xVal)
               ENDIF
               IF OOC_MODE
                  oApp:AddCell(xVal,iNew-iNew0+1)
               ELSE
                  oRange:NumberFormat = "@"
                  oRange:Value := HB_OEMTOANSI( xVal )
                  IF lBorder
                     SetBorder( oRange, nItogoColor, .T. )
                  ENDIF
               ENDIF
            ENDIF
         ENDIF
         i0   := i
         n0   := n
         nLen := 0
      ENDIF
      nLen += LEN( cToken ) + 1
   NEXT
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function RepairForTxt()
*+
*+    Called from ( outrep_h.prg )   1 - function str2file()
*+                                   1 - static procedure strtoword()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION RepairForTxt( cString )

LOCAL i, cStr := "", n, cString1 := SUBSTR( cString, 2, LEN( cString ) - 3 )
LOCAL cc1 := "┐└┴┬├─┼┘┌┤│"
   IF LEN( aResultCol ) > 0
      //altd()

      IF "│" $ cString1 .OR. "┼" $ cString1 .OR. "┴" $ cString1 .OR. "┬" $ cString1
         FOR i := 1 TO LEN( aResultCol )
            n    := ATTOKEN( sFormat0, "│" + IF( lSpaceDelim, " ", "" ), aResultCol[ i ] ) - 1
            cStr += SUBSTR( cString, n, aColWidth[ i ] + 1 )
         NEXT
         cStr += RIGHT( TRIM( cString ), 1 )
      ELSEIF IsHead( cString )
         cStr := ALLTRIM( cString )
      ELSE
         FOR i := 1 TO NumToken( cString1, " " )
            cStr += " " + Token( cString1, " ", i )
         NEXT
         cStr := cString[ 1 ] + PADR( ALLTRIM( cStr ), LEN( sFormat ) - 2 ) + ;
                 IF( RIGHT( TRIM( cString ), 1 ) $ cc1, RIGHT( TRIM( cString ), 1 ), " " )
      ENDIF
   ELSE
      cStr := cString
   ENDIF
RETURN cStr

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function IncDone()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   3 - static procedure printgroup()
*+                                   1 - function str2file()
*+                                   2 - static function hdrtoexcel()
*+                                   1 - static function strtoexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION IncDone( n )
LOCAL nIndex,oAS0,i
   #ifndef __PLATFORM__Linux
   IF EXCEL_MODE.AND.nDoneExcel>=65535
      //altd()
      oAS0:=oAS
      WriteBuffer()
      
      nIndex:=oAS:Index
      IF oApp:sheets:count<nIndex+2
         oApp:sheets(oApp:sheets:count):select()
         oApp:sheets:add()
      ENDIF
      oAS := oApp:Sheets( nIndex+1 )
      oAS:activate()
      oAS:Name:="Report"+ALLTRIM(STR(nIndex+1))
      MakeFormatExcel()
      nDoneExcel:=0
      
   ENDIF
   #endif

   IF n = NIL
      nDone ++
      nDoneExcel++
   ELSE
      nDone += n
      nDoneExcel += n
   ENDIF
RETURN 1

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetRange()
*+
*+    Called from ( outrep_h.prg )   2 - static procedure printgroup()
*+                                   3 - static function hdrtoexcel()
*+                                   1 - static function strtoexcel()
*+                                   1 - static procedure repairforexcel()
*+                                   3 - static procedure xxtoexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetRange( nCol1, nCol2, nRow1, nRow2,nSheet1,nSheet2 )

   IF nRow1 == NIL  //строка
      RETURN GetMyCol( nCol1) + ALLTRIM( STR( nDoneExcel ) ) + ":" + GetMyCol( nCol2 ) + ALLTRIM( STR( nDoneExcel ) )
   ENDIF            
RETURN GetMySheet(nSheet1)+GetMyCol( nCol1 ) + ALLTRIM( STR( nRow1 ) ) + ":" + GetMySheet(nSheet2)+GetMyCol( nCol1 ) + ALLTRIM( STR( nRow2 ) )

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetMyCol()
*+
*+    Called from ( outrep_h.prg )   4 - static function getrange()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetMyCol( nCol )

   IF nCol <= 26
      RETURN CHR( ASC( "A" ) + nCol - 1 )
   ELSEIF nCol > 26 * 8
      RETURN "H" + CHR( ASC( "A" ) + nCol - 26 * 8 - 1 )
   ELSEIF nCol > 26 * 7
      RETURN "G" + CHR( ASC( "A" ) + nCol - 26 * 7 - 1 )
   ELSEIF nCol > 26 * 6
      RETURN "F" + CHR( ASC( "A" ) + nCol - 26 * 6 - 1 )
   ELSEIF nCol > 26 * 5
      RETURN "E" + CHR( ASC( "A" ) + nCol - 26 * 5 - 1 )
   ELSEIF nCol > 26 * 4
      RETURN "D" + CHR( ASC( "A" ) + nCol - 26 * 4 - 1 )
   ELSEIF nCol > 26 * 3
      RETURN "C" + CHR( ASC( "A" ) + nCol - 26 * 3 - 1 )
   ELSEIF nCol > 26 * 2
      RETURN "B" + CHR( ASC( "A" ) + nCol - 26 * 2 - 1 )
   ELSEIF nCol > 26
      RETURN "A" + CHR( ASC( "A" ) + nCol - 26 - 1 )
   ENDIF
RETURN CHR( ASC( "A" ) + nCol - 1 )


*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetMySheet()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetMySheet( nSheet )
//IF nSheet==NIL
   RETURN ""
//ENDIF
//RETURN "Report"+IF(nSheet==1,"",ALLTRIM(STR(nSheet)))+"!"


*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure SetBorder()
*+
*+    Called from ( outrep_h.prg )   1 - static function toexcel()
*+                                   2 - static function hdrtoexcel()
*+                                   1 - static function strtoexcel()
*+                                   1 - static procedure repairforexcel()
*+                                   1 - static procedure xxtoexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE SetBorder( o, nColorIndex, nBorder )

   IF nBorder == NIL
      nBorder := 0
   ELSEIF VALTYPE(nBorder)=="L"
      nBorder:=2
   ENDIF
   IF !EMPTY(nBorder)
      o:Borders( xlEdgeLeft ) :LineStyle := xlContinuous
      o:Borders( xlEdgeLeft ) :Weight = xlThin
      o:Borders( xlEdgeRight ) :LineStyle := xlContinuous
      o:Borders( xlEdgeRight ) :Weight = xlThin
      IF nBorder>1
         o:Borders( xlEdgeTop ) :LineStyle := xlContinuous
         o:Borders( xlEdgeTop ) :Weight = xlThin
         o:Borders( xlEdgeBottom ) :LineStyle := xlContinuous
        o:Borders( xlEdgeBottom ) :Weight = xlThin
      ENDIF
   ENDIF
   IF nColorIndex != NIL
      o:Interior:colorIndex := nColorIndex
      o:Interior:Pattern    := xlSolid
   ENDIF
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function Correct()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   3 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION Correct( aFName, aFieldsHead, aFieldsHead1, aFTot, aGrup, abPicture, lStandard, lContinue )

LOCAL nTop     := 2, nLeft := 1, nBottom := 23, nRight := 77, nBottom1 := 10
LOCAL nLen     := nRight - nLeft - 3, cTitle := " Включить в отчет "
LOCAL nSelect1 := 1

LOCAL nArea       := SELECT()
LOCAL sRest       := SAVESCREEN()
LOCAL cLastColor  := SETCOLOR( COL_HEADR )
LOCAL nCursor     := SETCURSOR()
LOCAL aSetKey     := SaveSetKey()
LOCAL aHead       := {}, cc, i, j, n, n1, n2
LOCAL aRes0
LOCAL cc1         := "┐└┴┬├─┼┘┌┤│"
LOCAL cc2         := "┐└┴┬├┼┘┌┤"
LOCAL cc3         := REPLICATE( "│", LEN( cc2 ) )
LOCAL aHead1, cString, nLen1
LOCAL cFormat
LOCAL aReportHead := {}
LOCAL lOut        := .F., cToken, jj, nn, aCountRight, lRet
LOCAL nLastKey    := LASTKEY()

#ifdef __PLATFORM__Linux
LOCAL aMode       := {1}
PRIVATE aSelect := { ;
                        PADR( "  DOS-печать", nLen ) ;
                        }
#else
LOCAL aMode
PRIVATE aSelect

GetaSelectModeFromXML_SETUP(@aMode,@aSelect,nLen)


#endif


altd()


   aRes := {}


   IF !(lStandard != NIL .AND. lContinue == NIL)
      IF (i:=ASCAN(aMode,6))>0 //убираем XML
         ADEL( m->aSelect, i ) 
         ADEL( aMode, i ) 
         ASIZE( m->aSelect, LEN( m->aSelect ) - 1 )
         ASIZE( aMode, LEN( aMode ) - 1 )
      ENDIF
   ENDIF

   IF TYPE( "lFromMaker" ) == "L" .AND. m->lFromMaker .AND. !( TYPE( "lHardKart" ) = "L" .AND. m->lHardKart )
      nSelectMode := 1
      RestSetKey( aSetKey )
      RESTSCREEN(,,,, sRest )
      RETURN LASTKEY() != K_ESC
   ENDIF
   IF EMPTY( aResultCol := GetCheckPos( aFieldsHead, aMode ) )
      nSelectMode := 3
   ELSE
      nSelectMode := aResultCol[ 1 ]
      ADEL( aResultCol, 1 )
      ASIZE( aResultCol, LEN( aResultCol ) - 1 )
   ENDIF

   IF lKart  //строгая форма
      IF TYPE( "nHeadHeight" ) = "N" .AND. aFieldsHead != NIL                   //высота шапки жестко определена извне

         j := MIN( m->nHeadHeight, LEN( aFieldsHead ) )
         IF j < LEN( aFieldsHead )
            FOR jj := j + 1 TO LEN( aFieldsHead )
               AADD( aFieldsHead1, aFieldsHead[ jj ] )
            NEXT
            ASIZE( aFieldsHead, j )
         ENDIF
      ENDIF
      IF (i:=ASCAN(aMode,4))>0
         ADEL( m->aSelect, i ) 
         ADEL( aMode, i ) 
         ASIZE( m->aSelect, LEN( m->aSelect ) - 1 )
         ASIZE( aMode, LEN( aMode ) - 1 )
      ENDIF
      nBottom1:=nTop+2+LEN(aSelect)

      i := ASCAN( aMode, nSelectMode )
      i := BoxMenu( PADC( " Формат выдачи отчета ", nRight - nLeft - 4, "─" ), nTop + 1, nLeft + 1, m->aSelect,, i, FRAMES1,,,, nBottom1,, { | nMode, nI, nRow | AchCurr1( nMode, nI, nRow ) }, "noShadow" )
      IF i > 0
         nSelectMode := aMode[ i ]
         SetDefaultProp()
      ENDIF
      RestSetKey( aSetKey )
      SETCOLOR( cLastColor )
      SetCheckPos( nSelectMode, aResultCol, aFieldsHead, aMode )

      lRet := LASTKEY() != K_ESC
      SETLASTKEY( nLastKey )
      RESTSCREEN(,,,, sRest )
      RETURN lRet
   ENDIF

   nBottom1:=nTop+2+LEN(aSelect)

   cc2          += "─"
   cc3          += " "
   aFieldsHead1 := {}

   //Смотрим, где реально последняя линия заголовка

   IF TYPE( "nHeadHeight" ) = "N"       //высота шапки жестко определена извне
      j := jj := MIN( m->nHeadHeight, LEN( aFieldsHead ) )

   ELSE
      //Сначала попытаемся дойти до конца шапки +1
      FOR jj := 1 TO LEN( aFieldsHead )
         cc := aFieldsHead[ jj ]
         cc := SUBSTR( cc, 2, LEN( cc ) - 2 )

         IF !"│" $ cc .AND. !"┼" $ cc .AND. !"┴" $ cc .AND. ( !"─" $ cc .OR. "─ " $ cc ) .AND. ;
                    ( cc == PADC( ALLTRIM( cc ), LEN( cc ) ) )                  //заголовок группы - значит шапка кончилась
            EXIT
         ENDIF
      NEXT

      jj := MIN( LEN( aFieldsHead ), jj )

      //теперь идем снизу
      FOR j := jj TO 1 STEP - 1
         IF "──" $ aFieldsHead[ j ] .AND. !"─ " $ aFieldsHead[ j ] .AND. aFieldsHead[ j , 1 ] != "└"
            EXIT
         ENDIF
      NEXT
   ENDIF
   IF j < LEN( aFieldsHead )
      FOR jj := j + 1 TO LEN( aFieldsHead )
         AADD( aFieldsHead1, aFieldsHead[ jj ] )
      NEXT
      ASIZE( aFieldsHead, j )
   ENDIF

   IF aFName == NIL
      lOut := .T.
      IF (i:=ASCAN(aMode,4))>0
         ADEL( m->aSelect, i ) 
         ADEL( aMode, i ) 
         ASIZE( m->aSelect, LEN( m->aSelect ) - 1 )
         ASIZE( aMode, LEN( aMode ) - 1 )
      ENDIF
      IF TYPE("privateFormat") == "C"
         sFormat0 := sFormat := m->privateFormat //помощь извне
      ELSE
         sFormat0  := sFormat := CHARREPL( cc2, aFieldsHead[ j ], cc3 )
      ENDIF
      lIsNum    := .F.
      aFName    := ARRAY( NumToken( sFormat, "│" + IF( lSpaceDelim, " ", "" ) ) )
      nFields   := LEN( aFName )
      abPicture := ARRAY( nFields )
      aColWidth := {}
      aPicture  := {}

   ENDIF

   cFormat := IF( lIsNum, "│     ", "" ) + sFormat

   nStrWid := LEN( cFormat )

   FOR i := 1 TO j  //LEN(aFieldsHead)
      IF !EMPTY( TRIM( ( cc := CHARREM( cc1, aFieldsHead[ i ] ) ) ) )
         AADD( aHead, CHARREPL( cc2, aFieldsHead[ i ], cc3 ) )
      ENDIF
   NEXT

   aHead1 := ARRAY( LEN( aFName ) + IF( lIsNum, 1, 0 ), LEN( aHead ) )

   FOR i := 1 TO LEN( aHead1 )
      AADD( aRes, "" )
      n := ATTOKEN( cFormat, "│" + IF( lSpaceDelim, " ", "" ), i ) - 1
      IF lOut       //внешний вход с неопределенным форматом
         AADD( aColWidth, LEN( TOKEN( cFormat, "│" + IF( lSpaceDelim, " ", "" ), i ) ) )
         //пройтись вглубь для формирования picture
         cc := ""
         IF TYPE( "privateFormat" ) == "C"
            cc := SUBSTR( privateFormat,n+1,ATAIL(aColWidth) )
         ELSEIF !EMPTY(aFieldsHead1)
            aCountRight := {}
            FOR jj := 1 TO LEN( aFieldsHead1 )
               IF EMPTY( cc )
                  cToken := SUBSTR( aFieldsHead1[ jj ], n + 1, ATAIL( aColWidth ) )
                  IF aFieldsHead1[ jj , n ] == "│" .AND. EMPTY( TRIM( CHARREM( "-0123456789.,", cToken ) ) ) .AND. ;
                             ! EMPTY( cToken ) .AND. EMPTY( cToken[ 1 ] ) .AND. ;
                             ( LEFT( ALLTRIM( cToken ), 1 ) != "0" .OR. "." $ ALLTRIM( cToken ) )
                     IF "." $ cToken
                        cc := CHARREPL( "-0123456789", cToken, "99999999999" )
                        cc := CHARREM( ",", cc )
                        nn := 1
                        WHILE EMPTY( cc[ nn ] ) .AND. nn <= LEN( cc )
                           cc := STUFF( cc, nn ++, 1, "9" )
                        ENDDO
                     ELSE
                        AADD( aCountRight, COUNTRIGHT( cToken ) )               //может это целое - сравним кол-во пробелов справа
                     ENDIF
                  ENDIF
               ELSE
                  EXIT
               ENDIF
            NEXT
            IF EMPTY( cc )
               IF LEN( aCountRight ) > 1
                  FOR jj := 2 TO LEN( aCountRight )
                     IF aCountRight[ jj - 1 ] != aCountRight[ jj ]              //явно не число
                        cc := "!!!"
                        EXIT
                     ENDIF
                  NEXT
                  IF cc != "!!!"
                     //скорее всего целое
                     cc := CHARREPL( "-0123456789", cToken, "99999999999" )
                     cc := CHARREM( ",", cc )
                     nn := 1
                     WHILE EMPTY( cc[ nn ] ) .AND. nn <= LEN( cc )
                        cc := STUFF( cc, nn ++, 1, "9" )
                     ENDDO
                  ELSE
                     cc := ""
                  ENDIF
               ENDIF
               IF EMPTY( cc )
                  cc := REPLICATE( "#", ATAIL( aColWidth ) )
               ENDIF
            ENDIF
         ENDIF
         AADD( aPicture, cc )
      ENDIF

      FOR j := 1 TO LEN( aHead )
         cc := aHead[ j ]
         n1 := n
         IF j < LEN( aHead )
            WHILE SUBSTR( cc, n1, 1 ) != "│" .AND. n1 > 0
               n1 --
            ENDDO

            IF ( n2 := AT( "│", cc, n1 + 1 ) ) = 0
               n2 := LEN( cc )
            ENDIF
         ELSE
            IF ( n2 := AT( "│", cFormat, n1 + 1 ) ) = 0
               n2 := LEN( cc )
            ENDIF
         ENDIF

         IF !EMPTY( ( cc := ALLTRIM( SUBSTR( cc, n1 + 1, n2 - n1 - 1 ) ) ) )
            aRes[ i ] += IF( EMPTY( aRes[ i ] ), "", "-" ) + cc
         ENDIF
         aHead1[ i, j ] := cc
      NEXT

   NEXT

   IF lIsNum
      ADEL( aRes, 1 )
      ASIZE( aRes, LEN( aRes ) - 1 )
   ENDIF

   aRes0 := ACLONE( aRes )

   IF EMPTY( aResultCol )
      FOR i := 1 TO LEN( aRes )
         AADD( aResultCol, i )
      NEXT
   ELSEIF LEN( aResultCol ) > LEN( aRes )
      ASIZE( aResultCol, LEN( aRes ) )
   ENDIF

   ShadowBox( " Параметры отчета ", nTop, nLeft, nBottom, nRight,,,, "noShadow" )
   ShadowBox( "", nBottom1 + 1, nLeft + 1, nBottom - 1, nRight - 1,, FRAMES1,, "noShadow" )
   @ nBottom1 + 1 + 2, nLeft + 1 + 1 TO nBottom1 + 1 + 2, nRight - 2
   Title( nBottom1 + 1 + 1, cTitle, nLeft + 1 + 1, nRight - 1 - 1 )

   AEVAL( aRes0, { | x, i | SAYSCREEN( IF( i $ aResultCol, CHR( 251 ), " " ) + " " + x, nBottom1 + 3 + i, nLeft + 3 ) },, nBottom - nBottom1 - 5 )

   SETLASTKEY( 0 )

   WHILE LASTKEY() != K_ESC .AND. LASTKEY() != K_RETURN

      ScrTitul( 24, "<+>/<->:Шрифт <Пробел>:Ориентация бумаги Tab:Выбрать поля ENTER:Выполнить")
      i := ASCAN( aMode, nSelectMode )
      i := BoxMenu( PADC( " Формат выдачи ", nRight - nLeft - 4, "─" ), nTop + 1, nLeft + 1, m->aSelect,, i, FRAMES1,,, "noClear", nBottom1,, { | nMode, nI, nRow | AchCurr1( nMode, nI, nRow ) }, "noShadow" )
      IF i > 0
         nSelectMode := aMode[ i ]
         SetDefaultProp()
      ENDIF
      IF LASTKEY() = K_ESC .OR. LASTKEY() = K_RETURN

         EXIT
      ENDIF
      ScrTitul( 24, "Ins:Отметить/Снять +/-:Все поля ENTER:Выполнить Tab:В верхнее окно" )
      aRes := ACLONE( aRes0 )

      nSelect1 := AchMenu( cTitle, nBottom1 + 1, nLeft + 1, @aRes, nSelect1, FRAMES1, COL_HEADR, COL_HEADR, .T.,, nBottom - 1, nRight - 1, "noShadow" )         //,cPreKey)
      IF LASTKEY() != K_ESC
         aResultCol := {}
         FOR i := 1 TO LEN( aRes0 )
            IF ( j := ASCAN( aRes, aRes0[ i ] ) ) > 0
               AADD( aResultCol, i )
            ENDIF
         NEXT
      ENDIF
      IF LASTKEY() = K_TAB
         COLORWIN( nBottom1 + 4, nLeft + 2, nBottom - 2, nRight - 2, COL_HEADR )
      ENDIF
   ENDDO
   IF LASTKEY() = K_RETURN
      altd()
      IF LEN( aResultCol ) = 0
         SayError( "Не отмечено ни одного поля!" )
         SETLASTKEY( K_ESC )
      ELSEIF XML_MODE
      IF EMPTY(cPublicFile:=InputFile(cPublicFile,".xml",.T.))
         lRet:=.F.
      ELSE
         SetCheckPos(nSelectMode,aResultCol,aFieldsHead, aMode)
      ENDIF
      ELSE
         IF LEN( aResultCol ) >= LEN( aRes0 ) .AND. !EXCEL_OOC_MODE
            SetCheckPos( nSelectMode, aResultCol, aFieldsHead,aMode )
         ELSE
            IF lIsNum
               lIsNum := .F.
               ADEL( aHead1, 1 )
               ASIZE( aHead1, LEN( aHead1 ) - 1 )
            ENDIF
            SetCheckPos( nSelectMode, aResultCol, aFieldsHead,aMode )
            FOR i := 1 TO LEN( aRes0 )
               IF !i $ aResultCol
                  aFName[ i ]    := "!!!"
                  aHead1[ i ]    := "!!!"
                  abPicture[ i ] := "!!!"
                  IF lOut
                     aPicture[ i ]  := "!!!"
                     aColWidth[ i ] := "!!!"
                  ENDIF
                  n       := ATTOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), i )
                  cc      := TOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), i )
                  sFormat := STUFF( sFormat, n, LEN( cc ), REPLICATE( "|", LEN( cc ) ) )
               ENDIF
            NEXT

            WHILE ( j := ASCAN( aFName, "!!!" ) ) > 0
               ADEL( aFName, j )
            ENDDO
            WHILE ( j := ASCAN( aHead1, "!!!" ) ) > 0
               ADEL( aHead1, j )
            ENDDO
            WHILE ( j := ASCAN( abPicture, "!!!" ) ) > 0
               ADEL( abPicture, j )
            ENDDO
            IF lOut
               WHILE ( j := ASCAN( aPicture, "!!!" ) ) > 0
                  ADEL( aPicture, j )
               ENDDO
               WHILE ( j := ASCAN( aColWidth, "!!!" ) ) > 0
                  ADEL( aColWidth, j )
               ENDDO
            ENDIF
            ASIZE( aFName, LEN( aResultCol ) )
            ASIZE( aHead1, LEN( aResultCol ) )
            ASIZE( abPicture, LEN( aResultCol ) )
            IF lOut
               ASIZE( aPicture, LEN( aResultCol ) )
               ASIZE( aColWidth, LEN( aResultCol ) )
            ENDIF
            sFormat := STRTRAN( sFormat, "|", "" )
            WHILE "││" $ sFormat
               sFormat := STRTRAN( sFormat, "││", "│" )
            ENDDO
            nStrWid := LEN( IF( lIsNum, "│     ", "" ) + sFormat )
            nFields := LEN( aFName )
            IF aFTot != NIL
               FOR i := 1 TO LEN( aFTot )
                  IF ( j := ASCAN( aResultCol, aFTot[ i ] ) ) = 0
                     aFTot[ i ] := 0
                  ELSE
                     aFTot[ i ] := j
                  ENDIF
               NEXT
               WHILE ( j := ASCAN( aFTot, 0 ) ) > 0
                  ADEL( aFTot, j )
                  ASIZE( aFTot, LEN( aFTot ) - 1 )
               ENDDO
            ENDIF
            IF aGrup != NIL
               FOR i := 1 TO LEN( aGrup )
                  FOR n := 4 TO LEN( aGrup[ i ] )
                     IF ( j := ASCAN( aResultCol, aGrup[ i, n ] ) ) = 0
                        aGrup[ i, n ] := 0
                     ELSE
                        aGrup[ i, n ] := j
                     ENDIF
                  NEXT
                  WHILE ( j := ASCAN( aGrup[ i ], 0 ) ) > 0
                     ADEL( aGrup[ i ], j )
                     ASIZE( aGrup[ i ], LEN( aGrup[ i ] ) - 1 )
                  ENDDO
               NEXT
            ENDIF

            //заголовок
            aFieldsHead := {}
            //altd()
            FOR i := 1 TO LEN( aHead1[ 1 ] )
               cc      := "`"
               cString := ""
               n1      := 0
               nLen1   := 0
               FOR j := 1 TO LEN( aFName )
                  IF NewHeadElement( cc, aHead1, j, i )
                     IF n1 > 0
                        cString := STUFF( cString, n1, nLen1, PADC( cc, nLen1 ), nLen1 )
                     ENDIF
                     cString += "│"
                     n1      := LEN( cString ) + 1
                     nLen1   := 0
                     cc      := aHead1[ j, i ]
                  ELSE
                     nLen ++
                     cString += SPACE( 1 )
                  ENDIF
                  n       := LEN( TOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), j ) )
                  nLen1   += n
                  cString += SPACE( n )
               NEXT
               cString := STUFF( cString, n1, nLen1, PADC( cc, nLen1 ), nLen1 )
               cString += "│"
               AADD( aFieldsHead, cString )
            NEXT
            AADD( aFieldsHead, NIL )
            cc := "┌" + REPLICATE( "─", LEN( sFormat ) - 2 ) + "┐"
            AINS( aFieldsHead, 1, cc )
            cc := "├"
            FOR i := 1 TO LEN( aFName )
               cc += REPLICATE( "─", LEN( TOKEN( sFormat, "│" + IF( lSpaceDelim, " ", "" ), i ) ) ) + IF( i < LEN( aFName ), "┼", "┤" )
            NEXT
            AADD( aFieldsHead, cc )
         ENDIF
      ENDIF
   ENDIF
   SETCOLOR( cLastColor )
   SETCURSOR( nCursor )
   RestSetKey( aSetKey )
   RESTSCREEN(,,,, sRest )
   lRet := ( LASTKEY() != K_ESC )
   SETLASTKEY( nLastKey )
RETURN lRet

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function NewHeadElement()
*+
*+    Called from ( outrep_h.prg )   1 - static function correct()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION NewHeadElement( cc, aHead, j, i )

LOCAL n, lRet := .F.
   IF !EMPTY( cc + aHead[ j, i ] ) .OR. j = 1 .OR. i = 1
      RETURN !cc == aHead[ j, i ]
   ENDIF
   FOR n := i - 1 TO 1 STEP - 1
      IF ALLTRIM( aHead[ j, n ] ) != ALLTRIM( aHead[ j - 1, n ] )
         lRet := .T.
         EXIT
      ENDIF
   NEXT
RETURN lRet

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function AchCurr1()
*+
*+    Called from ( outrep_h.prg )   2 - static function correct()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION AchCurr1( nMode, nTekEl, Poz )

LOCAL nKey  := LASTKEY()
LOCAL nFont, aFont := { ;
                           " 6", ;
                           " 7", ;
                           " 8", ;
                           " 9", ;
                           "10", ;
                           "12", ;
                           "14", ;
                           "15" ;
                           }
LOCAL nOrient,aOrient:={;
"портрет ",;
"ландшафт";
}


   IF nMode == AC_EXCEPT
      DO CASE

      CASE "шрифт" $ m->aSelect[ nTekEl ].AND.;
          (nKey == ASC( "+" ).OR.nKey == ASC( "-" ))
         nFont := ASCAN( aFont, { | x | SUBSTR( m->aSelect[ nTekEl ], 36, 2 ) == x } )
         IF nFont = 0
            nFont := 3
         ELSEIF nKey == ASC( "-" )
            nFont --
            IF nFont < 1
               nFont := LEN(aFont)
            ENDIF
         ELSE
            nFont ++
            IF nFont > LEN( aFont )
               nFont := 1
            ENDIF
         ENDIF
         m->aSelect[ nTekEl ] := STUFF( m->aSelect[ nTekEl ], 36, 2, aFont[ nFont ] )

      CASE "ориентация" $ m->aSelect[ nTekEl ].AND.nKey == ASC( " " )
         nOrient := ASCAN( aOrient, { | x | SUBSTR( m->aSelect[ nTekEl ], 52, 8 ) == x } )
         IF nOrient = 0
            nOrient := 1
         ELSE
            nOrient ++
            IF nOrient > LEN( aOrient )
               nOrient := 1
            ENDIF
         ENDIF
         m->aSelect[ nTekEl ] := STUFF( m->aSelect[ nTekEl ], 52, 8, aOrient[ nOrient ] )


      CASE nKey == K_ESC
         RETURN AC_ABORT
      CASE nKey == K_ENTER .OR. nKey == K_TAB
         IF EMPTY(nSelectFont := VAL( SUBSTR( m->aSelect[ nTekEl ], 36, 2 ) ))
            nSelectFont:=8
         ENDIF
         cSelectOrient := SUBSTR( m->aSelect[ nTekEl ], 52, 1 )
         cExcelFont:=GetExcelFont()
         RETURN AC_SELECT
      ENDCASE
      CLEAR TYPEAHEAD
      SETLASTKEY( 255 )
   ENDIF
RETURN AC_CONT

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function AchMenu()
*+
*+    Called from ( outrep_h.prg )   1 - static function correct()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION AchMenu( cTitle, nTop, nLeft, aDisp, nChoice, cFrame, cColor, cColor1, lIns, aTake, nBottom, nRight, noShadow, cPreKey )

   // Если задано lIns=.T., то можно для множественного выбора пометить галочками элементы массива
   // aDisp. При этом на выходе (при передаче параметра по ссылке) этот массив укоротится
   // до выбранных значений, так же как и параллельный массив aTake.

LOCAL Old      := SETCOLOR(), Old_Cursor := SETCURSOR( 0 )
LOCAL nLen     := 0, i := 1, aColor_
LOCAL nRight_T, aRetDisp := {}, aRetTake := {}
LOCAL _lIns    := .F.
   IF lIns == NIL
      lIns := .F.
   ENDIF
PRIVATE aDisp1 := aDisp
   IF lIns
      // будет функция пользователя с возможностью выбора нескольких значений по INS

      AEVAL( aDisp, { | x, y | aDisp[ y ] := IF( y $ aResultCol, CHR( 251 ), " " ) + " " + x } )

      IF aTake == NIL
         aTake := ARRAY( LEN( aDisp ) )
      ENDIF
      IF LEN( aTake ) < LEN( aDisp )
         ASIZE( aTake, LEN( aDisp ) )
      ENDIF
   ENDIF
   cColor  := IF( EMPTY( cColor ), COL_INPUT, cColor )
   cColor1 := IF( EMPTY( cColor1 ), COL_INPUTF, cColor1 )
   cTitle  := IF( EMPTY( cTitle ) .OR. cTitle == NIL, "", cTitle )
   nChoice := IF( nChoice = 0 .OR. nChoice == NIL, nChoice = 1, nChoice )
   cFrame  := IF( EMPTY( cFrame ) .OR. cFrame == NIL, "", cFrame )
   AEVAL( aDisp, { || nLen := IF( LEN( aDisp[ i ] ) > nLen, LEN( aDisp[ i ] ), nLen ), i ++ } )
   IF nRight == NIL
      nRight   := nLeft + nLen + 3
      nRight_T := nLeft + LEN( cTitle ) + 3
      nRight   := IF( nRight > nRight_T, nRight, nRight_T )
   ENDIF
   IF nBottom == NIL
      nBottom := IF( ( nTop + LEN( aDisp ) + 3 ) > 21, 21, nTop + LEN( aDisp ) + 3 )
   ENDIF
   ShadowBox( "", nTop, nLeft, nBottom, nRight, cColor, cFrame,,, noShadow )
   SETCOLOR( cColor )
   @ nTop + 2, nLeft + 1 TO nTop + 2, nRight - 1
   //@ nTop+2, nLeft  SAY chr(199) HARBOUR
   //@ nTop+2, nRight SAY chr(182) HARBOUR
   SETCOLOR( cColor1 )
   Title( nTop + 1, cTitle, nLeft + 1, nRight - 1 )
   SETCOLOR( cColor )
   CLEAR TYPEAHEAD
   SETLASTKEY( 255 )
   IF cPreKey != NIL
      KEYBOARD cPreKey
   ENDIF
   nChoice := ACHOICE( nTop + 3, nLeft + 2, nBottom - 1, nRight - 2, aDisp,, IF( lIns, { | nMode, nI, nRow | AchCurr( nMode, nI, nRow, nTop, nLeft, nBottom, nRight ) }, ) )
   IF nChoice <> 0 .AND. lIns
      // сформировать выборку
      AEVAL( aDisp, { | x, y | IF( LEFT( x, 1 ) == CHR( 251 ), ( AADD( aRetDisp, RIGHT( x, LEN( x ) - 2 ) ), AADD( aRetTake, aTake[ y ] ) ), NIL ) } )

      // Если не было помечено ни одного пункта
      AEVAL( aDisp, { | x | IF( LEFT( x, 1 ) == CHR( 251 ), _lIns := .T., NIL ) } )
      IF !_lIns     // тогда выборка - это единственный выбранный элемент
         AADD( aRetDisp, RIGHT( aDisp[ nChoice ], LEN( aDisp[ nChoice ] ) - 2 ) )
         AADD( aRetTake, aTake[ nChoice ] )
      ENDIF
      IF !EMPTY( aRetDisp )
         aDisp := aRetDisp
         aTake := aRetTake
      ENDIF
   ENDIF
   SETCOLOR( Old )
   SETCURSOR( Old_Cursor )
RETURN nChoice

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function AchCurr()
*+
*+    Called from ( outrep_h.prg )   1 - static function achmenu()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION AchCurr( nRejim, nTekEl, Poz, nTop, nLeft, nBottom, nRight )

LOCAL nKey := LASTKEY()

   IF nRejim == AC_EXCEPT
      DO CASE

      CASE nKey == K_INS
         IF LEFT( aDisp1[ nTekEl ], 1 ) == CHR( 251 )
            // снять галочку
            aDisp1[ nTekEl ] := "  " + RIGHT( aDisp1[ nTekEl ], LEN( aDisp1[ nTekEl ] ) - 2 )
         ELSE
            // поставить галочку
            aDisp1[ nTekEl ] := CHR( 251 ) + " " + RIGHT( aDisp1[ nTekEl ], LEN( aDisp1[ nTekEl ] ) - 2 )
         ENDIF
         SAYSCREEN( m->aDisp1[ nTekEl , 1 ], nTop + Poz + 3, nLeft + 2 )
         KEYBOARD CHR( K_DOWN )
         RETURN 2
      CASE nKey == ASC( "+" )
         AEVAL( m->aDisp1, { | x, i | m->aDisp1[ i ] := CHR( 251 ) + " " + RIGHT( x, LEN( x ) - 2 ), ;
                             IF( nTop + i + 2 < nBottom, SAYSCREEN( m->aDisp1[ i , 1 ], nTop + i + 2, nLeft + 2 ), ) } )

         //    AEVAL(aDisp1,{|x,i|aDisp1[i]:=CHR(251)+" "+RIGHT(x,LEN(x)-2)})
      CASE nKey == ASC( "-" )

         AEVAL( m->aDisp1, { | x, i | m->aDisp1[ i ] := "  " + RIGHT( x, LEN( x ) - 2 ), ;
                             IF( nTop + i + 2 < nBottom, SAYSCREEN( m->aDisp1[ i , 1 ], nTop + i + 2, nLeft + 2 ), ) } )

         //    AEVAL(aDisp1,{|x,i|aDisp1[i]:=" "+" "+RIGHT(x,LEN(x)-2)})

      CASE nKey == K_ESC
         RETURN AC_ABORT
      CASE nKey == K_ENTER .OR. nKey == K_TAB
         RETURN AC_SELECT
      ENDCASE
      CLEAR TYPEAHEAD
      SETLASTKEY( 255 )
   ENDIF
RETURN AC_CONT

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetNumExcelPict()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - static procedure repairforexcel()
*+                                   1 - static procedure makeformatexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetNumExcelPict( cPict )
LOCAL j := AT( ".", cPict )
   IF j = 0
      cPict := "# ##0"

   ELSE 
      cPict := "# ##0" + cDecSep + REPLICATE( "0", LEN( cPict ) - j )
   ENDIF

RETURN cPict

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function Reconfigure()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION Reconfigure( aTot, n )

LOCAL i
LOCAL aTot1 := ARRAY( n )
   AFILL( aTot1, 0 )
   FOR i := 1 TO MIN( LEN( aResultCol ), n )
      aTot1[ aResultCol[ i ] ] := aTot[ i ]
   NEXT
RETURN aTot1

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetFileName()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetFileName( cFile, lContinue )

   IF cFile == NIL
      IF DOS_MODE
         cFile := TEMPFILE( _TMP_DIR, "REP" )
      ELSEIF WIN_MODE
         cFile := TEMPFILE( _TMP_DIR, "txt" )
      ELSEIF XML_MODE
         cFile:=InputFile(cFile,".xml")
      ENDIF
   ELSEIF !( DOS_MODE .OR. WIN_MODE )
      IF "." $ cFile
         cFile := LEFT( cFile, RAT( ".", cFile ) - 1 )
      ELSE
         cFile := TRIM( cFile )
      ENDIF
      IF EXCEL_MODE
         cFile += ".xls"
      ELSEIF OOC_MODE
         cFile += ".ods"
      ELSEIF OOC_MODE
         cFile += ".odt"
      ELSEIF XML_MODE
         cFile += ".xml"
      ENDIF
   ENDIF

RETURN cFile

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function GetCheckPos()
*+
*+    Called from ( outrep_h.prg )   1 - static function correct()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetCheckPos( aFieldsHead, aMode )

LOCAL nArea := SELECT(), a := {}
LOCAL cc:= m->GlobalTask
LOCAL i, cKey, cToken, lFont := .F.,lOrient:=.F.,nSel := 0,j
MEMVAR aSelect

altd()
   IF VALTYPE( aFieldsHead ) = "A"
      IF TYPE( "nHeadHeight" ) != "N"
         PRIVATE nHeadHeight := LEN( aFieldsHead )
      ENDIF

      FOR i := 1 TO MIN(2,MIN( LEN( aFieldsHead ), nHeadHeight ))
         cc += aFieldsHead[ i ]
      NEXT
   ENDIF
   cKey := STR( CheckSum( cc + PROCNAME( 2 ) + PROCNAME( 3 ) + PROCNAME( 4 ) + PROCNAME( 5 ) + PROCNAME( 6 ) + PROCNAME( 7 ) ), 15, 0 )

   IF FILE( "CheckPos.dbf" ) .AND. NetUse( "CheckPos", "CheckPos" )
      IF DBSEEK( UPPER( IDENT_USER + cKey ) )
         IF RIGHT( cc := TRIM( FIELD->CheckPos ), 1 ) != ","
            cc += ","
         ENDIF
         FOR i := 1 TO NUMTOKEN( cc, "," )
            IF ( cToken := TOKEN( cc, ",", i ) ) = "##"
               lFont := .T.
               lOrient:=.F.
               nSel:=0
               LOOP
            ELSEIF ( cToken := TOKEN( cc, ",", i ) ) = "$$"
               lOrient := .T.
               lFont:=.F.
               nSel:=0
               LOOP
            ELSEIF cToken = "!!" .AND. !EMPTY( SUBSTR( cToken, 3 ) )
               cPublicFile := SUBSTR( cToken, 3 )
               LOOP
            ENDIF
            IF !lFont.AND.!lOrient
               AADD( a, VAL( cToken ) )
            ELSEIF lFont
               nSel ++
               IF (j:=ASCAN(aMode,nSel))>0.AND. "шрифт" $ aSelect[ j ]
                  aSelect[ j ] := STUFF( aSelect[ j ], 36, 2, PADL(ALLTRIM(cToken),2) )
               ENDIF
            ELSEIF lOrient
               nSel ++
               IF (j:=ASCAN(aMode,nSel))>0.AND. "ориентация" $ aSelect[j]
                  aSelect[j] := STUFF( aSelect[j], 52, 8, SelectOrient(  cToken ) )
               ENDIF
            ENDIF
         NEXT
      ENDIF
      CLOSE
   ENDIF
   SELECT( nArea )
   FOR i:=1 TO LEN(m->aSelect)
   m->aSelect[i]:=STRTRAN(m->aSelect[i],"шрифт: 0","шрифт: 8")
   NEXT

RETURN a

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure SetCheckPos()
*+
*+    Called from ( outrep_h.prg )   3 - static function correct()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE SetCheckPos( n, aa, aFieldsHead, aMode )

LOCAL nCheckSum, cKey
LOCAL nArea     := SELECT(), c := ""
LOCAL lOpen, i
LOCAL a, cc := m->GlobalTask
LOCAL aOrient:=ARRAY(20)
LOCAL aFont:=ARRAY(20)
MEMVAR aSelect

AFILL(aOrient,"п")
AFILL(aFont,"8")
FOR i:=1 TO LEN(aMode)
IF !EMPTY(aMode[i])
   aOrient[aMode[i]]:=SUBSTR(aSelect[i],52,1)
   aFont[aMode[i]]:=SUBSTR(aSelect[i],36,2)
ENDIF
NEXT


altd()

   IF VALTYPE( aFieldsHead ) = "A"
      IF TYPE( "nHeadHeight" ) != "N"
        PRIVATE nHeadHeight := LEN( aFieldsHead )
      ENDIF

      FOR i := 1 TO MIN(2,MIN( LEN( aFieldsHead ), nHeadHeight ))
         cc += aFieldsHead[ i ]
      NEXT

   ENDIF
   nCheckSum := CheckSum( cc + PROCNAME( 2 ) + PROCNAME( 3 ) + PROCNAME( 4 ) + PROCNAME( 5 ) + PROCNAME( 6 ) + PROCNAME( 7 ) )
   cKey      := STR( nCheckSum, 15, 0 )

   //altd()

   //IF aa==NIL
   //   a:=ACLONE(n)
   //ELSE
   a := ACLONE( aa )
   ASIZE( a, LEN( a ) + 1 )
   AINS( a, 1 )
   a[ 1 ] := n
   AADD( a, "##" )  //дальше идут шрифты

   FOR i := 1 TO LEN(aFont)
      AADD( a, aFont[i] )
   NEXT
   AADD( a, "$$" )  //дальше идут первые буквы ориентации бумаги
   FOR i := 1 TO LEN( aOrient )
      AADD( a, aOrient[i] ) 
   NEXT

   IF FILE( "CheckPos.dbf" ) .AND. LEN( a ) > 0 .AND. NetUse( "CheckPos", "CheckPos" )
      FOR i := 1 TO LEN( a )

         IF VALTYPE( a[ i ] ) = "C" 
            cc:= ALLTRIM( a[ i ] )
         ELSE
            cc:= ALLTRIM( STR( a[ i ] ) )
         ENDIF
         IF EMPTY(cc)
            cc:="0"
         ENDIF
         c+=cc+","
      NEXT
      c += "!!" + IF( EMPTY( cPublicFile ), "", cPublicFile )
      IF !DBSEEK( UPPER( IDENT_USER + cKey ) )
         APPEND BLANK
      ELSE
         Bs_RLock()
      ENDIF
      REPLACE USER WITH IDENT_USER, CheckSum WITH nCheckSum, CheckPos WITH c
      UNLOCK
      CLOSE
   ENDIF
   SELECT( nArea )
RETURN

STATIC FUNCTION CreateExcel()
LOCAL oWorkBook,cc,i
LOCAL lIniFormat:=!EMPTY(SetExcelFormat())

   TRY
   oApp := CreateObject( "Excel.Application" )
   CATCH
   TRY
   oApp := CreateObject( "Excel.Application.11" )
   CATCH
   TRY
   oApp := CreateObject( "Excel.Application.10" )
   CATCH
   TRY
   oApp := CreateObject( "Excel.Application.9" )
   CATCH
   TRY
   oApp := CreateObject( "Excel.Application.8" )
   CATCH
   ALERT( "Excel не доступен!" )
   ClearTotRepStatic()
   RETURN .F.
   END
END
END
END
END

altd()


//Busy(.T., 'Формирование отчета ')

oApp:Visible        := .F.
oApp:screenUpdating := .F.
oApp:displayAlerts  := .F.



cListSep := oApp:International( xlListSeparator )
cDecSep  := oApp:International( xlDecimalSeparator )

lIsRus := ( oApp:International( xlCountryCode ) == 7 )

oWorkBook := oApp:WorkBooks:Add()
IF oWorkBook:Worksheets:Count < 1
   oAS := oWorkBook:Worksheets():Add()
ELSE
   oAS := oWorkBook:Worksheets( 1 )
ENDIF
oAS:Name := "Report"
oAS:Activate()
oApp:calculation := xlCalculationManual
nDone            := 1
nDoneExcel       := 1

IF !EMPTY(lIniFormat)
   aPicture:=StrToArray(SetExcelFormat(),"│")
   nFields:=LEN(aPicture)
   aColWidth:=ARRAY(nFields)
   aResultCol:=ARRAY(nFields)
   FOR i:=1 TO LEN(aPicture)
   aColWidth[i]:=LEN(aPicture[i])
   aResultCol[i]:=i
   NEXT
   sFormat:=sFormat0:=SetExcelFormat()
   MakeFormatExcel()
//   SetExcelStyle("TEXT") 
   SetExcelStyle("") 
ENDIF

IF (TYPE("lHardKart")=="L".AND.m->lHardKart).OR.lKart.OR.!EMPTY(SetExcelFormat())
   oAS:Cells:Font:Name := "Courier New"
//   Str2File(DTOC(DATE())+"  "+TIME())
   SetExcelStyle(0)   
ELSE
   oAS:Cells:Font:Name := cExcelFont
   StrToExcel(DTOC(DATE())+"  "+TIME())
ENDIF
RETURN .T.

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function CreateWord()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   3 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION CreateWord()

LOCAL oWorkBook

   TRY
   oApp := CreateObject( "Word.Application" )
   CATCH
   TRY
   oApp := CreateObject( "Word.Application.11" )
   CATCH
   TRY
   oApp := CreateObject( "Word.Application.10" )
   CATCH
   TRY
   oApp := CreateObject( "Word.Application.9" )
   CATCH
   TRY
   oApp := CreateObject( "Word.Application.8" )
   CATCH
   ALERT( "Word не доступен!" )
   ClearTotRepStatic()
   RETURN .F.
   END
END
END
END
END

oApp:Visible                       := .F.
oApp:Options:CheckGrammarAsYouType := .F.

//oApp:screenUpdating:=.F.
//oApp:displayAlerts:=.F.

oApp:Documents:Add()
oApp:Options:Overtype := .F.
oAS                   := oApp:Selection()
oAS:Font:Name         := "Courier New"
oAS:Font:Size         := SelectFont()

nDone := 1
nDoneExcel := 1

RETURN .T.

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function CreateXML(cFile)
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION CreateXML(cFile)

LOCAL oElement
   FERASE(cFile)

   TRY
   oApp := CreateObject( "MSXML2.DomDocument.4.0" )
   CATCH
   ALERT( "MsXml2 не доступен!" )
   RETURN .F.
   END

   oApp:setProperty( "NewParser", .T. )
   oApp:appendChild(oApp:createProcessingInstruction('xml', 'version="1.0" encoding='+GetCPXML()))
   oDataPacket := oApp:AppendChild( oApp:createElement( "DATAPACKET" ) )
   oDataPacket:setAttribute( "Version", "2.0" )

RETURN .T.

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function WinView()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION WinView( cFile, lContinue )
LOCAL o,i,nIndex

   
   //Busy(.F.)

   IF DOS_MODE .OR. ( nSelectMode = 0 .AND. cFile != NIL .AND. FILE( cFile ) )
      RETURN 1
   ENDIF
   IF RIGHT( cFile, 1 ) = "."
      cFile := LEFT( cFile, LEN( cFile ) - 1 )
   ENDIF

   IF !( cFile[ 2 ] $ ":/\" )
      cFile := DIRNAME() + "\" + cFile
   ENDIF

   IF WIN_MODE
#ifndef __PLATFORM__Linux
      RunShell( "notepad",, cFile )
      sleep( 500 )
#endif
   ELSEIF WORD_MODE
#ifndef __PLATFORM__Linux
      WriteBuffer()
      IF TYPE("lExtendFormat")=="L".AND.m->lExtendFormat //для расчетных листков
         oApp:Selection:WholeStory()
         oApp:Selection:ParagraphFormat:KeepTogether = .T.
      ENDIF
      TRY
         IF cSelectOrient="л"
               oApp:ActiveDocument:PageSetup:Orientation := wdOrientLandscape
         ELSE 
               oApp:ActiveDocument:PageSetup:Orientation := wdOrientPortrait
         ENDIF
      END

      oApp:Selection:HomeKey( wdStory )
      oApp:Options:CheckGrammarAsYouType := .T.
      oApp:Visible                       := .T.
#endif
   ELSEIF OOW_MODE

#ifdef __PLATFORM__Linux
      // alert( curdir()+" "+iif(File("./zipoow.sh"),"T","F") )
      oApp:Save("./zipoow.sh")
#else
      oApp:Save(.T.)
altd()
      cPublicFile := Nil
#endif
   ELSEIF EXCEL_MODE
#ifndef __PLATFORM__Linux
      nIndex:=oAS:Index
      WriteBuffer()
      Busy(.T.,"Подготовка параметров страницы")
      FOR i:=1 TO oApp:Sheets:count()
      oAS:=oApp:Sheets(i)
      oAS:activate()
      oAS:Cells:Font:Size := SelectFont()
      IF EXCEL_DRILL.AND.nIndex==1
         oAS:Outline:SummaryRow := xlAbove
         IF VALTYPE( nGroup ) = "N" .AND. nGroup > 0 .AND. EMPTY( aGroup[ 1, 2 ] )
            oAS:Outline:SummaryRow := xlBelow
         ENDIF
         oAS:Outline:ShowLevels( 1 )
      ENDIF
      TRY
         IF UseVariant()=="0"
            oAS:PageSetup:LeftMargin := oApp:InchesToPoints(0)
            oAS:PageSetup:RightMargin := oApp:InchesToPoints(0)
            oAS:PageSetup:TopMargin := oApp:InchesToPoints(0)
            oAS:PageSetup:BottomMargin := oApp:InchesToPoints(0)
            //oAS:PageSetup:FitToPagesWide := 1
         ENDIF
         IF cSelectOrient="л"
               oAS:PageSetup:Orientation := xlLandscape
         ELSE
               oAS:PageSetup:Orientation := xlPortrait
         ENDIF
      END
      
      IF nIndex==1.AND.!(TYPE("lHardKart")="L".AND.m->lHardKart).AND.!(TYPE("lHardHead")="L".AND.m->lHardHead).AND.EMPTY(SetExcelFormat())
         oAS:Cells:Select()
         oApp:Selection:Columns:AutoFit()
      ENDIF
      oAs:Range( "A1" ):Select()
      NEXT
      Busy(.F.)

      oApp:screenUpdating := .T.
      oApp:calculation    := xlCalculationAutomatic
      oApp:displayAlerts  := .T.
      oAS:=oApp:Sheets(1)
      oAS:activate()
      oAs:Range( "A1" ):Select()
      oApp:Visible        := .T.
#endif
   ELSEIF OOC_MODE
#ifndef __PLATFORM__Linux
      Busy(.T.,"Подготовка формата")
      oApp:Save(.T.)
      Busy(.F.)
      cPublicFile := NIL
#endif
   ELSEIF XML_MODE
#ifndef __PLATFORM__Linux
      oApp:Save( OemToAnsi( cPublicFile + ".xml" ) )
      SayAndWait( "Файл " + cPublicFile + ".xml сформирован!", 8 )
      cPublicFile := NIL
#endif
   ENDIF
   ClearTotRepStatic()
RETURN 0

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function GetPictFromToken()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION GetPictFromToken( cToken )

LOCAL n   := AT( ".", cToken )
LOCAL cc1 := "-0123456789"
LOCAL cc2 := "99999999999"
   IF n = 0
      RETURN ""
   ENDIF
RETURN CHARREPL( cc1, cToken, cc2 )

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure MakeFormatExcel()
*+
*+    Called from ( outrep_h.prg )   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE MakeFormatExcel(cFormat)

#ifndef __PLATFORM__Linux
LOCAL i
IF cFormat!=NIL

ENDIF



   FOR i := 1 TO LEN( aPicture )
         oAS:columns( i ) :ColumnWidth := aColWidth[ i ] + 1
      
         IF !EMPTY(aPicture[ i ]).AND.EMPTY( TRIM( CHARREM( "-0123456789.,", aPicture[ i ] ) ) )
            oAS:columns[ i ] :Rows:NumberFormat := GetNumExcelPict( aPicture[ i ] )
            aPicture[ i ]                       := STRTRAN( aPicture[ i ], ',', "" )
//            aPicture[ i ]                       := STRTRAN( aPicture[ i ], '.', cDecSep )
         ELSE
            oAS:columns[ i ] :Rows:NumberFormat = "@"
         ENDIF
   NEXT
#endif
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Function GetXFile()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
FUNCTION GetXFile( cFile )

LOCAL cXFile

   IF "." $ cFile
      cXFile := LEFT( cFile, RAT( ".", cFile ) - 1 )
   ELSE
      cXFile := TRIM( cFile )
   ENDIF
   IF LEN( TRIM( SUBSTR( cXFile, RAT( "\", cXFile ) + 1 ) ) ) >= 8
      cXFile := LEFT( TRIM( cXFile ), LEN( TRIM( cXFile ) ) - 1 )
   ENDIF
RETURN cXFile + "_.dbf"

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function XXTOC()
*+
*+    Called from ( outrep_h.prg )   5 - static procedure printgroup()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION XXTOC( uVal, i, oRow, oFields )

LOCAL cType := VALTYPE( uVal ), cc, cFstr, cPict
   IF LEFT( LTRIM( aPict0[ i ] ), 1 ) = 'H'
      aPicture[ i ] := EVAL( bStFormat, i, LEN( aPicture[ i ] ), aPicture[ i ] )
   ENDIF

   DO CASE
   CASE cType = "N"
      IF EXCEL_MODE.AND.!lKart
         cFStr := IF( uVal = 0, "", STRTRAN( TRANSFORM( uVal, aPicture[ i ] ), ".", cDecSep ) )
      ELSE
         cPict := LEFT( LTRIM( aPict0[ i ] ), 1 )
         DO CASE
         CASE cPict = 'V' .AND. SELECT( 'VALUTA' ) > 0
            aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), Valuta->Accuracy )
         CASE cPict = 'W' .AND. SELECT( 'VALUTA' ) > 0
            aPicture[ i ] := SummaPic( Valuta->Accuracy, LEN( aPicture[ i ] ), .T. )
         CASE cPict = 'Q' .AND. SELECT( 'MGrup' ) > 0
            aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), MGrup->Kol_ )
         CASE cPict = 'K' .AND. SELECT( 'MGrup' ) > 0
            aPicture[ i ] := GetPict( LEN( aPicture[ i ] ), MGrup->Kol1_ )
         ENDCASE
         uVal  := VAL( ATREPL( ',', ( cc := TRANSFORM( uVal, LTRIM( aPicture[ i ] ) ) ), '' ) )
         cFStr := IF( uVal != 0, PADC( cc, aColWidth[ i ] ), SPACE( aColWidth[ i ] ) )
      ENDIF
   CASE cType = "D"
      cFStr := PADC( DTOC( uVal ), aColWidth[ i ] )
   CASE cType = "L"
      IF uVal
         IF ( TYPE( "sYesSyn" ) = "U" )
            cFStr := PADC( "Да", aColWidth[ i ] )
         ELSE
            cFStr := PADC( sYesSyn, aColWidth[ i ] )
         ENDIF
      ELSE
         IF ( TYPE( "sNoSyn" ) = "U" )
            cFStr := PADC( "Нет", aColWidth[ i ] )
         ELSE
            cFStr := PADC( sNoSyn, aColWidth[ i ] )
         ENDIF
      ENDIF
   CASE cType = "U"
      cFStr := ""
   OTHERWISE
      IF EXCEL_MODE.AND.!lKart
         cFStr := TRIM( uVal )
      ELSE
         uVal  := MEMOTRAN( TRIM( uVal ), " ", " " )
         cFStr := PADR( SPACE( COUNTLEFT( aPicture[ i ] ) ) + ;
                        MEMOLINE( uVal, LEN( LTRIM( aPicture[ i ] ) ), 1 ), aColWidth[ i ] )
      ENDIF
   ENDCASE
RETURN cFstr

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure XXToExcel()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   3 - static procedure printgroup()
*+                                   1 - static procedure repairforexcel()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE XXToExcel( cString, aMerge, aFormul, nColor, lBorder,lBreak)

#ifndef __PLATFORM__Linux
LOCAL n := LEN( cString ), oRange, i
IF TYPE("lHardKart")=="L".AND.m->lHardKart
   cString:=STRTRAN(cString,CHR(K_TAB),"│")
   Str2File(cString)
ELSEIF EXCEL_MODE
   IF cString[ 1 ] == CHR( K_TAB )
      cString := SUBSTR( cString, 2 )
   ENDIF
   IF RIGHT( cString, 1 ) == CHR( K_TAB )
      cString := LEFT( cString, LEN( cString ) - 1 )
   ENDIF
   cString += CHR( 13 ) + CHR( 10 )

   ToBuffer( cString )
   IF aMerge != NIL
      WriteBuffer()
      oAS:Range( GetRange( aMerge[ 1 ], aMerge[ 2 ] ) ) :MergeCells := .T.
   ENDIF
   IF !EMPTY(aFormul)
      
      WriteBuffer()
      IF !(TYPE("lNoFormuls")="L".AND.m->lNoFormuls).AND.oAS:Index=1
         FOR i := 1 TO LEN( aFormul )
            
            oAs:Cells( nDoneExcel, aFormul[ i, 1 ] ) :Formula := ;
                    OEMTOANSI( IF( lIsRus, "=ПРОМЕЖУТОЧНЫЕ.ИТОГИ(9" + cListSep, "=SUBTOTAL(9" + cListSep ) + GetRange( aFormul[ i, 1 ], aFormul[ i, 1 ], aFormul[ i, 2 ], aFormul[ i, 3 ], aFormul[ i, 4 ], aFormul[ i, 5 ] ) + ")" )
         NEXT
      ENDIF
   ENDIF
   IF nColor != NIL
      WriteBuffer()
      oRange := oAS:Range( GetRange( 1, nFields ) )
      SetBorder( oRange, nColor, lBorder )
   ENDIF
ELSE   
   IF VALTYPE(cString)=="C".AND.CHR(K_TAB)$cString
      cString:=TabStringToArray()
   ENDIF
//altd()
   oApp:AddRow(cString,StyleType(nColor),IF(aMerge!=NIL,aMerge[2],),aFormul,lBreak)
ENDIF
#endif




RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure InitXmlRow()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE InitXmlRow()

RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure ToBuffer()
*+
*+    Called from ( outrep_h.prg )   1 - static procedure xxtoexcel()
*+                                   1 - static procedure strtoword()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE ToBuffer( cString )
IF !OOC_MODE
   IF '"' $ cString
      cString := STRTRAN( cString, '"', "'" )
   ENDIF

   IF EMPTY( cBuffer )
      nLineBuffer := nDoneExcel
   ENDIF
   cBuffer += cString
   IF LEN( cBuffer ) > 60000
      WriteBuffer()
   ENDIF
ENDIF
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure WriteBuffer()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - procedure cleartotrepstatic()
*+                                   1 - static function toexcel()
*+                                   1 - static procedure excelheader()
*+                                   1 - static function hdrtoexcel()
*+                                   1 - static function strtoexcel()
*+                                   1 - static procedure repairforexcel()
*+                                   2 - function winview()
*+                                   3 - static procedure xxtoexcel()
*+                                   1 - static procedure tobuffer()
*+                                   1 - static procedure strtoword()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE WriteBuffer(lNoCRLF)
#ifndef __PLATFORM__Linux
IF !OOC_MODE
   IF (!EMPTY( cBuffer ).OR.(CHR(13)+CHR(10))$cBuffer) .AND. oAS != NIL
      Wvt_SetClipBoard( cBuffer )
      IF EXCEL_MODE
         oAs:Cells( nLineBuffer, 1 ):Select()
         oAS:Paste()
         oApp:Selection() :wraptext := .T.
      ELSE
         TRY
            oAS:Paste()
         END
         IF EMPTY(lNoCRLF)
            oAS:typeText( CHR( 13 ) + CHR( 10 ) )
         ENDIF
      ENDIF
   ENDIF
   cBuffer := ""
ENDIF
#endif
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure StrToWord()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   5 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE StrToWord( cString, lRepair )
   IF lRepair == NIL
      lRepair := .T.
   ENDIF
   IF CHR( 12 ) $ cString
/******************
.OR.(nDone>10.AND.;
     "Касса за "$cString.AND.;
     "Лист"$cString.AND.!"Лист    1"$cString) //в том числе для кассовой книги
*****************/

//altd()

      IF TYPE("lExtendFormat")=="L".AND.m->lExtendFormat //для расчетных листков
         cString:=STRTRAN(cString,CHR(12),CHR(13)+CHR(10))
         ToBuffer(cString)
         WriteBuffer()
      ELSE
         WriteBuffer()
         oAs:InsertBreak()
      ENDIF
      cString:=STRTRAN(cString,CHR(12),"")
      IF EMPTY(cString)
         RETURN
      ENDIF
   ENDIF

   IF sFormat != NIL .AND. LEN( cString ) > LEN( sFormat ) + 1 .AND. lRepair
      cString := RepairForTxt( cString )
   ENDIF
   IF TYPE("lExtendFormat")=="L".AND.m->lExtendFormat
      ToBuffer(cString)
      WriteBuffer("NoCrLf")
      oAs:InsertBreak(wdLineBreak)
   ELSE
      ToBuffer( cString + CHR( 13 ) + CHR( 10 ) )
   ENDIF
RETURN


*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure HdrToWord()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE HdrToWord( a, lContinue )

#ifndef __PLATFORM__Linux
LOCAL x, i, lBold := lContinue == NIL .OR. !lContinue
   IF ( lContinue == NIL .OR. !lContinue )
      x := DTOC( DATE() ) + " " + TIME() + " "
      Wvt_SetClipBoard( x )
      oAS:Font:Bold := .F.
      oAS:Paste()
      oAS:typeText( CHR( 13 ) + CHR( 10 ) )
   ENDIF
   FOR i := 1 TO LEN( a )
      x := a[ i ]
      IF ( lContinue == NIL .OR. !lContinue )
         oAS:Font:Bold := lBold
      ENDIF
      IF nStrWid != NIL
         IF !EMPTY( LEFT( x, 3 ) ) .AND. !"ПРЕДПРИЯТИЕ" $ UPPER( x )
            lBold := .F.
         ENDIF
         x := IF( EMPTY( LEFT( x, 3 ) ) .AND. !lKart.AND.;
         !(TYPE( "lHardKart" ) = "L" .AND. m->lHardKart),;
         PADC( ALLTRIM( x ), nStrWid ), PADR( x, nStrWid ) )
      ENDIF
      x := STRTRAN( x, " :", ":" )
      oAS:Font:Bold := lBold
      IF EMPTY( x )
         oAS:typeText( CHR( 13 ) + CHR( 10 ) )
      ELSE
         oAS:typeText( SPACE( CountLeft( x ) ) )
         Wvt_SetClipBoard( LTRIM( x ) )
         oAS:Paste()
         oAS:typeText( CHR( 13 ) + CHR( 10 ) )
      ENDIF
   NEXT
   oAS:Font:Bold := .F.
#endif
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure HeadToWord()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE HeadToWord( a, lContinue )

#ifndef __PLATFORM__Linux
LOCAL cString := ""
   AEVAL( a, { | x | cString += x + CHR( 13 ) + CHR( 10 ) } )
   Wvt_SetClipBoard( cString )
   oAS:Paste()

   IF ( lContinue == NIL .OR. !lContinue ) .AND. ;
      TYPE( "pNoColontitul" ) == "U".AND.!(TYPE( "lHardKart" ) = "L" .AND. m->lHardKart)
      IF oApp:ActiveWindow:View:SplitSpecial = wdPaneNone
         oApp:ActiveWindow:ActivePane:View:Type := wdPrintView
      ELSE
         oApp:ActiveWindow:View:Type := wdPrintView
      ENDIF

      oApp:ActiveWindow:ActivePane:View:SeekView := wdSeekCurrentPageHeader
      oApp:Selection():Font:Name := "Courier New"
      oApp:Selection():Font:Size := SelectFont()
      oAS:Paste()
      oApp:ActiveWindow:ActivePane:View:SeekView := wdSeekMainDocument
      oApp:ActiveDocument:PageSetup:DifferentFirstPageHeaderFooter := .T.

      IF oApp:ActiveWindow:View:SplitSpecial = wdPaneNone
         oApp:ActiveWindow:ActivePane:View:Type := wdNormalView
      ELSE
         oApp:ActiveWindow:View:Type := wdNormalView
      ENDIF
   ENDIF

#endif
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function ReconfigureTotVal()
*+
*+    Called from ( outrep_h.prg )   2 - static procedure printgroup()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION ReconfigureTotVal( nGNum )

LOCAL i, n, j
LOCAL aGrupTotVal
   aGrupTotVal := ARRAY( LEN( aTotFields0[ nGNum ] ) )
   IF sFormat0 != NIL .AND. sFormat == sFormat0
      RETURN aTotVal[ nGNum ]
   ENDIF
   AFILL( aGrupTotVal, 0 )
   FOR i := 1 TO LEN( aTotFields[ nGNum ] )
      n := aResultCol[ aTotFields[ nGNum, i ] ]
      j := ASCAN( aTotFields0[ nGNum ], n )
      aGrupTotVal[ j ] := aTotVal[ nGNum, i ]
   NEXT
RETURN aGrupTotVal

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function SelectFont()
*+
*+    Called from ( outrep_h.prg )   1 - static function createword()
*+                                   1 - function winview()
*+                                   1 - static procedure headtoword()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION SelectFont()

   IF VALTYPE( nSelectFont ) = "N" .AND. nSelectFont > 2 .AND. nSelectFont < 20
      RETURN nSelectFont
   ENDIF
RETURN 8

STATIC FUNCTION SelectOrient(cToken)
RETURN IF(cToken="л","ландшафт","портрет ")



*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function IsHead()
*+
*+    Called from ( outrep_h.prg )   1 - function str2file()
*+                                   1 - static function repairfortxt()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION IsHead( cString )

RETURN ;
       UPPER( m->LBL_BOSS2 ) $ UPPER( cString ) .OR. ;
        UPPER( LBL_SHEF2 ) $ UPPER( cString ) .OR. ;
        "ИТОГО" $ UPPER( cString ) .OR. ;
        "ОСТАТОК" $ UPPER( cString ) .OR. ;
        "СУММАРНЫЙ ОБОРОТ" $ UPPER( cString ) .OR. ;
        UPPER( LTRIM( cString ) ) = "ОБОРОТ" .OR. ;
        "САЛЬДО" $ UPPER( cString )

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function IsHead()
*+
*+    Called from ( outrep_h.prg )   1 - function str2file()
*+                                   1 - static function repairfortxt()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION IsHead1( cString )

RETURN ;
        (":"$cString.AND.;
         (;
        "От кого получено"$cString.OR."или кому выдано"$cString.OR.;
         ("   5  "$cString.AND." 2 "$cString);
         ))


*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure WriteXmlRow()
*+
*+    Called from ( outrep_h.prg )   1 - static procedure printgroup()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE WriteXmlRow()

LOCAL i, lMetaIni := .F., oRow, oMetaData, uVal, oField, cType

   IF oFields == NIL
      lMetaIni  := .T.
      oMetaData := oDataPacket:AppendChild( oApp:createElement( "METADATA" ) )
      oFields   := oMetadata:AppendChild( oApp:createElement( "FIELDS" ) )
   ENDIF

   IF oRowData == NIL
      oRowData := oDataPacket:AppendChild( oApp:createElement( "ROWDATA" ) )
   ENDIF
   oRow := oRowData:AppendChild( oApp:createElement( "ROW" ) )
   FOR i := 1 TO nFields
      uVal := IF( VALTYPE( aBlockPicture[ i ] ) == 'B', EVAL( aBlockPicture[ i ] ), &( aFieldsName[ i ] ) )
      IF lMetaIni
         oField:=oFields:AppendChild(oApp:createElement("FIELD"))
         oField:SetAttribute("head",xmlVal(aRes[i]))
         oField:SetAttribute("attrname","F"+ALLTRIM(STR(i)))
         oField:SetAttribute("fieldtype",XmlType(cType:=VALTYPE(uVal),aPicture[i]))
         IF cType=="C"
            oField:SetAttribute("width",LEN(uVal))
         ENDIF
      ENDIF

      oRow:SetAttribute("F"+ALLTRIM(STR(i)),XmlVal(uVal))
   NEXT
   IncDone()
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function XmlType()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION XmlType( cType, cPict )

LOCAL cRet := "string"
   DO CASE
   CASE cType == "N"
      IF "." $ cPict
         cRet := "i4"
      ELSE
         cRet := "r8"
      ENDIF
   CASE cType == "D"
      cRet := "date"
   CASE cType == "L"
      cRet := "boolean"
   ENDCASE
RETURN cRet

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure StrToOOW()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   5 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE StrToOOW( cString, lRepair )

   IF lRepair == NIL
      lRepair := .T.
   ENDIF
   IF CHR( 12 ) $ cString
      oApp:AddPara( oStyleBreak )
      ADDTEXT2OOW(STRTRAN(cString,CHR(12),""))
      RETURN
   ENDIF

   IF sFormat != NIL .AND. LEN( cString ) > LEN( sFormat ) + 1 .AND. lRepair
      cString := RepairForTxt( cString )
   ENDIF
   oApp:AddPara( oStyleNorm )
   ADDTEXT2OOW( cString )
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure HdrToOOW()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE HdrToOOW( a, lContinue )

LOCAL x, i, lBold := .T.
   IF ( lContinue == NIL .OR. !lContinue )
      oApp:AddPara( oStyleNorm )
      ADDTEXT2OOW( DTOC( DATE() ) + " " + TIME() )
   ENDIF
   FOR i := 1 TO LEN( a )
      x := a[ i ]
      IF nStrWid != NIL
         IF !EMPTY( LEFT( x, 3 ) ) .AND. !"ПРЕДПРИЯТИЕ" $ UPPER( x )
            lBold := .F.
         ENDIF
         x := IF( EMPTY( LEFT( x, 3 ) ) .AND. !lKart, PADC( ALLTRIM( x ), nStrWid ), PADR( x, nStrWid ) )
      ENDIF
      x := STRTRAN( x, " :", ":" )
      IF EMPTY( x )
         oApp:AddPara( oStyleNorm )
      ELSEIF CHR(12)$x
         oApp:AddPara(oStyleBreak)
         ADDTEXT2OOW(StrTran(x,CHR(12),""))
      ELSE
         oApp:AddPara( Iif( lBold,oStyleBold,oStyleNorm ) )
         ADDTEXT2OOW( SPACE( CountLeft( x ) ) + LTRIM( x ) )
      ENDIF
   NEXT
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Procedure HeadToOOW()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   1 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC PROCEDURE HeadToOOW( a, lContinue )

   AEVAL( a, {|x| ( oApp:AddPara(IF(CHR(12)$x,oStyleBreak,oStyleNorm),ADDTEXT2OOW(STRTRAN(x,CHR(12),""))) ) } )
   
RETURN

*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
*+    Static Function CreateOOW()
*+
*+    Called from ( outrep_h.prg )   1 - function totrep()
*+                                   3 - function str2file()
*+
*+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
*+
STATIC FUNCTION CreateOOW()

   cPublicFile := TempFile(_TMP_DIR,"odt")
   oApp:=HOOWriter():New(cPublicFile,m->GlobalTmpPath)
   oStyleNorm := HOOStyle():New( "Courier New",SelectFont() )
   oStyleBold := HOOStyle():New( "Courier New",SelectFont(),.T. )
   oStyleBreak:= HOOStyle():New( "Courier New",SelectFont(),,,,,.T.)
RETURN .T.

STATIC FUNCTION CreateOOC(nLen)
LOCAL nCols,aWidth:=ARRAY(nCols),aPict,i
LOCAL lIniFormat:=!EMPTY(SetExcelFormat())

IF !EMPTY(lIniFormat).AND.EMPTY(aPicture)
   aPicture:=StrToArray(SetExcelFormat(),"│")
   nFields:=LEN(aPicture)
   aColWidth:=ARRAY(nFields)
   aResultCol:=ARRAY(nFields)
   FOR i:=1 TO LEN(aPicture)
   aColWidth[i]:=LEN(aPicture[i])
   aResultCol[i]:=i
   NEXT
   sFormat:=sFormat0:=SetExcelFormat()
   nLen:=NIL
   SetExcelStyle("")
ENDIF

   cPublicFile := TempFile(_TMP_DIR,"ods")
   IF EMPTY(nLen)
      oApp:=HOOCalc():New(cPublicFile,,aColWidth,aPicture,m->GlobalTmpPath,IF(!EMPTY(lIniFormat).OR.(TYPE( "lHardKart" ) = "L" .AND. lHardKart),"Courier New",cExcelFont),nSelectFont,EMPTY(lIniFormat))
   ELSE
      IF nLen==500
         nCols:=1
         aWidth:=ARRAY(nCols)
         aPict:=ARRAY(nCols)
         AFILL(aWidth,nLen)
         AFILL(aPict,REPLICATE("X",nLen))
      ELSE
         nCols:=INT(nLen/11)+2
         aWidth:=ARRAY(nCols)
         aPict:=ARRAY(nCols)
         AFILL(aWidth,11)
         AFILL(aPict,REPLICATE("X",11))
      ENDIF
      oApp:=HOOCalc():New(cPublicFile,,aWidth,aPict,m->GlobalTmpPath,"Courier New",nSelectFont)
   ENDIF
   cListSep := ";"
   cDecSep  := "."
RETURN .T.



STATIC FUNCTION ADDTEXT2OOW( s )
Local i, i1, nLen

   IF CHR(255)$s
      s:=STRTRAN(s,CHR(255)," ")
   ENDIF


   DO WHILE .T.
      IF ( i := At( "  ",s ) ) == 0
         EXIT
      ELSE       
         oApp:AddText( TOUTF8( Left( s,i-1 ) ) )
         i1 := i + 2
         nLen := Len( s )
         DO WHILE i1 <= nLen .AND. Substr( s,i1,1 ) == " "
            i1 ++
         ENDDO
         oApp:AddSpaces( i1-i-1 )
         s := Substr( s,i1 )
      ENDIF
   ENDDO


   oApp:AddText( TOUTF8( s ) )

RETURN Nil

STATIC FUNCTION TOUTF8( s )

   s := OEM2UTF8( s )
RETURN s

STATIC FUNCTION IsMyNumber(cc)
RETURN !EMPTY(cc).AND.EMPTY(TRIM(CHARREM("-0123456789.,"+CHR(13)+CHR(10),cc))).AND.;
(EMPTY(cc[1])) //.OR.cc[1]!="0")


STATIC FUNCTION StyleType(nColorIndex,nAlignment)
IF nColorIndex==nHeadColor
   RETURN 1
ELSEIF nColorIndex==nItogoColor
   RETURN 2
ELSEIF nAlignment==xlCenter
   RETURN 3
ENDIF
RETURN NIL


STATIC FUNCTION TabStringToArray(cString)
LOCAL aArray:={}, i
LOCAL cDelim:=CHR(K_TAB)
IF RIGHT(cString,2)==CHR(13)+CHR(10)
   cString:=LEFT(cString,LEN(cString)-2)
ENDIF
While ( (i:=AT(cDelim,cString)) > 0 )
  AADD(aArray, LEFT(cString, i-1))
  cString:=LTRIM(SUBSTR(cString,i+1))
End
If !EMPTY(cString)
  AADD(aArray,cString)
EndIf
RETURN (aArray)

FUNCTION GetExcelFont()
LOCAL cFont:="Courier New",cFontFile:="xlsfont.txt",cc
IF FILE(cFontFile).AND.!EMPTY(cc:=CHARREM(CHR(13)+CHR(10),MEMOREAD(cFontFile)))
   cFont:=cc
ENDIF
RETURN cFont



FUNCTION StrToArray(cString,cDelim)
LOCAL aArray:={}, i, a:={}, n:=1
cDelim:=If(cDelim==Nil,";",cDelim)
n:=NumToken(cString,cDelim)
IF n>0
   For i:=1 To n
     AADD(aArray,Token(cString,cDelim,i))
   Next
ENDIF
RETURN (aArray)

FUNCTION SetExcelFormat(cFormat) //новая технология работы с Екселем и OOC
//Задает жесткую форму с заданным форматом 
STATIC sF:=""
IF VALTYPE(cFormat)=="C"
   sF:=cFormat
ENDIF
RETURN sF

FUNCTION SetExcelStyle(cStyle)
/*
Работает только в новой технологии
TEXT - обычная строка текста
TABHEAD - заголовок таблицы 
TAB0 - строка таблицы 
TAB1 - строка таблицы с разделителями столбцов
TABTOTAL - строка таблицы итого
*/
STATIC sStyle:=""

IF VALTYPE(cStyle)=="C"
   sStyle:=UPPER(cStyle)
   IF EMPTY(cStyle).OR.sStyle$"TEXT,TABHEAD,TAB0,TAB1,TABTOTAL"
      sStyle:=cStyle
   ENDIF
ENDIF
RETURN sStyle


STATIC PROCEDURE GetaSelectModeFromXML_SETUP(aMode,aSelect,nLen)
LOCAL cX:=PADR(SUBSTR(_XML_SETUP,11),20) 
LOCAL i,j
STATIC  aSelect0
IF EMPTY(aSelect0)
   aSelect0 := { ;
   PADR( "  DOS-печать", nLen ),;
   PADR( "  Notepad-блокнот", nLen ),;
   PADR( "  MS Excel                   шрифт: 8  ориентация: портрет ", nLen),;
   PADR( "  MS Excel с группировкой    шрифт: 8  ориентация: портрет ", nLen),;
   PADR( "  MS Word                    шрифт: 8  ориентация: портрет ", nLen),;
   PADR( "  XML", nLen ),;
   PADR( "  OpenOffice Calc   2.0      шрифт: 8                      ", nLen),;
   PADR( "  OpenOffice Writer 2.0      шрифт: 8                      ", nLen);
   }
ENDIF
altd()

aMode:=ARRAY(10)
aSelect:=ARRAY(10)
FOR i:=1 TO LEN(aSelect0)
IF (j:=VAL(SUBSTR(cX,i*2-1,2)))>0.AND.j<=LEN(aSelect0)
   aSelect[j]:=aSelect0[i]
   aMode[j]:=i
ENDIF
NEXT
WHILE (j:=ASCAN(aMode,NIL))>0
   ADEL(aMode,j)
   ADEL(aSelect,j)
   ASIZE(aMode,LEN(aMode)-1)
   ASIZE(aSelect,LEN(aSelect)-1)
ENDDO
RETURN



PROCEDURE SetDefaultProp(nFont1,nOrient1,nFont2,nOrient2,lClear)
LOCAL i
STATIC sFont1,sOrient1,sFont2,sOrient2
IF !EMPTY(lClear)
   sFont:=NIL
   sOrient:=NIL
ELSEIF nFont1==NIL.AND.TYPE("aSelect")=="A"
   FOR i:=1 TO LEN(m->aSelect)
   IF "Excel   "$m->aSelect[i]
      sFont1:=VAL(SUBSTR(m->aSelect[i],36,2))
      sOrient1:=IF("ландш"$m->aSelect[i],2,1)
   ELSEIF "Calc"$m->aSelect[i]
      sFont2:=VAL(SUBSTR(m->aSelect[i],36,2))
      sOrient2:=IF("ландш"$m->aSelect[i],2,1)
   ENDIF
   NEXT
ELSEIF !EMPTY(sFont1)
   nFont1:=sFont1
   nOrient1:=sOrient1
   nFont2:=sFont2
   nOrient2:=sOrient2
ENDIF
RETURN 









