Понадобилось мне сегодня сделать паузу в коде. Работа присходит на сервере, так что Предупреждение не подходит. Мотать цикл тоже не подходит, ибо грузит сильно проц. На просторах было найдено такое решение:
ИнтервалОжидания = Таймаут*1000;
ИмяФайлаВрем = ПолучитьИмяВременногоФайла("js");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст
(
"if (WScript.Arguments.Count()==0)
| WScript.Quit();
|else
| if (isNaN(parseInt(WScript.Arguments(0))))
| WScript.Quit();
|WScript.Sleep(WScript.Arguments(0));"
);
ТекстовыйДокумент.Записать(ИмяФайлаВрем,КодировкаТекста.ANSI);
WshShell = Новый COMОбъект("WScript.Shell");
WshShell.Run("wscript.exe """+ИмяФайлаВрем+""" "+Формат(ИнтервалОжидания,"ЧГ=0"),0,-1);
УдалитьФайлы(ИмяФайлаВрем);
Ээх. И опять исключительно виндовый способ
Линуксовй вроде только один: поднять web сервер, там простейший cgi скрипт sleep и на сервере вызывать страничку через http соединение.
Делал задержку на 1С так, вместо 28882 можно любой свободный порт.
Procedure Ожидание(Таймаут)
ВремяЗавершения = CurrentDate() + Таймаут;
While CurrentDate() < ВремяЗавершения Do
Try
Соединение = New FTPConnection("127.0.0.1", 28882);
Except
EndTry;
EndDo;
EndProcedure
На "заре" программирования, меня учили, что передача управления на маркер и ожидание - это как минимум плохой код, и допустим только в крайнем случае...
Зачем нужна пауза?
Обычно в это время что-то происходит. Тогда этим "что-то" можно (нужно) управлять. Например запускается внешняя программа и нужно ждать ее окончания - тогда:
Перем oExec Экспорт
Функция ЗапуститьПрограмму() Экспорт
Попытка
WshShell = НОВЫЙ COMОбъект("WScript.Shell");
oExec = WshShell.Exec("d:\Program Files\Программа.exe");
//Сообщить(СокрЛП(oExec.Status), СтатусСообщения.Информация);
//ИД= oExec.ProcessID;
//Сообщить("ИД процесса:"+ИД, СтатусСообщения.Информация);
Возврат Истина;
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
oExec=Неопределено;
Возврат Ложь;
КонецПопытки;
КонецФункции
Процедура ЗакрытьПрограмму() Экспорт
СостояниеПрограммы=oExec.Status;
НомерПопытки=0;
Пока СостояниеПрограммы=0 Цикл
//ОбработкаПрерыванияПользователя();
НомерПопытки=НомерПопытки+1;
Состояние("Закрытие ПРОГРАММЫ - "+СокрЛП(НомерПопытки));
oExec.Terminate();
СостояниеПрограммы=oExec.Status;
Если НомерПопытки>50 Тогда
Сообщить("Не смогли выгрузить ПРОГРАММУ за 50 попыток", СтатусСообщения.Внимание);
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры;
yaxus , не пробовал ещё, но возьму на заметку .
Хотя поторопился. Тоже ж цикл используете..
add: хотя, если добавлять таймаут, то ваш вариант имеет место быть
AnryMc, замечательно. Вот только про цикл я писал в самом первом сообщении.
можно использовать банальный ping 127.0.0.1 и таймаут и количество - все можно задать параметрами
Написал такое, потом подумал, может что-то есть оптимальней, но не нашел...
Процедура Пауза(Секунд = 1)
КонецПаузы = ТекущаяДата() + Секунд;
Пока ТекущаяДата() < КонецПаузы Цикл
// ...
КонецЦикла;
КонецПроцедуры
logist, такой метод - убийство для процессора.
Если нужен метод не использующий внешнюю среду :
Создаем форму выбора, в ней через ПодключитьОбработчикОжидания делаем аля таймер, если больше определенного времени, то форму выбора закрыть.
В нужной нам части алгоритма вызываем ( не открываем ) эту формувыбора модально ждем... профит.
ВБСкрипт = СоздатьОбъект("WScript.Shell");
ВБСкрипт.Run("cscript "+ ИмяСкрипта , 0,-1); // Пауза
Вставлю свои 5 коп., хотя в 8-й версии не пишу. В 7.7. очень хорошо с таким заданием справляется DialMail.dll и мне что-то кажется что 8-я ее тоже поддерживает.
Синтаксис на 7.7.
Ожидание(<Мсек>);
Назначение
Приостанавливает работу 1С на <Мсек> миллисекунд без загрузки процессора. Окно 1С в данное время не перерисовывается.
Возвращаемое значение:
НЕТ
Параметры:
<Мсек> - число. Количество миллисекунд ожидания.
Пример кода на 7.7.:
Перем SystComm;
Процедура При открытии()
Если ЗагрузитьВнешнююКомпоненту("DialMail.dll") <> 1 Тогда
Сообщить("Компонента 'DialMail.dll' не найдена", "!");
КонецЕсли;
SystComm = СоздатьОбъект("AddIn.SystComm");
КонецПроцедуры;
Процедура Пауза(Время)
SystComm.Ожидание(прВремя);
КонецПроцедуры
Сегодня понадобилось снова сделать паузу. Нашел ещё один вариант решения:
ВС_Шелл = Новый COMОбъект("WScript.Shell"); // для 7.7: ВС_Шелл = СоздатьОбъект("WScript.Shell");
КоличествоСекунд = 10;
ВС_Шелл.Run("ping 127.0.0.1 -n "+КоличествоСекунд, 0, 1);
Также вот столкнулся с проблемой паузы.
Запретили использование как скриптов так и внешних компонент. Возмутило страшно, тем более что не обосновали такой подход (хз. может на Линуксе парятся и что-то переписывают).
Идея: реализовать паузу с использованием ОбработкиОжидания, передать ей список объектов и пусть она кусками выполняет действия через определенное время.
Изменяемые реквизиты существующих объектов передавать в ТаблицеЗначений. Графа Объект - Объект МД, графа реквизиты (тип - СписокЗначений) -список изменяемых реквизитов (типа ДобавитьЗначение("ИмяРеквизита",Значение)).
Для наглядности привожу такой код перепроведения документов с помощью внешней обработки:
перем гпСписДоков;//глобальный список значений
//======================================================================
Процедура ПровестиОжидая()
Если ПустоеЗначение(гпСписДоков) = 1 Тогда
Форма.Заголовок("Проведены все документы");
Форма.ОбработкаОжидания("ПровестиОжидая",0);//Отключаем ожидание
Иначе
НачатьТранзакцию();
лпБлок = 0; // Признак того что документ кем-то открыт
лпДокумент = СоздатьОбъект("Документ");
лпКоличествоДокументов = Мин(100,гпСписДоков.РазмерСписка());
Для лпНомСпис = 1 По лпКоличествоДокументов Цикл
лпДокумент.НайтиДокумент(гпСписДоков.ПолучитьЗначение(лпНомСпис));
Если (лпДокумент.Блокировка(1)=1) Тогда
лпДокумент.Блокировка(0);
лпДокумент.Провести();
Иначе
ОтменитьТранзакцию();
лпБлок = 1;
Прервать;
КонецЕсли;
КонецЦикла;
Если лпБлок = 0 Тогда
Попытка
ЗафиксироватьТранзакцию();
гпСписДоков.УдалитьЗначение(1,лпКоличествоДокументов);
Исключение
ОтменитьТранзакцию();
КонецПопытки;
КонецЕсли;
Форма.Заголовок("Осталось провести "+гпСписДоков.РазмерСписка()+" документов");
КонецЕсли;
КонецПроцедуры // ОжиданиеПроведения
//======================================================================
Процедура Сформировать()
гпСписДоков = СоздатьОбъект("СписокЗначений");
лпДокумент = СоздатьОбъект("Документ");
лпДокумент.ВыбратьДокументы();
Пока лпДокумент.ПолучитьДокумент(НачДата, КонДата) = 1 Цикл
Если лпДокумент.Проведен() = 1 Тогда
гпСписДоков.ДобавитьЗначение(лпДокумент.ТекущийДокумент());
КонецЕсли;
КонецЦикла;
Форма.ОбработкаОжидания("ПровестиОжидая",10);//Запуск через 10 сек.
КонецПроцедуры
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7
https://pro1c.org.ua