:: Visual Foxpro, Foxpro for DOS
Как выйти из программы после ошибки?
spammail_88
Автор

Сообщений: 108
Дата регистрации: 13.11.2010
Программа запускается как отдельный exe. Не в среде VFP. Хочу сделать так, чтобы при возникновении ошибки, программа выводила данные об ошибке и сразу закрывалась, не рискуя потерять данные в таблицах.

Все это выглядит приблизительно так: Запускается форма TopLevel. В ней ещё несколько модальных форм. В последней модальной стартует длинная сложная функция. И, допустим, в середине этой функции происходит ошибка. Ловлю ее так:
ON ERROR DO fShowError

Дальше вывожу сообщение и выхожу:
FUNCTION fShowError()
MESSAGEBOX("Error...")
fQuit()

И вот с выходом проблемы:
FUNCTION fQuit()
ON ERROR *
ON SHUTDOWN
nForm=_Screen.FormCount
FOR iForm=1 to nForm
oForm=_Screen.Forms(iForm)
WITH oForm
.Closable=.T.
.Release()
ENDWITH
NEXT
CLOSE TABLES
CLEAR ALL
CLEAR PROGRAM
CLOSE ALL
CLEAR EVENTS
QUIT
И вот после QUIT мне программа 100500 раз дает диалоговое окно OPEN DBF. То есть, продолжает выполнятся функция, где разные там ZAP, INDEX, USE ... и т.п. И каждый раз оно просит таблицу.

Так все же, как в случае возникновения ошибки грамотно остановить выполнение последующего кода, закрыть все таблицы, формы (на которых есть таймеры), отпустить индексы, курсоры, и выйти из программы? И все это втихую. Без каких-либо сообщений об ошибках, которые будут возникать при закрытии.



Исправлено 1 раз(а). Последнее : spammail_88, 07.10.18 00:39
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не обрабатывая ошибку "снаружи", пытаясь при этом корректно всё закрыть, а обрабатывая ошибки по всей цепочке вызовов - удобнее это делать через try catch, включая возможную эскалацию ошибки в вызывающий код (если корректно обработать ошибку и продолжить выполнение программы нельзя). Но это должно быть ВЕЗДЕ - по всем методам и процедурам, включая стартовую с READ EVENTS.
Для "тупого" выхода есть RETURN TO, и кроме того закрывать формы нужно в обратном порядке, предусматривая при этом что некоторые формы могут закрыться "сами собой" (т.е. грубо говоря при закрытии 5-й формы вполне может автоматически закрыться и 3-я с 4-й, и простой цикл закрытия "сломается" на попытке обратиться к 4-й форме).
Таймеры не исполняют свой код пока работает другой фоксовый код - т.е. они не будут запускаться ни "в процессе", ни тем более после "закрытия всего". Конечно если явно не дать им такой возможности, создав состояние ожидания.


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как выйти из программы после ошибки?
spammail_88
Автор

Сообщений: 108
Дата регистрации: 13.11.2010
Igor Korolyov
а обрабатывая ошибки по всей цепочке вызовов - удобнее это делать через try catch
Нереально, много переписывать. (весь код обепить в TRY ... CATCH)

Igor Korolyov
закрывать формы нужно в обратном порядке
Я сам был удивлен, но, почему то, последняя запущенная форма в массиве .Forms имеет индекс 1. А основная 5. То есть так и выходит, что формы закрываются в обратном порядке. На момент завершения цикла у каждой формы .Release уже сработал, а элемент массива .Forms еще остался. То есть смещения массива не происходит.

Igor Korolyov
и простой цикл закрытия "сломается"
Как мне кажется, от таких ситуаций помогает это:
ON ERROR *

spammail_88
Для "тупого" выхода есть RETURN TO
После RETURN TO MASTER в fQuit() больше ничего не выполняется в том числе и QUIT. И программа не закрывается, даже не смотря на то, что главная программа выглядит как то так:
DO FORM MainForm
READ EVENTS
CLOSE TABLES
RELEASE ALL EXTENDED
CLEAR EVENTS
QUIT



