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



Памятка-инструкция по исправлению этой ошибки.

Хотя я в заголовке указал, что база файловая — без sql сервера, чтобы исправить эту ошибку нам не обойтись.

Для решения этой проблемы я использовал сервер PostgreSQL, PgAdmin4, Excel и самописную обработку на 1С (находится во вложении к статье).

1. Первым делом требуется развернуть поврежденную базу на SQL сервере.

2. Нужно сопоставить имя таблиц базы на SQL с именами метаданных конфигурации 1С.

Делал я это с помощью своей обработки. Обработка тестировалась на платформе 8.3.12 и выше.

Принцип прост. Тестирование и исправление нам дает название метаданных, которые нужно исправить. Например:

Проверка логической целостности. Документы. ИзменениеПлановыхНачислений. Табличная часть имеет записи, не относящиеся ни к одной записи главной таблицы. Количество — 1.

Запускаем базу в пользовательском режиме. Запускаем обработку и получаем наименования таблиц в БД PostgreSQL и наименования полей "Ссылка". скрин 1

3. Требуется найти в базе PostgreSQL записи не относящиеся ни к одной записи главной таблицы с помощью SQL запросов.

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

Открываем PgAdmin, запускаем Query Tool.

Query Tool скрин

С помощью следующих запросов выбираем все ссылки и сохраняем их в csv.

select distinct encode(FieldName,'hex') as linkId from TableName order by encode(FieldName,'hex')

FieldName замените на имя поля ссылки. TableName замените на имя таблицы.

Скрин. Выполнение запросов в PgAdmin

С помощью Экселя или средствами 1С, или вообще как вам удобнее — найдите битые ссылки. То есть такие ссылки, которые присутствуют во вспомогательных таблицах, но отсутствуют в основной таблице документа.

4. SQL запросом удаляем некорректную строку.

delete from TableName where encode(FieldName,'hex') = '00000000000000000000000000000000'

TableName замените на имя таблицы. FieldName замените на имя поля ссылки. ‘00000000000000000000000000000000’ замените на найденную некорректную ссылку. Апострофы должны остаться.

5. Проверить внутренним тестированием 1С, что проблема решена.

6. Выгрузить базу обратно в файловый вариант.

Дополнение от kosmo0.

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

СтрокаGUID = "00000000-0000-0000-0000-000000000000"; //Здесь должна быть ваша ссылка
НаименованиеДокумента = "СтрокаНаименования" //Заменить на реальное наименование документа

НовыйGUID = Новый УникальныйИдентификатор(СтрокаGUID);
ДокОбъект = Документы.[НаименованиеДокумента].СоздатьДокумент();
ДокОбъект.УстановитьСсылкуНового(Документы.[НаименованиеДокумента].ПолучитьСсылку(НовыйGUID));
//Возможно здесь потребуется дозаполнить реквизиты объекта, без которых он отказывается записываться
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать();

Затем, можно удалить этот объект программно, что решит проблему.

Если в поле "Ссылка" находится пустая ссылка на документ, то ошибка исправляется только описанным выше способом.

