В практике работы с программами 1С часто возникает ситуация, когда при попытке изменить единицу хранения остатков или коэффициент единицы измерения в карточке номенклатуры система выдает ошибку: «Единица является единицей хранения остатков и уже участвует в товародвижении. Изменить коэффициент уже нельзя!». Это происходит потому, что 1С жестко контролирует целостность данных: если по товару были записи в регистрах накопления (остатки на складах, продажи, закупки), изменение единицы измерения «задним числом» приведет к тому, что все количественные показатели в базе станут неверными.
В данной статье мы разберем, как обойти это ограничение, проанализируем причины блокировки и рассмотрим несколько способов решения проблемы — от «легальных» до административных методов вмешательства в структуру БД.
Прежде чем переходить к действиям, проанализируем ситуацию. В конфигурациях 1С (таких как УТ 10.3, УПП 1.3 или старые версии БП) количество в регистрах хранится в базовых единицах. Если в карточке номенклатуры Номенклатура указано, что 1 коробка равна 10 штукам, и вы провели документ на 1 коробку, в регистр ТоварыНаСкладах запишется число 10. Если вы просто измените коэффициент на 5, то старые отчеты внезапно покажут, что у вас на складе не 10 штук, а 5 (или наоборот), так как система будет пересчитывать остатки по новому значению. Именно для защиты от такого «развала» базы разработчики ставят программный запрет.
Это самый правильный, но и самый трудоемкий метод. Нам необходимо найти все документы, в которых участвует данная номенклатура, отменить их проведение, изменить коэффициент и провести заново. Рассмотрим подробнее, как это сделать.
Для поиска всех ссылок на объект воспользуемся стандартной функцией «Поиск ссылок на объект». В обычных формах это меню «Операции» — «Поиск ссылок на объекты». В управляемых — «Функции для технического специалиста» (ранее «Все функции») в разделе «Стандартные».
ГрупповаяОбработкаСправочниковИДокументов (или «Изменение выделенных элементов» в новых версиях) отменяем проведение всех найденных документов.ТоварыНаСкладах и другим не останется (проверить можно отчетом «Ведомость по товарам на складах»), система позволит изменить коэффициент в справочнике.Важно: Если документов тысячи и они относятся к закрытым периодам, этот метод может быть неприемлем из-за риска изменения данных прошлых периодов.
Если нам нужно принудительно изменить реквизит, не снимая документы с проведения (например, если ошибка была допущена при загрузке данных и коэффициенты изначально неверные, но «цифры» в базе уже правильные), можно временно «отключить» глаза программе. Проанализируем, где именно живет эта проверка.
Как правило, код проверки находится в Модуле объекта справочника Номенклатура или ЕдиницыИзмерения. Нам нужно найти процедуру ПередЗаписью.
Выполним следующие шаги:
Номенклатура, правой кнопкой мыши — «Открыть модуль объекта».ПередЗаписью(Отказ)."уже участвует в товародвижении").
// Процедура ПередЗаписью(Отказ)
// ... какой-то код ...
// Если ЭтоНоваяЕдиница И ЕстьДвиженияПоТовару(Ссылка) Тогда
// ОбщегоНазначения.СообщитьОбОшибке("Изменить коэффициент нельзя!");
// Отказ = Истина;
// КонецЕсли;
После этого сохраняем конфигурацию базы данных, заходим в режим «1С:Предприятие», спокойно меняем коэффициент и сохраняем карточку. Обязательно верните код в исходное состояние после завершения операции!
Для продвинутых пользователей существует способ обойти проверку без внесения изменений в конфигурацию. Специализированные обработки, такие как «Инструменты разработчика» (авторства Сергея Старых) или универсальные редакторы реквизитов, позволяют записывать объекты с параметром ОбменДанными.Загрузка = Истина.
Когда мы устанавливаем этот признак, платформа 1С понимает, что данные загружаются (например, из другой базы) и большинство прикладных проверок в модулях (код в ПередЗаписью и ПриЗаписи) просто игнорируются. Рассмотрим на примере кода, как это работает программно:
ОбъектНоменклатура = Справочники.Номенклатура.НайтиПоНаименованию("Очень-востребованный-товар").ПолучитьОбъект();
// Устанавливаем режим загрузки, чтобы пропустить проверки
ОбъектНоменклатура.ОбменДанными.Загрузка = Истина;
// Находим нужную единицу и меняем коэффициент напрямую
// Внимание: это пример логики, структура зависит от конфигурации
ОбъектНоменклатура.ЕдиницаХраненияОстатков.Коэффициент = 1;
ОбъектНоменклатура.Записать();
При использовании внешней обработки UniversalSelection (Универсальный подбор и обработка объектов) или IR, ищите галочку «Записывать в режиме обмена данными» или «Без проверок».
Если база работает на MS SQL Server или PostgreSQL и вы обладаете навыками администратора БД, можно изменить значение напрямую в таблицах. Этот способ самый быстрый для массовых изменений, но и самый опасный.
Проанализируем алгоритм:
_Reference85).UPDATE для изменения поля коэффициента.Внимание: После такого изменения 1С даже «не узнает», что данные поменялись, кэш сервера приложений может хранить старые значения, а итоги в регистрах не пересчитаются автоматически. Этот метод требует обязательной очистки кэша и последующего пересчета итогов.
Если вы опасаетесь «сломать» учет в старых периодах, наиболее разумным решением будет создание дубля номенклатуры с правильными настройками единиц измерения.
Рассмотрим по шагам:
СписаниеТоваров для старой карточки и ОприходованиеТоваров для новой (или используем КомплектацияНоменклатуры).Таким образом, история за прошлый год останется корректной в старых единицах, а текущий учет пойдет правильно. Это сохранит нервы бухгалтеру и обеспечит чистоту базы без программных «хаков».
Мы рассмотрели различные варианты решения проблемы. Если документов немного — используйте Способ 1. Если вы программист и понимаете риски — Способ 2 или 3 являются самыми эффективными. Если же вопрос касается официальной отчетности и налогового учета, лучше всего подойдет Способ 5.
Критически важно: Перед любыми действиями, связанными с изменением коэффициентов или единиц хранения в уже проведенных документах, делайте резервную копию базы данных. Ошибка в коэффициенте может «умножить на ноль» или увеличить в тысячи раз все ваши складские остатки в денежном выражении.