пятница, 9 июля 2010 г.

1С: Автовыгон

Прошу прощение, что давно не писал. Произошло много событий с момента последнего сообщения, а именно:
  • Прошел обучение 1С: Введение в конфигурирование в 1С: Предприятие v8.1
  • Запустили-таки два маршрута с новыми PPC на базе HP IPAQ 114 (win mobile 6.1)
  • Много мелких доработок отчетов, в основном аналитика.
  • Основные проекты забросил :(, но думаю я к ним еще вернусь :)
В этой статье я хотел бы поделиться такой удобной штукой как "Автовыгон". Кто работал в 8-ке знает, что это такое. Выставляем время и к указанному моменту пользователей работающих в 1С не остается. Удобно, особенно в организациях с филиалами в разных городах с одной базой 1С.
Итак, что нам понадобится:
  • Константа: ВыгнатьВ - строка (5 символов). Например: 00:00.
  • Константа: ПричинаВыгона - строка (30 символов). Например: пересчет.
  • Обработка: УстановитьВремяВыгона - обработка для установки времени и причины.
Больше изменений не будет.
Идея такая:
  1. Каждые 5 минут (можно и 1), запускается обработка назовем ее: КонтрольЗаРаботой.
  2. Проверяется сколько осталось до выгона.
  3. Момент наступил или упущен: выходим без предупреждения.
  4. До необходимого момента осталось менее 15 минут: предупреждаем о приближающемся событии.
Ну и чтобы нам никто не помешал:
  1. При начале работы системы вставим проверку.
  2. Если до наступления события меньше 5 или больше 15: минут выходим с предупреждением о предстоящем событии.
А для того чтобы не открывать весь список констант (дабы не запутаться). Сделаем отчет:
  1. ПриОткрытии, загружает данные из констант.
  2. ПоКнопкеСохранить, записывает данные в константы.
Начнем с реализации ПриНачалеРаботыСистемы:
Функция ПроверкаВхода()
    // Вынес в отдельную функцию, дабы не нагружать ПриНачалеРаботыСистемы()
    тВремя = ТекущееВремя(); // возвращает время с датой
    тВремя = Лев(тВремя, 5); // поэтому берем только левые 5 символов
    тЧас = Число(Лев(тВремя, 2)); // узнаем что такое час
    тМин = Число(Прав(тВремя, 2));// узнаем что такое минута

    // собираем информацию из констант
    кВремя = Константа.ВыгнатьВ;
    Если кВремя = "24:00" Тогда
        // это время я использую как по умолчанию
        Возврат 1;
    КонецЕсли;

    кЧас = Число(Лев(кВремя, 2)); // Часы по константе
    кМин = Число(Прав(кВремя, 2));// минуты по константе

    // узнаем сколько минут осталось до события
    рМин = (кЧас - тЧас)*60 + (кМин - тМин);
    Если (рМин <= 5) и (рМин >= -15) Тогда // 20 мин на вход
        Если МонопольныйРежим() = 0 Тогда // зашел простой смертный
            // вывели для него предупреждение. т.к. пользователь у компьютера
            // с вероятностью 98% он нажмет на кнопку, и времени пройдет не так много
            Предупреждение("Запланирован(а/о): " + СокрЛП(Константа.ПричинаВыгона) +
                           " на: " + кВремя + ", попробуйте позже");

            // говорим что не будем ждать
            Возврат 0;
        Иначе
            // вошли в монопольный режим, собственно чего и добивались
            // обнуляем константу
            Константа.УстановитьАтрибут("ВыгнатьВ","24:00");
        КонецЕсли;
    КонецЕсли;
    // прошли нормально
    Возврат 1;
КонецФункции
В обработке ПриНачалеРаботыСистемы добавляем в самое начало строчку:
СтатусВозврата(ПроверкаВхода());
Это позволит нам не перегружать основную функцию. Дальше функция проверки времени:
Процедура КонтрольЗаРаботой()
    // рассчитываем сколько осталось до блокирования
    тВремя = ТекущееВремя();
    тВремя = Лев(тВремя, 5);
    тЧас = Число(Лев(тВремя, 2));
    тМин = Число(Прав(тВремя, 2));
 
    кВремя = Константа.ВыгнатьВ;
    Если кВремя = "24:00" Тогда
        Возврат;
    КонецЕсли;

    кЧас = Число(Лев(кВремя, 2));
    кМин = Число(Прав(кВремя, 2));

    // узнаем сколько минут осталось до события
    рМин = (кЧас - тЧас)*60 + (кМин - тМин);
    Если рМин <= 0 Тогда       
        // закрываем приложение!
        ЗавершитьРаботуСистемы(0);
    ИначеЕсли (рМин >= 1) и (рМин <= 15) Тогда
        // предлагаем сохраниться
        // изначально сделал с предупреждением, но если от компа отошли 
        // и не нажали на кнопку, в назначенную минуту 1С не закроется
        Сообщить(тВремя + " Закройте 1С, через " + рМин +
                " минут(ы), запланировано:" +  
                СокрЛП(Константа.ПричинаВыгона) +
                ". Пожалуйста сохраните данные и закройте 1С","!!!");
        Если рМин <= 5 Тогда
             // перезапускаем обработку (обеспечиваем 100% выход ко времени)
             ОбработкаОжидания("КонтрольЗаРаботой",рМин * 60);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры
Помещаем вызов куда нибудь в конце ПриНачалеРаботыСистемы
ОбработкаОжидания("КонтрольЗаРаботой",300); // каждые 5мин
Осталось написать обработку для задания времени.
Я сделал следующим образом:
  1. На форму бросил два поля со списком: Час и Минут
  2. А так же поле для ввода текста: Причина
  3. При открытии заполняю поля из данных константы
  4. При нажатии сохранить их записываю.
Теперь по порядку:
Процедура ПриОткрытии()
    Для ц = 1 По 24 Цикл // час любой
        Час.ДобавитьЗначение(Формат(Строка(ц),"Ч(0)2"),Формат(Строка(ц),"Ч(0)2"));
    КонецЦикла;

    Для ц = 0 По 12-1 Цикл // шаг 5 минут
        Минут.ДобавитьЗначение(Формат(Строка(ц*5),"Ч(0)2"),
                              Формат(Строка(ц*5),"Ч(0)2"));
    КонецЦикла;
    
    // указываем начальный выбор
    Час.ТекущаяСтрока(Число(Лев(Константа.ВыгнатьВ,2)));
    Минут.ТекущаяСтрока(Число(Прав(Константа.ВыгнатьВ,2))/5+1);
    // ну и причина
    Причина = Константа.ПричинаВыгона;
КонецПроцедуры

Процедура Выполнить()
    ВыгнатьВ = Час.ПолучитьЗначение(Час.ТекущаяСтрока()) + ":" +
               Минут.ПолучитьЗначение(минут.ТекущаяСтрока());
    Константа.УстановитьАтрибут("ВыгнатьВ",ВыгнатьВ);
    Константа.УстановитьАтрибут("ПричинаВыгона",Причина);
    Форма.Закрыть(); // если не закрывать, оставался вопрос: я сохранил или нет?
КонецПроцедуры
Ну вот и все.
Спасибо за внимание!

Комментариев нет:

Отправить комментарий