dExcel

Программы на Clarion, шаблоны, библиотеки и пр.

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Гость

Сообщение Гость »

Здравствуйте, все

Есть брауз, где много-много записей.
Хотелось бы узнать, есть ли метод формирования xls-файла по всему View, или то, что нужно вывести в файл, обязательно загонять в очередь.
Возможно я еще не до конца разобрался ;). Подскажите.

"Дмитрий Гудков" <gudkov_net@mail.ru>

Написал: ClaList(2)
Гость

Сообщение Гость »

См. пример, который идет вместе с либой - просто вместо метода Write:Table() пишешь что-то типа:

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

! Предполагаем что бровз из четырех колонок:
! BrwQueue  QUEUE
! Name        LIKE(FILE:Name)
! Name:Icon   SHORT
! Price       LIKE(FILE:Price)
! Total       LIKE(FILE:Total)
! Summa       LIKE(LOC:Summa)
!           END
!
! Предполагаем, что лист бровза уже был обработан
! методом SetTblFormat() и уже вывели заголовок
! методом Write:Header().
!

  Open(BrwView)
  Set(BrwWiew)
  Loop
    Next(BrwView); if ErrorCode() then Break.
    LOC:Summa = FILE:Price*FILE:Total
    Write:Row(Clip(FILE:Name) &'!'& FILE:Price &'!'& !
              FILE:Total &'!'& LOC:Summa)
  .
  Close(BrwView)
Это - один из вариантов.
Вместо оператора LOC:Summa можно вызывать рутинку от самого бровза, которая формирует все поля бровза и использовать уже их прямо из буфера очереди BrwQueue. Особенно рекомендую, если в бровзе много колонок и часть из них составляются из данных файла в рантайме. Если используется доп. фильтр, сортировка и пр. "навороты", которые явно не указаны в обьявлении BrwView, то рекомендую использовать мой шаблон BrowseViewRead, который генерит нужные рутинки для "охвата" ВСЕХ вышеперечисленных "наворотов", которые генерятся шаблоном бровза и вставляются разработчиком ручками в нужные точки вставки:

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

  do BRWx::ViewRead:Init
  Loop
    do BRWx::ViewRead:Next
    if BRWx::ViewRead:Complete then Break.
    Write:Row(Clip(BrwQueue.Name) &'!'& BrwQueue.Price &'!'& !
              BrwQueue.Total &'!'& BrwQueue.Summa)
  .
  do BRWx::ViewRead:Done
Я этот шаблон как-то уже "бросал" в числе нескольких других.
Можно посмотреть на общедоступных Кларион-сайтах.

Ну и, в конце концов, можно вместо использования метода Write:Row() самому записывать значения прямо в нужные ячейки таблицы. Правда, муторно это! :D - прийдется делать самому всю черновую работу, которую и делают методы класса dExcelTbl.

=============================
С уважением, Олег А. Руденко.
Oleg_Rudenko@mail.ru
Oleg_Rudenko@mail333.com
Библиотека DynaLib
http://dynalib.narod.ru

Большое спасибо за совет.
Шаблона нигде не нашел, может кинешь на мыло <gudkov_net@mail.ru>,если не трудно.

Дмитрий Гудков
Написал: ClaList(2)
Гость

Сообщение Гость »

Шаблон небольшой и, возможно, пригодится еще кому, так что - "кидаю" прямо в рассылку.

ШВС С55, последняя версия.
Одно замечание - не помню точно есть-ли в них нужные точки вставки, так что перед установкой шаблона следует проверить их наличие:
- файл CTLBROW.TPW
- рутинка %InstancePrefix:FillRecord ROUTINE

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

    ...
    #EMBED(%FillRecordStartLoop,'FillRecord ROUTINE - Начало цикла считывания
записей'),%ActiveTemplateInstance,MAP(%ActiveTemplateInstance,%ActiveTemplateinstanceDescription),HIDE
    ...
    #EMBED(%FillRecordEndLoop,'FillRecord ROUTINE - Конец цикла считывания
записей'),%ActiveTemplateInstance,MAP(%ActiveTemplateInstance,%ActiveTemplateinstanceDescription),HIDE

