Базовый курс. Занятие №5

Второе занятием по 1-му блоку базового курса.

Необходимо изучить следующие главы 1-го блока.
Глава 5. Свойства конфигурации
Глава 6. Подсистемы
Глава 7. Константы
Глава 8. Справочники

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

Задание необходимо выполнять в ИБ после предыдущего ДЗ.

В этой же теме необходимо написать отчет о выполнении задания.

ps. Участники курса без доступа в мастер-группу отчитаться по домашним заданиям не получиться.

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

Если не активировали токен — посмотрите видео-инструкцию (видео N5)

Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —
напишите нам на e-mail поддержки.

комментариев 112 на “Базовый курс. Занятие №5”

  1. задание выполнил.
    были проблемы:
    1. сперва забыл что в модуле Управляемого приложения нельзя определять серверные методы.
    2. чтобы определить выбрал ли пользователь меню на сегодня СтруФильтр = Новый Структура(“Дата”,ТекущаяДата()) и индексировал дату хотя представление выбрал без времени, оно все равно помешало отбору. и пришлось перебирать

    ВыборОбедов = Справочники.ОбедыПользователей.Выбрать(ТекПольз);

    Пока ВыборОбедов.Следующий() Цикл
    ДатаОбеда = Число(Формат(ВыборОбедов.Дата,”ДФ=yyyyMMdd”));
    ТекДата = Число(Формат(ТекущаяДата(),”ДФ=yyyyMMdd”));
    Если ДатаОбеда = ТекДата Тогда

    Возврат Истина;
    ВыборОбедов = Справочники.ОбедыПользователей.Выбрать(ТекПольз); Пока ВыборОбедов.Следующий() Цикл ДатаОбеда = Число(Формат(ВыборОбедов.Дата,”ДФ=yyyyMMdd”)); ТекДата = Число(Формат(ТекущаяДата(),”ДФ=yyyyMMdd”)); Если ДатаОбеда = ТекДата Тогда Возврат Истина;

    • дописал(= дата = НачалоДня(ТекущаяДата())

  2. Задание выполнила. Справочники, константы- все по заданию-сложностей не возникло. Все работает, но провозилась целый день.
    У меня возник вопрос: в задании есть условие, что пользователь может добавлять свой вариант обеда, у меня получается, что пользователь выбирает  обед в модальной форме списка с отметками, а в этой форме нельзя ничего добавить, или имеется ввиду что он может добавить открыв справочник с вариантами обедов после входа и выбора обеда, а не в момент входа?

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

  3. Максим Ефимов 06.02.2011 в 17:09

    Справочник «Пользователи» должен автоматически синхронизироваться со списком
    пользователей. Для этого при старте приложения проверяйте есть ли текущий пользователь в
    справочнике. Если нет, его нужно программно добавить.

    Проверка при входе и выходе и диалог о запросе обеда не должны осуществляться
    для пользователей с флагом «Администратор»;

     
    Процедура ПриНачалеРаботыСистемы()

    ТекПользователь = ОбщиеФункцииСервер.ПолучитьПользователяИзСправочника();

    Если Не ОбщиеФункцииСервер.ПользовательАдминистратор(ТекПользователь)
    и Не ОбщиеФункцииСервер.ОбедВыбирался(ТекПользователь, ДатаЗапуска) Тогда
    ОбщиеФункцииКлиент.ВыбратьОбеды(ТекПользователь, ДатаЗапуска);
    КонецЕсли;
    КонецПроцедуры
     
    Функция  ПолучитьПользователяИзСправочника() Экспорт
    ИмяПользователя = ИмяПользователя();
    ТекПользователь = Справочники.Пользователи.НайтиПоКоду(ИмяПользователя);

    Если ЗначениеЗаполнено(ТекПользователь) Тогда
    Возврат ТекПользователь;
    Иначе
    ТекПользователь = Справочники.Пользователи.СоздатьЭлемент();
    ТекПользователь.Код = ИмяПользователя;
    ТекПользователь.Наименование = ИмяПользователя;
    ТекПользователь.Записать();
    Возврат ТекПользователь.Ссылка;
    КонецЕсли;    
    КонецФункции

    Время работы предприятия берется из констант;

    Процедура УстановитьГрафик(НачалоРаботы, ОкончаниеРаботы) Экспорт

    ДатаЗапуска = ОбщиеФункцииКлиент.ПолучитьДату();

    ГрафикРаботы = ОбщиеФункцииСервер.ПолучитьГрафикРаботы();
    ВремяНачалоРаботы = ГрафикРаботы.ВремяНачалоРаботы;
    ВремяОкончанияРаботы = ГрафикРаботы.ВремяОкончанияРаботы;

    НачалоРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),Час(ВремяНачалоРаботы),Минута(ВремяНачалоРаботы),Секунда(ВремяНачалоРаботы));
    ОкончаниеРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),Час(ВремяОкончанияРаботы),Минута(ВремяОкончанияРаботы),Секунда(ВремяОкончанияРаботы));
    //ОкончаниеРаботы = ‘00010101181142’;
    //НачалоРаботы = Дата(1,1,1,15,5,38);

    КонецПроцедуры
    Функция ПолучитьГрафикРаботы() Экспорт

    Возврат Новый Структура(“ВремяНачалоРаботы, ВремяОкончанияРаботы”, Константы.ВремяНачалоРаботы.Получить(),
    Константы.ВремяОкончаниеРаботы.Получить());
    КонецФункции
    Варианты обеда берутся из одноименного справочника (как минимум 3 варианта,
    но пользователь может добавить собственные). Причем из справочника нужно
    выбирать элементы, не помеченные на удаление;

    Функция ПолучитьМеню() Экспорт
    Выборка = Справочники.ВариантыОбедов.Выбрать();

    СписокЗначений = Новый СписокЗначений;

    Пока Выборка.Следующий() Цикл
    Если Выборка.ПометкаУдаления Тогда
    Продолжить;
    Иначе    
    СписокЗначений.Добавить(Выборка.Ссылка);
    КонецЕсли;    
    КонецЦикла;    

    Возврат ?(СписокЗначений.Количество()>0, СписокЗначений, Неопределено);
    КонецФункции // ПолучитьМеню()

    Результат выбора пользователя записывайте в справочник
    «ОбедыПользователей». При выборе нескольких вариантов выполняйте запись
    нескольких элементов справочника

    Процедура ВыбратьОбеды(Пользователь, Дата) Экспорт

    СписокОбедов = ОбщиеФункцииСервер.ПолучитьМеню();

    Если СписокОбедов = Неопределено Тогда Возврат; КонецЕсли;

    ВыбранОбед = Ложь;
    Пока Не ВыбранОбед Цикл
    СписокОбедов.ОтметитьЭлементы(“Выберите обед”);
    Для каждого Строка Из СписокОбедов Цикл

    Если Строка.Пометка Тогда

    ВыбранОбед = Истина;

    ОбщиеФункцииСервер.ДобавитьВариантОбедаПользователю(Пользователь, Строка.Значение, Дата);    

    КонецЕсли;

    КонецЦикла;

    КонецЦикла;

    КонецПроцедуры // ВыбратьОбеды()
     
    Процедура ДобавитьВариантОбедаПользователю(Пользователь, ВариантОбеда, Дата) Экспорт;
    Спр = Справочники.ОбедыПользователей.СоздатьЭлемент();
    Спр.ВариантОбеда = ВариантОбеда;
    Спр.Владелец = Пользователь;
    Спр.Дата = Дата;
    Спр.Записать();
    КонецПроцедуры
     
    Вопрос о выборе обеда должен задаваться только в том случае, если ранее
    пользователь не выбирал обед. Например, при первом входе в систему
    пользователь указал вариант обеда, тогда при втором запуске в эту же дату вопрос
    задавать не следует.

    Процедура ПриНачалеРаботыСистемы()

    ТекПользователь = ОбщиеФункцииСервер.ПолучитьПользователяИзСправочника();

    Если Не ОбщиеФункцииСервер.ПользовательАдминистратор(ТекПользователь)
    и Не ОбщиеФункцииСервер.ОбедВыбирался(ТекПользователь, ДатаЗапуска) Тогда
    ОбщиеФункцииКлиент.ВыбратьОбеды(ТекПользователь, ДатаЗапуска);
    КонецЕсли;
    КонецПроцедуры

    Функция ОбедВыбирался(Пользователь, Дата) Экспорт

    Отбор = Новый Структура(“Дата”, НачалоДня(Дата));
    Выборка = Справочники.ОбедыПользователей.Выбрать(,Пользователь,Отбор);

    Выбирался = Ложь;

    Если Выборка.Следующий() Тогда

    Выбирался = Истина    
    КонецЕсли;

    Возврат Выбирался;
    КонецФункции
     

  4. Отчёт по ДЗ 5 Блок1
    1. С созданием справочников  и пользователей проблем не возникло.

    Синхронизацию пользователей сделал следующим образом.

     
    В общем модуле (сервер+вызов сервера) описал процедуру которая получает ID текущего пользователя и сравнивает его с ID пользователя в справочнике, если не находит, то создаёт нового пользователя с данным ID.
    Процедура ПользовательСинхронизация() Экспорт
     МенеджерПользоветелей=ПользователиИнформационнойБазы;        ТекущийПользователь=МенеджерПользоветелей.ТекущийПользователь();   
    IdПользователя=ТекущийПользователь.УникальныйИдентификатор;
    ПользователиВСправочнике=Справочники.Пользователи;
    НоваяСсылка=ПользователиВСправочнике.ПолучитьСсылку(IdПользователя);
                Таб=Новый СписокЗначений;
    Выборка=ПользователиВСправочнике.Выбрать();
                Пока Выборка.Следующий() Цикл
                таб.Добавить(Выборка.Ссылка.УникальныйИдентификатор(),,Выборка.Ссылка.Администратор);
                КонецЦикла;
                Если таб.НайтиПоЗначению(IdПользователя)=Неопределено   Тогда
    НовыйПользователь=ПользователиВСправочнике.СоздатьЭлемент();              НовыйПользователь.Наименование=ТекущийПользователь.Имя;                   НовыйПользователь.УстановитьСсылкуНового(НоваяСсылка);
     НовыйПользователь.Записать();                                 
     КонецЕсли;    
    КонецПроцедуры // ПользовательСинхронизация()
     
    Так же сделал чтобы пользователь не смог записать нового пользователя просто так в справочник, а изменить текущий имел доступ. Для этого я в форме элемента  «Пользователи» сделал следущее
    &НаСервере
    Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
                Если ТекущийОбъект.ЭтоНовый() тогда
                            Сообщить(“Нельзя добавлять пользователя!”);
                            Отказ=Истина;
                КонецЕсли;
    КонецПроцедуры
     

    Для проверки флага Администратора  сделал следующее. В В общем модуле (сервер+вызов сервера) сделал функцию которая  по ID текущего пользователя сравнивает пользователя со справочником, потом проверяю флаг при помощи списка значений. Выглядит примерно так

     
    Функция ФлагАдминистратор () Экспорт
                 МенеджерПользоветелей=ПользователиИнформационнойБазы;
                 ТекущийПользователь=МенеджерПользоветелей.ТекущийПользователь();  
        IdПользователя=ТекущийПользователь.УникальныйИдентификатор;
       Таб=Новый СписокЗначений;
    Выборка=Справочники.Пользователи.Выбрать();
     Пока Выборка.Следующий() Цикл
      таб.Добавить(Выборка.Ссылка.УникальныйИдентификатор(),,Выборка.Ссылка.Администратор);
     КонецЦикла;
     Если таб.НайтиПоЗначению(IdПользователя).Пометка  Тогда
                            Возврат Истина;
                Иначе Возврат Ложь;
                            КонецЕсли;
    КонецФункции
     
    Ну а дальше в модуле приложения смотрю кто это и делаю соответствующие действия.
    Процедура ПередНачаломРаботыСистемы(Отказ)
                           
                ОбщиеПользователиСервер.ПользовательСинхронизация();
                                                  
                ОбщиеФункцииКлиент.УстановитьГрафик(НачалоРаботы, ОкончаниеРаботы);
               
                Если ОбщиеПользователиСервер.ФлагАдминистратор() Тогда
                            отказ=Ложь;
                 Иначе
                 Отказ = ОбщиеФункцииКлиент.ЗапускЗапрещен(НачалоРаботы, ДатаЗапуска, ОкончаниеРаботы);           
                 
                 КонецЕсли;
                           
    КонецПроцедуры
     
    Процедура ПередЗавершениемРаботыСистемы(Отказ)
               
                Если ОбщиеПользователиСервер.ФлагАдминистратор() Тогда
                            отказ=Ложь;
                Иначе
                           
                            Отказ = ОбщиеФункцииКлиент.ЗавершениеЗапрещено(ОкончаниеРаботы, ДатаЗапуска);
                КонецЕсли;
    КонецПроцедуры
     
    Процедура ПриНачалеРаботыСистемы()
                Если Не ОбщиеПользователиСервер.ФлагАдминистратор() Тогда
                            глОбед = ОбщиеФункцииКлиент.ВыбратьОбеды();      
                КонецЕсли;
               
    КонецПроцедуры
     
     

    Время работы берётся из констант, с этим вроде проблем не возникло.

     
    Про обеды пока не доделал, постараюсь сделать и доотчитаться(все болеем , как всегда опять какой  то вирус:)))

    • Варианты обеда берутся из справочника
      В функции(ОМ)  получаю список обедов которые не помечены на удаление
      Функция  ПолучитьСписокОбеды()  Экспорт
      СписокЗначений= Новый СписокЗначений;
      Выборка= Справочники.ВариантыОбедов.Выбрать();
       Пока Выборка.Следующий() Цикл
      Если не Выборка.ПометкаУдаления Тогда
        СписокЗначений.Добавить(Выборка.Наименование);
       КонецЕсли;
       КонецЦикла;
       Возврат СписокЗначений;
      КонецФункции
      Результат выбора записываю в справочник для конкретного пользователя
       Процедура  ВыбратьОбеды() Экспорт
       ТекущийПользователь=пользователиИнформационнойБазы.ТекущийПользователь();
      СписокОбедов=ОбщиеФункцииСервер.ПолучитьСписокОбеды();
       ВыбранОбед = Ложь;
                  Пока Не ВыбранОбед Цикл
                         СписокОбедов.ОтметитьЭлементы(“Выберите обед”);
                              Для каждого Строка Из СписокОбедов Цикл
      Если Строка.Пометка Тогда
      ВыбранОбед = Истина;
      НовыйЭлемент=Справочники.ОбедыПользователей.СоздатьЭлемент();
      НовыйЭлемент.Владелец= Справочники.Пользователи.НайтиПоНаименованию(ТекущийПользователь);
      НовыйЭлемент.Дата=НачалоДня(ТекущаяДата());
      НовыйЭлемент.Наименование=”Обед пользователя”;              НовыйЭлемент.ВариантОбеда=Справочники.ВариантыОбедов.НайтиПоНаименованию(Строка.Значение);
      НовыйЭлемент.Записать();
       КонецЕсли;
      КонецЦикла;
      КонецЦикла;
      КонецПроцедуры // ВыбратьОбеды()
       С помощью функции проверяю, а был ли заказан сегодня обед? Тут возникли проблемы, хотел сделать отбор, чтобы не обходить выборкой все обеды которые уже делал пользователь, но не понял до конца как работает ОТБОР.
      Функция ОбедЗаказан() Экспорт
      ТекущийПользователь=пользователиИнформационнойБазы.ТекущийПользователь();
      пользователь=Справочники.Пользователи.НайтиПоНаименованию(ТекущийПользователь);
       Заказ=Ложь;
      Выборка=Справочники.ОбедыПользователей.Выбрать(,пользователь);
                  пока   Выборка.Следующий() цикл
             Если НачалоДня(Выборка.Дата)=НачалоДня(ТекущаяДата())  Тогда
      заказ=Истина;
       Иначе
      Заказ=Ложь;
      КонецЕсли;
      КонецЦикла;
      Возврат заказ;
      КонецФункции
       В Модуле УП делаю проверку заказывал ли пользователь обед?
      Процедура ПриНачалеРаботыСистемы()
      Если Не ПользователиСервер.ФлагАдминистратор()или Не ОбщиеФункцииСервер.ОбедЗаказан() Тогда                  
                  ОбщиеФункцииСервер.ВыбратьОбеды();
            КонецЕсли;
      КонецПроцедуры

  5. Задание выполнил. Для пользователя я создал в параметрах системы ТекущегоПользователя с типом СправочникСсылка.Пользователи и в модуле сеанса :
    <code>

    УстановитьПривилегированныйРежим(Истина);
    ИдентификаторПользователяИБ = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

    Пользователь = Справочники.Пользователи.НайтиПоКоду(СокрЛП(ИдентификаторПользователяИБ));
    Если Не Пользователь.Пустая() Тогда
    ПараметрыСеанса.ТекущийПользователь = Пользователь;
    Иначе
    НовыйПользовательОбъект = Справочники.Пользователи.СоздатьЭлемент();
    НовыйПользовательОбъект.Код = ИдентификаторПользователяИБ;
    НовыйПользовательОбъект.Наименование = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя;
    НовыйПользовательОбъект.Записать();

    ПараметрыСеанса.ТекущийПользователь = НовыйПользовательОбъект.Ссылка;
    КонецЕсли;

    Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)

    УстановитьПривилегированныйРежим(Истина);
     
    ИдентификаторПользователяИБ = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

    Пользователь = Справочники.Пользователи.НайтиПоКоду(СокрЛП(ИдентификаторПользователяИБ));
    Если Не Пользователь.Пустая() Тогда
    ПараметрыСеанса.ТекущийПользователь = Пользователь;
    Иначе
    НовыйПользовательОбъект = Справочники.Пользователи.СоздатьЭлемент();
    НовыйПользовательОбъект.Код = ИдентификаторПользователяИБ;
    НовыйПользовательОбъект.Наименование = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя;
    НовыйПользовательОбъект.Записать();

    ПараметрыСеанса.ТекущийПользователь = НовыйПользовательОбъект.Ссылка;
    КонецЕсли;
     
    КонецПроцедуры

    </code>
     
    Создал две константы с  типом Дата и составом Время  которых храню значение Начала и Конца рабочего времени.  Далее как и впредыдущем задании обрабатываю эти данные при входе в систему. Сделал это правда только в управляемом приложении.
    Так же для пользователей, которые не являлись администраторами я сделал вывод выбора обеда в списке, перед этим вызвав серверную процедуру и загнав значения справочника вариантыОбеда в список значений, который и вывел для выбора пользователю.
    Сложно все объяснить, нужно весь конфигурационный файл выложить.
    Но у меня есть вопрос у меня были такие строчки кода и на этот код мне выдавала программа ошибку пр зпуске, что неверный параметр 3, в чем проблема?:
    <code>
    УсловиеОтбора = Новый Структура(“ПометкаУдаления”,
    Ложь);
    Выборка = Справочники.ВариантыОбеда(,, УсловияОтбора);
    </code>
    Я обошелся, конечно, запросом.

    • Установку привилегированного режима в модуле сеанса нет смысла делать.. ведь этот модуль всегда исполняется в привилегированном режиме.

      >у меня были такие строчки кода и на этот код мне выдавала программа ошибку пр зпуске, что неверный параметр 3
      Попробуйте передать структуру вторым параметром.

  6. respublica 06.02.2011 в 16:21

    Задание выполнено. Замечание не возникло.
    Опишу решение:
    1. Время начала и окончание работы перенес в константы, для них создал форму констант и добавил ее на рабочий стол. Для получения значений констант вклинился в процедуру УстановитьГрафик из предыдущего ДЗ.
    2. С созданием справочников и роли проблем не возникло. Синхронизацию справочника Пользователи и списка пользователей осуществляю через функцию модуля ОбщиеФункцииСервер, ее вызов разместил в начале функции ПриНачалеРаботыСистемы. В код элемента справочника помещаю имя из ТекущийПользователь, по коду же и ищу был ли пользователь записан в справочник. Функция возвращает в модуль приложения структуру с ссылкой на элемент справочника и его пометкой администратора.
    3. Для получение списка обедов вклинился в функции ВыбратьОбеды(), перебор элементов справочника делаю через выборку.
    4. Код для проверки факта выбора обеда и записи осуществленного выбора выглядит так:
    <code>
    Если НЕ (ДанныеОТекущемПользователе[“ПометкаАдминистратора”] ИЛИ ОбщиеФункцииСервер.ПользовательВыбралМеню(ДатаЗапуска, ТекущийПользовательСпр)) Тогда
    глОбед = ОбщиеФункцииКлиент.ВыбратьОбеды();
    ОбщиеФункцииСервер.ЗаписатьМенюПользователя(глОбед, ДатаЗапуска, ТекущийПользовательСпр);
    КонецЕсли;
    </code>

  7. 1. проверка и заполнение справочника Пользователи в модуле сеанса
    <code>Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    з=Новый Запрос;
    з.Текст=”ВЫБРАТЬ ПЕРВЫЕ 1
    |    Пользователи.Ссылка
    |ИЗ
    |    Справочник.Пользователи КАК Пользователи
    |ГДЕ
    |    Пользователи.Наименование = &ТекПользователь”;
    ТекПользователь=СокрЛП(ПользователиИнформационнойБазы.ТекущийПользователь().Имя);
    з.УстановитьПараметр(“ТекПользователь”,ТекПользователь);
    Выборка=з.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
    ПараметрыСеанса.ТекущийПользователь=Выборка.Ссылка;
    Иначе
    НовыйПользователь=Справочники.Пользователи.СоздатьЭлемент();
    НовыйПользователь.Наименование=ТекПользователь;
    Если ТекПользователь=”Администратор” Тогда
    НовыйПользователь.Администратор=Истина;
    КонецЕсли;
    НовыйПользователь.Записать();
    ПараметрыСеанса.ТекущийПользователь=НовыйПользователь.Ссылка;
    КонецЕсли;
    КонецПроцедуры</code>
    2. проверки на график работы
    На клиенте:
    <code>Функция ПолучитьДату()
    Возврат МестноеВремя(ОбщиеФункцииСервер.ПолучитьДату());
    КонецФункции

    Функция ВходЗапрещен(ДатаВхода) Экспорт
    ДатаВхода=ПолучитьДату();
    ГрафикРаботы=ОбщиеФункцииСервер.ПолучитьВремяРаботыПоГрафику();
    Если ГрафикРаботы=Неопределено Тогда Возврат Истина; КонецЕсли;
    НачалоГрафик=ГрафикРаботы.НачалоРаботы;
    НачалоРаботы=Дата(Год(ДатаВхода),Месяц(ДатаВхода),День(ДатаВхода),Час(НачалоГрафик),Минута(НачалоГрафик),Секунда(НачалоГрафик));
    ОкончаниеГрафик=ГрафикРаботы.КонецРаботы;
    ОкончаниеРаботы=Дата(Год(ДатаВхода),Месяц(ДатаВхода),День(ДатаВхода),Час(ОкончаниеГрафик),Минута(ОкончаниеГрафик),Секунда(ОкончаниеГрафик));
    Если ДатаВхода<НачалоРаботы ИЛИ ДатаВхода>ОкончаниеРаботы Тогда
    Предупреждение(“Нельзя заходить в нерабочее время!”);
    Возврат Истина;
    КонецЕсли;
    Возврат Ложь;
    КонецФункции // ЗапускЗапрещен()

    Функция ВыходЗапрещен() Экспорт
    ДатаВыхода=ПолучитьДату();
    ГрафикРаботы=ОбщиеФункцииСервер.ПолучитьВремяРаботыПоГрафику();
    Если ГрафикРаботы=Неопределено Тогда Возврат Истина; КонецЕсли;
    ОкончаниеГрафик=ГрафикРаботы.КонецРаботы;
    ОкончаниеРаботы=Дата(Год(ДатаВыхода),Месяц(ДатаВыхода),День(ДатаВыхода),Час(ОкончаниеГрафик),Минута(ОкончаниеГрафик),Секунда(ОкончаниеГрафик));
    Если ДатаВыхода<ОкончаниеРаботы Тогда
    Возврат (вопрос(“Рабочий день не закончился! Вы уверены что хотите выйти?”,РежимДиалогаВопрос.ДаНет)=КодВозвратаДиалога.нет);
    КонецЕсли;
    Возврат Ложь;
    КонецФункции</code>
    на сервере
    <code>Функция ПолучитьДату() Экспорт
    Возврат ТекущаяУниверсальнаяДата();
    КонецФункции // ПолучитьДату()()

    Функция ПолучитьВремяРаботыПоГрафику() Экспорт
    з=Новый Запрос;
    з.Текст=”ВЫБРАТЬ
    |    Константы.НачалоРаботы,
    |    Константы.КонецРаботы
    |ИЗ
    |    Константы КАК Константы”;
    Выборка=з.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
    Возврат Новый Структура(“НачалоРаботы,КонецРаботы”,Выборка.НачалоРаботы,Выборка.КонецРаботы);
    Иначе
    Возврат Неопределено;
    КонецЕсли;
    КонецФункции
    </code>
     
    3. обеды
    на клиенте
    <code>Процедура ВыбратьОбед(ДатаВхода) Экспорт
    спВариантовОбедов=ОбщиеФункцииСервер.ПолучитьВариантыОбеда(ДатаВхода);
    Если спВариантовОбедов=Неопределено Тогда Возврат;    КонецЕсли;
    ОбедВыбран=Ложь;
    мОбедов=Новый массив;
    Пока Не ОбедВыбран Цикл
    спВариантовОбедов.ОтметитьЭлементы(“Какой вариант обеда предпочитаете?”);
    Для Каждого СтрокаСписка ИЗ спВариантовОбедов Цикл
    Если СтрокаСписка.Пометка Тогда
    ОбедВыбран=Истина;
    мОбедов.Добавить(СтрокаСписка.Значение);
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;
    ОбщиеФункцииСервер.записатьОбеды(мОбедов,ДатаВхода);
    КонецПроцедуры
    </code>
    на сервере
    <code>Функция ПолучитьВариантыОбеда(ДатаВхода) Экспорт
    Если ПараметрыСеанса.ТекущийПользователь.Администратор Тогда
    Возврат Неопределено;
    КонецЕсли;
    з=Новый Запрос;
    з.Текст=”ВЫБРАТЬ ПЕРВЫЕ 1
    |    ОбедыПользователей.Ссылка
    |ИЗ
    |    Справочник.ОбедыПользователей КАК ОбедыПользователей
    |ГДЕ
    |    ОбедыПользователей.Дата = &Дата
    |    И ОбедыПользователей.Владелец = &Владелец
    |;
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВариантыОбедов.Ссылка,
    |    ВариантыОбедов.Наименование
    |ИЗ
    |    Справочник.ВариантыОбедов КАК ВариантыОбедов
    |ГДЕ
    |    (НЕ ВариантыОбедов.ПометкаУдаления)”;
    з.УстановитьПараметр(“Дата”,НачалоДня(ДатаВхода));
    з.УстановитьПараметр(“Владелец”,ПараметрыСеанса.ТекущийПользователь);
    Результат=з.ВыполнитьПакет();
    Если Не Результат[0].Пустой() Тогда Возврат Неопределено; КонецЕсли;
    Выборка=Результат[1].Выбрать();
    спВариантовОбеда=Новый СписокЗначений;
    Пока Выборка.Следующий() Цикл
    спВариантовОбеда.Добавить(Выборка.Ссылка,Выборка.Наименование);
    КонецЦикла;
    Возврат спВариантовОбеда;
    КонецФункции // ПолучитьВариантыОбеда()()

    Процедура ЗаписатьОбеды(мОбедов,ДатаВхода) Экспорт
    Для Каждого ЭлементМассива Из мОбедов Цикл
    НовыйОбед=Справочники.ОбедыПользователей.СоздатьЭлемент();
    НовыйОбед.Дата=ДатаВхода;
    НовыйОбед.Владелец=ПараметрыСеанса.ТекущийПользователь;
    НовыйОбед.ВариантОбеда=ЭлементМассива;
    НовыйОбед.Записать();
    КонецЦикла;
    КонецПроцедуры</code>

    • Просмотрел чужие ответы – наверное, надо было также делать функциями объектной модели, а не запросами. В следующий раз постараюсь исправиться.

      • Ну почему же. Запрос это правильная модель доступа к данным, все ок :)

    • Просьба приводить не весь код, а основные моменты решения.

  8. Добрый день!
    у меня несколько вопросов по 5 домашнему заданию.
    1. в Домашнем задании №4  Функция ЗапускЗапрещен использует переменную ДатаЗапуска, которая вроде как мы инициализируем в функции УстановитьГрафик.
    Однако при вызове Функции ЗапускЗапрещен она имеет значение Неопределено.
    2. Если в Справочнике Наименование равно 0, а есть другой реквизит типа строка… как его сделать основным представлением..при выборе элемента справочника из другой формы.

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

  9. Задание Выполнено
    Создал Роль «ПолныеПрава» и «ОбычныеПрава»
    В список пользователей добавил «Администратор» и «Менеджер» с полными правами, «Иван» с обычными правами.
    Создал Параметр Сеанса «ТекПользователь» тип СправочникСсылка.Пользователи.
    Создал НеобходимыеСправочники
    МодульСеанса
    Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    ТекущийПользователь=ПользователиИнформационнойБазы.ТекущийПользователь(); 
    IDПользователя=ТекущийПользователь.УникальныйИдентификатор;
    ПараметрыСеанса.ТекПользователь=Справочники.Пользователи.НайтиПоРеквизиту(“IDПользователя”,IDПользователя);
    Если ПараметрыСеанса.ТекПользователь=Справочники.Пользователи.ПустаяСсылка()
     Тогда
      НовыйПользователь=Справочники.Пользователи.СоздатьЭлемент();
      НовыйПользователь.IDПользователя=ТекущийПользователь.УникальныйИдентификатор;
      НовыйПользователь.ИмяПользователя=ТекущийПользователь.Имя;
      НовыйПользователь.Администратор=ТекущийПользователь.Роли.Содержит(Метаданные.Роли.ПолныеПрава);
      НовыйПользователь.Записать();
      ПараметрыСеанса.ТекПользователь=НовыйПользователь.Ссылка; 
    КонецЕсли; 
    КонецПроцедуры
    Модуль «ОбщиеФункцииСервер»
    Функция  ПользовательАдминистратор() Экспорт
    Возврат ПараметрыСеанса.ТекПользователь.Администратор 
    КонецФункции
    Функция ПолучитьВремяНачалаРаботы() Экспорт
    Возврат Константы.ВремяНачалаРаботы.Получить() 
    КонецФункции
                                                
    Функция ПолучитьВремяОкончанияРаботы() Экспорт
    Возврат Константы.ВремяОкончанияРаботы.Получить()
    КонецФункции
    Функция ПолучитьСписокОбедов() Экспорт
    СписокОбедов = Новый СписокЗначений;
    Выборка=Справочники.ВариантыОбедов.Выбрать();
    Пока Выборка.Следующий() Цикл
     Обед=Выборка.ПолучитьОбъект().Ссылка;
     Если (Обед.ПометкаУдаления=Ложь)
      тогда
       СписокОбедов.Добавить(Обед,Обед.Наименование); 
     КонецЕсли;
    КонецЦикла;
    Возврат СписокОбедов; 
    КонецФункции
    Функция ОбедВыбран(Дата) Экспорт
    Обед=Справочники.ОбедыПользователей.НайтиПоРеквизиту(“Дата”,Дата,,ПараметрыСеанса.ТекПользователь);
    Если Обед=Справочники.ОбедыПользователей.ПустаяСсылка()
     тогда
      Возврат Ложь 
     иначе
      Возврат Истина; 
    КонецЕсли; 
    КонецФункции
    Процедура ДобавитьОбеды(Дата,Обеды) Экспорт
     Для Каждого Элемент из Обеды Цикл
      НовыйОбед=Справочники.ОбедыПользователей.СоздатьЭлемент(); 
      НовыйОбед.Дата=Дата;
      НовыйОбед.Владелец=ПараметрыСеанса.ТекПользователь;
      НовыйОбед.ВариантОбеда=Элемент;
      НовыйОбед.Записать();
     КонецЦикла;
    КонецПроцедуры
    Модуль «ОбщиеФункцииКлиент»
    Процедура УстановитьГрафик(НачалоРаботы, ОкончаниеРаботы, ДатаЗапуска) Экспорт
    ДатаЗапуска = ОбщиеФункцииКлиент.ПолучитьДату();
    ВремяНачалаРаботы=ОбщиеФункцииСервер.ПолучитьВремяНачалаРаботы();
    ВремяОкончанияРаботы=ОбщиеФункцииСервер.ПолучитьВремяОкончанияРаботы();
    НачалоРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),9,5,38);
    ОкончаниеРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),18,11,42);
    КонецПроцедуры
    Процедура ВыбратьОбеды(Дата) Экспорт
     СписокОбедов =ОбщиеФункцииСервер.ПолучитьСписокОбедов();
     Обеды = Новый Массив;
     ВыбранОбед = Ложь;
     
     Пока Не ВыбранОбед Цикл
      СписокОбедов.ОтметитьЭлементы(“Выберите обед”);
      Для каждого Строка Из СписокОбедов Цикл
      
       Если Строка.Пометка Тогда
        ВыбранОбед = Истина;
        Обеды.Добавить(Строка.Значение);
       КонецЕсли;
      КонецЦикла;
     КонецЦикла;
     ОбщиеФункцииСервер.ДобавитьОбеды(Дата,Обеды); 
    КонецПроцедуры // ВыбратьОбеды() Эскорт()

  10. Справочник «Пользователи» должен автоматически синхронизироваться со списком пользователей. Для этого при старте приложения проверяйте есть ли текущий пользователь в справочнике. Если нет, его нужно программно добавить.
     
    Функция ПроверкаПользователя()Экспорт
      ПользовательКонфигурации=ПользователиИнформационнойБазы.ТекущийПользователь();      
                  Админ= ПользовательКонфигурации.Роли.Содержит(Метаданные.Роли.ПолныеПрава);
                  Если Не НаличиеПользовтеляВСправочнике(ПользовательКонфигурации.Имя)Тогда
                              НовыйОбъект=Справочники.Пользователи.СоздатьЭлемент();
                              НовыйОбъект.Наименование=ПользовательКонфигурации.Имя ;
                              НовыйОбъект.Администратор=Админ;
                              НовыйОбъект.Записать();
                                          КонецЕсли;
                  Если    ПользовательКонфигурации.Имя=”Администратор” И Админ Тогда
                              Возврат Истина
                  Иначе
                              Возврат Ложь
                  КонецЕсли;
    КонецФункции
     
    Функция НаличиеПользовтеляВСправочнике(Имя)
      ВыборкаПользователейСправочника=Справочники.Пользователи.Выбрать();
      Пока ВыборкаПользователейСправочника.Следующий()Цикл
                  Если  Имя=ВыборкаПользователейСправочника.Наименование Тогда
                              Возврат Истина;
                  КонецЕсли ;
      КонецЦикла ;
      Возврат Ложь;
    КонецФункции
     
     
    Проверка при входе и выходе и диалог о запросе обеда не должны осуществляться для пользователей с флагом «Администратор»
     
    Процедура ПередНачаломРаботыСистемы(Отказ)
            ВремяТек=МестноеВремя(Проверочный.ПолучитьВремя());
        
         Если не Проверочный.ПроверкаПользователя()тогда;
                     ВремяНР=  Проверочный.ПолучитьВремяНачалоРаботы();
                     ВремяОР=Проверочный.ПолучитьВремяОкончанияРаботы();
    ДатаНачалоРаботы=Дата(Год(ВремяТек),Месяц(ВремяТек),День(ВремяТек),Час(ВремяНР),Минута(ВремяНР),Секунда(ВремяНР));
                     ДатаОкончаниеработы=Дата(Год(ВремяТек),Месяц(ВремяТек),День(ВремяТек),Час(ВремяОР),Минута(ВремяОР),Секунда(ВремяОР)); 
                    
                     Если ВремяТек<ДатаНачалоРаботы или ВремяТек>ДатаОкончаниеработы Тогда
                                 Предупреждение(“Приходите в рабочее время”);
                                 Отказ=Истина;
                     КонецЕсли;
                    
         КонецЕсли
       КонецПроцедуры
     
    Время работы предприятия берется из констант;
    Функция ПолучитьВремя() Экспорт
                              Возврат УниверсальноеВремя(ТекущаяДата())  
                  КонецФункции
     
      Функция ПолучитьВремяНачалоРаботы() Экспорт
                              Возврат Константы.ВремяНачалаРабочегоДня.Получить();         
                  КонецФункции
     
      Функция ПолучитьВремяОкончанияРаботы() Экспорт
                                          Возврат Константы.ВремяОкончанияРабочегоДня.Получить();  
                  КонецФункции
     
    Варианты обеда берутся из одноименного справочника (как минимум 3 варианта, но пользователь может добавить собственные). Причем из справочника нужно выбирать элементы, не помеченные на удаление;
     
    Функция ПолучитьДанныеСправочника()   Экспорт
       Выборка=Справочники.ВариантыОбеда.Выбрать();
       СписокЗначений=Новый СписокЗначений;
        Пока Выборка.Следующий() Цикл
                   Если не Выборка.ПометкаУдаления  тогда
                               СписокЗначений.Добавить(Выборка.Наименование);
                   КонецЕсли;
       КонецЦикла;
                   Возврат СписокЗначений;
        КонецФункции
     
     
    Результат выбора пользователя записывайте в справочник «ОбедыПользователей». При выборе нескольких вариантов выполняйте запись нескольких элементов справочника;
    Процедура ЗаполнениеСправочникаОбедыПользователя(СписокЗначений,ТекВремя)Экспорт
                  ТекПользователь=ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
      ТекПользовательВСправочнике= Справочники.Пользователи.НайтиПоНаименованию(ТекПользователь);
      Для каждого Стр из СписокЗначений Цикл
                  НовОьект=Справочники.ОбедыПользователи.СоздатьЭлемент();
                  НовОьект.Владелец=ТекПользовательВСправочнике;
                  НовОьект.Дата= НачалоДня(ТекВремя);
                  НовОьект.Наименование= “Обед для “+ ТекПользовательВСправочнике+”а” ;
                  НовОьект.ВариантОбеда= Справочники.ВариантыОбеда.НайтиПоНаименованию(Стр) ;
                  НовОьект.Записать();
      КонецЦикла
     КонецПроцедуры
     
    Вопрос о выборе обеда должен задаваться только в том случае, если ранее пользователь не выбирал обед. Например, при первом входе в систему пользователь указал вариант обеда, тогда при втором запуске в эту же дату вопрос задавать не следует.
    Функция ПроверкаЗаполСправОбедыПользователя(ТекВремя)   Экспорт
                 Если не Справочники.ОбедыПользователи.Выбрать().Следующий() Тогда
                             Возврат Истина
                 Иначе
                             Если Справочники.ОбедыПользователи.НайтиПоРеквизиту(“Дата”,НачалоДня(ТекВремя))=Справочники.ОбедыПользователи.ПустаяСсылка() Тогда
                                        Возврат Истина;
                             Иначе
                                        Возврат Ложь
                             КонецЕсли                                                                           
                 КонецЕсли
     КонецФункции

  11. В модуле управляемого приложения определяем переменные “ТекущийПользователь”, “Администратор”. В процедуре ПередНачаломРаботыСистемы() присваиваем им значения с помощью функций ПолучитьТекущегоПользователя(), ЭтоАдминистратор(). “ТекущийПользователь” используется в функциях выбора обедов. “Администратор” используется в процедурах модуля управляемого приложения для осуществления проверок по условию “Если Не Администратор тогда”.
    В серверном модуле определяем функции ПолучитьТекущегоПользователья(), ЭтоАдминистратор(Пользователь), ПолучитьВариантыОбедов(), ЗаписатьОбедПользователя(Обеды,Пользователь), ОбедНеВыбран(Дата,Пользователь).
    Функция ПолучитьТекущегоПользователя() возвращает ссылку на справочник Пользователи, здесь же проводится синхронизация с текущим пользователем ИБ (если не найден, добавляем новый элемент и возвращаем ссылку на него). Используем свойство ПользователиИнформационнойБазы.ТекущийПользователь().Имя.
    Функция ЭтоАдминистратор(ТекущийПользователь) возвращает флаг администратора.
    Функция ПолучитьВариантыОбедов() возвращает массив, заполненный выборкой не помеченных на удаление элементов из справочника ВариантыОбедов. Этим массивом заполяем список значений: СписокОбедов.ЗагрузитьЗначения(ВариантыОбедов);
    Процедура ЗаписатьОбедПользователя(глОбед,ТекущийПользователь) записывает значения выбора в справочник ОбедыПользователей. Выполняется в процедуре ПриНачалеРаботыСистемы() после выбора обедов.
    Функция ОбедНеВыбран (ДатаЗапуска, ТекущийПользователь) выполяет поиск записей в справочнике Обеды пользователей по дате запуска и пользователю (Справочники.ОбедыПользователей.НайтиПоРеквизиту(“Дата”, НачалоДня(Дата),,Пользователь)). Выполняем проверку необходимости запроса на выбор обеда в процедуре ПриНачалеРаботыСистемы() – “Если Не Администратор и ОбщийСервер.ОбедНеВыбран()”.

  12. Тимур Шамиладзе 05.02.2011 в 16:45

    Все получилось.
    ТекущегоПользователя, в модуле сеанса записывал в ПараметрСеанса.
    И использовал два общих модуля, один с функциями на клиенте, а другой на сервере.
    Искал, существуют ли записи на эту дату, с помощью выборки и указания отбора в ней. Т.к в синтаксисе помошнике говорилось, что реквизит должен быть проиндексирован, то проиндексировал реквизит “Дата” для указания ее в отборе.

  13. Задание выполнено.

    Кроме описанных в задании констант и справочников система имеет два модуля: Модуль
    управляемого приложения и общий модуль для серверных вызовов. Пришлось долго помучится, пока не поставил флажок “Вызов сервера” в его свойствах.Постараюсь кратко описать процедуры и функции общего модуля:

    1. Процедура ПроверитьПользователя
    Параметры – ТекущийПользователь – Строковое значение текущего пользователя.
    Проверяет, есть ли пользователь с таким именем в справочнике пользователей и создает его, в случае отсутствия.

    2. Функция ВремяРабочее
    Возвращает истину, если время в диапазоне рабочего и ложь, если нет. В качестве входных
    параметров используются константы.

    3.Процедура ЗаполнитьВариантыОбеда
    Параметр ВариантыОбеда – СписокЗначений
    Процедура заполняет, передаваемый список значений, элементами справочника Варианты обеда.

    4.Функция ОбедЗаТекущуюДату
    Параметр Пользователь Структура с данными текщего пользователя.
    Возвращает истину, если за текущую дату для текущего пользователя обед уже был выбран.

    5.Процедура ЗаполнитьОбедыПользователей
    Параметры – Пользователь – Структура с данными текщего пользователя,
    – ВариантыВыбораОбеда – Список значений с отмеченным выбором.
    Заполняет справочник ОбедыПользователей выбранными обедами.

    6.Процедура СформироватьСтруктуруТекущегоПользователя
    Параметры – ТекщийПользователь структура
    Процедура Формирует структуру текущего пользователя, наполняя ее данными об имени текущего пользователя, Является ли пользователь администратором и и ссылкой на справочник пользователей. Вызов этой процедуры помещает структуру в глобальную переменную

    глТекущийПользователь.

    МодульПриложения использует следующие события: ПередНачаломРаботыСистемы,

    ПриНачалеРаботыСистемы, ПередЗавершениемРаботыСистемы. Также в этом модуле сделана функция ОтсутствуютВыбранныеЭлементы, которая определяет выбрал ли пользователь обед. При
    необходимости ее несложно перенести в серверный вызов. Если следующее задание будет на базе этого, то так и сделаю.

    • > Если следующее задание будет на базе этого
      Так и будет.

  14. Елена 05.02.2011 в 11:32

    А перед этим:
    Создала справочники, константы, роль с правами Администратора и пользователя.В справочнике Обеды Пользователей реквизиту Дата установила индекс.
    Пользователя храню в параметрах сеанса, который устанавливаю в модуле сеанса.

  15. Елена 05.02.2011 в 11:30

    3. Модуль ОбщиеФункцииСервера:
    Функция ПолучитьДату() Экспорт
     Возврат ТекущаяУниверсальнаяДата();
    КонецФункции // ПолучитьДату() Экспорт()
    Процедура  ПолучитьЗначенияКонстантВремениЗапуска(НачРДня,КонРДня) Экспорт
     НачРДня = Константы.НачалоРДня.Получить();
     КонРДня = Константы.ОкончаниеРДня.Получить();
    КонецПроцедуры
    Функция ЭтоАдминистратор(Пользователь) Экспорт
     Возврат Пользователь.Администратор;
    КонецФункции
    Функция ОпределитьПользователя() Экспорт
     Нашли = Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя());
     Если Нашли.Ссылка.Пустая() Тогда
      Нашли = Справочники.Пользователи.СоздатьЭлемент();
      Нашли.Наименование = ИмяПользователя();
      Нашли.Администратор = РольДоступна(“ПолныеПрава”);
      Нашли.Записать();
     КонецЕсли;
     Возврат Нашли.Ссылка;
    КонецФункции
    Процедура ЗаполнитьСписокОбедов(СписокОбедов)  Экспорт
     Выборка = Справочники.ВариантыОбедов.Выбрать();
     Пока Выборка.Следующий() Цикл
      Если Выборка.ПометкаУдаления Тогда
       Продолжить;
      КонецЕсли;
      СписокОбедов.Добавить(Выборка.Наименование);
     КонецЦикла;
    КонецПроцедуры
    Процедура ЗапомнитьВыборОбедов(глОбед,ДатаЗапуска,Пользователь) Экспорт
     Для Каждого блюдо из глОбед Цикл
      Нов          = Справочники.ОбедыПользователей.СоздатьЭлемент();
      Нов.Владелец = Пользователь;
      Нов.Дата     = НачалоДня(ДатаЗапуска);
      Нов.ВариантОбеда = Справочники.ВариантыОбедов.НайтиПоНаименованию(блюдо);
      Нов.Наименование = блюдо;
      Нов.Записать();
     КонецЦикла;
    КонецПроцедуры
    Функция НадоСпрашиватьОбеды(ДатаЗапуска,Пользователь) Экспорт
     Выборка = Справочники.ОбедыПользователей.Выбрать(,Пользователь,Новый Структура(“Дата”,НачалоДня(ДатаЗапуска)),);
     Пока Выборка.Следующий()Цикл
      Возврат Ложь;
     КонецЦикла;
     Возврат Истина;
    КонецФункции
    модуль ОбщиеФункцииКлиент
    Функция ПолучитьДату() Экспорт
     Возврат МестноеВремя(ОбщиеФункцииСервер.ПолучитьДату());
    КонецФункции // ПолучитьДату() Экспорт()
    Процедура УстановитьГрафик(НачалоРаботы, ОкончаниеРаботы) Экспорт
     ДатаЗапуска = ОбщиеФункцииКлиент.ПолучитьДату();
     
     НачРДня = “”;
     КонРДня = “”;
     ОбщиеФункцииСервер.ПолучитьЗначенияКонстантВремениЗапуска(НачРДня,КонРДня);
     НачалоРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),Лев(НачРДня,2),Сред(НачРДня,4,2),Прав(НачРДня,2));
     ОкончаниеРаботы = Дата(Год(ДатаЗапуска),Месяц(ДатаЗапуска),День(ДатаЗапуска),Лев(КонРДня,2),Сред(КонРДня,4,2),Прав(КонРДня,2));
     //ОкончаниеРаботы = ‘00010101181142’;
     //НачалоРаботы = Дата(1,1,1,15,5,38);
    КонецПроцедуры
    Функция ЗапускЗапрещен(НачалоРаботы, ДатаЗапуска, ОкончаниеРаботы) Экспорт
     ДатаЗапуска = ОбщиеФункцииКлиент.ПолучитьДату();
     
     Если (ДатаЗапуска<НачалоРаботы ИЛИ ДатаЗапуска>ОкончаниеРаботы) и НЕ ОбщиеФункцииСервер.ЭтоАдминистратор() Тогда
     
      Предупреждение(“Не время работать!”, 5);
      Возврат Истина;
     
     КонецЕсли;
     
     Возврат Ложь;
    КонецФункции // ЗапускЗапрещен(НачалоРаботы) Экспорт()
     
    Функция ЗавершениеЗапрещено(ОкончаниеРаботы, ДатаЗапуска) Экспорт
     ДатаВыхода = ОбщиеФункцииКлиент.ПолучитьДату();
     
     Если ДатаВыхода<ОкончаниеРаботы Тогда
     
      Если Вопрос(“Еще поработаем?!”, РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да Тогда
       Возврат Истина;
      КонецЕсли;
     
     КонецЕсли;
     
     Возврат Ложь;
    КонецФункции // ЗавершениеЗапрещено(ОкончаниеРаботы) Экспорт()

    Функция ВыбратьОбеды() Экспорт
     СписокОбедов = Новый СписокЗначений;
     ОбщиеФункцииСервер.ЗаполнитьСписокОбедов(СписокОбедов);
      
     //СписокОбедов.Добавить(“Мясо”);
     //СписокОбедов.Добавить(“Курица”);
     //СписокОбедов.Добавить(“Рыба”);
     
     Обеды = Новый Массив;
     ВыбранОбед = Ложь;
     
     Пока Не ВыбранОбед Цикл
      СписокОбедов.ОтметитьЭлементы(“Выберите обед”);
      Для каждого Строка Из СписокОбедов Цикл
       Если Строка.Пометка Тогда
        ВыбранОбед = Истина;
        Обеды.Добавить(Строка.Значение);
       КонецЕсли;
      КонецЦикла;
     КонецЦикла;
     
     Возврат Обеды;
    КонецФункции // ВыбратьОбеды()
    Модуль Управляемого приложения:
    Перем НачалоРаботы;
    Перем ОкончаниеРаботы;
    Перем ДатаЗапуска;
    Перем глОбед Экспорт;
    Перем глПользователь Экспорт;
    Процедура ПередНачаломРаботыСистемы(Отказ)
     
     Числа = Новый Структура();
     
     Для Сч=1 По 1000 Цикл
     
      Простое = Истина;
      Для Д=2 По Сч-1 Цикл
      
       Если Сч%Д = 0 Тогда
       
        Простое = Ложь;
        Прервать;
       
       КонецЕсли;
      
      КонецЦикла;
      
      Числа.Вставить(“Число”+Формат(Сч, “ЧГ=0”), ?(Простое, “Простое”, “Не простое”));
     
     КонецЦикла;
     
     Х = “Число591”;
     У = Неопределено;
     Найдено = Числа.Свойство(Х, У);
     
     глПользователь = ОбщиеФункцииСервер.ОпределитьПользователя();
     ОбщиеФункцииКлиент.УстановитьГрафик(НачалоРаботы, ОкончаниеРаботы);
     
     Отказ = ОбщиеФункцииКлиент.ЗапускЗапрещен(НачалоРаботы, ДатаЗапуска, ОкончаниеРаботы);
     
    КонецПроцедуры
    Процедура ПередЗавершениемРаботыСистемы(Отказ)
     Если НЕ ОбщиеФункцииСервер.ЭтоАдминистратор(глПользователь)Тогда
      Отказ = ОбщиеФункцииКлиент.ЗавершениеЗапрещено(ОкончаниеРаботы, ДатаЗапуска);
     КонецЕсли;
    КонецПроцедуры
    Процедура ПриНачалеРаботыСистемы()
     Если НЕ ОбщиеФункцииСервер.ЭтоАдминистратор(глПользователь) и ОбщиеФункцииСервер.НадоСпрашиватьОбеды(ДатаЗапуска,глПользователь) Тогда 
      глОбед = ОбщиеФункцииКлиент.ВыбратьОбеды();
      ОбщиеФункцииСервер.ЗапомнитьВыборОбедов(глОбед,ДатаЗапуска,глПользователь);
     КонецЕсли;
    КонецПроцедуры

    • Елена, просьба не приводить весь код, а только основные моменты.

  16. Создал константы: НачалоРабочегоДня и КонецРабочегоДня с типом “Дата” и Составом даты “Время” и  общую форму для их редактирования.
    процедуру общего клиентского модуля УстановитьГрафик  перенес в общий серверный модуль и произвел модификацию:
    Получение Даты Запуска вынес в событие ПередНачаломРаботыСистемы и  передаю это значение в нее в качестве параметра;
    Для проверки пустых значений констант использую метод глобального контекста ЗначениеЗаполнено(). И если значение пустое, то параметрам НачалоРаботы и ОкончаниеРаботы присваиваю значение Даты запуска. Т.е. пока значения констант не заданы, вход и выход возможен в любое время.
    Создал справочник с предопределенными значениями. Для созданной роли флаг Устанавливать права для новых объектов выставил. Далее вызвал контекстное меню на объекте конфигурация у нажал “Установить все права”.
    Одного пользователя создал и назначил ему роль. Сохранить не получилось, пока не вспомнил, что нужно предварительно сохранить конфигурацию. Дальше создание пользователей проблем не вызвало.
    Создал справочник Пользователи с необходимым реквизитом и подчиненный ему ОбедыПользователей. Определил для него реквизиты.
    Для хранения текущего пользователя создал параметр сеанса ТекущийПользователь с типом СправочникСсылка.Пользователи. Ничего лучшего для хранения глобальной серверной переменной не придумал.
    Для синхронизации Пользователей создал процедуру в общем серверном модуле.
    <code>
    Процедура ПровестиСинхронизациюПользователяИнфБазыСоСправочникомПользователей() Экспорт
    ПользовательИнфБазы = ПользователиИнформационнойБазы.ТекущийПользователь();
    СпрПользователь = Справочники.Пользователи.НайтиПоНаименованию(ПользовательИнфБазы.Имя, Истина);
    Если СпрПользователь = Справочники.Пользователи.ПустаяСсылка() Тогда
    Пользователь = Справочники.Пользователи.СоздатьЭлемент();
    Пользователь.Заполнить(Новый Структура(“Наименование”, ПользовательИнфБазы.Имя));
    Пользователь.Записать();
    ПараметрыСеанса.ТекущийПользователь = Пользователь.Ссылка;
    Иначе
    ПараметрыСеанса.ТекущийПользователь = СпрПользователь;
    КонецЕсли;
    КонецПроцедуры
    </code>
    В модуле объекта справочника Пользователи
    <code>
    Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    Перем НайдЗначение;
    Если ТипЗнч(ДанныеЗаполнения) = Тип(“Структура”) Тогда
    Если ДанныеЗаполнения.Свойство(“Наименование”, НайдЗначение) Тогда
    Наименование = НайдЗначение;
    Если СокрЛП(Наименование) = “Администратор” Тогда
    Администратор = Истина;
    КонецЕсли;
    КонецЕсли;
    КонецЕсли;
    КонецПроцедуры
    </code>
    Чтобы не осуществлять контроли для пользователей с флагом “Администратор” определил в общем серверном модуле функцию
    <code>
    Функция ПроизводитьКонтроль() Экспорт
    Возврат НЕ ПараметрыСеанса.ТекущийПользователь.Администратор;
    КонецФункции // ПроизводитьКонтроль
    </code>
    и модифицировал модуль приложения.

    Получение списка обедов из функции ВыбратьОбеды() вынес в общий серверный модуль. Заполнение осуществляется выборкой элементов справочника с проверкой пометки удаления.
    Саму функцию переделал в процедуру, теперь возвращать список выбранных обедов нет смысла. И передаю при ее вызове параметр ДатаЗапуска.
    Модифицировал реквизит Дата справочника ОбедыПользователей – установил индексацию, для возможности отбора по нему.
    В начале работы процедуры обращаюсь к функции в общем серверном модуле для проверки выбранных обедов на ДатаЗапуска
    <code>    
    Функция ОбедыВыбраны(ДатаЗапуска) Экспорт
    ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;
    СпрОбедыПользователей = Справочники.ОбедыПользователей.Выбрать(,ТекущийПользователь,Новый Структура(“Дата”, НачалоДня(ДатаЗапуска)));
    Если СпрОбедыПользователей.Следующий() Тогда
    Возврат Истина;
    КонецЕсли ;
    Возврат Ложь;
    КонецФункции // ОбедыВыбраны()
    </code>
    Результат выбора обедов записываю в процедуре общего серверного модуля, передав в нее массив выбранных обедов и ДатуЗапуска. Запись даты осуществляю на начало дня.
    После тестирования убрал реквизит Наименование для справочника ОбедыПользователей.

  17. Задание делал путем переработки Вашей базы по 4му заданию
    1) Создание объектов прошло довольно легко
    2)С остальным помучился, особенно с ошибкой про тонкого клиента, когда пытался работать с базой из модуля клиента и когда абывал записывать название общих модулей, но к концу дня привык. Код расписывать нет смысла, получилось много обращений из клиента к серверу, думаю что сделал неоптимально, но для меня пока главное, что все заработало, как мне это кажется . Вобщем день провозился не зря.

  18. Задание выполнил. Создал константы, справочники. Затруднений в этом нет. Написал код. Ошибок было много. Отладчиком и повтором уроков добился работоспособности.

  19. Задание выполнено.
    Созданы константы, роль с полными правами, справочники.
    Для определения рабочего времени дата используется системная, а время подставляется из констант.
    Все приведенные ниже фрагменты кода вызываются в серверном контексте
    Справочник пользователи синхронизируется с текущим пользователем системы следующим образом:
    Получить имя текущего пользователя системы.
    <code>
    Функция ПолучитьПользователя ()  Экспорт
    ТекущийПОльзователь = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
    Возврат ТекущийПользователь;
    КонецФункции</code>
    Если пользователя нет в базе, записать.
    <code>
    Процедура НайтиИЗаписать(Пользователь)  Экспорт
    ПользовательИмя = Справочники.Пользователи.НайтиПоНаименованию(Пользователь);
    Если НЕ ЗначениеЗаполнено(ПользовательИмя) Тогда
    НовыйОбъект = Справочники.Пользователи.СоздатьЭлемент();
    НовыйОбъект.Наименование = Пользователь;
    НовыйОбъект.Записать();
    КонецЕсли;
    </code>
    Проверка есть ли в реквизите Администратор флаг для данного пользователя
    <code>
    Функция Флаг(Пользователь) Экспорт
    Флаг = Справочники.Пользователи.НайтиПоНаименованию(Пользователь).Администратор;
    Возврат Флаг;
    </code>
    и совпадает ли текущая дата с датой выбора обеда для текущего пользователя
    <code>
    Функция ПроверкаЗаказов()  Экспорт
    ТекДата = НачалоДня(ТекущаяДата());
    Отбор = новый Структура(“Дата”, ТекДата);
    Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ПолучитьПользователя());
    Выборка = Справочники.ОбедыПользователей.Выбрать(, Пользователь, Отбор);
    Если  Выборка.Следующий() Тогда
    возврат Ложь;
    Иначе
    Возврат Истина;
    КонецЕсли;
    КонецФункции
    </code>
    если Флаг выставлен и даты совпадают то меню выбора обедов не показывать
    После выбора обедов происходит проверка элементов на пометку удаления и запись в справочник,
    <code>
    Процедура ЗаписатьОбеды(Обед)  Экспорт
    Если НЕ Справочники.ВариантыОбедов.НайтиПоНаименованию(Обед).ПометкаУдаления Тогда
    НовыйОбед = Справочники.ОбедыПользователей.СоздатьЭлемент();
    НовыйОбед.Наименование = “Обед”;
    НовыйОбед.Владелец = Справочники.Пользователи.НайтиПоНаименованию(ПолучитьПользователя());
    НовыйОбед.Дата = НачалоДня(ТекущаяДата());
    НовыйОбед.ВариантОбеда = Справочники.ВариантыОбедов.НайтиПоНаименованию(Обед);
    НовыйОбед.Записать();
    КонецЕсли;
    КонецПроцедуры<code/>
    Запись в справочник происходит в цикле, на каждой интерации записывается новый выбранный вариант обеда.
     

  20. Задание выполнено.
    Все необходимые пользователи, константы и справочники созданы. В справочник Пользователи добавлен строковый индексируемый реквизит Логин,
    т.к. наименование и логин пользователя в общем случае могут различаться. Проверка на административные привилегии осуществляется в модуле управляемого приложения вызововом экспортной процедуры общего модуля
    <code>
    Перем Админ;
    Перем глОбед Экспорт;
    //Проверка времени входа в систему
    Процедура ПередНачаломРаботыСистемы(Отказ)
    РаботаСПользователями.ПроверитьПользователя(Админ);
    Если (НЕ Админ) Тогда
    Если (НЕ ОбщиеФункцииСервер.ПроверитьВремя()) Тогда
    Предупреждение(“Работать нельзя”,7);
    Отказ = Истина;
    КонецЕсли;
    КонецЕсли;
    КонецПроцедуры

    Процедура ПроверитьПользователя(Админ) Экспорт
    Логин = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
    Пользователи = Справочники.Пользователи;
    Пусто = Пользователи.ПустаяСсылка();
    НайденнаяСсылка = Пользователи.НайтиПоРеквизиту(“Логин”,Логин);
    Если НайденнаяСсылка = Пусто Тогда
    НовыйПользователь = Пользователи.СоздатьЭлемент();
    НовыйПользователь.Наименование = Логин;
    НовыйПользователь.Логин = Логин;
    НовыйПользователь.Администратор = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя =”Администратор”;
    НовыйПользователь.Записать();
    КонецЕсли;
    Админ = ПользователиИнформационнойБазы.ТекущийПользователь().ПолноеИмя = “Администратор”
    КонецПроцедуры // ПроверитьПользователя()
    Функция ПроверитьВремя() Экспорт
    ТекДата = ТекущаяДата();
    ТекЧас = Час(ТекДата);
    ТекМинута = Минута(ТекДата);
    ТекСекунда = Секунда(ТекДата);
    ТекВремя = Дата(1,1,1,ТекЧас, ТекМинута, ТекСекунда);
    НачалоРаботы = Константы.НачалоРаботы.Получить();
    КонецРаботы = Константы.КонецРаботы.Получить();
    Возврат НачалоРаботы < ТекВремя И КонецРаботы > ТекВремя ;
    КонецФункции //ПроверитьВремя

    </code>
    Аналогично проверяется время выхода из системы в процедре ПередЗавершениемРаботыСистемы(Отказ).
    Выбор меню осуществляется небольшой модификацией аналогичной задачи из домашнего задания 4 посредством заполнения списка значений данными из соответствующего справочника
    <code>
    Процедура ПриНачалеРаботыСистемы()
    МенюОбед = Новый СписокЗначений;
    ОбщиеФункцииСервер.ЗаполнитьМеню(МенюОбед);
    Выход = Истина;
    Пока Выход Цикл
    Если МенюОбед.ОтметитьЭлементы(“Выберите, пожалуйста, обед”) Тогда
    Для каждого Элемент из МенюОбед Цикл
    Если Элемент.Пометка Тогда
    Выход = Ложь;
    глОбед.Добавить(Элемент.Значение);
    ОбщиеФункцииСервер.ЗаполнитьОбедПользователя(Элемент.Значение);
    КонецЕсли;
    КонецЦикла;
    КонецЕсли;
    КонецЦикла;
    КонецПроцедуры
    Процедура ЗаполнитьМеню(Меню) Экспорт
    Обед = Справочники.ВариантыОбедов.Выбрать();
    Пока Обед.Следующий() Цикл
    Если не Обед.ПометкаУдаления Тогда
    Меню.Добавить(Обед.Код, Обед.Наименование);
    КонецЕсли;
    КонецЦикла;
    КонецПроцедуры // ЗаполнитьМеню()

    </code>
    Заполнение справочника ОбедыПользователей производится на основе отбора по владельцу и по дате заказа без использования запроса.

  21. Константы, справочники, роль добавлены… процедуры работы с объектами метаданных перенесены в общий модуль с галочками: “сервер”, “вызов сервера”. Пользователя запоминаю в параметрах сеанса, чтоб постоянно по справочнику не бегать. Заполняю параметры в соответствующем модуле.
    При написании кода было сделано предположение, что время, как и часовой пояс, пользователь менять не может (запрет политиками домена)
    Небольшие примеры кода (весь код становится выкладывать сложнее и сложнее :-))
    Функция ПроверитьОбедПользователя() Экспорт
    Возврат Справочники.ОбедыПользователей.Выбрать(,ПараметрыСеанса.ТекущийПользователь.Ссылка,Новый Структура(“Дата”,НачалоДня(ТекущаяДата()))).Следующий();
    КонецФункции // ПроверитьОбедПользователя()
    Функция ПолучитьЗначениеРеквизитаПараметраСеанса(ИмяПараметра,ИмяРеквизита) Экспорт

    Возврат ПараметрыСеанса[ИмяПараметра][ИмяРеквизита];

    КонецФункции // ПолучитьЗначениеРеквизита()

    Процедура ЗапомнитьОбедПользователя(СЗ) Экспорт

    Спр = Справочники.ОбедыПользователей;
    Для Каждого Эл Из СЗ Цикл
    Если Эл.Пометка Тогда
    НовЭлемент = Спр.СоздатьЭлемент();
    НовЭлемент.Владелец = ПараметрыСеанса.ТекущийПользователь;
    НовЭлемент.Дата = ТекущаяДата();
    НовЭлемент.ВариантОбеда = Справочники.ВариантыОбедов.НайтиПоНаименованию(Эл.Значение);
    НовЭлемент.Записать();
    КонецЕсли;
    КонецЦикла;

    КонецПроцедуры // ЗапомнитьОбедПользователя()
    Функция ПроверитьВремяПользователя(ТекДата) Экспорт
    ВремяВхода = Дата(1,1,1,Час(ТекДата),Минута(ТекДата),Секунда(ТекДата));

    Возврат ВремяВхода >= Константы.НачалоРаботы.Получить() и ВремяВхода <= Константы.ОкончаниеРаботы.Получить();

    КонецФункции // ПроверитьВремяПользователя()

    Если НЕ РаботаСПользователемСервер.ПолучитьЗначениеРеквизитаПараметраСеанса(“ТекущийПользователь”,”Администратор”) и НЕ РаботаСПользователемСервер.ПроверитьОбедПользователя() Тогда
    …..
    КонецЕсли;
    Код отлажен и проверен на работоспособность.
    Проблемы, с которыми столкнулся в процессе выполнения:
    – Пока тяжело делить Клиент и Сервер…с непривычки после 8.1…код кажется излишним

  22. Создал необходимые константы(ВремяНачалаРаботы и ВремяОкончанияРаботы) и справочники( ВариантыОбедов,  Пользователи, ОбедыПользователей с индексированным реквизитом дата).
    Создал 2 роли Администратор и Менеджер с полными правами с возможностью распространятся на новые объекты в системе
    функции получения констант, поиск пользователя, создание пользователя, выбор обедов, проверки пользователя по реквизиту “администратор”, проверка на наличие выбранных обедов для пользователя, добавить выбранные обеды,  все функции вынесены в “ОбщиеФункцииНаСервере”, в модуль “ОбщиеФункцииНаКлиенте” вынесены функции  получить дату, и процедура выбор обедов (в теле процедцры обращение к общему модулю на сервере)

  23. Виктор Вахненко 04.02.2011 в 00:46

    Создал необходимые справочники: ВариантыОбедов,  Пользователи, ОбедыПользователей.
    Установил параметр “Индексировать” для реквизита “Дата” справочника ОбедыПользователей. Это нужно для того, чтобы проверку существования выбранных обедов для пользователя можно было сделать с помощью функции Выбрать объекта СправочникМенеджер.
    Константы для хранения времени начала и окончания рабочего дня остались с прошлого домашнего задания.
    Создал роль с полными правами на все объекты конфигурации, а также двух пользователей.
    Все процедуры и функции для работы с данными информационной базы разместил в общем модуле. Этот модуль имеет флаг компиляции “Сервер” и установленный параметр “Вызов сервера”.
    В общем модуле есть такие процедуры и функции: 1) Процедура для проверки наличий текущего пользователя в справочнике “Пользователи”; 2) Функция проверки признака “Администратор” у текущего пользователя; 3) Процедура заполнения списка обедов для последующего выбора пользователем; 4) Процедура добавления нового обеда в справочник “ОбедыПользователей”; 5) Функция, которая проверяет, выбран ли обед для текущего пользователя в границах текущей даты.
    Проверил на работоспособность написанный код.

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

    • Почитал комментарии других участников и понял, что в функ-и проверки обедов можно было делать выборку с отбором по владельцу, а я все элементы в ЕСЛИ сравнивал…

  25. Гуляев Алексей 03.02.2011 в 16:49

    Сделано
    1. Все что требовалось создать я успешно добавил.
    2. ПередНачаломРаботыСистемы(Отказ).
    Сначала из базы получаю.
    НачалоРаботыВремя = ОбщиеФункцииСервер.ПолучитьКонстантуНачалоРаботы();
    ОкончаниеРаботыВремя = ОбщиеФункцииСервер.ПолучитьКонстантуОкончаниеРаботы();
    ТекущийПользователь = ОбщиеФункцииСервер.ПолучитьТекущегоПользователя();
    Администратор = ОбщиеФункцииСервер.ТекущийПользовательАдминистратор();
    Далее
    ОбщиеФункцииСервер.ПроверкаИДобавлениеПользователя();
    Пользователю Администратор автоматически ставиться соответствующая галочка
    После этого
    Если Не Администратор Тогда
    КонецЕсли;

    т.е. проверяем есть ли у текущего пользователя галочка Администратор если нет, проверяем время входа в систему.
    3. ПриНачалеРаботыСистемы().
    Сначала получаем
    НеВыбранОбедПользователя = ОбщиеФункцииСервер.НеВыбранОбедПользователя();
    Далее
    Если НеВыбранОбедПользователя Тогда

    КонецЕсли;
    В этом условии получаем
    СписокОбедов = ОбщиеФункцииСервер.ПолучитьСписокОбедов();
    И выкидываем его на экран пользователю, а также
    ОбщиеФункцииСервер.ЗаписьОбедовВСправочник(глОбед);
    4. ПередЗавершениемРаботыСистемы(Отказ)
    Проверяем только
    Если Не Администратор Тогда
    КонецЕсли;

    Если не администратор, то спрашиваем о Выходе.
    P.S. Что да данный урок.

    Наконец-то понял как сравнивать Справочник.Ссылки, и все то что на сервер отправлять надо, а не на клиент.
    Понял как правильно работать с отладчиком (а то сначала неправильно вылавливал ошибку проверки обедов).

    Спасибо.

  26. Павел Конов 03.02.2011 в 10:13

    сделано.
    для проверки пользователей с создания нового использовал Модуль сеанса.
    Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
    Юзер = Справочники.Пользователи;
    Ссылка=Юзер.НайтиПонаименованию(ИмяПользователя(),Истина);
    Если Ссылка=Юзер.пустаяСсылка() тогда
    НЮ=Юзер.СоздатьЭлемент();
    НЮ.Наименование=ИмяПользователя();
    Если ИмяПользователя()=”Администратор” тогда
    Ню.Администратор=Истина
    КонецЕсли;
    Ню.Записать();
    КонецЕсли;
    КонецПроцедуры

    Это оказалось единственным местом где не было проблем.
    Поскольку изначально решил не использовать форму справочника – оставил старую конструкцию. Список значения  заполняется из справочника – выбор данных пользователемм уходит в массив. Из массива при необходимости создаем записи в подчиненном справочнике. Получил туже ошибку что и Mark – решил ее костылем вида
    ОбщийСерверныйВызов.созданиеобедДата(Строка(ГлОбед.Получить(Индекс)));
    В конце так и не смог победить Выборку по владельцу. Запрос использовать не стал (мы их еще не проходили), а отбор выдавал ошибку вида Несоответствие типов (параметр номер ‘2’)
    В итоге сделал плохо – чтением всех элементов и сверкой владельца и даты.
    Очень не нравится в коде вызов клиентсокого метода из которого потом вызывается серверный. Вообщем ушел пересматривать главы по модулям…
     

    • > так и не смог победить Выборку по владельцу
      Если во второй параметра метода СправочникМенеджер..Выбрать() передать владельца разве не работает.
      Разумеется тип должен быть СправочникСсылка, и соответствовать владельцу данного справочника.

      • Павел Конов 03.02.2011 в 14:23

        Юзер = Справочники.Пользователи;
        Ссылка=Юзер.НайтиПонаименованию(ИмяПользователя(),Истина);
        Вот так передавал владельца.  Сегодня еще раз буду разбираться….

      • Павел Конов 03.02.2011 в 23:25

        я переформулирую вопрос
        по пользователю я могу сделать выборку в подчиненном справочнике. а как реализовать следующую конструкцию: сделать выборку по владельцу, а внутри выборку по Дате.
        Юзер = Справочники.Пользователи;
        Ссылка=Юзер.НайтиПонаименованию(ИмяПользователя(),Истина);
        Отбор = Новый Структура;
        Отбор.Вставить(“ДатаОбеда”,ТекущаяДата());
        обеды = Справочники.ОбедыПользователей;
        Выборка = Обеды.Выбрать(,Ссылка,Отбор,);

         

        • Приведенный Вами код не работает?
          ДатаОбеда – индексированный реквизит?

          • Павел Конов 04.02.2011 в 13:03

            Код дает пустую выборку. Реквизит  индексированный.
             

            • Полагаю, что код выдает именно тот результат, который вы просите.
              Посмотрите как записывается дата в справочнике, наверняка без секунд (состав даты – Дата).
              В выборку вы передаете текущую дату и текущее время.
              Попробуйте фильтровать по НачалоДня(ТекущаяДата()).
              Сообщите о результате.

              • Павел Конов 04.02.2011 в 21:48

                Спасибо! Заработало…
                Теперь я почти доволен кодом )
                ps я смотрел как хранится дата в справочнике (только дата без времени) и приводил Текущуюдату к такому же формату. Но другой командой.

  27. Федор 03.02.2011 в 08:44

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

    Модуль сеанса
    <code>
    Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
     Пользователи.ОпределитьТекущегоПользователя();
    КонецПроцедуры
    </code>

    Модуль управляемого приложения
    <code>
    Процедура ПриНачалеРаботыСистемы()
     Если  НЕ Пользователи.ПользовательАдминистратор() Тогда 
      Если Пользователи.РабочийДень() Тогда 
       Если  НЕ Пользователи.Менюсформированно() Тогда
        
        СписокОбед = Пользователи.Меню();
        МенюСформированно = Ложь;
        
        Пока НЕ МенюСформированно Цикл
         СписокОбед.ОтметитьЭлементы(“Выберете меню на обед”);
         ВыбранноеМеню = Новый Массив;
         Для Каждого ЭлементСпискаОбед Из СписокОбед Цикл
          Если ЭлементСпискаОбед.Пометка Тогда
           ВыбранноеМеню.Добавить(ЭлементСпискаОбед.Значение);             
           Пользователи.ЗаполнитьМенюПользователя(ВыбранноеМеню, Пользователи.ТекущийПользователь());
           МенюСформированно = Истина;
          КонецЕсли;
         КонецЦикла;
         Если НЕ МенюСформированно Тогда
          Предупреждение(“Меню не сформированно”, 5);
         КонецЕсли;
        КонецЦикла;
       КонецЕсли; 
      Иначе  
       Предупреждение(“Время входа в сисмему не соответствует режиму работы, приложение будет закрыто”, 5);
       ЗавершитьРаботуСистемы();
      КонецЕсли;
     КонецЕсли;
    КонецПроцедуры
    Процедура ПередЗавершениемРаботыСистемы(Отказ)
     Если Пользователи.РабочийДень() И НЕ Пользователи.ПользовательАдминистратор() Тогда
      Ответ =Вопрос(“Рабочий день еще не завершон. Вы действительно хотите завершить работу с программой” , РежимДиалогаВопрос.ДаНет);
      Если Ответ = КодВозвратаДиалога.Нет Тогда 
       Отказ = Истина;
      КонецЕсли;
     КонецЕсли;
    КонецПроцедуры

    Пользователи.ИнициализироватьРежимРаботы();
    </code>
    Общий модуль пользователи
    <code>
    Процедура ОпределитьТекущегоПользователя() Экспорт
     ИмяПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
     Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ИмяПользователя);
     Если  Пользователь = Справочники.Пользователи.ПустаяСсылка() Тогда
      Пользователь = Справочники.Пользователи.СоздатьЭлемент();
      Пользователь.Администратор = Ложь;
      Пользователь.Наименование = ИмяПользователя;
      Пользователь.Записать();
      Пользователь = Пользователь.Ссылка;
     КонецЕсли;
     
     Запрос = Новый Запрос;
     Запрос.Текст = “ВЫБРАТЬ
                    | ОбедыПользователей.Ссылка
                    |ИЗ
                    | Справочник.ОбедыПользователей КАК ОбедыПользователей
                    |ГДЕ
                    | ОбедыПользователей.Дата = &Дата
                    | И ОбедыПользователей.Владелец = &Владелец”;
     Запрос.УстановитьПараметр(“Дата”, НачалоДня(ТекущаяДата()));
     Запрос.УстановитьПараметр(“Владелец”, Пользователь);
     
     Выборка = Запрос.Выполнить().Выбрать();
     
     ПараметрыСеанса.ТекущийПользователь = Пользователь;
        ПараметрыСеанса.МенюСформированно = Выборка.Следующий();
    КонецПроцедуры  
    Функция РабочийДень() Экспорт
        ТекДата  = ТекущаяДата();
     ТекЧас   = Час(ТекДата);
     ТекМинута  = Минута(ТекДата);
     ТекСекунда = Секунда(ТекДата);
     ТекВремя = Дата(1,1,1,ТекЧас, ТекМинута, ТекСекунда);
     НачалоРаботы = Константы.НачалоРабочегоДня.Получить();
     ОкончаниеРаботы = Константы.ОкончаниеРабочегоДня.Получить();
     Возврат НачалоРаботы <  ТекВремя И ОкончаниеРаботы > ТекВремя ;
    КонецФункции
    Функция ПользовательАдминистратор() Экспорт
     Возврат ПараметрыСеанса.ТекущийПользователь.Администратор;
    КонецФункции 
    Функция Меню() Экспорт
      СписокОбед = Новый  СписокЗначений;
      Запрос = Новый  Запрос;
      Запрос.Текст = “ВЫБРАТЬ
                     | ВариантыОбеда.Ссылка КАК ПункМеню
                     |ИЗ
                     | Справочник.ВариантыОбеда КАК ВариантыОбеда
                     |ГДЕ
                     | ВариантыОбеда.ПометкаУдаления = ЛОЖЬ”;
      Выборка = Запрос.Выполнить().Выбрать();
      
      Пока  Выборка.Следующий() Цикл  
       СписокОбед.Добавить(Выборка.ПункМеню);
      КонецЦикла;
      Возврат СписокОбед;
     КонецФункции
     
    Процедура ЗаполнитьМенюПользователя(ВыбранноеМеню, Пользователь) Экспорт
     Для Каждого ЭлементМеню Из ВыбранноеМеню Цикл
      НовыйЭлемент = Справочники.ОбедыПользователей.СоздатьЭлемент();
      НовыйЭлемент.Владелец = Пользователь;
      НовыйЭлемент.Дата = НачалоДня(ТекущаяДата());
      НовыйЭлемент.ВариантОбеда = ЭлементМеню;
      НовыйЭлемент.Записать();
     КонецЦикла;
    КонецПроцедуры
    Функция ТекущийПользователь() Экспорт
     Возврат  ПараметрыСеанса.ТекущийПользователь;
    КонецФункции
                                                 
    Функция Менюсформированно() Экспорт
     Возврат  ПараметрыСеанса.МенюСформированно;
    КонецФункции
    Процедура ИнициализироватьРежимРаботы() Экспорт
     Константы.НачалоРабочегоДня.Установить(?(Константы.НачалоРабочегоДня.Получить() = Дата(1,1,1,0,0,0), Дата(1,1,1,9,0,0), Константы.НачалоРабочегоДня.Получить()));
     Константы.ОкончаниеРабочегоДня.Установить(?(Константы.ОкончаниеРабочегоДня.Получить() = Дата(1,1,1,0,0,0), Дата(1,1,1,18,0,0), Константы.ОкончаниеРабочегоДня.Получить()));
    КонецПроцедуры
     

    </code>

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

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

  28. Прошу прощение данный способ не срабатывает.

    • Ок, остается надеется, что в будущих релизах платформы интеллект возрастет :)

      • Пока он не возрос использую конструкцию типа
        если Ложь тогда
        <переданныйПараметр>=Справочники.<Имя>.пустаяСсылка();
        КонецЕсли
        очень помогает если нужно обрабатывать много реквизитов со сложными названиями. Может быть кому пригодится)

        • Можно использовать такой ход конем:

          #Если Нечто Тогда
          ПараметрТакойТо =Справочники..пустаяСсылка();
          #КонецЕсли

  29. Обратил внимание на следующую интересную особенность при передаче ссылки на объект, в процедуру не работает подсказка. Однако если запустить систему в режиме отладки и писать код в этом режиме то подсказка срабатывает. Я так понял, что система точно понимает с каким объектом мы работаем.

    • То что контекстная подсказка в этом случае не работает это документированное поведение.
      Система действительно не знает типа данных параметра метода, и не может выполнить подсказку.

      Однако, с отладкой кода ситуация неясна. В этом случае контекстная подсказка действительно срабатывает?
      Провел эксперимент, в модуле сеанса:

      Процедура УстановкаПараметровСеанса(ТребуемыеПараметры)
         
          ОбработкаСсылки(Справочники.Контрагенты.Налоги);
         
      КонецПроцедуры

      Процедура ОбработкаСсылки(Ссылка)

          Ссылка.

      КонецПроцедуры

      Однако, контекстная подсказка не сработала даже в режиме отладки, в том числе при входе в указанную процедуру.

      Опишите свой пример подробнее.

  30. Данное домашнее задание было выполнено на основе ДЗ№4, которое было модифицировано в части получения серверного времени с учетом часовых поясов; также был добавлен таймаут на предупреждение о невозможности входа в систему в нерабочее время; запрос обеда был перенесен из события “ПередНачаломРаботыСистемы” в событие “ПриНачалеРаботыСистемы”.
    Перечислю самые интересные моменты при решении задания:
    1. В справочник “Пользователи” был добавлен дополнительный реквизит типа “УникальныйИдентификатор”, по которому однозначно определеяется каждый пользователь системы. Получение уникального идентификатора пользователя осуществлялось следующим образом:
    ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор
    2. Флаг “Администратор” элемента справочника “Пользователи” автоматически устанавливается если имя текущего пользователя равно строке “Администратор”. Однако впоследствии этот флаг можно снять/установить, изменения вступают в силу после перезапуска приложения.
    3. Для выбора варианта обеда пришлось создать форму выбора справочника “ВариантыОбедов” – это необходимо, чтобы осуществить поддержку множественного выбора в списке формы. Форма открывается модально в цикле до тех пор, пока пользователь что-нибудь не выберет. При множественном выборе функция “ОткрытьМодально” возвращает массив выбранных значений. Если пользователь ничего не выбрал – то возвращается “Неопределено”. Также в параметры формы перед ее открытием передается отбор “ПометкаУдаления = Ложь”.

  31. Час делал, час отлаживался. Наступил на все грабли :) Так и не понял, почему из клиента (модуль управляемого приложения) в Процедуру на сервере можно передать переменную и присвоить ей значение СправочникСсылка, а при попытке напрямую вернуть Функцией это значение вылетает ошибка XDTO.

    • >а при попытке напрямую вернуть Функцией это значение вылетает ошибка XDTO
      Вернуть СправчоникСсылка можно.
      Скорее всего вы возвращаете другое значение, например элемент списка значений.

  32. Задание выполнено.
    Создал 2 константы для хранения начала и конца раб.дня с типом “Дата” и составом даты  “Время”. В серверном общем модуле процедура, возвращающая в параметрах начало и конец текущего раб. дня, причем число/день/месяц берется из текущей даты, а часы/минуты/секунды из констант.
    С созданием справочника вариантов обеда (с предопределенными элементами), пользователей, роли “Полные права” и самих пользователей трудностей не было.
    В справочнике “Обеды пользователей” реквизит Дата с типом “Дата” с составом даты “Дата”, ВариантОбеда – тип СправочникСсылка.ВариантыОбедов. Для реквизита Дата также установлен признак “Индексировать”, нужно для поиска обедов на определенную дату.
    В модуле упр.приложения определена глоб. переменная Администратор, в проц-ре ПередНачаломРаботыСистемы() вызываю процедуру общего серверного модуля УстановитьПользователя(Администратор);
    <code>
    Процедура УстановитьПользователя(Админ) Экспорт
    ИмяП=ИмяПользователя();
    ПользСсылка=Справочники.Пользователи.НайтиПоНаименованию(ИмяП);
    Если ПользСсылка.Пустая() Тогда
    Польз = Справочники.Пользователи.СоздатьЭлемент();
    Польз.Наименование = ИмяП;
    Польз.ФИО = ПолноеИмяПользователя();
    Польз.Администратор = ИмяП = “Администратор”;
    Польз.Записать();
    ПользСсылка = Польз.Ссылка;
    КонецЕсли;
    Админ = ПользСсылка.Администратор;
    КонецПроцедуры
    </code>
    далее на основании полученного признака админа и границ раб. дня определяем возможность входа.
    Для работы с обедами создал отдельный серверный общий модуль “Обеды” с флагом “вызов сервера”. Содержит следующее:
    <code>
    Функция ОбедВыбран(ИмяП, ДатаОбеда) Экспорт
    _ДатаОбеда = Дата(Год(ДатаОбеда), Месяц(ДатаОбеда), День(ДатаОбеда));
    Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ИмяП);
    ОП = Справочники.ОбедыПользователей.Выбрать( , Пользователь, Новый Структура(“Дата”, _ДатаОбеда));
    Пока ОП.Следующий() Цикл
    Если не ОП.ПометкаУдаления Тогда
    Возврат Истина;
    КонецЕсли;
    КонецЦикла;
    Возврат Ложь;
    КонецФункции // ОбедВыбран()

    Функция ПолучитьВариантыОбеда() Экспорт
    Варианты = Новый СписокЗначений;
    ВыбВар = Справочники.ВариантыОбедов.Выбрать();
    Пока ВыбВар.Следующий() Цикл
    Если не ВыбВар.ПометкаУдаления Тогда
    Варианты.Добавить(ВыбВар.Код, ВыбВар.Наименование);
    КонецЕсли;
    КонецЦикла;
    Возврат Варианты;
    КонецФункции // ПолучитьВариантыОбеда()

    Процедура СохранитьВыборОбеда(ИмяП, ДатаОбеда, Выбрано) Экспорт
    Пользователь = Справочники.Пользователи.НайтиПоНаименованию(ИмяП);
    Для каждого Блюдо Из Выбрано Цикл
    Обед = Справочники.ОбедыПользователей.СоздатьЭлемент();
    Обед.Владелец = Пользователь;
    Обед.Дата = ДатаОбеда;
    Обед.ВариантОбеда = Справочники.ВариантыОбедов.НайтиПоКоду(Блюдо);
    Обед.Записать();
    КонецЦикла;
    КонецПроцедуры
    </code>
    При начале работы проверяем (если пользователь не админ), есть ли уже обед у этого пользователя на дату начала работы. Если нет, то запрашиваем список возможных вариантов, дожидаемся выбора, заполняем массив кодами выбранных блюд, и вызываем процедуру сохранения выбора.
    Понравилась возможность выборки с одновременным отбором по значению, жаль что структура может содержать в этом случае только 1 элемент :-)
    Процедура УстановитьПользователя(Админ) Экспорт

    ИмяП=ИмяПользователя();
    ПользСсылка=Справочники.Пользователи.НайтиПоНаименованию(ИмяП);

    Если ПользСсылка.Пустая() Тогда
    Польз = Справочники.Пользователи.СоздатьЭлемент();
    Польз.Наименование = ИмяП;
    Польз.ФИО = ПолноеИмяПользователя();
    Польз.Администратор = ИмяП = “Администратор”;
    Польз.Записать();

    ПользСсылка = Польз.Ссылка;
    КонецЕсли;

    Админ = ПользСсылка.Администратор;

    КонецПроцедуры

  33. Задание выполнено
    1) В процедуре ПередНачаломРаботыСистемы последовательно выполняем: проверяем заполненость констант начала и конца времени рабочего дня, если не заполнены – заполняем по умолчанию; добавляем пользователя в справочник Пользователи, при этом определяем для удобства работы ПараметрыСеанса.глПользователь (ссылка на справочник Пользователи); определяем ПараметрыСеанса.ВремяВхода (дата+время), для проверки входа и выхода из системы; вначале идет проверка на свойство пользователя Администратор, а уж потом (если необходимо) проверяем на интервал рабочего времени, сравнивая с параметром сеанса ВремяВхода. Все проверки и действия выполняем в общем модуле с свойством Сервер.
    2) В процедуре ПриНачалеРаботыСистемы открываем общую форму для выбора данного объекта, при условии выполнения функции (в серверном общем модуле)
    <code>

    Функция НужноСправшиватьОбОбеде() Экспорт
    Если ПараметрыСеанса.глПользователь.Администратор Тогда
    Возврат Ложь;
    КонецЕсли;

    СписокОбедов = Справочники.ОбедыПользователей.Выбрать(, ПараметрыСеанса.глПользователь,,);
    Возврат НЕ СписокОбедов.Следующий();

    КонецФункции // НужноСправшиватьОбОбеде()
    Функция НужноСправшиватьОбОбеде() Экспорт
    Если ПараметрыСеанса.глПользователь.Администратор Тогда
    Возврат Ложь;
    КонецЕсли;
    СписокОбедов = Справочники.ОбедыПользователей.Выбрать(, ПараметрыСеанса.глПользователь,,);
    Возврат НЕ СписокОбедов.Следующий();
    КонецФункции // НужноСправшиватьОбОбеде()
    </code>
    3) создана общая форма, в которой идет выбор обедов. В форму добавила булевский реквизит БылВыбор, который на самой форме не отражается. Форма закрывается только при установке этого реквизита в истина (проверка ПередЗакрытием). Устанавливаем истина когда добавлен хоть один элемент в справочник Обеды пользователей для данного пользователя.
    Помимо этого создала еще форму констант для изменения времени начала и окончания рабочего дня, создала подсистему Настройка и все туда разместила.
    Вообщем то все…

  34. Задание выполнено.
    1. Синхронизация справочника “Пользователи” и списка пользователей
    <code>
    пользователь.Код = ИмяПользователя();
    пользователь.Наименование = ПолноеИмяПользователя();
    пользователь.Администратор = РольДоступна(“ПолныеПрава”);
    </code>
    2.  При выборке из справочников “ВариантыОбедов”, “ОбедыПользователя” использовал запросы.  Переделаю на Выбрать().
    3.  Трудностей не было, повторил контексты модулей.
     

  35. 1. Создал роль ПолныеПрава, константы НачалоРабочегоДня и КонецРабочегоДня. форму констант.
    2. Создал справочник ВариантыОбедов. В предопределенные значения занес Рыба, Мясо, Курица. Создаем Форму выбора.
    3. Создал пользователей Администратор и Менеджер, справочник Пользователи с булевским реквизитом Администратор, справочник ОбедыПользователей, подчиненный справочнику Пользователи.
    4. Создаем серверную процедуру ПроверитьЗаполнениеКонстантГрафика(). В случае пустых дат в константа заполняем их соответственно датами (1,1,1,9,5,38) и (1,1,1,18,11,42). При необходимости можно сделать предупреждение о первоначальном заполнении констант.
    5. Создаем серверную функцию ПроверкаСправочникаПользователи(). Выполняем поиск в справочнике Пользователи по имени текущего пользователя информационной базы. В случае возврата поиском пустой ссылки – создаем нового пользователя. Если имя текущего пользователя в верхнем регистре АДМИНИСТРАТОР, то устанавливаем реквизиту Администратор значение Истина. Возвращаемое значение – ссылка на элемент справочника пользователи.
    6. При помощи серверной функции ЭтоАдминистратор() получаем значение реквизита Администратор. Если это истина то не проверяем время входа и не выводим список обедов.
    7. Создаем серверную функцию ЕстьВариантОбеда. Создаем выборку из справочника ОбедыПользователей с отбором по дате и пользователю. Если выборка не пустая – то вариант обеда есть.
    8. Модально открываем форму Справочник.ВариантыОбедов.ФормаВыбора. с признаком множественного выбора и отбором ПометкаУдаления = Ложь. Если форма при выборе не передает значение Неопределенно, передаем массив обедов в серверную процедуру ЗаписатьОбедДляПользователя.
    9. Перебираем массив. Для каждой строки создаем новый элемент справочника ОбедыПользователей с владельцем текущий пользователь и датой обеда = началоДня(датаЗапуска);

    Сложностей было и есть множество. Форма выбора не получилось по настоящему модальной, код просто ужасен. Шаблоны и подсказки не дотягивают до семерошного Телепата. Буду ждать конечный вариант решения.

    • >Шаблоны и подсказки не дотягивают до семерошного Телепата.
      К сожалению, это так.
      Возможно в будущих релизах ситуация изменится.

  36. Добрый день, Евгений. Скажите, пожалуйста, домашнее задание №5 нужно выполнять в своей базе или в выгруженной Вами?

  37.  
    1. Создал параметры сеанса. Определил в них реквизит ТекущийПользователь.
    В процедуре УстановкаПараметровСеанса модуля сеанса проверяю, если ТребуемыеПараметры=Неопределено и
    пользователь по имени не найден, то создаю нового и заодно для Администратора ставлю
    сразу соотв. булевый признак.
    2. В общем модуле на сервере создаю:
    <code>
    Функция ПроверитьКонстанты() Экспорт
    //инициируем обновление констант
    НаборКонстант = Константы.СоздатьНабор(“ВремяНачалаРабочегоДня,ВремяОкончанияРабочегоДня”);
    НаборКонстант.Записать();
    КонецФункции
    </code>
    При этом в модулях менеджера значения каждой константы определяю в ПередЗаписью(Отказ) такой код:
    <code>
    СтЗнач = Константы.ВремяНачалаРабочегоДня.Получить();
    ПустоеВремя = Дата(“00010101000000”);
    Если СтЗнач=ПустоеВремя ИЛИ Значение=ПустоеВремя Тогда
    Значение = Дата(“00010101090109”);
    КонецЕсли;
    </code>
    Таким образом при первом запуске константы заполняются в дефолтные. Если они вдруг в них потом пишут пустое время,
    то тоже идет сброс на дефолтные.
    3. В общем модуле сервера определяю ВыбранСегодняОбед(ТекПользователь). Использую для выборки по справочнику владельца ТекПользователь,
    структуру отбора со значением текущей даты и проверкой на пометку удаления. Также в этом модуле добавлены:
    <code>
    Функция ПолучитьТекущегоПользователя() Экспорт
    Возврат ПараметрыСеанса.ТекущийПользователь;
    КонецФункции
    Функция ПолучитьЗначениеКонстанты(ИмяКонстанты) Экспорт
    Возврат Константы[ИмяКонстанты].Получить();
    КонецФункции
    </code>
    4. В том же общем модуле сервера создаю СохранитьСписокБлюд(СписокБлюд, ТекПользователь), где для каждого помеченного блюда,
    записываю его в справочник ОбедыПользователей, используя владельца ТекПользователь.
    5. Ну и в модуле управляемого приложения в процедуре ПриНачалеРаботыСистемы кратко:
    <code>
    ТекПользователь = ОМ_Сервер.ПолучитьТекущегоПользователя();
    Если (НЕ ОМ_Сервер.ВыбранСегодняОбед(ТекПользователь)) И (НЕ ТекПользователь.Администратор) Тогда
    СписокБлюд = ОМ_Сервер.ПолучитьСписокОбедов();
    <Тут наш цикл с выбором блюд>
    ОМ_Сервер.СохранитьСписокБлюд(СписокБлюд, ТекПользователь);
    КонецЕсли;
    </code>

  38. Задание выполнено. Лучше бы, конечно, выложить cf или dt, но попробую описать словами.
    Константы созданы. Для корректного входа необходимо сделать проверку на пустые константы (т.к. они еще не заполнены и пока нет пользователя с флагом “Администратор”). Т.е. при первом запуске их устанавливаем в начало и конец дня.
    Пользователи создаются в справочнике. Если у пользователя установлен флаг “Администратор”, то он может работать круглосуточно и без обеда  :)
    Для остальных выполняется проверка на время входа и заказал ли он обед на сегодня. Для проверки на заказ обеда используется следующий код:
    <code>
    Отбор = Новый Структура;
    Отбор.Вставить(“Дата”, НачалоДня(ДатаЗапуска));

    Выборка = Справочники.ОбедыПользователей.Выбрать(, ТекущийПользователь, Отбор);
    Возврат    Выборка.Следующий();
    </code>
    Чтобы реквизит “Дата” мог быть использован в отборе, пришлось ему назначить индексирование.
    Если сегодня ничего не было заказано, то выдается список значений для выбора обеда и затем это записывается в справочник. В противном случае ничего не запрашивается.
    P.S. Лучше бы, конечно, в некоторых случаях данного задания воспользоваться запросом, но т.к. это самое начало, пришлось использовать выборку.

  39. Гуляев Алексей 01.02.2011 в 20:37

    А может текст задания это для следующего Д.З.
    Либо нужно описать что глав побольше изучить!

    • С какой частью задания возникли затруднения?

  40. Задание готово, модифицировал алгоритмы работы дом. задания №4 ,  вынес код  в общие клиентские и серверные модули.
    1.       Создал константы для хранения времени начала окончания работы.
    Тип дата , состав «время». ,  указал проверку заполнения, создал форму констант.
    С учетом данных изменений изменил алгоритм проверки входа, получение значений констант реализовал в экспортной процедуре серверного модуля.
    2.       Создал справочники «варианты обедов» , «пользователи», «ОбедыПользователей».
    3.      Создал роль, после создания роли , нужно было сохранить изменения в конфигурации БД иначе роль не видно при создании пользователей.
    4.       При входе пользователей в систему , в серверном модуле методом менеджера справочника осуществляю поиск по имени пользователя полученному функцией глобального контекста  ИмяПользователя(),  при отсутствии такого элемента, программно создаю элемент.
    5.       Осуществляю проверку в экспортной функции серверного модуля , а не администратор ли это , получая данные из реквизита “Администратор”  ссылки справочника и зависимости от возврата функции предлагаю обеды, после выбора создаю в подчиненном справочнику «пользователи» , «обеды пользователей» новые элементы . При повторном входе у пользователя который уже выбирал обед, диалог выбора не появляется.
     
    Особых трудностей при выполнении задания не возникло, только при указании отбора на выборку справочника «Обеды пользователей»  реквизит «дата» был указан как не индексированный, отчего метод Выбрать()  не мог поставить отбор.