Фиксация данных

Фиксация данных – это инструмент для автоматического отслеживания изменений в данных.

Проблема

Во всех, или почти во всех конфигурациях на платформе 1С есть механизмы запрета изменений задним числом. И во всех, или почти во всех реальных внедрениях они успешно игнорируются пользователями.

Потребность в изменении документов прошлого периода возникает регулярно. Меняться может не только сам документ, сколько состояние регистров – например, при перепроведении документов за месяц, квартал или год. Вроде бы, в документах изменений нет, а оборотка, или регистры себестоимости изменились.

Неприятность в том, что такие изменения очень трудно поймать. Изменение границы запрета изменений данных если и фиксируется, то только в журнале регистрации, но без конкретных данных – не удастся выяснить, какая именно граница была изменена. Некто, например заместитель главного бухгалтера, или добросердечный программист, сдвигает границу назад, человек меняет или просто перепроводит документ, и все живут надеждой, что ничего не изменилось.

Реально проконтролировать, изменилось что-то или нет, практически невозможно. В жизни используются три способа.

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

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

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

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

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

Если же шло закрытие квартала, и бухгалтерия перепроводила все документы, например по ТМЦ, то версионирование не поможет – оно честно скажет, что изменено несколько тысяч документов, причем реквизиты и таб.части все на месте, их просто перепровели.

Проблема понятна – версионирование фиксирует изменение первичных данных, а не регистров. А нам, в данной задаче, нужно именно изменение регистров, и только потом – первичные данные. Изменение документа не всегда влечет за собой расхождения в регистрах – например, могли поменять ничего не значащий реквизит, вроде комментария, но регистр все равно поехал.

Еще один источник проблем – изменение настроек и алгоритмов с течением времени. Сегодня документ при проведении ведет себя так, а завтра разработчики 1С или собственные программисты внесли изменения в код, и документ стал вести себя иначе. Вчера он делал одни движения по регистрам, завтра сделает другие.

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

Копирование регистров

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

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

Именно большой размер копий регистров в свое время оттолкнул нас от такого подхода, хотя задачу отслеживания изменений решать удавалось, хоть и с трудом.

Другой вариант – хранить не весь регистр, а, например, только остатки. Вариант так себе, потому что одинаковые остатки на конец периода не гарантируют того, что внутри периода изменений нет. Но идея, сама по себе, неплоха – хранить не весь регистр, а некий уменьшенный слепок.

Скомбинировав оба варианта, мы нашли приемлемое решение – хранить свернутую копию регистра.

Свернутая копия регистра

Рассмотрим решение задачи отслеживания изменений на примере. Допустим, мы работаем с регистром накопления «Продажи». В нем есть организация, контрагент, договор, номенклатура, характеристика и т.д. И у нас есть система версионирования, которая знает – кто, когда и какой документ изменил. И нам надо решить задачу отслеживания изменений.

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

Мы создаем некий регистр накопления, в котором пока нет никаких измерений. На данном этапе он бесполезен.

Первое, что надо знать – в каком периоде произошли изменения. Периодом может быть день, неделя, месяц и т.д., в зависимости от интенсивности наполнения основного регистра («Продажи»). Допустим, мы решили, что нам достаточно знать месяц, в котором произошли изменения.

Делаем копирование исходного регистра, и тащим из него одно поле – период. Но не в чистом виде (дата со временем), а приводим дату к началу месяца. Так у нас получится одна запись регистра-копии на каждый месяц продаж.

Уже неплохо, потому что объем данных в копии будет очень невелик. Теперь, чтобы определить, были ли изменения, нам достаточно сравнить обороты регистра и его копии в разрезе периодов, свернутых до месяца. Если изменения были, сравнение покажет – например, изменен март 2018 г.

Дальше нам надо идти в версионирование, и по имеющейся у нас информации наложить правильный фильтр – нам нужны документы за март 2018 года. Их может быть немного, тогда задача будет решена.

А может быть много, тогда фильтр надо делать более точным. Добавляем, например, в нашу копию поле «Организация», и получаем более точные данные – изменен март 2018 г. по организации «ООО Рога и Копыта». Снова идем в версионирование, и уточненный фильтр показывает нам чуть меньше документов.

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

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

Тут очень важен момент, когда остановиться. В принципе, в копии можно хранить и документ-регистратор, и заказ покупателя, и номенклатуру с характеристикой. Тогда и в версионирование ходить не придется – все данные об изменениях будут в нашей копии. Только объем регистра-копии станет равным оригиналу, и толку от свертки не будет.

Принцип, надеюсь, понятен. Храним свернутую копию регистра, с необходимой точностью. Точность определяется возможностями версионирования, доступными в конкретной конфигурации и базе данных. Теперь переходим к решению «Фиксация данных».

Фиксация данных

Фиксация данных – это инструмент, реализующий описанную выше методику настройки, создания и хранения свернутых копий регистров, а также автоматического отслеживания расхождений.

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

Разделение фиксируемых данных выполняет справочник «Настройки фиксации данных».

Настройки фиксации данных

Настройка – это основной разрез фиксации данных. Например, вот так выглядит настройка для регистра «Продажи»:

image

