При переходе на новые релизы конфигураций 1С (особенно при глобальной смене редакций, например, с 1.0 на 2.0) администраторы и программисты нередко сталкиваются с ошибкой реструктуризации базы данных: «Имеются записи с одинаковыми измерениями». Ситуация часто заходит в тупик, когда после ручной очистки проблемного регистра перед обновлением ошибка повторяется снова.
Разберем детально механизм возникновения этой проблемы, выясним, почему записи возвращаются обратно в регистр сведений, и рассмотрим проверенные способы успешного обновления конфигурации.
Механизм обновления платформы 1С устроен так, что при изменении состава или типов измерений регистра сведений в СУБД формируется новая таблица. В нее переносятся данные из старой таблицы, после чего накладывается уникальный индекс по комбинации измерений. Ошибка возникает в следующих случаях:
Проанализируем фрагмент кода, который часто размещают в общих модулях конфигураций для сохранения состояния пользовательского интерфейса:
Процедура СохрЗнач(Форма, Реквизит, Значение, Вариант = "") Экспорт
#Если ТолстыйКлиентОбычноеПриложение ИЛИ ТолстыйКлиентУправляемоеПриложение Тогда
СохранитьЗначение(Питание_НаСервере.ПолучитьИдентификаторФормы(Форма)+"_"+Реквизит, Значение);
#Иначе
Идентификатор = Питание_НаСервере.ПолучитьИдентификаторФормы(Форма)+"_"+Реквизит;
Пользователь = ПараметрыСеанса.ТекущийПользователь;
НаборЗаписей = РегистрыСведений.Питание_ХранилищеНастроек.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Идентификатор.Установить(Идентификатор);
НаборЗаписей.Отбор.Пользователь.Установить(Пользователь);
НаборЗаписей.Отбор.Вариант.Установить(Вариант);
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Идентификатор = Идентификатор;
НоваяЗапись.Пользователь = Пользователь;
НоваяЗапись.Вариант = Вариант;
НоваяЗапись.Значение = Новый ХранилищеЗначения(Значение);
НаборЗаписей.Записать();
#КонецЕсли
КонецПроцедуры
Вы очищаете регистр через обработку, закрываете сеанс «1С:Предприятия», чтобы начать реструктуризацию в конфигураторе, но в момент штатного выхода из программы срабатывают события форм ПередЗакрытием, ПриЗакрытии или обработчики модуля приложения ПередЗавершениемРаботыСистемы. Процедура сохранения настроек моментально записывает данные текущего пользователя обратно в регистр сведений.
Рассмотрим самый быстрый способ предотвратить срабатывание обработчиков закрытия форм:
1cv8.exe (либо выполняем команду taskkill /f /im 1cv8.exe).Если в регистре содержатся важные пользовательские настройки, которые нежелательно полностью удалять, локализуем конфликтные данные. Напишем запрос к регистру по тем измерениям, которые останутся в целевой конфигурации после обновления:
ВЫБРАТЬ
Идентификатор,
Пользователь,
КОЛИЧЕСТВО(*) КАК КоличествоДублей
ИЗ
РегистрСведений.Питание_ХранилищеНастроек
СГРУППИРОВАТЬ ПО
Идентификатор,
Пользователь
ИМЕЮЩИЕ
КОЛИЧЕСТВО(*) > 1
Посмотрим на результат выполнения запроса: сгруппированные строки покажут, у каких именно пользователей и по каким элементам форм образуются неуникальные ключи. Лишние записи можно точечно удалить набором записей, оставив только актуальные настройки.
В клиент-серверном варианте работы информационной базы можно полностью исключить влияние клиентских сеансов и фоновых заданий:
ПолучитьСтруктуруХраненияБазыДанных() определяем имя физической таблицы СУБД, соответствующей регистру./UC и завершаем реструктуризацию.Если конфигурация уже находится на поддержке с возможностью редактирования, можно временно отключить процедуру сохранения настроек:
СохрЗнач общего модуля и комментируем вызов НаборЗаписей.Записать().