Можно данный шаблон "засунуть" в один из TPW-файлов
из стандартного набора ШВС, например в конец файла EXTENS.TPW.
Или создать новый набор шаблонов, создав новый TPL-файл:
#!------------------------------------------------------------------------------
#TEMPLATE(Browse_Extensions,'Дополнительные шаблоны для BROWSE')
#!------------------------------------------------------------------------------

и вставить в него нижеприведенный код.
Только не забудьте после этого зарегистрировать этот новый
набор шаблонов.
    
#!------------------------------------------------------------------------------
#!------------------------------------------------------------------------------
#EXTENSION(BrowseViewRead,'Чтение записей в BrowseBox'),DESCRIPTION('Чтение записей в BrowseBox для ' &
%Primary),REQ(BrowseBox(Clarion))
#!------------------------------------------------------------------------------
#BOXED('')
  #DISPLAY('Данный шаблон генерит рутинки, которые позволяют')
  #DISPLAY('легко организовать чтение записей из текущего View,')
  #DISPLAY('учитывая все рукописные фильтры во вставках.')
#ENDBOXED
#SHEET
  #TAB('Рутинки')
    #BOXED('')
      #DISPLAY('BRWx::ViewRead:Init - Инициализация')
      #DISPLAY('    Запоминает текущую позицию во View.')
      #DISPLAY('    Инициализирует View для последующего чтения.')
      #DISPLAY('BRWx::ViewRead:Next - Следующая запись')
      #DISPLAY('    Читает в буфер следующую запись, которая')
      #DISPLAY('    удовлетворяет всем условиям фильтрации.')
      #DISPLAY('BRWx::ViewRead:Prev - Предыдущая запись')
      #DISPLAY('    Читает в буфер предыдущую запись, которая')
      #DISPLAY('    удовлетворяет всем условиям фильтрации.')
      #DISPLAY('BRWx::ViewRead:Done - Завершение')
      #DISPLAY('    Возвращает указатель во View в позицию')
      #DISPLAY('    перед инициализацией.')
    #ENDBOXED
  #ENDTAB
  #TAB('Переменные')
    #BOXED('')
      #DISPLAY('Перед чтением можно задать кол-во записей,')
      #DISPLAY('которые следует пропустить - BRWx::ViewRead:Skip.')
      #DISPLAY('При инициализации и после каждого чтения данная')
      #DISPLAY('переменная обнуляется.')
      #DISPLAY('')
      #DISPLAY('После операций чтения следует проверять')
      #DISPLAY('переменную BRWx::ViewRead:Complete.')
      #DISPLAY('Данная переменная выставляется в True при')
      #DISPLAY('достижении конца или начала текущего View.')
      #DISPLAY('')
      #DISPLAY('Можно, так-же, использовать:')
      #DISPLAY('BRWx::ViewRead:TotalRecs - Всего записей во View')
      #DISPLAY('BRWx::ViewRead:Counter - Считано записей')
    #ENDBOXED
  #ENDTAB
#ENDSHEET
#!
#ATSTART
  #DECLARE(%ReadPrefix)
  #SET(%ReadPrefix,%InstancePrefix&':ViewRead')
  #COMMENT(50)
