XML   ODS   ODT   HTML/HTM   Главная   Страница в Интернет
Бланк в ODT и готовый отчет по нему.



Для запуска примера кликните m4rg.exe, программа выведет форму для выбора бланка ( ODS, XML,ODT, HTML/HTM), после чего сформированный отчет будет тут-же показан на экране.

ПРИМЕР ЗАПУСКА на основе бланка ODT
DO m4rg.exe WITH "test_lists_odt.odt","проба test_lists2.odt",0

или c конвертацией в doc (должен быть установлен Open Office!)
DO m4rg.exe WITH "test_lists_odt.odt","проба test_lists2.doc",0



ГЕНЕРАЦИЯ ОТЧЕТА НА ОСНОВЕ БЛАНКА ODT

Почему именно ODT?
Во первых, я разобрался с ODS :-), а разница между форматами ODS и ODT НЕВЕЛИКА.
Во вторых - я не разобрался с XLSX :-( , основным конкурентом ODS (ну, это я так думаю).

В бланках ODT продолжена традиция описания действий в примечаниях (т.е. точно так же, как и в ODS и XML).
В нужном месте вставляете примечание, в самом примечании - описываете необходимый код. Вот и все операции.

Типы размещаемого кода FoxPro
Код может быть так же (как в ODS/XML) в двух синтаксисах:
синтаксис 1 - если примечание НЕ НАЧИНАЕТСЯ с &, предполагается, что дальнейшее - код foxpro
return test_.saldo
или
return dtoc(date())
или "сложный" код (это пример, здесь можно написать что угодно :-) )
local ii
ii=test_.saldo
return ii

синтаксис 2 - начинаясь с & - предполагается, что дальнейшее - это поле, функция или переменная
пример:
&test_.saldo
или
&dtoc(date())


Особенности бланков формата ODT
1. Отличие (от ODS и XML) написания формулы расчета суммы по колонке.
Сумма по колонке считается не по фактически нарисованной таблице в файле, а по данным источника - курсора или таблицы (в отличие от формата ODS или XML - где данные собираются прямо ИЗ ЯЧЕЕК).
Главная причина, почему это сделано - отсутствие подитогов в ODT.
Поэтому, для расчета суммы нужно записать, например:
return rowssum('test_.saldo')
или
&rowssum('test_.saldo')
т.е. указав поле, по которому сумма будет расчитываться.
ОБРАТИТЕ ВНИМАНИЕ! 'test_.saldo' взято в скобки!
Использование функций rowsrecno() - № строки в группе/отчете и rowscount() - количество строк в группе/отчете - осталось без изменений.


2. Одна служебная колонка вместо трех.
Колонка может выполнять функцию ОБЫЧНОЙ колонки, хотя это НЕ РЕКОМЕНДУЕТСЯ - результат в этом случае НЕПРЕДСКАЗУЕМ.

3. Код FoxPro должен возвращать (оператором return - в 1 синтаксисе) значение, которое будет вставлено в генерируемый файл.

4. В бланках ODT отсутствуют управляющие операторы thisdata, thisformula, thiscomment и функция add_report() - которые использовались в ODS и XML соответственно, для указания значения ячейки, указания формулы, указания примечания и генерации нового листа книги (возможно, в дальнейшем сделаю генерацию зависимых отчетов).
Как задать значение в тексте ODT или в ячейке таблицы? Смотрите чуть ниже.

5. Значение, которое будет получено кодом FoxPro или функцией/полем/переменной может быть различных типов.
Но, при генерации в отчет будет вставлено текстовое значение.

Вместо Numeric - STRTRAN(LTRIM(STR(значение,15,2)),".",",") - т.е. с 2 разрядами после запятой
Вместо Date - DTOC(значение)
Вместо DateTime - TTOC(значение)
Вместо Character - текст БЕЗ ИЗМЕНЕНИЙ
Иные типы - пустая строка - ""

Поэтому, если Вас не устраивает автоматичесое приведение к тексту - можете заранее это сделать сами.
например, для возврата ЦЕЛОГО значения ВМЕСТО
return test_.saldo
или
&test_.saldo

ВВЕДИТЕ
return str(test_.saldo)
или
&str(test_.saldo)



Разработка бланка ODT.
1. Открываете/создаете документ в формате ODT, в котором нужно разместить каркас документа.
2. В нужных местах - вставляете [[]] , а между [[ и ]] - примечание. Если примечание начинается с & - предполагается что дальше - поле, функция или переменная. В ином случае - предполагается, что дальше идет код FoxPro, который должен вернуть значение оператором return (Что, впрочем необязательно).
Например, можно разместить дату генерации отчета:
&dtoc(date())
или
return dtoc(date())