Исправлено 1 раз(а). Последнее : spammail_88, 07.10.18 09:47
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
PaulWist

Сообщений: 14618
Дата регистрации: 01.04.2004
spammail_88
После RETURN TO MASTER в fQuit() больше ничего не выполняется в том числе и QUIT. И программа не закрывается, даже не смотря на то, что главная программа выглядит как то так:
DO FORM MainForm
READ EVENTS
CLOSE TABLES
RELEASE ALL EXTENDED
CLEAR EVENTS
QUIT

И крестик в правом углу становится недоступным?

Остаются висящие ссылки.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
spammail_88
...
READ EVENTS
...
...
CLEAR EVENTS
QUIT
Не пробовали думать над тем "как ЭТО может работать"? Отключаем ожидание после отключения ожидания?

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
spammail_88
Автор

Сообщений: 108
Дата регистрации: 13.11.2010
PaulWist
Остаются висящие ссылки.
В этом и вопрос. Как их убрать «оптом»? (Закрыть программу “без шума и пыли”, и потери данных, независимо от того, что происходило до появления ошибки)

ssa
Не пробовали думать над тем "как ЭТО может работать"? Отключаем ожидание после отключения ожидания?
Ну, по идее, на CLEAR EVENTS все должно закончится, а QUIT так, для верности.
Честно говоря, тупо переписал без глубокого понимания вот отсюда:
www.tek-tips.com
или отсюда:
fox.wikis.com



Исправлено 1 раз(а). Последнее : spammail_88, 08.10.18 23:23
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
В общем случае никак. Т.к. сама программа должна уметь способствовать своему корректному закрытию. Формы должны уметь корректно разгружаться, в т.ч. откатывать транзакции, закрывать буферизованные курсоры, покидать "невалидные" поля ввода, обходить запросы на "закрытие с сохранением" если таковое предусмотрено, не должно быть ссылок на внутренние контролы форм (или должен быть предусмотрен механизм их принудительного обнуления), должен быть выстроен строгий порядок закрытия форм, особенно если имеются модальные "цепочки" - тупой проход по коллекции forms совершенно "не катит" в этом случае... В общем проще забить, чем делать "правильно и надёжно работающее в любых ситуациях решение"
Ну и да, в большинстве случаев ошибка НЕ должна приводить к закрытию всей программы - таковых ошибок на самом деле весьма мало, и как правило они не позволяют адекватно себя обработать (скажем нехватка памяти или пространства стека - когда даже банальное присвоение значения переменной может вызывать целый каскад ошибок завершающихся c005)... Большинство "ошибок" должны обрабатываться сугубо локально и просто завершать некоторую "процедуру" с соответстсувующим статусом/возвращаемым значением, не пытаясь убить нах всю прогу


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
ssa

Сообщений: 13007
Откуда: Москва
Дата регистрации: 23.03.2005
spammail_88
ssa
Не пробовали думать над тем "как ЭТО может работать"? Отключаем ожидание после отключения ожидания?
Ну, по идее, на CLEAR EVENTS все должно закончится, а QUIT так, для верности.
Честно говоря, тупо переписал без глубокого понимания вот отсюда:
www.tek-tips.com
или отсюда:
fox.wikis.com
По какой идее? До Clear Events как собрались доходить? С какого перепугу Read Evrents должен закончиться? Если еще и учесть, что именно Clear Events заставляет завершиться Read Events и перейти на следущую за Read Events команду?

------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
spammail_88
Автор

Сообщений: 108
Дата регистрации: 13.11.2010
Методом танцев с бубном пришел к следующему:
FUNCTION fQuit()
ON ERROR *
ON SHUTDOWN fQuit() && !!
nForm=_Screen.FormCount
FOR iForm=1 to nForm
oForm=_Screen.Forms(iForm)
WITH oForm
.Closable=.T.
.Release()
ENDWITH
NEXT
CLOSE TABLES
CLEAR ALL
CLEAR PROGRAM
CLOSE ALL
CLEAR EVENTS
CREATE CURSOR A (A c(1)) && !!
ON ERROR CANCEL && !!
QUIT

