Почему при изменении цены одной номенклатуры меняется цена другой в 1С 7.7?

Программист 1С v7.7 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В процессе работы в конфигурации «Торговля и Склад» (или комплексных конфигурациях на платформе 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 ошибочно выдается выборкой для разных владельцев.

Пошаговое восстановление целостности индексов

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

  1. Завершите все пользовательские сеансы. Убедитесь через монитор пользователей или системные процессы сервера, что с базой никто не работает.
  2. Создайте резервную копию. Скопируйте каталог информационной базы целиком в надежное место.
  3. Удалите индексные файлы. Перейдите в каталог базы данных и найдите все файлы с расширением .cdx. Удалите их вручную. В таблицах DBF хранятся сами данные, а файлы CDX содержат только деревья индексов, которые платформа умеет пересоздавать с нуля.
  4. Выполните переиндексацию. Запустите программу в режиме «1С:Предприятие» или «Конфигуратор». Система обнаружит отсутствие индексных файлов и автоматически предложит переиндексировать информационную базу. Подтвердите операцию.
  5. Проверьте результат. Откройте проблемные позиции номенклатуры и проверьте подчиненные элементы цен.

Причины регулярного разрушения индексов в файловых базах

Если индексы повреждаются периодически, рассмотрим основные системные факторы, приводящие к сбоям в файловых базах 1С 7.7:

  1. Сетевое кэширование Windows (Oplocks / SMB Leasing). При многопользовательской работе через общий сетевой ресурс встроенные механизмы кэширования операционной системы нарушают синхронизацию одновременной записи в файлы DBF и CDX. Для устранения сбоев рекомендуется отключить Opportunistic Locking (Oplocks) на сервере или перевести пользователей на работу через терминальный сервер (RDP).
  2. Нестабильность локальной сети. Кратковременные разрывы соединения, особенно при подключении клиентов по Wi-Fi, приводят к аварийному обрыву транзакций записи.
  3. Блокировки антивирусным ПО. Фоновое сканирование открытых файлов базы данных антивирусом может блокировать монопольный доступ к индексам. Добавьте весь каталог базы и расширения .dbf, .cdx, .md, .usr в исключения антивирусной защиты.
  4. Ограничение размера таблиц. Контролируйте размер самых больших файлов в каталоге базы: приближение любого файла DBF или CDX к объему в 2 ГБ вызывает разрушение таблиц.

Ошибки в программном коде и обработках

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

Посмотрим на пример правильного позиционирования и поиска цен для номенклатуры:


СпрЦены = СоздатьОбъект("Справочник.Цены");
// Обязательно ограничиваем выборку конкретным товаром-владельцем
СпрЦены.ИспользоватьВладельца(ТекущийТовар);

Если СпрЦены.НайтиПоРеквизиту("ТипЦен", НужныйТипЦен, 0) = 1 Тогда
    // Элемент найден именно у текущего товара
    СпрЦены.Цена.Установить(ТекущаяДата(), НоваяЦена);
    СпрЦены.Записать();
Иначе
    // Если цены такого типа еще нет - создаем новую подчиненную запись
    СпрЦены.Новый();
    СпрЦены.ТипЦен = НужныйТипЦен;
    СпрЦены.Цена.Установить(ТекущаяДата(), НоваяЦена);
    СпрЦены.Записать();
КонецЕсли;

Если разработчик забывает вызвать метод ИспользоватьВладельца() перед вызовом поиска или выборки, метод НайтиПоРеквизиту() выполняет поиск по всей таблице SC319.DBF и может изменить цену другого товара, у которого совпал тип цен.

Также помните, что числовое значение периодического реквизита «Цена» хранится не в файле SC319.DBF, а в общей системной таблице периодических значений 1SCONST.DBF. При серьезных сбоях структуры данных переиндексация базы полностью восстанавливает связку между объектами и историей их периодических реквизитов.

← На главную