3. Если необходимо в документе разместить расчетную таблицу (она будет формироваться по селекту) - рисуете ее с учетом того, что колонок будет на единицу больше (служебная колонка) и не забудьте задать особое название.

ОБЯЗАТЕЛЬНО ЗАДАЙТЕ НАЗВАНИЕ ДЛЯ РАСЧЕТНОЙ ТАБЛИЦЫ, начинающееся с report!
Иначе, таблица либо вообще генериться НЕ БУДЕТ, либо генератор выдаст ошибку при формировании.

Сделать это можно через пункты меню Таблица - Свойства таблицы , и, далее, введя, например, в поле название reportТаблица1
Повторюсь, ТОЛЬКО задав название таблицы с report в начале, Вы определяете, что это именно расчетная таблица!

Если у Вас несколько расчетных таблиц в одном odt-файле - нужно для КАЖДОЙ задать имя, начинающееся с report.
Например, reportТаблица1, reportТаблица2, и т.д. или
report1, report2, report3 и т.д.
Названия расчетных таблиц не должны совпадать. К сожалению, Open Office Вас не предупредит об этом, и попытается сам вставить что-либо другое. Будьте бдительны!

После "рисования" в служебной колонке определяете тип строки.
Например,
Thistype='reportheader' - для заголовка отчета или группы.
Thistype='detail' - для обычной строки отчета.
Thistype='reportfooter' - для строки подвала отчета или группы.
Далее, нужно определить параметры группировки.

В этой же колонке, например
Thisgroup='test_.t2'
или
Thisgroup='test_.t1'
Если Thisgroup='' или не задано - считается, что строка относится не к группе, а к отчету (заголовку или подвалу отчета).

4. После задания служебной информации нужно проставить, что Вы хотите видеть в каждой ячейке строки расчетной таблицы.
Если это обычный текст - так его и вводите.
Для размещения значения поля таблицы нужно вставить
[[]] с текстом примечания между [[ и ]] (что не обязательно, но очень рекомендуется)
В тексте примечания ячеки строки detail вписываете, например:
для показа значения поля test_.saldo
(1 синтаксис)
Return test_.saldo
или
(2 синтаксис)
&test_.saldo


Значение может быть довольно сложным, например
&test_.t1+test_.addr
или
Return alltrim(test_.fam)+' '+alltrim(test_.im)+' '+alltrim(test_.ot)

В строке reportheader или reportfooter можно разместить специальную функцию для подсчета суммы по полю таблицы, например по test_.saldo
return rowssum('test_.saldo')
или
&rowssum('test_.saldo')
Обратите внимание на кавычки - они строго необходимы, так как программа будет собирать итоги именно по этому полю, а не по значениям в генерируемой таблице (отличие от ODS и XML)!

В ячейке первой колонки первой строки для таблицы нужно определить по какому селекту/курсору эта таблица будет строиться.
В примечании пишете:
Procedure Init
Select * from test into cursor test_ order by t1,t2,user_id
т.е. точно так же, как при работе с ODS/XML

В одном документе может быть несколько (решать Вам) таблиц с разных ресурсов, главное - задать в первой ячейке первой служебной колонке procedure init с кодом инициализации!

5. Уменьшите ширину служебных колонок всех таблиц до минимального уровня - мышкой (перетаскиванием) это сделать не получится, зато можно сделать по другому - кликаете мышкой по границе, выбираете столбец - ширина - и задаете ширину 0 для первой колонки.

6. Сохраняете документ, запускаете генератор, выбираете сохраненный шаблон ODT и получаете готовый документ. Все.
Один нюанс. Пока генератор НЕ ПОДДЕРЖИВАЕТ встроенные друг в друга расчетные таблицы! Будьте внимательны!

Рекомендации по бланкам ODT:

1. Рекомендуется перед вставкой примечания внести [[]], а уже само примечание разместить между [[ и ]]
Зачем?
Написав [[]] вы определяете стиль текста (например, цвет, размер, шрифт и т.д.), который будет сгенерен примечанием (иначе - результат может быть НЕПРЕДСКАЗУЕМ).
Ну и, кроме того, это дополнительная (но не обязательная!) метка для сигнализации - "тут есть некоторое действие!"
Кстати, символы [[ и ]] будут из конечного текста удалены.

Rambler's Top100 Рейтинг@Mail.ru Участник проекта CMS Magazine