#ENDAT
#!
#AT(%DataSectionAfterWindow)
!-------------------------------------------------------------------------------
#SET(%ValueConstruct,%ReadPrefix&':Complete')
%[20]ValueConstruct BYTE                         #<! Конец или начало View
#SET(%ValueConstruct,%ReadPrefix&':TotalRecs')
%[20]ValueConstruct LONG                         #<! Кол-во записей во View
#SET(%ValueConstruct,%ReadPrefix&':Counter')
%[20]ValueConstruct LONG                         #<! Всего считано записей
#SET(%ValueConstruct,%ReadPrefix&':Skip')
%[20]ValueConstruct LONG                         #<! Перескочить столько записей
#SET(%ValueConstruct,%ReadPrefix&':SaveViewPos')
%[20]ValueConstruct STRING(1024)                 #<! Позиция во View перед инициализацией
!-------------------------------------------------------------------------------
#ENDAT
#!
#AT(%FillRecordStartLoop),WHERE(%Control = %ListControl)
%ReadPrefix:Complete = True
#ENDAT
#!
#AT(%FillRecordEndLoop),WHERE(%Control = %ListControl)
%ReadPrefix:Complete = False
#ENDAT
#!
#AT(%ProcedureRoutines)
!-------------------------------------------------------------------------------
! Реализация "ручного" чтения записей из %ListView
!-------------------------------------------------------------------------------
#SET(%ValueConstruct,%ReadPrefix & ':Init')
%[20]ValueConstruct ROUTINE
  %ReadPrefix:Complete = False
  %ReadPrefix:SaveViewPos = POSITION(%ListView)
  DO %InstancePrefix:Reset
  %ReadPrefix:TotalRecs = RECORDS(%ListView)
  %ReadPrefix:Counter = 0
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Next')
%[20]ValueConstruct ROUTINE
  %InstancePrefix:FillDirection = FillForward
  %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
  CLEAR(%InstancePrefix:RecordCount)
  %InstancePrefix:AddQueue = False
  DO %InstancePrefix:FillRecord
  IF ~%ReadPrefix:Complete
     %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
  END
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Prev')
%[20]ValueConstruct ROUTINE
  %InstancePrefix:FillDirection = FillBackward
  %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
  CLEAR(%InstancePrefix:RecordCount)
  %InstancePrefix:AddQueue = False
  DO %InstancePrefix:FillRecord
  IF ~%ReadPrefix:Complete
     %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
  END
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Done')
%[20]ValueConstruct ROUTINE
  REGET(%ListView,%ReadPrefix:SaveViewPos)
  DO %InstancePrefix:RefreshPage
!-------------------------------------------------------------------------------
#ENDAT
Удачи!

=============================
С уважением, Олег А. Руденко

Вариант без шаблона работает, (правда если как говорилось выше нет фильтров и т.п.)
А вот вариант с шаблоном не пашет.
Все вроде сделал как написано, а не работает :(
Вот embed на accepte у кнопки, может чего не так??:

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

XLS.ShowError = True
XLS.CreateFile('booksall.xls')
XLS.SetTblFormat(?list)
XLS.Write:Header()
do BRW2::ViewRead:Init
  Loop
    do BRW2::ViewRead:Next
    if BRW2::ViewRead:Complete then Break.
        xls.Write:Row(Clip(Queue:Browse.BRW2::all:title) &'!'& Queue:Browse.BRW2::ser:seria &'!'& !
                      Queue:Browse.BRW2::pub:publ &'!'& Queue:Browse.BRW2::all:year)
  .
do BRW2::ViewRead:Done
Шаблон записал в tpl все зарегистрировал, вроде все нормально, может еще какие вставки надо сделать?
В xls-файл пихается только выбранная строка,
но столько раз сколько записей в View(т.е например 5000 одинаковых записей в xls-таблице получается),фильтры учитываються, тут все нормально.

Что не так подскажите пожалуйста.

"Дмитрий Гудков" <gudkov_net@mail.ru>

Написал: ClaList(2)
Гость

Сообщение Гость »

Сорри, забыл добавить в прошлом письме, что шаблон сам НЕ обновляет буфер записи очереди BRWxxx - не стал этого делать сознательно - кто его знает, возможно буфер используется другими шаблонами для своих целей. Тем более, что я, обычно, использую только обновленные буфера файлов, задействованных в рабочей VIEW.
Поэтому, если необходимо обновление буфера, то надо после вызова рутинки ViewRead:Next просто вставить вызов рутинки BRWxxx::FillQueue.
В Вашем, Дмитрий, случае это:

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

  Loop
    do BRW2::ViewRead:Next
    do BRW2::FillQueue
    if BRW2::ViewRead:Complete then Break.
       xls.Write:Row(Clip(Queue:Browse.BRW2::all:title) &'!'& !
                     Queue:Browse.BRW2::ser:seria &'!'& !
                     Queue:Browse.BRW2::pub:publ &'!'& !
                     Queue:Browse.BRW2::all:year)
  .

Вот теперь, после считывания очередной записи VIEW
будет заполнен буфер записи рабочей очереди именно
теми значениями, которые выводятся на экран.

Или воспользуйтесь доработанной версией шаблона.
Если включить переключатель, то рутинки ViewRead:Next/Prev
сами будут вызывать рутинку обновления рабочей очереди.
Т.е., таким образом, Ваш исходный код останется без
изменений, но работать будет уже так, как необходимо.

#!------------------------------------------------------------------------------
#!------------------------------------------------------------------------------
#EXTENSION(BrowseViewRead,'Чтение записей в BrowseBox'),DESCRIPTION('Чтение записей в BrowseBox для ' &
%Primary),REQ(BrowseBox(Clarion))
#!------------------------------------------------------------------------------
#BOXED('')
  #DISPLAY('Данный шаблон генерит рутинки, которые позволяют')
  #DISPLAY('легко организовать чтение записей из текущего View,')
  #DISPLAY('учитывая все рукописные фильтры во вставках.')
  #PROMPT('Обновлять буфер рабочей очереди?',CHECK),%ViewReadFillQueue,AT(10),DEFAULT(%False)
#ENDBOXED
#SHEET
  #TAB('Рутинки')
    #BOXED('')
      #DISPLAY('BRWx::ViewRead:Init - Инициализация')
      #DISPLAY('    Запоминает текущую позицию во View.')
      #DISPLAY('    Инициализирует View для последующего чтения.')
      #DISPLAY('BRWx::ViewRead:Next - Следующая запись')
      #DISPLAY('    Читает в буфер следующую запись, которая')
      #DISPLAY('    удовлетворяет всем условиям фильтрации.')
      #DISPLAY('BRWx::ViewRead:Prev - Предыдущая запись')
      #DISPLAY('    Читает в буфер предыдущую запись, которая')
      #DISPLAY('    удовлетворяет всем условиям фильтрации.')
      #DISPLAY('BRWx::ViewRead:Done - Завершение')
      #DISPLAY('    Возвращает указатель во View в позицию')
      #DISPLAY('    перед инициализацией.')
    #ENDBOXED
  #ENDTAB
  #TAB('Переменные')
    #BOXED('')
      #DISPLAY('Перед чтением можно задать кол-во записей,')
      #DISPLAY('которые следует пропустить - BRWx::ViewRead:Skip.')
      #DISPLAY('При инициализации и после каждого чтения данная')
      #DISPLAY('переменная обнуляется.')
      #DISPLAY('')
      #DISPLAY('После операций чтения следует проверять')
      #DISPLAY('переменную BRWx::ViewRead:Complete.')
      #DISPLAY('Данная переменная выставляется в True при')
      #DISPLAY('достижении конца или начала текущего View.')
      #DISPLAY('')
      #DISPLAY('Можно, так-же, использовать:')
      #DISPLAY('BRWx::ViewRead:TotalRecs - Всего записей во View')
      #DISPLAY('BRWx::ViewRead:Counter - Считано записей')
    #ENDBOXED
  #ENDTAB
#ENDSHEET
#!
#ATSTART
  #DECLARE(%ReadPrefix)
  #SET(%ReadPrefix,%InstancePrefix&':ViewRead')
  #COMMENT(50)
#ENDAT
#!
#AT(%DataSectionAfterWindow)
!-------------------------------------------------------------------------------
#SET(%ValueConstruct,%ReadPrefix&':Complete')
%[20]ValueConstruct BYTE                         #<! Конец или начало View
#SET(%ValueConstruct,%ReadPrefix&':TotalRecs')
%[20]ValueConstruct LONG                         #<! Кол-во записей во View
#SET(%ValueConstruct,%ReadPrefix&':Counter')
%[20]ValueConstruct LONG                         #<! Всего считано записей
#SET(%ValueConstruct,%ReadPrefix&':Skip')
%[20]ValueConstruct LONG                         #<! Перескочить столько записей
#SET(%ValueConstruct,%ReadPrefix&':SaveViewPos')
%[20]ValueConstruct STRING(1024)                 #<! Позиция во View перед инициализацией
!-------------------------------------------------------------------------------
#ENDAT
#!
#AT(%FillRecordStartLoop),WHERE(%Control = %ListControl)
%ReadPrefix:Complete = True
#ENDAT
#!
#AT(%FillRecordEndLoop),WHERE(%Control = %ListControl)
%ReadPrefix:Complete = False
#ENDAT
#!
#AT(%ProcedureRoutines)
!-------------------------------------------------------------------------------
! Реализация "ручного" чтения записей из %ListView
!-------------------------------------------------------------------------------
#SET(%ValueConstruct,%ReadPrefix & ':Init')
%[20]ValueConstruct ROUTINE
  %ReadPrefix:Complete = False
  %ReadPrefix:SaveViewPos = POSITION(%ListView)
  DO %InstancePrefix:Reset
  %ReadPrefix:TotalRecs = RECORDS(%ListView)
  %ReadPrefix:Counter = 0
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Next')
%[20]ValueConstruct ROUTINE
  %InstancePrefix:FillDirection = FillForward
  %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
  CLEAR(%InstancePrefix:RecordCount)
  %InstancePrefix:AddQueue = False
  DO %InstancePrefix:FillRecord
  IF ~%ReadPrefix:Complete
     %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
    #IF(%ViewReadFillQueue)
  ELSE
     DO %InstancePrefix:FillQueue
    #ENDIF
  END
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Prev')
%[20]ValueConstruct ROUTINE
  %InstancePrefix:FillDirection = FillBackward
  %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
  CLEAR(%InstancePrefix:RecordCount)
  %InstancePrefix:AddQueue = False
  DO %InstancePrefix:FillRecord
  IF ~%ReadPrefix:Complete
     %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
    #IF(%ViewReadFillQueue)
  ELSE
     DO %InstancePrefix:FillQueue
    #ENDIF
  END
  %ReadPrefix:Skip = 0

#SET(%ValueConstruct,%ReadPrefix & ':Done')
%[20]ValueConstruct ROUTINE
  REGET(%ListView,%ReadPrefix:SaveViewPos)
  DO %InstancePrefix:RefreshPage
!-------------------------------------------------------------------------------
#ENDAT
=============================
С уважением, Олег А. Руденко
Написал: ClaList(2)
Гость

Сообщение Гость »

Т.е., таким образом, Ваш исходный код останется без изменений, но работать будет уже так, как необходимо.
Ошибочка "вкралась"! :)

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

ОАР> #SET(%ValueConstruct,%ReadPrefix & ':Next')
ОАР> %[20]ValueConstruct ROUTINE
ОАР>   %InstancePrefix:FillDirection = FillForward
ОАР>   %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
ОАР>   CLEAR(%InstancePrefix:RecordCount)
ОАР>   %InstancePrefix:AddQueue = False
ОАР>   DO %InstancePrefix:FillRecord
ОАР>   IF ~%ReadPrefix:Complete
ОАР>      %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
ОАР>     #IF(%ViewReadFillQueue)

!!!!!!! Эту строку надо убрать !!!!!!!!
ОАР>   ELSE
!!!!!!! Эту строку надо убрать !!!!!!!!

ОАР>      DO %InstancePrefix:FillQueue
ОАР>     #ENDIF
ОАР>   END
ОАР>   %ReadPrefix:Skip = 0

ОАР> #SET(%ValueConstruct,%ReadPrefix & ':Prev')
ОАР> %[20]ValueConstruct ROUTINE
ОАР>   %InstancePrefix:FillDirection = FillBackward
ОАР>   %InstancePrefix:ItemsToFill = %ReadPrefix:Skip + 1
ОАР>   CLEAR(%InstancePrefix:RecordCount)
ОАР>   %InstancePrefix:AddQueue = False
ОАР>   DO %InstancePrefix:FillRecord
ОАР>   IF ~%ReadPrefix:Complete
ОАР>      %ReadPrefix:Counter += %ReadPrefix:Skip + 1 - %InstancePrefix:ItemsToFill
ОАР>     #IF(%ViewReadFillQueue)

!!!!!!! Эту строку надо убрать !!!!!!!!
ОАР>   ELSE
!!!!!!! Эту строку надо убрать !!!!!!!!

ОАР>      DO %InstancePrefix:FillQueue
ОАР>     #ENDIF
ОАР>   END
ОАР>   %ReadPrefix:Skip = 0
=============================
С уважением, Олег А. Руденко

(Добавление)

Спасибо большое Олег, все работает на ура.

Дмитрий Гудков
Написал: ClaList(2)
Ответить