Логическая целостность журналов документов



Большинство 1сников уверены, что клиент серверная версия 1с застрахована от потери целостности данных, если не лазить шаловливыми ручками напрямую в базу данных. Я тоже думал так до недавнего времени.

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

Один из вариантов решения этой проблемы — на картинке анонса, это проведение ТиИ с проверкой логической целостности. По крайней мере, я надеюсь, что это так, но проверить это предположение у меня возможности не было — база очень большая, и логическая целостность выполняется весьма продолжительное время, остановить работу на пару суток не представляется возможным.

Причиной является расхождение данных в основной таблице документа _DocumentXXX и данных в таблице журнала _DocumentJournalXXX. Определить это возможно с помощью прямого сравнения этих таблиц, даже стандартными запросами 1с (с незначительным ограничением, если графа журналов неограниченной длины).

Проверить свою базу на наличие таких вот скрытых «мин» вы можете, воспользовавшись отчетом «ПроверкаЛогическойЦелостностиЖурналов» из данной публикации, который в удобном виде выдаст результат сравнения. Или ничего не выдаст — тогда можете радоваться — значит данные в таблицах документов и таблицах журнаолв согласованы. Ну, по крайней мере без учета реквизитов неограниченной длины, которые не сравнить в запросе в общем виде.

Отчет работает на любых видах баз — клиент-серверных и файловых. Скорость выполнения отчета естественно, зависит размера и структуры базы, однако на нормальном сервере MS SQL для 500гб базы он формируется несколько минут. На других СУБД, естественно, не проверял.

Из-за того, что отчет использует запросы 1с, при использовании общих реквизитов в режиме разделения данных «независимо» — отчет строится только для данных в пределах текущего разделителя (так как из запроса не обратиться к такому реквизиту).

В обновленной версии псевдонимы длятаблиц запросов поменяны на менее вероятные (было — «Журнал» и «Документы», стало «ТабПроверяемыйЖурнал» и «ТабПроверяемыеДокументы», спасибо kapustinag за указание на ошибку)

Что делать, если отчет показал не пустой результат? Прямых средств воздействия на значения в таблице журналов у нас нет. Изменение «кривых» документов не помогает — в таблице журналов все равно остаются неправильные данные (Ну, по крайней мере у меня не прокатило). Можно сделать Тестирование и Исправление, однако это требует монопольного доступа, а также занимает очень много времени, зачастую, на которое остановить работу невозможно.

Обработка «ИсправлениеЛогическойЦелостностиЖурналов» — это «генератор запросов» для исправления неправильных данных в таблице журналов документов. Обработка работает, цепляясь через ADO к серверу СУБД и напрямую изменяя там данные. Обработка используя методы 1с, такие как ПолучитьСтруктуруХраненияБазыДанных() определяет таблицы, в которых находятся неправильные данные, а также предлагает «для ознакомления» (из-за лицензионных ограничений 1с) тексты запросов для СУБД, которые бы могли бы исправить ситуацию. Сначала генерируется запрос для удаления строк, которые не совпадают с данными в основных таблицах документов, или вообще не должны быть в журнале (например, докумены другого вида, или удаленные из основной таблицы), потом для создания строк, которых не хватает в журнале (т.е. строк с правильными данными взамен удаленных на первом шаге, а также те, которые в принципе отсутствовали в журнале)

Из-за того, что используется ADO, работает только на windows (win-сервере или в неуправляемых формах), протестирована на MS SQL, однако учитывая то, что используются элементарные запросы вида «DELETE FR OM table WH ERE field = value» и «INS ERT INTO table (field) VALUES (val ue)» работать должна на любой СУБД. Данные для удаления и вставки получаются целиком срествами 1с, аналогично получению данных в отчете.

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

ВНИМАНИЕ! Если вы (вдруг) решите использовать сгенерированные запросы, сначала протестируйте их на копии — ведь никто не застрахован от ошибок, вдруг я не учел какой-то случай, особенно если в базе активно используются разделители.