14 Comments

  1. leosoft

    Ничего не понял — когда и где возникает такая ситуация?

    ТиИ не помогает?

    Reply
  2. Dipod

    (1)Эта ошибка возникает при тестировании и исправлении из конфигуратора. И платформа не умеет автоматически исправлять эту ошибку.

    Reply
  3. TMV

    (2) наверное, имели ввиду, что сообщение об ошибке выходит во время ТиИ? Вряд ли ошибка возникает в этот момент.

    Reply
  4. TMV

    Для файловой базы есть ещё кстати утилита checkdbf, она не помогает?

    Reply
  5. Dipod

    (4)Нет, эта утилита не помогает от этой ошибки.

    Reply
  6. Dipod

    (3)Да, именно так.

    Reply
  7. kosmo0

    А такой алгоритм — запросом по табличным частям. В колонке ссылка находим все <Объект не найден>. То есть получаем список уникальных идентификаторов (УИД) документов отсутствующих в БД. На основании этих УИД создаем документы, а потом эти вновь созданные документы корректно удаляем вместе с табличными частями.

    А сопоставление имен таблиц базы на SQL с именами метаданных конфигурации 1С можно глянуть в инструментах разработчика (их можно скачать бесплатно не только с данного ресурса). Да и консоль запросов там есть.

    Reply
  8. Dipod

    (7)

    А такой алгоритм — запросом по табличным частям. В колонке ссылка находим все <Объект не найден>. То есть получаем список уникальных идентификаторов (УИД) документов отсутствующих в БД. На основании этих УИД создаем документы, а потом эти вновь созданные документы корректно удаляем вместе с табличными частями.

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

    Ваш способ сработает, если ссылка осталась в исходном виде.

    А сопоставление имен таблиц базы на SQL с именами метаданных конфигурации 1С можно глянуть в инструментах разработчика (их можно скачать бесплатно не только с данного ресурса). Да и консоль запросов там есть.

    Согласен. Я, чтобы написать обработку из вложения, потратил 15 минут. Её код очень прост и прозрачен. Быстрое гугление легко находит функцию глобального контекста сопоставления метаданных и таблиц БД ПолучитьСтруктуруХраненияБазыДанных(), которую я использовал в обработке.

    Я исхожу из того, что любой труд должен быть оплачен. Если моя обработка сэкономит кому-то время, которое он мог потратить на более полезные вещи, то потратить 1SM за неё не должно быть жалко. Кому этот вариант не подходит, тоже могут спокойно написать себе обработку за 15 минут, как это сделал я.

    Reply
  9. echo77

    (8) а если самому создать документ с такой ссылкой?

    Reply
  10. Dipod

    (9)А как вы создадите документ с пустой ссылкой? Сейчас специально проверил на платформе 8.3.15, но думаю и на более ранних такой код не прокатит.

     ДокОбъект = Документы.Test.СоздатьДокумент();
    ДокОбъект.УстановитьСсылкуНового(Документы.Test.ПустаяСсылка());
    ДокОбъект.Дата = ТекущаяДата();
    ДокОбъект.ОбменДанными.Загрузка = Истина;
    ДокОбъект.Записать();
    UID  = ДокОбъект.Ссылка.УникальныйИдентификатор();
    Сообщить(UID);

    Документ создается, но не с пустой ссылкой.

    Reply
  11. Fox-trot

    (2)

    Эта ошибка возникает при тестировании и исправлении из конфигуратора. И платформа не умеет автоматически исправлять эту ошибку.

    платформа сама создает проблемы и потом не может их решить. так?

    Reply
  12. Dipod

    (11)Нет. Платформа при тестировании просто сообщает о наличии некорректной записи в подчиненной таблице, но не умеет удалять некорректную строку.

    Как сказал (7), эту ошибку можно обойти, если при ТиИ создать объект по битой ссылке, а потом корректно его удалить. Но этот способ сработает только в том случае, если в строке подчиненной таблицы в поле «Ссылка» не стоит пустая ссылка. Пустая ссылка там может возникнуть, если кто-то ранее выполнил ТиИ с настройкой «Удалять ссылки».

    Reply
  13. kosmo0

    (12) Вообще то не очень понятно почему при ТиС платформа чистит ссылку при имеющихся табличных частях. Это либо косяк платформы либо кто-то залез своими шаловливыми ручками.

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

    Reply
  14. Dipod

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

    Я не знаю истоков проблемы. Но почему-то случилась у клиента ситуация, при которой основная запись по документу в таблице удалилась, а запись во вспомогательной таблице по этому документу нет. Можно только гадать о причинах. Знаю только то, что эта проблема довольно распространена. Регулярно с ней сталкиваюсь у клиентов.

    Reply

Leave a Comment

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