Имя: Пароль:
1C
1С v8
История элементов справочника
0 NewBieOneS
 
07.02.17
21:25
Доброго времени суток!

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

1. Создать справочник "История". В нем - единственный реквизит - ссылка на элемент отслеживаемого справочника. Далее - табличная часть с реквизитами: дата, тип, значение. Ну и писать туда данные.

2. Создавать при изменении значений копии элементов отслеживаемого справочника с условным флагом - "история".

3. Тоже самое, что и в пункте 1, но с использованием регистра сведений, т.е. вместо реквизита - измерение (+ измерение "период"), а  вместо табличной части - реквизиты: дата, тип, значение.

Посоветуйте, куда смотреть.
1 Волшебник
 
модератор
07.02.17
21:31
прикрути БСП
2 abuca
 
07.02.17
22:34
В XML выгружай как объект при каждой записи эл. справочника.
Когда надо, загружаешь обратно без сохранения в ИБ.
Будет видно все, что изменилось.
Однако, ссылочные типы данного элемента будут браться не из XMLа (или из XMLа)... Аааа... голова не работает, поправьте меня!

Мда... XMLей накопится в какой-то папке...
Тогда создаем DBF, и каждая новая запись будет строкой с XMLем изменений справочника.

На выходных реализую, просили сделать журнал всех изменений в ИБ, чтобы проверить кто, что и зачем.
3 Torquader
 
07.02.17
22:43
У меня всё писалось просто в ЛОГ. При этом, перед записью бралась копия элемента из базы и пореквизитно сравнивалась - отличия писались в виде "Реквизит:ЧтоБыло=>ЧтоСтало".
С табличными частями было сложнее, так как удаление одной строки приводит к появлению несовпадений по всем остальным строкам - делалось сравнение с шагами 1 и т.д., чтобы найти минимальный блок изменений, но всё равно писалось либо добавление либо удаление либо изменение строки целиком.
4 jsmith82
 
07.02.17
23:42
мне 2 нравится
дешево и сердито
только юзать можно не тот же справочник, а копию - МойСправочникИстория
5 Torquader
 
07.02.17
23:46
(4) При изменении одного поля мы делаем копию элемента - чтоб вам диска было мало.
6 jsmith82
 
07.02.17
23:53
(5) ну я думаю, что менять не часто будут
7 Tateossian
 
08.02.17
01:39
(2) В XML нельзя сохранять, так как при изменении пространства имен XML перестанет быть валидным; ну или сохранять, но не в куем случае не загружать.

(3) Для этого (полного сравнения) есть волшебная функция "СравнитьФайлы" - все сразу становится видно.
8 Злопчинский
 
08.02.17
02:27
на ИСе этих отслеживателй изменений для восьмерки - не один и не два.
9 Emery
 
08.02.17
08:23
(0) В более общем случае можно говорить о проблеме учета времени в пространственных базах данных. Так в статье «Обработка временных данных (СУБД Oracle)» http://bourabai.ru/dbt/servers/07.html пишут:

«Наш собственный опыт показал, что неправильная обработка временных данных может быть одной из основных причин серьезных проблем с производительностью и функциональностью в Oracle-системах.

Почему временные данные так трудно обрабатывать? Главная причина состоит в том, что эти данные не очень хорошо вписываются в двумерную реляционную модель. Вследствие этого в большинстве случаев мы не можем использовать для поиска и выборки данных сравнение на равенство.
. . .
В SQL нет операции, позволяющей непосредственно задать такое соединение, поэтому его реализация сложна для программирования и неэффективна в плане выполнения. (Кроме того, чем больше используется неопределенных значений, тем сложнее становится код.)»

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

«К сожалению, даже при выполнении всех этих указаний обработка временных данных не будет легкой задачей».

Конечно, вы можете сказать, что у вас относительно простой случай и общие идеи учета дополнительного временного измерения в пространственных базах данных вам не нужны. Тогда вы вполне можете использовать собственные идеи, например, использовать регистр сведений, как и рекомендуется в подобных случаях «восьмеркой». Тогда останется только обсуждать детали реализации.

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

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

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

Естественно, что такого рода авральная деятельность ставит вопрос о поиске адекватной модели учета. Которая бы выдерживала все эти изменения. Главное из которых – учет изменений данных и алгоритмов во времени.

Так что у автора топика «это не проблема, а всего лишь задача» :) .
10 rphosts
 
08.02.17
08:27
(7) расскажи это авторам БСП и пользователям всех типовых и прочих построенных на БСП с включенным версионированием
11 Save_Vol
 
