Как найти задвоенные единицы измерения номенклатуры в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При подготовке базы 1С 7.7 к миграции данных на платформу 1С 8 (например, с использованием правил Конвертации Данных) разработчики часто сталкиваются с ошибками загрузки. Одной из частых причин является наличие у одного элемента справочника Номенклатура нескольких подчиненных единиц измерения из справочника Единицы с одинаковым кодом ОКЕИ или одинаковым наименованием.

Рассмотрим несколько способов поиска таких дубликатов встроенными средствами языка 1С 7.7 и с помощью прямых SQL-запросов.

Способ 1. Использование Таблицы Значений и метода Свернуть()

Разберем самый понятный и надежный способ для файловых баз (DBF). Алгоритм заключается в последовательном обходе справочника Номенклатура, сборе всех связанных единиц измерения в объект ТаблицаЗначений и последующем сворачивании таблицы по названию единицы и ссылке на владельца.

Проанализируем пример кода обработки:


ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Номенклатура", "Справочник.Номенклатура");
ТЗ.НоваяКолонка("Единица", "Строка", 20);
ТЗ.НоваяКолонка("Количество", "Число", 15, 0);

Спр = СоздатьОбъект("Справочник.Номенклатура");
СпрЕдиницы = СоздатьОбъект("Справочник.Единицы");

Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент() = 1 Цикл
    Если Спр.ЭтоГруппа() = 1 Тогда
        Продолжить;
    КонецЕсли;
    
    СпрЕдиницы.ИспользоватьВладельца(Спр.ТекущийЭлемент());
    СпрЕдиницы.ВыбратьЭлементы();
    Пока СпрЕдиницы.ПолучитьЭлемент() = 1 Цикл
        ТЗ.НоваяСтрока();
        ТЗ.Номенклатура = Спр.ТекущийЭлемент();
        ТЗ.Единица = СокрЛП(СпрЕдиницы.Наименование);
        ТЗ.Количество = 1;
    КонецЦикла;    
КонецЦикла;

// Сворачиваем таблицу: если одинаковых единиц у одной номенклатуры несколько, 
// колонка Количество просуммируется
ТЗ.Свернуть("Номенклатура, Единица", "Количество");

ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку() = 1 Цикл
    Если ТЗ.Количество > 1 Тогда
        Сообщить("Найден дубль единицы (" + ТЗ.Единица + ") у позици: " + ТЗ.Номенклатура);
    КонецЕсли;
КонецЦикла;

Способ 2. Оптимизированный сплошной перебор подчиненного справочника

Рассмотрим вариант оптимизации обхода для крупных баз данных. В платформе 1С 7.7 при вызове метода ВыбратьЭлементы() для подчиненного справочника Единицы без предварительной установки ИспользоватьВладельца() выполняются сплошная выборка всех единиц базы данных. Из текущего элемента справочника единиц доступна ссылка на родительскую номенклатуру через системный реквизит Владелец.

Этот способ позволяет избежать лишних повторных перевыборок в цикле и существенно ускоряет работу в файловом режиме.

Способ 3. Прямой SQL-запрос для клиент-серверного режима

Если база данных работает под управлением MS SQL Server (или используются внешние компоненты прямых запросов, такие как 1CPP), выясним ситуацию с помощью группирующего SQL-запроса. Запрос связывает таблицы номенклатуры и единиц по полю связи ParentExt и находит позиции, у которых общее количество единиц не совпадает со количеством уникальных кодов ОКЕИ.

Рассмотрим структуру SQL-запроса:


SELECT 
    спрНоменклатура.id [Номенклатура $Справочник.Номенклатура],
    COUNT(спрЕдиницы.ОКЕИ) [ВсегоЕдиниц],
    COUNT(DISTINCT спрЕдиницы.ОКЕИ) [УникальныхОКЕИ]
FROM Справочник.Номенклатура спрНоменклатура
INNER JOIN Справочник.Единицы спрЕдиницы 
    ON спрНоменклатура.id = спрЕдиницы.ParentExt
GROUP BY спрНоменклатура.id
HAVING COUNT(спрЕдиницы.ОКЕИ) <> COUNT(DISTINCT спрЕдиницы.ОКЕИ)

Что делать с найденными дублями перед выгрузкой в 1С 8?

Посмотрим на порядок действий после получения списка проблемных позиций:

  1. Проверим исправление ссылочной целостности: перед физическим удалением дублирующей единицы выполним стандартный поиск ссылок с помощью функции НайтиСсылки(), чтобы убедиться, что дубль не используется в проведенных документах.
  2. Перепроведем или перенаправим документы на «основную» единицу измерения, после чего пометим дубликат на удаление.
  3. В правилах конвертации данных (КД 2.0) настроим поля поиска подчиненного справочника так, чтобы сопоставление выполнялось не только по коду/наименованию, но и с учетом уникального идентификатора (GUID) или ссылки владельца.
← На главную