Чтобы не вылетали окна типа OPEN DBF… дописал CREATE CURSOR A (A c(1)), чтобы что-то было в активной области.

Поскольку перед QUIT все таблицы уже закрыты, хвосты которые будут выполнятся после QUIT в таблицах уже ничего не впишут. И по любому выпадут ошибкой. А ON ERROR CANCEL прикроит их.

Работало, но иногда вылетало окно “Cannot Quit Visual FoxPro”. Нажимал ОК и все закрывалось. Дописал ON SHUTDOWN fQuit(). Теперь на QUIT делает еще раз проход по всей функции fQuit() и окно “Cannot Quit Visual FoxPro” не вылетает.

Соглашусь, так не делается. Коряво, горбато, неправильно, но в моем случае работает. Спасибо всем откликнувшимся.
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
spammail_88
Коряво, горбато, неправильно, но в моем случае работает.
На том и стоим


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
Chemberzhy

Сообщений: 13142
Откуда: Измаил
Дата регистрации: 28.04.2009
spammail_88
Как выйти из программы после ошибки?
Тихонько, чтобы никто не увидел

Sorry за offtop [sm016]


------------------
Что-то с памятью моей стало, всё что было не со мной- помню.
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
Божья_коровка

Сообщений: 25731
Дата регистрации: 23.08.2001
Igor Korolyov
Ну и да, в большинстве случаев ошибка НЕ должна приводить к закрытию всей программы - таковых ошибок на самом деле весьма мало, и как правило они не позволяют адекватно себя обработать (скажем нехватка памяти или пространства стека - когда даже банальное присвоение значения переменной может вызывать целый каскад ошибок завершающихся c005)... Большинство "ошибок" должны обрабатываться сугубо локально и просто завершать некоторую "процедуру" с соответстсувующим статусом/возвращаемым значением, не пытаясь убить нах всю прогу
+100

Я немного недопонимаю, для чего ТС-у закрывать всё приложение при возникновении какой либо ошибки (он так и не написал при любой ошибке он это делает или нет). И ведь если просто закрыть прогу с ошибкой, то как потом ТС будет ее исправлять. Т.е. нужно понять что за ошибка, в следствие чего она возникла, хотя бы иметь в наличии текст ошибки. А если приложение сразу автоматом срубается и текст ошибки нигде не фиксируется (ну мало ли может у ТС предусмотрен журнал куда он фиксирует ошибки или лог какой, он ничего не написал), то как потом распознавать, что же произошло....Если ошибка никак не обрабатывается, то что потом с ней делать?


------------------
Жись, она как зёбра, полоса белая, полоса черная, а мне всегда задница достается...




Исправлено 2 раз(а). Последнее : Божья_коровка, 11.10.18 08:44
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
spammail_88
Автор

Сообщений: 108
Дата регистрации: 13.11.2010
Божья_коровка
для чего ТС-у закрывать всё приложение при возникновении какой либо ошибки (он так и не написал при любой ошибке он это делает или нет)
Да, при любой. Программа прямая как линия, никакой многозадачности. Везде модальные формы, в центре программы – одна функция. В случае проблемы закрываю, чтобы перестраховаться, что в результате ошибки я не получу неправильные данные (никаких результатов лучше, чем неправильный результат). Хороший результат – это когда программа запустилась с нуля и отработала без ошибок.

Божья_коровка
хотя бы иметь в наличии текст ошибки
spammail_88
Хочу сделать так, чтобы при возникновении ошибки, программа выводила данные об ошибке и сразу закрывалась
spammail_88
FUNCTION fShowError()
MESSAGEBOX("Error...")
fQuit()

Божья_коровка
ну мало ли может у ТС предусмотрен журнал куда он фиксирует ошибки или лог какой, он ничего не написал)
Конечно, есть лог. Без этого никуда. О нем, и о многих других вещах умолчал, так как на прямую сути вопроса (принудительное закрытие программы) они не касаются.
Ratings: 0 negative/0 positive
Re: Как выйти из программы после ошибки?
прошелмимо

