8.х Задача учета данных

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем kogor, 27 мар 2010.

  1. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Здравствуйте.

    Решаю такую задачу:

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

    Посоветуйте как мне лучше реализовать конфигурацию для решения такой задачи.

    Я изучил книгу Радченко "Практическое пособие разработчика"

    Моя идея:

    1. Создать Документ ЗаполнениеСчетчиков
    Табличная часть: Прибор, СчетчикВчера, СчетчикСегодня, Разница

    2. Создать РегистрНакопления УчетСчетчиков.
    Вид регистра: Остатки
    Измерения: Прибор
    Ресурсы: Разница

    3. Сделать Документ ЗаполнениеСчетчиков регистратором для регистра накопления УчетСчетчиков
    Настроить движения Документа ЗаполнениеСчетчиков по этому регистру для полей Прибор, Разница.
    Тип движения регистра: Приход

    4. Создать отчет, который отображал бы значения счетчиков приборов и разницу "сегодня-вчера" каждый день. И выводил значение общего счетчика.

    Вопросы:
    1. Правильна ли вообще эта идея?
    Если да, то:
    2. Каким образом хранить значения счетчиков за предыдущий день? Можно ли их "достать" из регистра накопления?
    3. Каким образом вычитать из "сегодняшних" значений "вчерашние"?
    4. Каким образом хранить накапливаемое значение общего счетчика? Общий счетчик - что-то типа глобальной переменной.

    Если есть какие-то мысли или идеи, буду рад услышать..
  2. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    1. Создаем документ. ТЧ годиться, только вот показания "вчера" не нужны. Они должны определятся по РС в момент проведения.

    2. Создаем периодический РС, регистратор - наш документ, периодичность - день.
    • Измерения
      • Прибор (видимо, перечисление или справочник)
    • Ресурсы
      • Значение (Значение показания)
    3. Создаем РН типа обороты, регистратор - наш документ. Значение будет равно Значение "вчера" - "значение сегодня". Понять, как это будет, если сегодня больше, чем вчера.
    • Измерения
      • Прибор (тип см. в РС)
    • Ресурсы
      • Значение (Значение показания)
    ЗЫ. А вообще задача странная... Что это за такой общий счетчик? Среднее отклонение?

    4. Создаем отчет. Особенностью отчета будет то, что к РС надо будет обращаться два раза со смещением дат, что бы в одной строке могли вывести показания за "вчера" и сегодня".
    Либо, как вариант, делать левое соединение к РН и вычислять это поле.
  3. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    То есть показания приборов будут храниться в регистре сведений? А каким образом можно обратиться к значениям например за предыдущий день? Программно. Мне нужно уметь вычитать/складывать эти значения. Хорошо бы примерчик..

    А какую функцию будет выполнять РН? Ведь данные будут храниться в РС...

    Не понимаю как обратиться к значению за вчера (за сегодня). РН ведь хранит суммарное значение ресурса. А почему именно Значение "вчера" - "значение сегодня", а не наоборот?

    Обычно именно так "значение сегодня" > "значение вчера".

    Общий счетчик суммирует разницу между значениями "сегодня" и "вчера" со всех приборов. Кроме этого вычитает некоторые другие значения. В общем нужно проводить операции сложения/вычитания. Как мне его организовать? Еще один регистр накопления? В языках программирования есть понятие "глобальной переменной", оно бы сюда подошло. Можно в 1С создать глобальную переменную? Чтобы можно было задать вначале ее первоначальное значение, а потом прибавлять/вычитать от нее??
  4. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    1. Смотрите, что такое СрезПоследних() для периодического РС
    2. Функцию счетчика.
    3. Порядок вычитание - определите сами (я же не знаю алгоритма :))
    Пример для курса валют:
    Код:
    "ВЫБРАТЬ
    Сегодня.Валюта,
    Сегодня.Курс КАК КурсСегодня,
    Вчера.Курс КАК КурсВчера
    ИЗ
    РегистрСведений.КурсыВалют.СрезПоследних(&Период, ) КАК Сегодня
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют.СрезПоследних(ДОБАВИТЬКДАТЕ(&Период, ДЕНЬ, -1), ) КАК Вчера
    ПО Сегодня.Валюта = Вчера.Валюта"
    
    5. Обычно - не значит, что так всегда. А рассматривать на до все ситуации и понимать, как будет меняться счетчик.
    6. Глобальные переменные - это моветон. + для этого случая - не годятся.
  5. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Создал РС и РН.

    РегистрСведений УчетСчетчиков
    Измерения: Комната, Прибор
    Ресурсы: ЗначениеВход, ЗначениеВыход

    РегистрНакоплений Счетчик
    Измерения:Комната, Прибор
    Ресурсы:ЗначениеВход, ЗначениеВыход, Разница

    Настроил движения:

    Код:
    Процедура ОбработкаПроведения(Отказ, Режим)
    //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    // Данный фрагмент построен конструктором.
    // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!
    Для Каждого ТекСтрокаПриборы Из Приборы Цикл
    // регистр УчетСчетчиков 
    Движение = Движения.УчетСчетчиков.Добавить();
    Движение.Период = Дата;
    Движение.Комната = Комната;
    Движение.Прибор = ТекСтрокаПриборы.Прибор;
    Движение.ЗначениеВход = ТекСтрокаПриборы.ЗначениеВход;
    Движение.ЗначениеВыход = ТекСтрокаПриборы.ЗначениеВыход;
    КонецЦикла;
    Для Каждого ТекСтрокаПриборы Из Приборы Цикл
    // регистр Счетчик 
    Движение = Движения.Счетчик.Добавить();
    Движение.Период = Дата;
    Движение.Комната = Комната;
    Движение.Прибор = ТекСтрокаПриборы.Прибор;
    Движение.ЗначениеВход = ТекСтрокаПриборы.ЗначениеВход;
    Движение.ЗначениеВыход = ТекСтрокаПриборы.ЗначениеВыход;
    Движение.Разница = ТекСтрокаПриборы.Разница;
    КонецЦикла;
    //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ
    КонецПроцедуры
    
    
    При попытке проведения документов выдает ошибку:
    Почему такая ошибка возникает? Если меняю например значение Комната1 на Комната2, то проводит, а следующий документ уже не проводит, возникает эта ошибка... Может это из-за того что периодичность РС - день, т.е. в один день проводить документы с одинаковыми реквизитами нельзя?
  6. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
    Поставьте переодичность РС. По позиции регистратора и проблем не будет. А так да . В один день 2 дока с одинаковыми ключевыми полями не проведете
  7. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    Вам нужен только один реквизит: разница.
    Ибо это оборотный регистр, а значения входа и выхода хранятся в РС
  8. Stack_G
    Offline

    Stack_G Опытный в 1С

    Регистрация:
    10 дек 2007
    Сообщения:
    786
    Симпатии:
    2
    Баллы:
    26
    Посмотрев еще одну твою тему:
    Хорошо бы еще один РС сделать - привязку приборов к комнатам. (периодический, чтобы можно было с течением времени менять состав приборов в комнате) Чтобы при измениии комнаты приборы заполнялись из его.
  9. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Пока я сделал это по-простому: у каждого прибора есть реквизит "Комната". При заполнении ТЧ перебираю в цикле все приборы и проверяю, если реквизит и выбранная пользователем комната совпадают, то добавляю прибор в ТЧ.

    Спасибо за идею с РС. Наверно, так сделать будет грамотнее. Попробую
  10. Stack_G
    Offline

    Stack_G Опытный в 1С

    Регистрация:
    10 дек 2007
    Сообщения:
    786
    Симпатии:
    2
    Баллы:
    26
    Но тогда нельзя чтобы один и тот же Прибор (элемент справочника) принадлежал разным комнатам.
    Если устраивает, то тогда уж лучше:
    Справочник "Комнаты" - владелец справочника "Приборы".
  11. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Понял, действительно реквизиты в регистрах у меня повторяются.

    А какими методами можно обращаться к данным, хранящимся в РН? Запрос к виртуальной таблице Обороты? Например, мне необходимо значение Разница на текущий момент, на вчерашний день или за месяц?
  12. BabySG
    Offline

    BabySG Администраторы Команда форума Администратор

    Регистрация:
    10 июн 2007
    Сообщения:
    11.853
    Симпатии:
    12
    Баллы:
    29
    Разница на текущий момент - это просто без указания периода
    На вчера - конечный период вчера
    За месяц - указываете начало периода и конец периода
  13. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Вернулся к разработке этой конфигурации (см. сообщение №1).

    Вкратце: есть несколько комнат, в которых стоят приборы. С приборов снимаются показания. За каждой комнатой закреплен Ответственный (один человек может быть ответственным за одну или несколько комнат).

    На данный момент механизм снятия показаний приборов реализован и работает :unsure:.

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

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

    Первая мысль: при открытии формы списка справочника Приборы сделать отбор по реквизиту: в справочнике Приборы реквизит Комната и в справочнике Ответственные ТЧ Комнаты, в которую можно вносить одну или несколько "подответственных" комнат.

    Эта идея реализована и работает.

    Однако командная панель в форме списка справочника Приборы позволяет пользователю сбросить фильтрацию отбора и таким образом получить доступ ко всем элементам справочника.

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

    Второй вариант - наложить ограничения на права доступа для роли пользователя. Однако опыта в этой области у меня нет.

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

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

    Все это касалось только ограничений на справочник Приборы. Аналогично нужно ограничить доступ к документу учета показаний и отчету.

    Оцените, пожалуйста, мои идеи или предложите какие-нибудь другие пути решения.
  14. Draco
    Offline

    Draco Модераторы Команда форума Модератор

    Регистрация:
    28 окт 2009
    Сообщения:
    13.628
    Симпатии:
    946
    Баллы:
    204
  15. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Спасибо за пример, но я заранее не могу ввести в регистры или еще куда то список запрещенных комнат. Определение подответственных комнат должно происходить при открытии списка справочника или документа.

    Для справочника решил ограничить права при помощи свойств формы элемента.

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

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

    Конечно, было бы здорово убрать совсем кнопку Отбора из командной панели. Кто-нибудь знает, это возможно??
  16. TopicStarter Overlay
    kogor
    Offline

    kogor Опытный в 1С

    Регистрация:
    5 фев 2010
    Сообщения:
    412
    Симпатии:
    0
    Баллы:
    26
    Здравствуйте.

    Справочники и документы я ограничил вышеизложенным способом.

    Теперь необходимо ограничить отчеты.

    Сейчас в отчетах выдается информация по всем Комнатам. И все ответственные видят информацию по всем Комнатам.

    Необходимо, чтобы в отчете отображались только те данные, которые может видеть данный пользователь согласно тому, какими Комнатами он занимается (определяется по измерению регистра накопления Комната).

    Отчет я формирую с помощью схемы компоновки данных. Как в ней задать условие, чтобы сначала определялся список доступных пользователю комнат, а затем данные выводимые в отчет отфильтровывались по этому списку?

    Возможно ли сделать такое в СКМ? Или нужно создавать форму отчета. И с помощью Построителя задавать условия, формировать отчет?

    Подскажите, пожалуйста, как лучше это сделать?

Поделиться этой страницей