08.02.17
08:43
Писать строки в регистр сведений через разделитель.Наименование метаданных в одной строке и второй строкой значение реквизита.
12 Fish
 
08.02.17
08:45
А чем БСП не подходит?
13 rphosts
 
08.02.17
10:53
(12) "каждый одинэснег должен написать своё версионирование"
14 abuca
 
12.02.17
12:03
Вот это запишет в каталог с файловой базой объект при изменении:

        СтрокаСоединенияИнформационнойБазы =  СтрокаСоединенияИнформационнойБазы();
        ПутьКБД = Сред(СтрокаСоединенияИнформационнойБазы, 7, СтрДлина(СтрокаСоединенияИнформационнойБазы) - 8);
        ЗаписьXML=Новый ЗаписьXML();
        ЗаписьXML.ОткрытьФайл(ПутьКБД + "\" + СокрЛП(ТипЗнч(Объект))+Объект.Номер + ".xml");
        ЗаписьXML.ЗаписатьНачалоЭлемента("Root");
        
        // Получить объект по ссылке.
        ВыгружаемыйОбъект=Объект.ПолучитьОбъект();
        
        // С помощью средств сериализации записать объект в файл.
        ЗаписатьXML(ЗаписьXML,ВыгружаемыйОбъект);
        
        ЗаписьXML.ЗаписатьКонецЭлемента();
        ЗаписьXML.Закрыть();



А вот это его прочитает:


    Файл = Новый ЧтениеXML;
    Файл.ОткрытьФайл(ИмяФайла);
    Пока Файл.Прочитать () Цикл
            Объект_ = ПрочитатьXML(Файл);
            Объект_.Записать();
    КонецЦикла;
    Файл.Закрыть();    //и перезапишет, если нам требуется!    
    

Остальное - на усмотрение.
15 abuca
 
12.02.17
12:08
(14) Эта конструкция мной применялась для перехода на новую БГУ.
Дописал выгрузку в XML в исключение по невозможности записи вводов остатков вследствие неуникальности ключевых полей регистров по ОС (был групповой учет, пытается в новую БГУ записать 10 строк с одинаковой номенклатурой).
А там строк в документе тыщи! Руками никак. Поэтому все что не могло сразу записаться в ИБ мы потом загрузчиком из XML подтягиваем, исправляем нужные строчки и записываем!
Внедренцы бьют в ладоши)))
16 abuca
 
12.02.17
12:12
(15) Подумал... Вдруг кому пригодится...

БГУ 2.0.48.59. Обработка.УниверсальныйОбменДаннымиXML:Модуль объекта.

Процедура ЗаписатьОбъектВИБ(Объект, Тип)
        
    Попытка
        
        УстановитьОбменДаннымиЗагрузка(Объект);
        Объект.Записать();
        
    Исключение
//Наше:
        СтрокаСоединенияИнформационнойБазы =  СтрокаСоединенияИнформационнойБазы();
        ПутьКБД = Сред(СтрокаСоединенияИнформационнойБазы, 7, СтрДлина(СтрокаСоединенияИнформационнойБазы) - 8);
        ЗаписьXML=Новый ЗаписьXML();
        ЗаписьXML.ОткрытьФайл(ПутьКБД + "\" + СокрЛП(ТипЗнч(Объект))+Объект.Номер + ".xml");
        ЗаписьXML.ЗаписатьНачалоЭлемента("Root");
        
        // Получить объект по ссылке.
        ВыгружаемыйОбъект=Объект.ПолучитьОбъект();
        
        // С помощью средств сериализации записать объект в файл.
        ЗаписатьXML(ЗаписьXML,ВыгружаемыйОбъект);
        
        ЗаписьXML.ЗаписатьКонецЭлемента();
        ЗаписьXML.Закрыть();
        
    //ОдинЭсовое:    
        
        СтрокаСообщенияОбОшибке = ЗаписатьИнформациюОбОшибкеВПротокол(26, ОписаниеОшибки(), Объект, Тип);
        
        Если Не ФлагРежимОтладки Тогда
            ВызватьИсключение СтрокаСообщенияОбОшибке;
        КонецЕсли;
        
    КонецПопытки;
    
КонецПроцедуры
17 abuca
 
12.02.17
12:15
(16) Ошибочка:


  //ВыгружаемыйОбъект=Объект.ПолучитьОбъект(); //Неверно
  ВыгружаемыйОбъект=Объект; // Верно!