Visual FoxPro 9.0 обеспечивает существенные расширения процесса создания вывода, включая новые возможности вызывать прикладной код во время штатного внутреннего управления Системой Отчетов и процедуру рендеринга вывода. Чтобы соответственно обеспечить пользователей возможностью разрабатывать такие программы, Visual FoxPro 9.0 расширяет также сообщения об ошибках и систему отлаживания в течение выполнения отчета.

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

Обратите внимание:
Прикладные компоненты типа Report Output Application и Report Preview Application взаимодействуют с Visual FoxPro Report System во время осуществления вывода. Они функционируют как устройства обеспечения соответствующих объектных ссылкок на Механизм Отчета. Хотя эти компоненты могут вызвать ошибки и требовать отладки, они не активны в течение внутреннего выполнения отчета, который охватывает события обработки от события BeforeReport до события AfterReport. Вы можете отладить любые проблемы этими компонентами, подобно любому другому приложению Visual FoxPro; они не не охватываются полностью данной темой. Для подробной информации о последовательности событий в выполняемом отчете, см. Understanding Visual FoxPro Object-Assisted Reporting .

Совет:
Вы можете использовать все стандартные средства отладки Visual FoxPro, типа Trace Window при исследовании кода вашей системы отчетов. Вы также найдете ReportListener Debug Foundation Class полезным, по мере Вашего изучения последовательности событий отчета.

Стратегии обработки ошибок в течение выполнения отчета

Поскольку последовательность обработки вывода Visual FoxPro может включать обширный пользовательский код, Вам может потребоваться закончить выполнение отчета прежде, чем он завершится из-за ошибки в коде. Вы можете также захотеть заввершить выполенние отчета преждевременно, потому что конечный пользователь желает его прервать. Дополнительно, внешний обработчик ошибки может обнаружить причину для завершения вашего приложения, в то время как выполнение отчета находится в процессе.

Во всех этих ситуациях, Вы можете вызвать метод ReportListener CancelReport чтобы быть уверенным, что Visual FoxPro сделает любую специальную очистку, типа закрытия очереди на печать, необходимое для безопасного завершения отчета и вашего приложения. См. CancelReport Method для подробной информации.

ReportListener User Feedback Foundation Class обеспечивает добротную модель отмены отчета в ответ на запрос конечного пользователя. См. тему DoMessage Method для получения кода метода этого класса CancelReport. Обратите внимание, что метод применяет NODEFAULT, если конечный пользователь решил возобновить выполнение отчета через диалоговое окно. Ваш код может придерживаться подобной стратегии в ответ на некритичные ошибки. Для критичных ошибок, Вы можете предпочесть завершить отчет в одностороннем порядке, и закончить выполнение приложение после завершения отчета.

Вы можете выяснить, завершился ли отчет нормально использованием функции SYS(2024). Эта функция возвратит "Y" во время выполнения отчета, через событие завершения Unload, если выполнение отчета не было завершено нормально. В этой точке, внутренняя обработка Системы Отчетов Visual FoxPro завершается. Если Вы решаете, что аварийное завершение выполнения отчета произошло не как ответ на действия конечного пользователя, то Вы можете безопасно выполнить CANCEL или QUIT или выполнить подобную обработку из внешнего объекта приложения. Для подробной информации, см. Microsoft Visual FoxPro Technical Support .

Пример 1: Отмена отчета

В следующем примере, ошибка происходит в событии ReportListener'а BeforeReport, и его обработчик события Error отвечает вызовом метода CancelReport этого класса. Код обработки события UnLoadReport сообщает о значении SYS(2024) равном "Y", как результате срабатывания события Error.

Обратите внимание:
Если бы ошибка произошла во время обработки события LoadReport, SYS(2024) не возвратила бы "Y". Никакого внутреннего процесса отчета в этот момент еще не происходит, так что механизму Отчета не требуется выполнения кода очистки.