Дата начала определяет, с какой даты нужно фиксировать данные. На скриншоте выбрано начало 2010 года – это значит, что продажи 2009 года фиксироваться не будут. Периодичность фиксации указывает, как данные будут сворачиваться по периоду. Чем шире периодичность, тем меньше данных будет в регистре, но тем больше выборка документов в версионировании. Отставание фиксации – это размер текущего периода, в котором нас не интересует изменение данных. Например, текущий месяц – зачем его фиксировать? Он ведь каждый день меняется по несколько раз.

Данные, которые будут фиксироваться, выбираются с помощью схемы компоновки. Например, для регистра «Продажи» мы делаем запрос очень простым:

image

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

Требований к схеме компоновки немного:

  1. Данные должны возвращаться в виде плоской таблицы, без группировок и итогов;
  2. Запрос должен иметь параметры «НачалоПериода» и «КонецПериода».

Наша схема для регистра «Продажи» настроена так:

image

Остальные настройки схемы, как и запрос – на ваше усмотрение. Можно соединять несколько регистров в запросе, можно фильтровать по значениям измерений, если вам нужны только определенные записи для фиксации, и т.д.

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

image

Хранение данных

Значительное внимание в «Фиксации данных» уделено оптимизации хранения этих самых данных.

Все зафиксированные данные лежат в одном регистре накопления, с достаточно лаконичными метаданными:

image

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

Измерение «Документ фиксации» хранит в себе ссылку на служебный документ, о котором мы поговорим позже. Пока посмотрим внимательнее на измерение «КлючФиксации». Он имеет тип справочник «КлючиФиксацииДанных».

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

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

image

Что именно попадает в ключ, решает настройщик в справочнике «Настройки фиксации данных»:

image

Запрос может возвращать много полей, а в ключ попадут только нужные, указанные в настройке.

Типы аналитик ключа

Было бы неразумно с нашей стороны поставить тип «Любая ссылка» для аналитик ключа, т.к. любое изменение метаданных конфигурации приводило бы к долгой реструктуризации. Поэтому мы сделали просто: доступные типы аналитик регулируются планом видов характеристик «флТипыКлючейФиксацииДанных».

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

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

Документ «Фиксация данных»

Это служебный документ, который выполняет три функции:

  1. Фиксирует данные;
  2. Фиксирует расхождения;
  3. Акцептует расхождения.

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

image

Значимых реквизитов три: настройка фиксации, начало и конец периода фиксации.

Алгоритм работы

Алгоритм работы достаточно прост:

  1. Создаем настройку фиксации, пишем запрос и схему компоновки, определяем параметры фиксации;
  2. Регламентное задание «Фиксация данных» выполняет, собственно, фиксацию данных – создает на каждый период документ «Фиксация данных», который пишет свернутые данные в наш регистр накопления. Количество создаваемых документов равно количеству периодов. Например, если выбрана периодичность месяц, и фиксируются данные за 3 года, то получится 36 документов.
  3. То же регламентное задание «Фиксация данных» периодически выполняется и ищет новые периоды, для которых еще не выполнена фиксация. Прошел еще один месяц – добавит один новый документ. Важно: фиксация периода выполняется только один раз, т.е. заново переформировывать документы регл.задание не будет.
  4. Регламентное задание «Проверка фиксации данных» выполняет главную функцию – контролирует, соответствуют ли текущие данные зафискированным. Работает просто – выполняет тот же запрос, за тот же период, и сверяет два результата. Если изменений нет, идет дальше. Если изменения есть, фиксирует расхождения в отдельном регистре накопления «Расхождения фиксации данных»:

image

Как видите, этот регистр почти не отличается от предыдущего, разница только в наличии реквизита «Дата регистрации» - там запоминается дата обнаружения расхождения. В регистр же просто пишутся разница ресурсов и ключи, по которым эта разница обнаружена:

image

Например, на этом скриншоте видно, что изменилось значение ресурса 1 (это у нас количество) и ресурса 2 (это сумма) по ключу «Другой некий контрагент». Щелкнув по ключу, мы узнаем его состав – в нашем случае, это контрагент. Щелкнув по документу, мы узнаем период, в котором произошли изменения – в нашем случае это сентябрь 2017 года. Ну и дата регистрации нам говорит, что изменения зафиксированы 07.01.2019 г. в 9:24.

Остается сходить в версионирование, отфильтровать изменения по дате (07.01.2019), типам документов (реализации, корректировки реализаций), дате этих документов (сентябрь 2017 г.) и контрагенту («Другой некий контрагент»). Останется выборка из нескольких (а скорее - одного) документов, с указанием пользователя, внесшего изменения.

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

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

Если кто-то усугубит ситуацию, добавив в тот же период еще немного расхождений, данные в регистре «Расхождения фиксации данных» просто обновятся.

  1. Если расхождения признаны законными, и исправлять их никто уже не будет, то необходимо акцептовать эти изменения. Делается это просто – открываем из регистра документ фиксации, и проводим его вручную.

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

Отслеживание изменений

Все отслеживание изменений сводится к одному простому действию – контролю наличия записей в регистре накопления «Расхождение фиксации данных». Нормальное состояние этого регистра – когда он пустой.

Как только в нем появились данные – кто-то что-то испортил. Что с этим делать – написано выше. Важно только не пускать этот процесс на самотек, а решать судьбу каждого расхождения – либо исправлять данные, либо акцептовать расхождения.

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