Сообщений: 784
Дата регистрации: 21.02.2012
дарю слона, посмотреть.

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

на старте пишем
on error DO merror ;
WITH ERROR(), MESSAGE(), PROGRAM(), LINENO(1), MESSAGE(1) IN merror.fxp

#DEFINE _lf CHR(13)+CHR(10)
****************
PROCEDURE MError
****************
PARAMETERS m.cod, ;
m.mess,;
m.prg, ;
m.lin,;
m.mess1
IF SET('ESCAPE') = 'ON'
SET ESCAPE OFF
STORE 'ON' TO m.esc_set
ELSE
STORE 'OFF' TO m.esc_set
ENDIF
_i = 1
m.chain = ''
DO WHILE LEN(PROGRAM(_i)) <> 0
m.chain = m.chain + ' -> ' + PROGRAM(_i)
_i = _i + 2
ENDDO
**********************************************************************
** Запрос на откат транзакции:
**********************************************************************
If type("oServer")="O"
local llSuccessTestConnection
try
llSuccessTestConnection = (oServer.sqlexec('select 1') > 0)
catch
endtry
use in select("sqlResult")
if llSuccessTestConnection
lnTrancount = oServer.sqlReturn("select @@trancount")
If lnTrancount > 0
If MessageBox("Существуют незавершенные транзакции! Откатить транзакции?",4+32,"Внимание")=6
oServer.sqlexec("if @@trancount > 0 rollback transaction")
else
oServer.sqlexec("while @@trancount > 0 commit transaction")
endif
endif
endif
endif
**********************************************************************
** Сообщения о следующих ошибках в базе errorinf.DBF не фиксируем:
** 1707 Structural CDX file not found.
** 221 Left margin plus indent must be less than right margin.
**********************************************************************
IF !(m.cod = 1707 OR m.cod = 221)
=ErrToDbf(m.prg, m.cod, m.mess, m.lin, m.mess1, m.chain)
ENDIF
**************************** Создание окна сообщения *****************
lcText = ""
lcText1 = ""
lcText2 = ""
lcText3 = ""
lcText4 = ""
lbWhatShow = 1
lbVisible = 3
DO CASE
CASE m.cod = 108 OR m.cod = 1705
DO CASE
CASE m.Cod = 108
lcText = ' Файл БД открыт другим пользователем. Дождитесь, пока файл не освободится.'
CASE m.Cod = 1705
lcText = ' Или файл открыт другим пользователем или у ВАС недостаточно прав для создания файлов на сетевом диске.'
ENDCASE
CASE m.cod = 26 OR 'Database is not ordered.' $ m.mess OR m.cod = 114 ;
OR 'Index does not match database file.' $ m.mess
m.temp = DBF()
m.temp = LEFT(m.temp, LEN(m.temp) - 4) + '.CDX'
lcText = ' Индексный файл ' + m.temp + ' отсутствует или разрушен. Выполните процедуру индексации.'
CASE m.cod = 1102 OR 'Cannot create file.' $ m.mess
lcText = 'Неудачная попытка создания файла. Возможно на диске больше нет места или у ВАС нет прав для создания файлов на сетевом диске.'
CASE m.cod = 1157 OR m.cod = 1160 OR 'Not enough disk space' $ m.mess
lcText = 'На диске нет места для продолжения работы. Также возможен сбой диска'
CASE m.cod = 1410 OR 'Unable to create temporary work file(s).' $ m.mess
lcText = 'FoxPro не может создать временный файл для работы. Диск может быть полон. Или у ВАС нет прав для создания файлов на сетевом диске.'
CASE m.cod = 15 OR 'Not a database file.' $ m.mess
lcText = 'Файл ' + SUBSTR(DBF(),3) + ' поврежден. Выполните программу ремонта.'
OTHERWISE
lbWhatShow = 2
lcText = ""
lcText1 = prg
lcText2 = LTRIM(STR(m.cod))
lcText3 = m.mess
lcText4 = LTRIM(STR(lin))
lbVisible = 7
endcase
local lnRes
lnRes = 0
IF m.cod = 1707 && Игонорируем и выполняем заново (CDX file is not found)
lnRes = 3
ELSE
IF m.cod = 221 OR m.cod = 55 OR m.cod = 1642
lnRes = 2
ELSE
DO FORM ERR_FORM WITH lbWhatShow,;
lcText, ;
lcText1, ;
lcText2, ;
lcText3, ;
lcText4, ;
lbVisible, ;
m.mess1 TO lnRes
ENDIF
ENDIF
************************* Обработка событий нажатия кнопок ************************
DO CASE
CASE lnRes = 1 && Главное меню
ReturnCalledProgramm()
CASE lnRes = 2 && Игнорировать
ON ESCAPE
SET ESCAPE &esc_set
SET CONSOLE OFF
ON ERROR DO merror ;
WITH ERROR(), MESSAGE(), PROGRAM(), LINENO(1), MESSAGE(1)
CASE lnRes = 3
ON ESCAPE
SET ESCAPE &esc_set
ON ERROR DO merror ;
WITH ERROR(), MESSAGE(), PROGRAM(), LINENO(1), MESSAGE(1)
RETRY
RETURN
OTHERWISE
ReturnCalledProgramm()
ENDCASE
RETURN 1
********************************
FUNCTION ReturnCalledProgramm
********************************
CLEAR GETS
SET DEVICE TO SCREEN
ON ESCAPE
SET ESCAPE &esc_set
SET CURSOR ON
ON KEY LABEL F2
ON KEY LABEL F3
ON KEY LABEL F4
ON KEY LABEL F5
ON KEY LABEL F6
ON KEY LABEL F7
ON KEY LABEL F8
ON KEY LABEL F9
ON KEY LABEL ENTER
ON KEY LABEL INS
ON KEY LABEL TAB
ON KEY LABEL BACKTAB
ON KEY LABEL ESC
ON ERROR DO merror ;
WITH ERROR(), MESSAGE(), PROGRAM(), LINENO(1), MESSAGE(1)
*** Закрываем все окна приложения
e_nFormCount = _SCREEN.FORMCOUNT
FOR e_nNum = e_nFormCount TO 1 STEP -1
IF !(UPPER(ALLT(_SCREEN.FORMS(e_nNum).NAME)) == "G_GROUP_DOC")
_SCREEN.FORMS(e_nNUm).LockScreen = .F.
_SCREEN.FORMS(e_nNum).VISIBLE = .F.
_SCREEN.FORMS(e_nNum).RELEASE ()
ENDIF
ENDFOR
IF TYPE("pcMenu_Name") # "C"
SET SKIP OF MENU main_menu .F.
ELSE
SET SKIP OF MENU &pcMenu_Name .F.
ENDIF
RETURN TO main_pr2
********************
FUNCTION ErrToDbf
********************
PARAMETERS m.prg, m.cod, m.mess, m.lin, m.mess1, m.chain
return
PRIVATE m.savealias
m.savealias = ALIAS()
* Переделана работа с файлом errorinf
* проверяем предварительно есть ли атрибут "Только для чтения" и сбрасываем его, если есть
IF NOT FILE('errorinf.DBF')
CREATE DBF errorinf ( ;
program C ( 8), ;
chain C ( 80), ;
errorno N ( 6), ;
errormsg C ( 80), ;
lineno N ( 6), ;
badcode C (128), ;
alias C ( 8), ;
date D ( 8), ;
time C ( 5) )
ENDIF
USE IN select("errorinf")
IF ADIR(_laFiles,'errorinf.dbf') > 0
IF "R" $ _laFiles[1,5] && файл имеет признак ReadOnly, пробуем его убрать
DECLARE INTEGER SetFileAttributes IN win32api STRING, INTEGER
=SetFileAttributes('errorinf.dbf',128) && 0x00000080
* IF SetFileAttributes('errorinf.dbf',128)=0 && 0x00000080 - не удалось убрать файл
ENDIF
ENDIF
* Открываем файл
USE errorinf in 0
APPEND BLANK
REPLACE NEXT 1 ;
program WITH m.prg , ;
chain WITH m.chain , ;
errorno WITH m.cod , ;
errormsg WITH m.mess , ;
lineno WITH m.lin , ;
badcode WITH m.mess1 , ;
alias WITH m.savealias, ;
date WITH DATE() , ;
time WITH SUBSTR(TIME(),1,5)
use in select("errorinf")
IF NOT EMPTY(m.savealias)
SELECT (m.savealias)
endif
return


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

