В процессе работы в конфигурации «Торговля и Склад» (или комплексных конфигурациях на платформе 1С:Предприятие 7.7) пользователи иногда сталкиваются с критической аномалией: при редактировании цены у одной позиции номенклатуры автоматически изменяется цена у совершенно другого товара. Создается визуальное впечатление, что один и тот же элемент подчиненного справочника Цены одновременно привязан к двум разным элементам справочника Номенклатура. Разберем детально, почему это происходит и как правильно восстановить целостность базы данных.
Проанализируем техническую сторону вопроса: физически в базе данных формата DBF один элемент подчиненного справочника не может принадлежать двум разным владельцам. В таблице справочника цен за связь с владельцем (номенклатурой) отвечает всего одно поле — PARENTEXT. В нем может храниться только один 9-символьный идентификатор родительского объекта.
Посмотрим на описание структуры таблицы справочника цен из словаря данных (1cv7.dd):
#===============================================================================
#==TABLE no 49 : Справочник Цены
# Name |Descr |Type[A/S/U]|DBTableName|ReUsable
T=SC319 |Справочник Цены |A |SC319 |1
#-----Fields-------
# Name |Descr |Type|Length|Precision
F=ID |ID object |C |9 |0
F=PARENTEXT |Parent in other tabl|C |9 |0
F=ISMARK |Flag Object is Marke|C |1 |0
F=VERSTAMP |Version stamp |C |6 |0
F=SP6681 |(P)Валюта |C |9 |0
F=SP6682 |(P)Процент |N |7 |2
F=SP327 |(P)ТипЦен |C |9 |0
#----Indexes------
# Name |Descr |Unique|Indexed fields |DBName
I=IDD |of ID |0 |ID |IDD
I=PCODE |of PARENT |0 |PARENTEXT |PCODE
I=VI327 |VI327 |0 |SP327 |VI327
I=VIP327 |VIP327 |0 |PARENTEXT,SP327 |VIP327
Выясним причину ошибки: когда разрушаются индексные файлы (в частности, индексы PCODE и VIP327 в файле SC319.CDX), платформа при поиске подчиненных элементов по полю PARENTEXT начинает считывать некорректные смещения записей. В результате один и тот же элемент физической таблицы SC319.DBF ошибочно выдается выборкой для разных владельцев.
Если возникла подобная проблема, не спешите запускать стандартное «Тестирование и исправление ИБ» с созданием новых связей, так как это может зафиксировать логические ошибки в данных. Разберем правильный порядок действий:
.cdx. Удалите их вручную. В таблицах DBF хранятся сами данные, а файлы CDX содержат только деревья индексов, которые платформа умеет пересоздавать с нуля.Если индексы повреждаются периодически, рассмотрим основные системные факторы, приводящие к сбоям в файловых базах 1С 7.7:
.dbf, .cdx, .md, .usr в исключения антивирусной защиты.Проанализируем еще одну возможную причину: некорректно написанные внешние обработки загрузки или переоценки номенклатуры. При программной работе с подчиненными справочниками обязательно должен быть установлен контекст владельца.
Посмотрим на пример правильного позиционирования и поиска цен для номенклатуры:
СпрЦены = СоздатьОбъект("Справочник.Цены");
// Обязательно ограничиваем выборку конкретным товаром-владельцем
СпрЦены.ИспользоватьВладельца(ТекущийТовар);
Если СпрЦены.НайтиПоРеквизиту("ТипЦен", НужныйТипЦен, 0) = 1 Тогда
// Элемент найден именно у текущего товара
СпрЦены.Цена.Установить(ТекущаяДата(), НоваяЦена);
СпрЦены.Записать();
Иначе
// Если цены такого типа еще нет - создаем новую подчиненную запись
СпрЦены.Новый();
СпрЦены.ТипЦен = НужныйТипЦен;
СпрЦены.Цена.Установить(ТекущаяДата(), НоваяЦена);
СпрЦены.Записать();
КонецЕсли;
Если разработчик забывает вызвать метод ИспользоватьВладельца() перед вызовом поиска или выборки, метод НайтиПоРеквизиту() выполняет поиск по всей таблице SC319.DBF и может изменить цену другого товара, у которого совпал тип цен.
Также помните, что числовое значение периодического реквизита «Цена» хранится не в файле SC319.DBF, а в общей системной таблице периодических значений 1SCONST.DBF. При серьезных сбоях структуры данных переиндексация базы полностью восстанавливает связку между объектами и историей их периодических реквизитов.