В процессе эксплуатации файловых баз данных 1С пользователи и администраторы нередко сталкиваются с аппаратными и программными сбоями. Одним из наиболее уязвимых мест в конфигурации 1С:Розница является регистр сведений Штрихкоды (или ШтрихкодыНоменклатуры в более свежих редакциях). Это связано с колоссальной нагрузкой на данную таблицу: к ней обращаются при каждом сканировании товара на кассовом узле (РМК), при проведении инвентаризаций, поступлений и любых складских операций.
В данной статье мы подробно разберем, почему возникает критическая ошибка «Файл базы данных поврежден» при обращении к штрихкодам, почему стандартное тестирование и исправление (ТИИ) делает таблицу пустой, и как правильно восстановить эти данные, даже если конфигурация резервной копии отличается от рабочей базы.
Файловая СУБД 1С хранит все данные в одном файле 1Cv8.1CD. Запись в таблицы происходит транзакционно. Если в момент записи нового штрихкода или считывания номенклатуры на кассе происходит резкое отключение питания, сбой локальной сети или зависание компьютера, целостность внутренних индексов и страниц данных нарушается. Движок платформы теряет возможность корректно адресовать записи, из-за чего при попытке открыть список штрихкодов система выдает критическую ошибку повреждения СУБД.
Проанализируем ситуацию, которая происходит при запуске утилиты проверки chdbfl.exe или встроенного механизма Тестирование и исправление (ТИИ) с флагом «Очищать объекты». Эти инструменты нацелены на восстановление физической работоспособности файла базы данных любой ценой. Если структура внутренней таблицы повреждена настолько, что восстановить связи невозможно, утилита просто отбрасывает поврежденные страницы данных. В результате вся таблица регистра сведений Штрихкоды признается некорректной и полностью очищается. База снова начинает открываться, но вся информация о штрихкодах товаров бесследно исчезает.
Рассмотрим сценарий, с которым столкнулся автор темы. На руках имеется поврежденная рабочая база 1С:Розница версии 2.2 (после ТИИ регистр штрихкодов пуст) и старый бэкап месячной давности на версии 2.1. Прямой перенос данных с помощью стандартной обработки ВыгрузкаЗагрузкаДанныхXML83 завершается ошибкой преобразования XDTO.
Выясним причину этой ошибки. Между релизами 2.1 и 2.2 разработчики 1С изменили структуру метаданных регистра сведений Штрихкоды (добавились новые измерения, изменились типы связей с характеристиками или упаковками). Поскольку XML-выгрузка жестко привязана к типам данных и схеме XDTO конкретной версии, при импорте файла из старой версии в новую парсер выдает ошибку несоответствия схем.
Разберем по шагам правильный алгоритм решения этой проблемы через выравнивание конфигураций:
ВыгрузкаЗагрузкаДанныхXML83. В списке объектов для выгрузки находим и отмечаем только регистр сведений Штрихкоды (или ШтрихкодыНоменклатуры). Формируем файл выгрузки.ВыгрузкаЗагрузкаДанныхXML83 на вкладке «Загрузка» и выбираем созданный XML-файл. Поскольку структуры баз теперь идентичны, загрузка пройдет быстро и без ошибок XDTO.Если разница между конфигурациями бэкапа и рабочей базы слишком велика или обновление архивной копии занимает много времени, мы можем написать простую обработку. Программный метод хорош тем, что мы можем перенести данные через простой текстовый формат, сопоставляя номенклатуру по её уникальному идентификатору (GUID), коду или артикулу, полностью игнорируя различия в структуре метаданных регистра.
Посмотрим на пример кода для выгрузки штрихкодов в базе-источнике (старом бэкапе):
// Выгрузка штрихкодов в текстовый файл с разделителями
ПутьКФайлу = "C:\temp\barcodes_export.txt";
ТекстЗаписи = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);
Выборка = РегистрыСведений.Штрихкоды.Выбрать();
Пока Выборка.Следующий() Цикл
// Получаем уникальный идентификатор номенклатуры-владельца
ИдентификаторНоменклатуры = Строка(Выборка.Владелец.УникальныйИдентификатор());
ТекущийШтрихкод = Выборка.Штрихкод;
// Записываем строку данных: GUID;Штрихкод
ТекстЗаписи.ЗаписатьСтроку(ИдентификаторНоменклатуры + ";" + ТекущийШтрихкод);
КонецЦикла;
ТекстЗаписи.Закрыть();
Предупреждение("Выгрузка успешно завершена!");
Теперь рассмотрим код для загрузки полученных данных в рабочую базу-приемник. Этот код считывает текстовый файл, находит номенклатуру по GUID и создает новые записи в регистре сведений:
// Загрузка штрихкодов из текстового файла
ПутьКФайлу = "C:\temp\barcodes_export.txt";
ТекстЧтения = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);
СтрокаДанных = ТекстЧтения.ПрочитатьСтроку();
Пока СтрокаДанных <> Неопределено Цикл
// Разделяем строку по точке с запятой
МассивЧастей = СтрРазделить(СтрокаДанных, ";");
Если МассивЧастей.Количество() >= 2 Тогда
GUIDСтрока = МассивЧастей[0];
ЗначениеШтрихкода = МассивЧастей[1];
Попытка
// Пытаемся получить ссылку на номенклатуру по GUID
СсылкаНоменклатуры = Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(GUIDСтрока));
// Проверяем, существует ли физически этот элемент в базе данных
Если СсылкаНоменклатуры.ПолучитьОбъект() <> Неопределено Тогда
// Создаем и записываем менеджер записи регистра
МенеджерЗаписи = РегистрыСведений.Штрихкоды.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Владелец = СсылкаНоменклатуры;
МенеджерЗаписи.Штрихкод = ЗначениеШтрихкода;
// Для Розницы 2.2+ может потребоваться заполнение типа штрихкода по умолчанию
МенеджерЗаписи.ТипШтрихкода = ПланыВидовХарактеристик.ТипыШтрихкодов.EAN13;
// Записываем с заменой дубликатов
МенеджерЗаписи.Записать(Истина);
КонецЕсли;
Исключение
// Обработка исключений при некорректном формате GUID
ЗаписьЖурналаРегистрации("ПереносШтрихкодов", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка обработки строки: " + СтрокаДанных);
КонецПопытки;
КонецЕсли;
СтрокаДанных = ТекстЧтения.ПрочитатьСтроку();
КонецЦикла;
ТекстЧтения.Закрыть();
Предупреждение("Загрузка штрихкодов выполнена!");
Если у вас нет навыков написания программного кода и вы не хотите заниматься обновлением старых копий баз, можно воспользоваться штатным функционалом платформы 1С. Для этого нам понадобятся две стандартные функции: Универсальный отчет и обработка Загрузка данных из табличного документа.
Разберем этот процесс по шагам:
Регистр сведений, имя таблицы: Штрихкоды.Владелец.Код (или Владелец.Артикул для точной идентификации номенклатуры) и Штрихкод.В регистр сведений и указываем наш регистр Штрихкоды (или ШтрихкодыНоменклатуры).Владелец указываем режим поиска «По коду» или «По артикулу» (в зависимости от того, какое поле мы выгружали). Для поля Штрихкод указываем сопоставление с текстовой колонкой штрихкода.Наиболее неприятный момент в ситуации автора темы — резервная копия имеет возраст один месяц. Это означает, что все новые штрихкоды, которые сотрудники склада и кассиры заводили в течение последних 30 дней, будут безвозвратно утеряны после восстановления из бэкапа или очистки регистра при ТИИ.
Однако существует продвинутый способ «вытащить» эти актуальные данные напрямую из поврежденного файла базы данных, пока вы еще не запустили процедуру автоматического исправления. Для этого специалисты используют бесплатную низкоуровневую утилиту Tool1CD, которая умеет напрямую читать таблицы формата .1CD в обход СУБД 1С.
Проанализируем алгоритм спасения свежих штрихкодов:
1Cv8.1CD в безопасное место. Ни в коем случае не проводите эксперименты на оригинальном рабочем файле._InfoRegXXXX (где XXXX — порядковый номер таблицы). Чтобы узнать точное имя таблицы в вашей конфигурации, откройте системную таблицу _Metadata внутри Tool1CD и найдите строчку, содержащую описание регистра Штрихкоды.chdbfl.exe и процедуру ТИИ на рабочей базе. Она очистит поврежденный регистр и вернет базу в полностью работоспособное состояние. После этого, используя стандартную обработку загрузки из DBF/CSV или написав простой код чтения внешнего файла, мы загружаем абсолютно все актуальные штрихкоды (включая созданные за последний месяц) обратно в чистую рабочую базу.Используя приведенные методы, вы всегда сможете гарантированно восстановить работоспособность торговой точки и защитить бизнес от потери критически важных операционных данных при сбоях файловой системы 1С.