LPARAMETERS bWhatShow,; && Что показывать 1 - СООБЩЕНИЕ 2 - ошибку программы
cTextMessage,; && Текст сообщения
cText1,;
cText2,;
cText3,;
cText4,;
bBitVisibleButtons,; && Битовая маска визуализации кнопок
cText5 && строка программы
WITH THISFORM
.displayMemo()
.checkStack()
wait clear
LOCAL cStr, cBuff, nFHandle
IF !empty(bWhatShow) and bWhatShow = 1
* вывод сообщения
cStr = iif(vartype(cTextMessage)="C", cTextMessage, "")
store .f. to .Acommandbutton1.visible, ;
.Acommandbutton3.visible, ;
.DebugCommand.visible
store .t. to .cmdOk.Visible
ELSE
* сообщение по параметрам
cStr = "Модуль: " +alltrim(iif(vartype(cText1)="C",cText1,""))+CHR(13)+;
"Номер ошибки: " +alltrim(iif(vartype(cText1)="C",cText2,""))+CHR(13)+;
"Сообщение: " +alltrim(iif(vartype(cText1)="C",cText3,""))+CHR(13)+;
"Номер строки: " +alltrim(iif(vartype(cText1)="C",cText4,""))+CHR(13)+;
"Строка программы: "+alltrim(iif(vartype(cText1)="C",cText5,""))
* если есть файл с ошибками показываем его
IF FILE("c_debug.log",1)
nFHandle = FOPEN("c_debug.log")
IF nFHandle>0
cBuff = FREAD(nFHandle,1024*32)
IF !EMPTY(cBuff)
cStr = cBuff
ENDIF
=FCLOSE(nFHandle)
ENDIF
ENDIF
bBitVisibleButtons = iif(vartype(bBitVisibleButtons)<>"N",0,bBitVisibleButtons)
.Acommandbutton1.Enabled = BITTEST(bBitVisibleButtons,0)
*.Acommandbutton2.Enabled = BITTEST(bBitVisibleButtons,1)
.Acommandbutton3.Enabled = BITTEST(bBitVisibleButtons,2)
.DebugCommand.visible = (version(2)=2)
endif
this.pf1.page1.AeditBox1.Value = cStr
.Resizer1.Get_sizes()
*.Left = 50
*.Top = 50
.Caption = iif( !empty(bWhatShow) and bWhatShow=1, "Сообщение", " Cообщение об ошибке")
.RETURN_VALUE = 0
ENDWITH

начитка стека вызова
local laStack[1], lcStack
astackinfo(laStack)
lcStack = ""
for lnRow = alen(laStack, 1)-3 to 1 Step -1
lcStack = lcStack + "Исп.метод: (" + transform(laStack[lnRow,2]) + ") " + transform(laStack[lnRow,3]) + chr(13)+ chr(10) + ;
"Строка: " + transform(laStack[lnRow,5]) + chr(13) + chr(10) + ;
"Команда: " + alltrim(transform(laStack[lnRow,6])) + chr(13)+ chr(10) + ;
chr(13)+ chr(10)
endfor
this.pf1.page2.aeditbox1.Value = lcStack

на прослучай, - как у немцев, тока я и без соплей до этого додумывался
local lcTempFile
lcTempFile = Addbs(Sys(2023))+Sys(2015)+".tmp"
display memory to (lcTempFile) noconsole
thisform.pf1.page3.aeditbox1.Value = filetostr(lcTempFile)
erase (lcTempFile)



Исправлено 3 раз(а). Последнее : прошелмимо, 12.10.18 11:56
Ratings: 0 negative/1 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 24 Victoriacom  (Гостей: 23)

© 2000-2024 Fox Club 
Яндекс.Метрика