19 Comments

  1. Danil.Potapov

    Наверное актуально для тех, у кого база работала еще на версии 8.1, там в каком-то релизе был ваг в работе журналов.

    Reply
  2. kapustinag

    (0) Интересное совпадение по времени. Не далее как в субботу боролся с проблемой, которая, похоже, имеет схожие корни с описанными в данной статье.

    Клиент-серверная 1С УПП 1.3.41.1, платформа 8.2.16.368, MS SQL 2005.

    Ситуация:

    — Пытаюсь удалить организацию, помеченную на удаление. Контроль возможности удаления выдает один документ «Требование-накладная», в котором есть ссылка на эту организацию. И еще одна ссылка в регистре сведений «Учетная политика по расчету з/п организаций». Всего две ссылки по всей базе;

    — В самом документе ссылки на организацию нет (ни при открытии форм документа, ни при использовании «Инспектора объектов», консоли запросов и т.п.);

    — нет ссылки на организацию и в движениях документа;

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

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

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

    Попробую Ваш отчет на копии базы. Интересно все-же, где конкретно «сидит» эта невидимая ссылка.

    Reply
  3. Fragster

    (1) Dpotapov, в текущей базе нашлось 17 «кривых» документов, последний — июля этого года, хотя база на 8.2 работает уже больше года (правда режим совместимости 8.1 сняли совсем недавно).

    Reply
  4. Fragster

    (2) kapustinag, будет интересно, если причина именно в кривой записи в журнале и логическая целостность не помогает… У меня просто нет возможности ТиИ делать на базе, по этому приходится извращаться, а так я думал, что оно помогает 🙂

    Reply
  5. kapustinag

    Да, вот еще что: «Редактор объекта БД (ИР)» из «мобильных инструментов разработчика» версии 2.82 при открытии данного «требования-накладной» выругался, но все-же открыл объект. Ошибка была «В поле введены некорректные данные. Отменить ввод?» — это я ввел номер документа в поле выбора.

    Может быть, это означает несоответствие индекса по номеру документа реальным данным. Но переиндексирование я тоже сделал во время ТИИ, оно молча выполнилось, а проблема осталась.

    Reply
  6. kapustinag

    Запускал Ваш отчет на проблемной информационной базе. Устанавливал отбор по «Вид документа» содержит, или «Ссылка» равно, или «Дата» равно, или вообще без отборов — отчет выполнялся, в строке состояния менялись сообщения о проверке журналов и документов, и во всех вариантах получил одну и ту же ошибку:

    Ошибка исполнения отчета

    по причине:

    Ошибка при выполнении обработчика — ‘ПриКомпоновкеРезультата’

    по причине:

    {ВнешнийОтчет.ПроверкаЛогическойЦелостностиЖурналов.МодульОбъекта(158)}: Ошибка при вызове метода контекста (Выполнить)

    по причине:

    {(14, 6)}: Неоднозначное поле «Документы.Ссылка»

    <<?>>Документы.Ссылка,

    Причина нашлась: в конфигурации «Управление производственным предприятием», в документе «ОтменаСкидокНоменклатуры», есть табличная часть «Документы», а в запросе в процедуре ПолучитьТаблицуКривыхДокументов() использовался синоним «Документы», что и вызывало неоднозначность.

    Если заменить в запросе синоним «Документы», например, на «ПроверяемыеДокументы» — ошибка устраняется.

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

    Прикладываю файл — исправленный отчет (0).

    Reply
  7. Fragster

    (6) kapustinag, спасибо за замечание, поправил в публикации

    Reply
  8. hanio

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

    Reply
  9. Fragster

    (8) hanio, Ну, про физическую целостность — это вряд-ли получится. А про реструктуризацию — мысли есть, просто требуют проработки. если востребовано — то готов сделать (по аналогии с текущей обработкой). Но там надо будет несколько больше кнопок жать, ибо программно определить, чем отличаются конфигурация БД от текущей конфигурации — вряд-ли возможно.

    Reply
  10. hanio

    Ну на Ваше усмотрение если не отнимет много времени и конечно желательно не переводить в платную вещь ))

    Reply
  11. mybracho

    {ВнешнийОтчет.ПроверкаЛогическойЦелостностиЖурналов.МодульОбъекта(158)}: Ошибка при вызове метода контекста (Выполнить)

    Результат = Запрос.Выполнить();

    по причине:

    {(14, 6)}: Неоднозначное поле «Документы.Ссылка»

    <<?>>Документы.Ссылка,

    Как быть ?

    Reply
  12. mybracho

    {ВнешнийОтчет.ПроверкаЛогическойЦелостностиЖурналов.МодульОбъекта(158)}: Ошибка при вызове метода контекста (Выполнить)

    Результат = Запрос.Выполнить();

    по причине:

    {(14, 6)}: Неоднозначное поле «Документы.Ссылка»

    <<?>>Документы.Ссылка,

    Reply
  13. Fragster

    (12) mybracho, в модуле отчета в процедуре «ПолучитьТаблицуКривыхДокументов» поменяйте запрос на что-нибудь типа

     ШаблонЗапроса = «ВЫБРАТЬ
    | Журнал.Ссылка,
    | Журнал.Дата,
    | Журнал.Номер,
    | Журнал.Проведен,
    | Журнал.ПометкаУдаления,
    | &_Графы
    |ИЗ
    | &_Журнал КАК Журнал
    |ГДЕ
    | &_УсловиеСсылки
    | И НЕ (Журнал.Ссылка, Журнал.Дата, Журнал.Номер, Журнал.Проведен, Журнал.ПометкаУдаления, &_Графы) В
    |    (ВЫБРАТЬ
    |     ПсевдонимТаблицыДокументы.Ссылка,
    |     ПсевдонимТаблицыДокументы.Дата,
    |     ПсевдонимТаблицыДокументы.Номер,
    |     ПсевдонимТаблицыДокументы.Проведен,
    |     ПсевдонимТаблицыДокументы.ПометкаУдаления,
    |     &_РеквизитыГрафов
    |    ИЗ
    |     &_Документы КАК ПсевдонимТаблицыДокументы)
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    | ПсевдонимТаблицыДокументы.Ссылка,
    | NULL,
    | NULL,
    | NULL,
    | NULL,
    | &_РеквизитыГрафов
    |ИЗ
    | &_Документы КАК ПсевдонимТаблицыДокументы
    |ГДЕ
    | НЕ (ПсевдонимТаблицыДокументы.Ссылка, ИСТИНА) В
    |    (ВЫБРАТЬ
    |     Журнал.Ссылка,
    |     ИСТИНА
    |    ИЗ
    |     &_Журнал КАК Журнал)»;
    

    Показать

    Ну а так — я не знаю, насколько правильно называть реквизит/табличную часть «документы». Это в типовой?

    Reply
  14. Fragster

    (12) Обновил версию, теперь таблицы в этом запросе называются ТабПроверяемыйЖурнал и ТабПроверяемыеДокументы, что должно исключить ошибку «неоднозначное поле». Ну, конечно, если у вас нет реквизитов с таким именем.

    Reply
  15. xten

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

    Reply
  16. Fragster

    (15) и для тех и для тех

    Reply
  17. xten

    ок, спасибо большое и с наступающим Новым Годом! ))

    Reply
  18. 3762515

    Не работает:

    {ВнешняяОбработка.ИсправлениеЦелостностиЖурналов.МодульОбъекта(237)}: Ошибка при вызове метода контекста (Выполнить)

    Результат = Запрос.Выполнить();

    по причине:

    {(7, 85)}: Поле не найдено «ТабПроверяемыйЖурнал.Номер»

    И НЕ (ТабПроверяемыйЖурнал.Ссылка, ТабПроверяемыйЖурнал.Дата, ТабПроверяемыйЖурнал.<<?>>Номер, ТабПроверяемыйЖурнал.Проведен, ТабПроверяемыйЖурнал.ПометкаУдаления, ИСТИНА, ТабПроверяемыйЖурнал.НалоговыйПериод, ТабПроверяемыйЖурнал.Организация, ТабПроверяемыйЖурнал.Ответственный, ТабПроверяемыйЖурнал.ПериодСоставления) В

    Зря СМ только потратил:(

    Reply
  19. Fragster

    (18) 3762515, такая ошибка может быть, если в каком-либо из журналов отсутствует графа «номер». Прошу прислать .cf для того, чтобы можно было бы сделать доработанную обработку.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *