Имя: Пароль:
1C
1С v8
Похайте механиз контроля независимых регистров сведений
0 alextom81
 
22.03.13
07:21
Как придлумал:

1. Создаём свой РС (периодический) - период - секунда
2. Измерение - Автор (ТекущийПользователь) (индексируем)
3. Измерение - ИмяРегистра (Имя регистра сведений) (индексируем)
4. Ресурс  - Строка - старые значение регистра (тут парсим измерения и ресурсы старых значений)
5. Ресурс  - Строка - новые значение регистра (тут парсим измерения и ресурсы новых значений)
6. Периодически (раз в месяц) чистим РС, выгружая его в mxl документ, откуда затем получаем данные по предыдущим периодам в отчете (использую вт и добавляя туда текущие данные регистра)

Цель - контроль регистра сведений "штатная расстановка орг-й" - и любых других регистров сведений. Чтобы было понятно - что, кто и когда изменил. Допилы суются в модуль набора записей "перед записью"
1 KRV
 
22.03.13
07:23
Может проще сделать - запретить шелудивым рукам править сей регистр?
2 shuhard
 
22.03.13
07:23
(0) открой версионирование в УПП или БСП и сравни с проектом
3 AleksAnt
 
22.03.13
07:23
а чем не угодило версионирование объектов?
4 alextom81
 
22.03.13
07:26
(2) Версионирование в УПП, как ни странно - включено. Но оно работает только по документам и по справочникам. Штатное расписание - мимо. Учетная политика - мимо. Может ещё какие есть РС важные - не смотрел ещё.
5 alextom81
 
22.03.13
07:27
РС, штатное расписание организаций, ошибся :(
6 Cube
 
22.03.13
07:27
(0) "Допилы суются в модуль набора записей "перед записью""
Подписки на событие кошернее.
7 shuhard
 
22.03.13
07:27
(4) не учи форум устройству УПП
8 alextom81
 
22.03.13
07:30
(4) Форум, видимо, В Ваше лице - подскажите мне доступные значения измерения "Объект" у РС "ВерсииОбъектов" ?
9 alextom81
 
22.03.13
07:31
(6) - Да, thx. Забыл про подписки на набор записей.

Вопрос скорее - не будет ли оно дико тормозить работу пользователей.
10 alextom81
 
22.03.13
07:43
Вместо mxl делаем служебную базу SQL. - В неё изо всех баз делаем выгрузки раз в сутки. В отчете потом к ней обращаемся. Следующим шагом перетаскиваем туда версионирование, чтобы базы не пухли.
11 Cube
 
22.03.13
07:45
(10) "Вместо mxl делаем служебную базу SQL"
Делай на 1С. Отдельная база 1С для хранения истории. Так православнее)
12 alextom81
 
22.03.13
08:12
(11) Зато быстрее :)
Похоже, как и в v8: Отслеживать изменения в регистрах сведений советов нема - только смотри версионирование в БСП
13 Фрэнки
 
22.03.13
08:20
(0) Ну если дописывать чего-то в типовую УПП, так зачем ограничивать себя в масштабах дописок, которые в этом частном случае будут крутиться "рядом" с типовым механизмом и не будут его торомозить? Идею могу развить дальше, но то, что уже предложено в топике вижу неоптимальным. Я бы сделал подход с другой стороны.
14 alextom81
 
22.03.13
10:01
(13) Подскажите с какой ?
15 Фрэнки
 
22.03.13
20:55
(14) Днем отвлекли по работе и не только вечером вспомнил, что остался вопрос.

Я бы ввел небольшую подсистему из регистрируемых документами (в качестве регистраторов) записей в регистр накоплений с остатками, по которому можно будет учитывать количество свободных штатных единиц. А затем уже изменять типовые записи по завершению процесса регистрации движений по штату. Возможности прямой работы кадровикам со штатом оставить только в рамках подсистемы. В деталях всю эту идею можно подправлять достаточно долго по специфике конкретной политики, действующей на предприятии.
16 Лефмихалыч
 
22.03.13
20:58
проще всяких кого попало с опасно торчащими из жопы в разные стороны руками в регистр не пускать
17 Фрэнки
 
