При интеграции 1С 7.7 с маркетплейсами (Wildberries, Ozon и др.) разработчики часто сталкиваются с ограничением платформы: невозможно установить признак уникальности на реквизит табличной части документа. Поскольку идентификатор заказа (ID) маркетплейса обычно хранится именно в строках документа «Резерв» или «Счет», возникает риск дублирования данных при ручном копировании документов или ошибках в алгоритмах обмена. Рассмотрим подробнее, как обойти это ограничение и настроить надежный контроль.
В отличие от справочников, где реквизит можно сделать индексируемым (флаг «Сортировка») и контролировать его уникальность, табличные части документов в 1С 7.7 хранятся в общей таблице DT*, где индексы строятся только по системным полям (ID документа, номер строки). Прямая попытка СУБД проконтролировать уникальность значения в строке невозможна средствами конфигуратора. Разберем основные стратегии решения этой задачи.
Этот метод является наиболее «простым» и не требует изменения структуры базы данных. Мы перехватываем момент проведения документа и анализируем все существующие записи в базе. Проанализируем алгоритм:
ОбработкаПроведения создаем объект «Запрос» или используем выгрузку табличных частей.Пример кода для реализации такой проверки:
Процедура ОбработкаПроведения()
// Создаем таблицу значений для текущих строк
ТЗ_Текущие = СоздатьОбъект("ТаблицаЗначений");
ВыгрузитьТабличнуюЧасть(ТЗ_Текущие, "ID_Заказа");
// Удаляем пустые ID, если они допустимы
ТЗ_Текущие.ВыбратьСтроки();
Пока ТЗ_Текущие.ПолучитьСтроку() = 1 Цикл
Если ПустаяСтрока(ТЗ_Текущие.ID_Заказа) = 1 Тогда
ТЗ_Текущие.УдалитьСтроку();
КонецЕсли;
КонецЦикла;
// Для ускорения поиска можно использовать Запрос или Графу отбора
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|Период с ДобавитьМесяц(РабочаяДата(), -1) по РабочаяДата();
|ИдЗаказа = Документ.Резерв.ID_Заказа;
|ТекДок = Документ.Резерв.ТекущийДокумент;
|Группировка ИдЗаказа;
|Группировка ТекДок;
|Условие(ТекДок <> ТекущийДокумент());
|";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
Если ТЗ_Текущие.НайтиЗначение(Запрос.ИдЗаказа, , "ID_Заказа") > 0 Тогда
Запрос.Группировка(2);
Сообщить("Заказ " + Запрос.ИдЗаказа + " уже зарезервирован в документе " + Запрос.ТекДок);
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Чтобы избежать медленного перебора всех документов при каждой проверке, можно создать справочник ИндексыЗаказов. Выясним причину эффективности этого метода: поиск по справочнику в 1С 7.7 работает значительно быстрее благодаря штатным индексам.
Логика работы:
ИндексыЗаказов, где Наименование — это ID заказа маркетплейса.Если элемент с таким ID уже существует, 1С выдаст ошибку или мы сами обработаем это через НайтиПоНаименованию(). Это гарантирует уникальность даже в случае параллельной работы нескольких менеджеров.
Рассмотрим подробнее использование механизма «Графа отбора». Если включить реквизит табличной части в графу отбора, система создаст запись в таблице 1SCRDOC. Это фактически создает индекс, связывающий значение реквизита с документом.
Посмотрим на пример поиска через графу отбора:
Функция ПроверитьУникальностьПоГрафе(ЗначениеID)
ДокПоиска = СоздатьОбъект("Документ");
// Используем выборку по графе отбора
ДокПоиска.ВыбратьПоЗначению(, , "ГрафаIDЗаказа", ЗначениеID);
Пока ДокПоиска.ПолучитьДокумент() = 1 Цикл
Если ДокПоиска.ТекущийДокумент() <> ТекущийДокумент() Тогда
Возврат 0; // Нашли дубль в другом документе
КонецЕсли;
КонецЦикла;
Возврат 1;
КонецФункции
Если ваша база работает на MS SQL Server и вы используете внешнюю компоненту 1С++, это самый производительный способ. Мы можем выполнить прямой запрос к таблице DT* (строки документов), минуя объектную модель 1С. Выясним, как это выглядит на практике:
ТекстЗапроса = "
|SELECT TOP 1
| ParentID as [Док $Документ]
|FROM
| $ДокументСтроки.Резерв
|WHERE
| $ДокументСтроки.Резерв.ID_Заказа = :НужныйID
| AND ParentID <> :ТекущийДок
|";
// Выполнение через ODBCRecordset даст ответ за миллисекунды
Проанализируем ситуацию с человеческим фактором. Часто дубли возникают из-за того, что менеджеры «перекидывают» заказы между складами вручную. Чтобы минимизировать ошибки, рекомендуется:
ВводНаОсновании или проверку в ПриКопировании, чтобы очищать поле ID или выдавать предупреждение.Подведем итог: наиболее надежным и быстрым методом для 1С 7.7 является сочетание вспомогательного справочника (для жесткого контроля уникальности) и проверки в ОбработкеПроведения. Это позволит сохранить целостность данных при обмене с Wildberries и защитит базу от дублирования резервов.