Скопировать код
DEFINE CLASS errorListener as ReportListener
PROCEDURE BeforeReport()
REPORT FORM ?
ENDPROC
PROCEDURE Error(nError, cMethod, nLine)
WAIT WINDOW MESSAGE()
* MESSAGE() вернет:
* Отчет содержит ошибку вложения.
THIS.CancelReport()
ENDPROC
PROCEDURE UnloadReport()
WAIT WINDOW SYS(2024)
* SYS(2024) вернет: "Y"
ENDPROC
ENDDEFINE

Пример 2: Завершение приложения в результате ошибки отчета

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

Для определения из внешнего кода того, что статус соответствует моменту выполнения отчета, используйте функцию SYS(2040). Для подробной информации, см. SYS(2040) - Detect Report Status .

Следующий пример проверяет возвращаемое значение SYS(2040) в обработчике команды ON ERROR Command .

Скопировать код
PUBLIC oApp
oApp = CREATEOBJECT("MyApp")
ON ERROR oApp.ErrorHandler()
WAIT WINDOW "Some processing here..."
REPORT FORM ? OBJECT oApp.oE
WAIT WINDOW ;
"Some more processing here, " + ;
"will not occur because of error..."
DEFINE CLASS MyApp AS Custom
oE = NULL
PROCEDURE Init
THIS.oE = CREATEOBJECT("errorListener")
ENDPROC
PROCEDURE ErrorHandler
MESSAGEBOX("Error! " + MESSAGE())
IF SYS(2040) # "0"
THIS.oE.cancelReport()
ENDIF
IF _VFP.StartMode = 0
CANCEL
ELSE
QUIT
ENDIF
ENDPROC
ENDDEFINE
DEFINE CLASS errorListener as ReportListener
PROCEDURE BeforeBand()
* parameters are missing
ENDPROC
PROCEDURE CancelReport()
DODEFAULT()
MESSAGEBOX("Cancelling Report!")
ENDPROC
ENDDEFINE

Пример 3: Отмена отчета во время завершения приложения

Вы можете использовать подобную стратегию в обработчике ON SHUTDOWN, если это будет возможным для данного обработчика быть вызванным в процессе выполнения отчета. Обработчик ON SHUTDOWN требует ссылку на соответствующий объект ReportListener, так как это делает объект приложения в примере выше. Для подробной информации, см. ON SHUTDOWN Command .

Совет:
Таймеры не срабатывают при выполнении отчета или этикетки. Однако, не исключается возможность конечным пользователям принимать решение о закрытии вашего приложения, в то время как Visual FoxPro продолжает генерировать вывод. Поэтому, не считайте, что необходимость отмены отчета всегда связана с ошибкой.

Вы можете использовать следующий простой пример, чтобы проверить эту возможность.

Скопировать код
PUBLIC rl
ON SHUTDOWN DO MyShutdown
rl = CREATEOBJECT("reportListener")
REPORT FORM ? OBJECT rl && используйте достаточно длительный отчет!
* используйте значок закрытия главного окна Visual FoxPro
* во время выполнения отчета.
PROCEDURE MyShutDown
IF SYS(2040) # "0"
MESSAGEBOX("Now Cancelling Report!")
rl.CancelReport()
ENDIF
ON SHUTDOWN
IF _VFP.StartMode = 0
CANCEL
ELSE
QUIT
ENDIF
ENDPROC

Пример 4: Использование события Error ReportListener

В двух из тех трех примеров выше, класс ReportListener не имеет кода обработки события Error. Если Вы включаете обработку события Error в класс ReportListener, как показано в первом примере, этот код может решить обработать, или делегировать любую ошибку, которую он получает.

Если событие Error обрабатывает ошибку, оно может безопасно использовать CANCEL или QUIT. Вы можете использовать эти команды в других событиях или методах ReportListener. Тем не менее убедитесь, что Вы вызвали метод ReportListener'а CancelReport () перед применением инструкций CANCEL или QUIT .

В следующем примере, класс ReportListener использует собственное событие Error чтобы обработать ошибку и затем немедленно завершает отчет.

Совет:
Событие Error ReportListener'а не будет обрабатывать ошибки, которые происходят во время выполнения отчета, но обнаруживаются вне собственного кода ReportListener'а, например, ошибки определяемой пользователем функции (UDF), выполняемой в пределах отчета или ошибки в выражении отчета. По этой причине, наличие кода обработки ошибок ReportListener не освобождает ваш внешний обработчик ошибок от участия в обработке ошибок системы отчетов. Необходима комбинация разных подходов для обработки всех типов ошибок, которые могут произойти в ходе выполнения отчета.

Скопировать код
LOCAL oE
oE = CREATEOBJECT("errorListener")
WAIT WINDOW "Some processing here..."
REPORT FORM ? OBJECT oE
WAIT WINDOW ;
"Some more processing here, " + ;
"will not occur because of error..."
DEFINE CLASS errorListener as ReportListener
PROCEDURE BeforeBand()
* parameters are missing
ENDPROC
PROCEDURE Error(nError, cMethod, nLine)
WAIT WINDOW "Error occured! " + CHR(13) + ;
"SYS(2024) before CancelReport: " + SYS(2024)
THIS.CancelReport()
CANCEL
ENDPROC
PROCEDURE CancelReport()
IF SYS(2040) # "0"
MESSAGEBOX("Cancelling Report!")
DODEFAULT()
WAIT WINDOW "SYS(2024) is now: " + SYS(2024)
ENDIF
ENDPROC
ENDDEFINE

Пример 5: Использование структурной обработки ошибок отчетов

В качестве заключительной стратегии, Вы можете использовать структурную обработку ошибок в отчетах. Однако, когда Вы выполняете типовой код ниже, обратите внимание, что ваш код не добирается до конструкции CATCH, пока не закончится выполнение отчета в перспективе Системы Отчетов. Хотя Вы можете использовать метод CancelReport, пользовательский код которого должен быть предназначен для безопасного выполнения с учетом того, действительно ли отчет происходит фактически.

Скопировать код
LOCAL oE
TRY
oE = CREATEOBJECT("errorListener")
WAIT WINDOW "Some processing here..."
REPORT FORM ? OBJECT oE
WAIT WINDOW ;
"Some more processing here, " + ;
"will not occur because of error..."
CATCH WHEN .T.
WAIT WINDOW "An error occured! " + CHR(13) + ;
"SYS(2024)=" + SYS(2024) + CHR(13) + ;
"SYS(2040)=" + SYS(2040)
* SYS(2024) will report "N"
* SYS(2040) will report "0"
oE.CancelReport()
ENDTRY
DEFINE CLASS errorListener as ReportListener
PROCEDURE BeforeBand()
* parameters are missing
ENDPROC
PROCEDURE CancelReport()
IF SYS(2040) = "0"
MESSAGEBOX("No report in progress, " + CHR(13) + ;
"but this method can still do user cleanup!")
NODEFAULT
ELSE
MESSAGEBOX("Cancelling Report!")
DODEFAULT()
ENDIF
ENDPROC
ENDDEFINE

Ошибки в течение выполнения отчета, которые не содержатся в строках программы

В Visual FoxProе 9.0 и всех более ранних версиях имеется возможность ошибок в течение выполнения отчета, которые определенно не связаны с данными трассировки пользовательского кода. Такие ошибки включают выражения отчета или переменные отчета, которые Механизм Отчета не может распознать, так же как трудности инициализиции окружения данных отчета.

Visual FoxPro 9.0 поддерживает обратную совместимость с собственной обработкой таких ошибок, как описано в этом разделе.

Когда происходит ошибка во внешнем пользовательском коде, внутренняя обработка ошибок Visual FoxPro не предлагает Вам возможность приостановить отчет, потому что не существует строки программы, на которой можно остановиться.

Если Вы не имеете обработчика ON ERROR или конструкции TRY… ENDTRY в этом месте, Visual FoxPro не вызывает вашу обработку ошибок, пока он не выполнит внутренний код завершения и не закончит выполнение отчета.

Как демонстрируется в примерах этой темы, значение функции MESSAGE() доступно, если это происходит в коде ReportListener, или в другом пользовательском коде, который Вы вызываете в течение выполнения отчета. Однако, если ошибка не связана со строкой программы, MESSAGE() не присваивается, пока Механизм Отчета не завершает работу.

Если ошибка не связана со строкой программы, значение MESSAGE() не присваивается вообще, если Вы не имеете некоторого способа обработки ошибок в этом месте во время выполнения команд REPORT FORM или LABEL . Если Вы не имеете обработчика ошибок, и если Вы использовали команду CLEAR ERROR перед выполнением отчета, MESSAGE() имеет все ещё пустое значение после начала выполнения отчета. Если Вы не использовали CLEAR ERROR , MESSAGE() сохраняет свое предыдущее значение.

Команды, которые не поддерживаются в течение выполнения отчета

Для правильной обработки ошибок, Вы должны запланировать использование только тех команд, использование которые являются безопасным в течение выполнения отчета.

Все команды Visual FoxPro в таблице ниже не поддерживаются во время внутреннего выполнения вывода, между событиями BeforeReport и AfterReport (включительно).

Не все ошибки в этой таблице будут немедленно генерировать ошибку, но их использование во время процесса вывода ведет к непредсказуемым результатам.

Эти команды не поддерживаются, происходят ли они:

  • Непосредственно в коде события ReportListener'а.

  • В дополнительном коде, вызванном ReportListener'ом, типа кода из библиотеки процедур.

  • В окне command, в то время как выполнение приостановлено.

  • Использованием кода, вызванного непосредственно в выражениях отчета или этикетки, типа определяемых пользователем функций (UDFs).

В некоторых случаях, как обозначено в таблице, команды также не поддерживаются в событиях ReportListener'а LoadReport Event и UnloadReport Event . Эти два ограничивающих события обеспечивают пользовательский захват процесса внутреннего выполнения с обеих сторон.

Как последний, исключительный случай, это выполнение метода OutputPage Method, который может продолжаться после завершения отчета, если был вызван объектом PreviewContainer, когда, возможно, он нуждается в доступе к ресурсам, встроенным в приложение, типа файлов изображений, для продолжения выполнения своей задачи. По этой причине, использование команды типа CLEAR ALL, которое могло бы выгрузить вызываемое приложение из памяти, не поддерживается, пока предварительный просмотр не будет завершен. Когда команды REPORT FORM или LABEL включают ключевое слово NOWAIT , предварительный просмотр заканчивается при закрытии окна предварительного просмотра, если пользователь не начинает из него печать. Если пользователь выбирает печать, предварительный просмотр завершается в то время как Visual FoxPro заканчивает вывод отчета на принтер.

Обратите внимание:
В дополнение к нижеупомянутым командам, все команды, которые изменяют сессии, рабочие области, положение указателей зиписи, или другие атрибуты данных над которыми команды REPORT FORM и LABEL производят действия, должны использоваться с предостережением. Как в предыдущих версиях Visual FoxPro, ответственность за восстановление состояния данных при использовании этих команд, лежит на пользователе, при понимании того, что другие ReportListener'ы и дополнительный пользовательский код, так же как и внутренний Механизм Отчета могут оказаться под воздействием изменений этих состояний данных. Например, хотя команда BROWSE отсутствует в этой таблице, она потенциально может изменить указатель записи, вызвать срабатывание дополнительного кода, прикрепленного через определяемые пользователем функции (UDFs), и воздействовать на реляционные отношения данных и поэтому должна использоваться с предостережением.