22.03.13
20:59
(+15) Конечно, если штат очень большой, либо много структурных подразделений, распределенная база и т.п., то возникает соблазн построить вообще отдельную базу 1С для работы в штатном расписании и передаче в основную (типовую) только результатов плодотворной работы многочисленных департаментов.

(16) Да где их взять-то? И зачем лишать себя куска хлеба, решая оргвопросы вместо разработки мегапроектов ;)
18 bolder
 
22.03.13
21:35
(0) Если организация занимается только штатным рас писанием- не взлетит!
19 Diversus
 
22.03.13
22:40
Я занимался контролем изменения регистров, если интересно можете посмотреть на конфигурацию на демо-сервере на сайте можете найти ссылку: http://sys1c.ru/journal.html
20 Diversus
 
22.03.13
22:41
+ контролирует в том числе и изменение регистров сведений
21 alextom81
 
23.03.13
06:46
(19) Ок, спасибо, гляну. Хотя на самом деле уже сдалали стороннюю базу, разработчик один сейчас пишет фоновое задание для переноса туда данных регистрации.
(15) - хочется отслеживать все независимые регистры, не только штатку
22 alextom81
 
23.03.13
06:48
Написали процедуру, вставили в подписку, но возникает загвоздка - так как запись в РС изменяется два раза, а отбор периода - в пределах секунды, то в момент второй записи может выскочит эксепшн. Текст процедуры:

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

               // Тут храняться новые записи
               СтрТаб = Источник.Выгрузить();
               
               // Но в базе данных они ещё не изменились, можно прочитать старые значения
               СтараяЗапись = РегистрыСведений[Источник.Метаданные().Имя].СоздатьНаборЗаписей();
               
               
               //Динамически сформируем текст запроса к регистру сведений
               КоличествоИзмерений = СтараяЗапись.Метаданные().Измерения.Количество();
               КоличествоРесурсов  =  СтараяЗапись.Метаданные().Ресурсы.Количество();
               Номер = 0;
               
               Запрос = Новый Запрос("ВЫБРАТЬ ");
               
               Для Каждого СтандартныйРеквизит из СтараяЗапись.Метаданные().СтандартныеРеквизиты Цикл
                   Запрос.Текст = Запрос.Текст + Символы.ПС +"  " + Источник.Метаданные().Имя + "." + СтандартныйРеквизит.Имя + ",";
               КонецЦикла;
               
               НомерПрохода = 0;
               
               Пока НомерПрохода < КоличествоИзмерений Цикл
                   Запрос.Текст = Запрос.Текст + Символы.ПС +"   " + Источник.Метаданные().Имя + "." + СтараяЗапись.Метаданные().Измерения[НомерПрохода].Имя + ",";
                   НомерПрохода = НомерПрохода + 1;
               КонецЦикла;

               НомерПрохода = 0;
               
               Пока НомерПрохода < КоличествоРесурсов Цикл
                   Запрос.Текст = Запрос.Текст + Символы.ПС +"   " + Источник.Метаданные().Имя + "." + СтараяЗапись.Метаданные().Ресурсы[НомерПрохода].Имя;
                   Если НомерПрохода < КоличествоРесурсов-1 Тогда
                       Запрос.Текст = Запрос.Текст + ",";
                   КонецЕсли;
                   НомерПрохода = НомерПрохода + 1;
               КонецЦикла;

               Запрос.Текст = Запрос.Текст + Символы.ПС + "ИЗ
                                                             |    РегистрСведений."+Источник.Метаданные().Имя+" КАК "+Источник.Метаданные().Имя+"
                                                           |ГДЕ";
               Запрос.Текст = Запрос.Текст + Символы.ПС;                            
               Пока Номер < КоличествоИзмерений Цикл
                   Если Номер > 0 Тогда
                       Запрос.Текст = Запрос.Текст + " И ";
                   КонецЕсли;
                   Запрос.Текст = Запрос.Текст + Символы.ПС +"   " + Источник.Метаданные().Имя + "." + СтараяЗапись.Метаданные().Измерения[Номер].Имя + " = &" + СтараяЗапись.Метаданные().Измерения[Номер].Имя;
                   Запрос.УстановитьПараметр(СтараяЗапись.Метаданные().Измерения[Номер].Имя, Источник.Отбор[СтараяЗапись.Метаданные().Измерения[Номер].Имя].Значение);
                   Номер = Номер + 1;
               КонецЦикла;
               
               Для Каждого СтандартныйРеквизит из СтараяЗапись.Метаданные().СтандартныеРеквизиты Цикл
                   Запрос.Текст = Запрос.Текст + Символы.ПС +"И   " + Источник.Метаданные().Имя + "." + СтандартныйРеквизит.Имя + " = &" + СтандартныйРеквизит.Имя;
                   Запрос.УстановитьПараметр(СтандартныйРеквизит.Имя, Источник.Отбор[СтандартныйРеквизит.Имя].Значение);
               КонецЦикла;
               
               СтараяЗаписьРС = Запрос.Выполнить().Выгрузить();
               //Выгрузим запись
               
               Если СтараяЗаписьРС.Количество() > 0 Тогда
                   Для Каждого Стр из СтараяЗаписьРС Цикл
                       Для Каждого Колонка из СтараяЗаписьРС.Колонки Цикл
                           ЗаписьСтарая = ?(ЗаписьСтарая = Неопределено, "Данные: " +  Колонка.Имя + " = " + Стр[Колонка.Имя] +"; " , ЗаписьСтарая + Колонка.Имя + " = " + Стр[Колонка.Имя] + "; ");
                       КонецЦикла;
                   КонецЦикла;
                   Если ЗаписьВРС.Количество() = 0 Тогда
                       Строка                  = ЗаписьВРС.Добавить();
                       Строка.СтароеЗначение = ЗаписьСтарая;
                       Строка.Период          = ЗаписьВРС.Отбор.Период.Значение;
                       Строка.Регистр          = Источник.Метаданные().Синоним;
                       Строка.Пользователь   = ПараметрыСеанса.ТекущийПользователь;
                       ЗаписьВРС.Записать();
                   КонецЕсли;
               КонецЕсли;
               
               
               Для Каждого Стр из СтрТаб Цикл
                   
                   Для Каждого Колонка из СтрТаб.Колонки Цикл
                       ЗаписьНовая = ?(ЗаписьНовая = Неопределено, "Данные: " +  Колонка.Имя + " = " + Стр[Колонка.Имя] +"; " , ЗаписьНовая + Колонка.Имя + " = " + Стр[Колонка.Имя] + "; ");
                   КонецЦикла;
                   
                   Строка = ЗаписьВРС.Получить(0);
                   Строка.НовоеЗначение  = ЗаписьНовая;
                   // Запишем только в случае изменения значения реквизитов
                   Если Строка.НовоеЗначение <> Строка.СтароеЗначение Тогда
                       ЗаписьВРС.Записать();
                   Иначе
                       Если ЗаписьВРС.Количество() > 0 Тогда //Значит, запись у нас не менялась, удаляем строку записи
                           ЗаписьВРС.Удалить(Строка.НомерСтроки);
                           ЗаписьВРС.Записать();
                       КонецЕсли;
                   КонецЕсли;
               
               КонецЦикла;
               
           Исключение
               Сообщить("Произошла ошибка при записи данных. Просьба повторить");
               Отказ = Истина;
           КонецПопытки;
           
       КонецЕсли;
       
   #КонецЕсли

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


Хелпайте :)
23 hhhh
 
23.03.13
10:07
так может и просто несколько записей в регистр сведений произойти в пределах секунды. Что вы создали такое?
24 alextom81
 
25.03.13
11:05
(23) Всё, реализовали.  Понятно, что включаем только для независимых РС контроль, и только не для "загрузки" и для "клиента". Понятно, что регистры, которые документами формируются могут по несколько в секунду писаться (аналитики УЗ, например).
В данный момент включили подписки для Штатки и Учетных политик. Понадобиться ещё - будем смотреть.
Код в (22) поправили - во вторую запись вставили обращение к среду последних, а не 0 строку набора записей - работает. Потому версионирование и записывает версии "последовательно".