С переходом ЕГАИС на поштучный учет перед разработчиками на платформе 1С 7.7 встала серьезная задача: как эффективно хранить огромные массивы данных об акцизных марках. Каждая марка представляет собой уникальную строку длиной до 150 символов (с учетом криптохвоста), а количество таких записей в базе розничного магазина может исчисляться сотнями тысяч и миллионами. Стандартные механизмы "семерки" не всегда справляются с такими объемами из-за ограничений на длину индексируемых полей и размер файлов DBF.
В этой статье мы подробно разберем, как спроектировать архитектуру хранения марок, обойти системные ограничения и обеспечить высокую скорость поиска данных.
Первое, что мы должны сделать — это определить место хранения в структуре метаданных. Использование регистров в 1С 7.7 для этих целей нецелесообразно, так как регистры предназначены для накопления итогов, а марка — это уникальный идентификатор, требующий только фиксации наличия (статуса). Рассмотрим наиболее логичную структуру подчинения:
Справки2.Такая трехуровневая иерархия позволяет нам быстро ограничивать выборку марок при работе с конкретной накладной или партией товара, не перебирая весь массив данных. Однако здесь мы сталкиваемся с ограничением: длина наименования в 1С 7.7 не может превышать 100 символов, а марка имеет длину 150 символов.
Проанализируем ситуацию: нам нужно не просто хранить марку, но и искать по ней. Рассмотрим два способа решения проблемы длины:
Способ А: Использование дополнительного реквизита. Мы создаем текстовый реквизит КодМарки с длиной 150 символов. В наименовании при этом можно хранить только часть марки (например, первые 14-20 символов, которые визуально идентифицируют серию и номер для пользователя). Основной поиск будет вестись по реквизиту.
Способ Б: Хак с представлением. Существует "хитрый" способ: если установить длину наименования справочника в 0, а первым реквизитом создать строку нужной длины, то система будет использовать этот реквизит в качестве представления. Однако этот метод может привести к нестабильной работе некоторых стандартных функций, поэтому использовать его следует с осторожностью.
Если мы установим у реквизита КодМарки (150 символов) признак "Сортировка", база данных DBF начнет стремительно расти, так как индексы для таких длинных строк занимают много места. Более того, поиск по длинным строкам работает медленнее.
Разберем алгоритм оптимизации через хеширование:
Марки числовой или короткий строковый реквизит ХешМарки.ХешМарки. Так как хеш короткий, индекс работает мгновенно.Когда количество марок переваливает за миллион, файлы .dbf или таблицы SQL начинают тормозить всю систему. Рассмотрим продвинутый вариант — использование внешней библиотеки 1SQLite.dll. Это позволит хранить марки в сверхбыстрой базе данных прямо "в памяти" или в отдельном файле, не нагружая основную базу 1С.
Проанализируем пример кода для поиска марки с помощью SQLite без установки признака "Сортировка" в конфигураторе:
Функция НайтиМаркуSqlLite(ШК) Экспорт
Перем Запрос, Тз, ИскМарка;
Попытка
БазаДанных = СоздатьОбъект("SQLiteBase");
Исключение
ЗагрузитьВнешнююКомпоненту("1sqlite.dll");
БазаДанных = СоздатьОбъект("SQLiteBase");
КонецПопытки;
// Открываем базу в памяти для максимальной скорости
БазаДанных.Открыть(":memory:");
Запрос = БазаДанных.НовыйЗапрос();
// Создаем виртуальную таблицу, связанную со справочником 1С
Запрос.ВыполнитьЗапрос("create virtual table Марки using dbeng(Справочник.Марки)");
ТекстЗапроса = "
|SELECT
| id [Марка :Справочник.Марки]
|FROM Марки
|WHERE КодМарки LIKE '%" + СокрЛП(ШК) + "%'
|AND ismark <> '*'";
Попытка
Тз = Запрос.ВыполнитьЗапрос(ТекстЗапроса);
Исключение
Сообщить(ОписаниеОшибки());
Возврат 0;
КонецПопытки;
Если Тз.КоличествоСтрок() > 0 Тогда
ИскМарка = Тз.ПолучитьЗначение(1, "Марка");
Возврат ИскМарка;
Иначе
Возврат 0;
КонецЕсли;
КонецФункции
Этот подход позволяет эффективно искать марки даже по их фрагментам (например, если сканер считал код не полностью), при этом не создавая лишних индексов в самой 1С.
Выясним, почему недостаточно хранить только часть марки. В новых форматах акцизных марок первые 14 символов (серия и номер) могут повторяться в разных партиях или у разных производителей в теории, а уникальность гарантируется именно криптохвостом. Если ваша система будет проверять только начало кода, вы рискуете столкнуться с проблемой "дублей" при продаже, что в системе ЕГАИС карается серьезными штрафами.
Рекомендации по обслуживанию базы:
Статус (Принята, Продана, Списана). Это исключит повторную продажу одной и той же бутылки.Проверена (тип Число 0/1). При сканировании алкоголя на складе во время приемки устанавливайте 1. Это позволит сразу выявить пересортицу еще до того, как товар попадет на полки.Таким образом, для платформы 1С 7.7 оптимальным решением является сочетание иерархического справочника с использованием внешних средств поиска (SQLite) или механизмов хеширования. Это гарантирует стабильную работу программы даже при значительных объемах алкогольной продукции.