Команда (ы) Поддерживаемые в обработчике событий LoadReport и UnloadReport ? Замечания

CLEAR ALL

RELEASE ALL

CLOSE ALL

Нет

Это ограничение должно прежде всего сохранить ссылкку на ReportListener и таблицы данных как это ожидается Механизмом Отчета во время процессинга отчета.

RETRY

RETURN TO MASTER

RETURN TO <Procedure Name>

Нет

??????

\, \

@. .. SAY

EJECT, EJECT PAGE

PRINTJOB… ENDPRINTJOB

LIST, DISPLAY, TYPE

SET DEVICE,PRINTER

Да

Эти команды вывода поддерживаются во время выполнения вывода, если целевое устройство для выполнения вывода отличается от целевого устройства для команды вывода. Например, если ваша команда REPORT FORM имеет предложение PREVIEW, Вы можете выполнить LIST MEMO TO <filename> во время выполнения отчета.

BEGIN TRANSACTION и дополнительные связанные с транзакцией команды

Да

Транзакционные команды поддерживаются, если транзакция завершается в пределах одной используемой процедуры или одного события ReportListener.

MODIFY/CREATE CLASS, FORM, LABEL, REPORT […]

Да

Все команды, которые вовлекают интерактивные дизайнеры Visual FoxPro, являются неподдерживаемыми, как модальные, так и вызваные с ключевым словом NOWAIT . Вы можете вызвать текстовый редактор ( MODIFY FILE или COMMAND ).

REPORT FORM

LABEL

Нет

Команды REPORT FORM и LABEL не могут быть вложеными.

Ошибки связанные с Системой Отчетов Visual FoxPro

Следующая таблица представляет перечень ошибок, которые происходят по причинам, специфическим для процессинга отчетов и этикеток в run-time.

Сообщение об ошибке и номер Причина или сценарий

"name" is not an object (Error 1924)

Механизм отчета получил REPORT FORM Command или LABEL Command с предложением OBJECT <ref> и <ref> не является объектом.

Class definition "name" is not found (Error 1733)

Механизм получил NULL в ссылке как результат предложения OBJECT TYPE <N> в команде REPORT FORM или LABEL, указывая, что приложение заданное системной переменной _REPORTOUTPUT не смогло определить это значение как объектную ссылку ReportListener Object .

Data type is invalid for this property (Error 1732)

Механизм получает предложение OBJECT TYPE <N> в команде REPORT FORM или LABEL, и параметр <N> не имеет числового типа. Эта ошибка может также произойти в соединении с использованием метода OutputPage, обсуждаемого ниже.

Report contains a nesting error (Error 1645)

Команды REPORT FORM или LABEL была вызвана во время выполнения другого отчета или этикетки. Обратите внимание, что эта ошибка происходит, даже если вложенная команда использует обратно совместимый режим отчета, если запрашивается другой отчет, или если вложенная команда включает ссылку на другой объект ReportListener.

Syntax error (Error 10)

SET REPORTBEHAVIOR Command была применена с неправильным параметром.

The current object does not inherit from class "name" (Error 1935)

Механизм получил объектную ссылку, которая не унаследована от базового класса Visual FoxPro ReportListener.

Variable "variable" is not found (Error 12)

Механизм получил предложение OBJECT TYPE <N> в команде REPORT FORM или LABEL, и приложение, указанное системной переменной _REPORTOUTPUT не может быть найдено, или переменная имеет пустое значение.

Must specify additional parameters (Error 94)

Function argument value, type, or count is invalid (Error 11)

Data type is invalid for this property (Error 1732)

Error writing to file "file" (Error 1105)

Output page "page" is not available (Error 2194)

Все ошибки в этой группе указывают, что метод ReportListener'а OutputPage был вызван неправильно. Для подробной информации, см. OutputPage Method .

See Also