Загрузка данных


&НаСервере
Процедура СоздатьGTINs()

    ВыгрузитьРегистрВCSV();

    ТестовыйРежим = Истина;  // ← поменяйте на Ложь для реальной записи

    // 1. Один запрос, сразу отбираем только 13-значные (EAN13) через LIKE
    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    |    Штрихкоды.Владелец КАК Номенклатура,
    |    Штрихкоды.Характеристика КАК Характеристика,
    |    Штрихкоды.Штрихкод КАК Штрихкод
    |ИЗ
    |    РегистрСведений.Штрихкоды КАК Штрихкоды
    |ГДЕ
    |    Штрихкоды.Штрихкод <> """" 
    |    И Штрихкоды.Штрихкод LIKE '_____________'  // ровно 13 символов
    |";

    Состояние("Выполняется запрос к регистру штрихкодов...");
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
        Сообщить("Нет EAN13 штрихкодов.");
        Возврат;
    КонецЕсли;

    // 2. Группировка в памяти
    Состояние("Группировка данных...");
    Выборка = Результат.Выбрать();
    Группы = Новый Соответствие; // ключ: "Номенклатура|Характеристика", значение: структура с ссылками и массивом GTIN
    Пока Выборка.Следующий() Цикл
        Штрихкод = СокрЛП(Выборка.Штрихкод);
        GTIN = "0" + Штрихкод;

        НоменклатураСсылка = Выборка.Номенклатура;
        ХарактеристикаСсылка = Выборка.Характеристика;

        Ключ = Строка(НоменклатураСсылка) + "|" + Строка(ХарактеристикаСсылка);
        СтруктураГруппы = Группы.Получить(Ключ);
        Если СтруктураГруппы = Неопределено Тогда
            СтруктураГруппы = Новый Структура("Номенклатура, Характеристика, GTINМассив", НоменклатураСсылка, ХарактеристикаСсылка, Новый Массив);
            Группы.Вставить(Ключ, СтруктураГруппы);
        КонецЕсли;
        Массив = СтруктураГруппы.GTINМассив;
        Если Массив.Найти(GTIN) = Неопределено Тогда
            Массив.Добавить(GTIN);
        КонецЕсли;
    КонецЦикла;

    Если Группы.Количество() = 0 Тогда
        Сообщить("Нет групп с EAN13.");
        Возврат;
    КонецЕсли;

    // 3. Загружаем существующие GTIN из регистра ОписаниеGTINИС
    Состояние("Загрузка существующих GTIN...");
    ЗапросСущ = Новый Запрос;
    ЗапросСущ.Текст = "ВЫБРАТЬ ОписаниеGTINИС.GTIN ИЗ РегистрСведений.ОписаниеGTINИС КАК ОписаниеGTINИС";
    РезультатСущ = ЗапросСущ.Выполнить();
    СуществующиеGTIN = Новый Массив;
    Если РезультатСущ.Пустой() = Ложь Тогда
        ВыборкаСущ = РезультатСущ.Выбрать();
        Пока ВыборкаСущ.Следующий() Цикл
            СуществующиеGTIN.Добавить(ВыборкаСущ.GTIN);
        КонецЦикла;
    КонецЕсли;

    // 4. Подготовка статистики и коллекций
    КоличествоХарактеристик = 0;
    ВсегоУникальныхEAN13 = 0;
    КоличествоУжеСуществует = 0;
    КоличествоДобавленных = 0;

    НаборЗаписей = РегистрыСведений.ОписаниеGTINИС.СоздатьНаборЗаписей();
    СписокДобавляемых = Новый Массив;
    ОтчетныеЗаписи = Новый Массив;

    // 5. Основной цикл по группам с индикацией прогресса
    ВсегоГрупп = Группы.Количество();
    Обработано = 0;
    ШагПрогресса = 50; // обновляем состояние каждые 50 групп

    Состояние("Обработка групп (0 из " + ВсегоГрупп + ")...");
    Для каждого Элемент Из Группы Цикл
        Обработано = Обработано + 1;
        Если Обработано % ШагПрогресса = 0 Тогда
            Состояние("Обработано " + Обработано + " из " + ВсегоГрупп + " групп. Добавлено записей: " + КоличествоДобавленных);
        КонецЕсли;

        СтруктураГруппы = Элемент.Значение;
        НоменклатураСсылка = СтруктураГруппы.Номенклатура;
        ХарактеристикаСсылка = СтруктураГруппы.Характеристика;
        МассивGTIN = СтруктураГруппы.GTINМассив;

        КоличествоХарактеристик = КоличествоХарактеристик + 1;
        ВсегоУникальныхEAN13 = ВсегоУникальныхEAN13 + МассивGTIN.Количество();

        Для каждого GTIN Из МассивGTIN Цикл
            Если СуществующиеGTIN.Найти(GTIN) <> Неопределено Тогда
                КоличествоУжеСуществует = КоличествоУжеСуществует + 1;
                Продолжить;
            КонецЕсли;

            НоваяЗапись = НаборЗаписей.Добавить();
            НоваяЗапись.GTIN = GTIN;
            НоваяЗапись.ВидУпаковки = Перечисления.ВидыУпаковокИС.Потребительская;
            НоваяЗапись.КоличествоПотребительскихУпаковок = 1;

            КоличествоДобавленных = КоличествоДобавленных + 1;

            // Плоский список
            СтруктураЗаписи = Новый Структура;
            СтруктураЗаписи.Вставить("GTIN", GTIN);
            СтруктураЗаписи.Вставить("ВидУпаковки", Перечисления.ВидыУпаковокИС.Потребительская);
            СтруктураЗаписи.Вставить("КоличествоПотребительскихУпаковок", 1);
            СписокДобавляемых.Добавить(СтруктураЗаписи);

            // Отчёт по группам
            СтруктураОтчета = Новый Структура;
            СтруктураОтчета.Вставить("Номенклатура", НоменклатураСсылка.Наименование);
            СтруктураОтчета.Вставить("Характеристика", ?(ХарактеристикаСсылка.Пустая(), "Без характеристики", ХарактеристикаСсылка.Наименование));
            СтруктураОтчета.Вставить("GTIN", GTIN);
            ОтчетныеЗаписи.Добавить(СтруктураОтчета);
        КонецЦикла;
    КонецЦикла;

    Состояние("Сохранение отчётов...");

    // 6. Сохранение отчётов
    Если СписокДобавляемых.Количество() > 0 Тогда
        СохранитьСписокВCSV(СписокДобавляемых);
    КонецЕсли;

    Если ОтчетныеЗаписи.Количество() > 0 Тогда
        СохранитьОтчетПоДобавленным(ОтчетныеЗаписи);
    КонецЕсли;

    // 7. Запись или тест
    Если НаборЗаписей.Количество() > 0 Тогда
        Если ТестовыйРежим Тогда
            Сообщить("*** ТЕСТ: запись отключена. Будет добавлено записей: " + НаборЗаписей.Количество());
        Иначе
            НаборЗаписей.Записать();
            Сообщить("Данные записаны. Добавлено записей: " + НаборЗаписей.Количество());
        КонецЕсли;
    Иначе
        Сообщить("Нет новых записей для добавления.");
    КонецЕсли;

    Состояние(""); // сброс строки состояния

    // 8. Статистика
    Сообщить("========== СТАТИСТИКА ==========");
    Сообщить("Всего пар (Номенклатура + Характеристика) с EAN13: " + КоличествоХарактеристик);
    Сообщить("Всего уникальных EAN13 (преобразованных в GTIN): " + ВсегоУникальныхEAN13);
    Сообщить("Из них уже существовали в регистре: " + КоличествоУжеСуществует);
    Сообщить("Добавлено новых записей: " + КоличествоДобавленных);
    Сообщить("=================================");

    ЗаписьЖурналаРегистрации("Заполнение GTIN", УровеньЖурналаРегистрации.Информация,,
        "Тест: " + ?(ТестовыйРежим, "да", "нет") + " | Добавлено: " + КоличествоДобавленных);

КонецПроцедуры

// ============================================================
// Остальные функции (бэкап, сохранение списка, отчёта) остаются без изменений
// ============================================================
Процедура ВыгрузитьРегистрВCSV()
    ИмяФайла = "F:\ОписаниеGTINИС_бэкап_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".csv";
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ОписаниеGTINИС.GTIN, ОписаниеGTINИС.ВидУпаковки, ОписаниеGTINИС.КоличествоПотребительскихУпаковок ИЗ РегистрСведений.ОписаниеGTINИС КАК ОписаниеGTINИС";
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда 
        Сообщить("Регистр пуст."); 
        Возврат; 
    КонецЕсли;
    Выборка = Результат.Выбрать();
    ТекстCSV = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
    ТекстCSV.ЗаписатьСтроку("GTIN;ВидУпаковки;КоличествоУпаковок");
    Пока Выборка.Следующий() Цикл
        ТекстCSV.ЗаписатьСтроку(Выборка.GTIN + ";" + Строка(Выборка.ВидУпаковки) + ";" + Строка(Выборка.КоличествоПотребительскихУпаковок));
    КонецЦикла;
    ТекстCSV.Закрыть();
    Сообщить("Бэкап сохранён: " + ИмяФайла);
КонецПроцедуры

Процедура СохранитьСписокВCSV(СписокЗаписей)
    ИмяФайла = "F:\Добавляемые_GTIN_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".csv";
    ТекстCSV = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
    ТекстCSV.ЗаписатьСтроку("GTIN;ВидУпаковки;КоличествоУпаковок");
    Для каждого Запись Из СписокЗаписей Цикл
        ТекстCSV.ЗаписатьСтроку(Запись.GTIN + ";" + Строка(Запись.ВидУпаковки) + ";" + Строка(Запись.КоличествоПотребительскихУпаковок));
    КонецЦикла;
    ТекстCSV.Закрыть();
    Сообщить("Список добавляемых GTIN сохранён: " + ИмяФайла);
КонецПроцедуры

Процедура СохранитьОтчетПоДобавленным(ОтчетныеЗаписи)
    Если ОтчетныеЗаписи.Количество() = 0 Тогда
        Сообщить("Нет данных для отчёта.");
        Возврат;
    КонецЕсли;
    Группы = Новый Соответствие;
    Для каждого Запись Из ОтчетныеЗаписи Цикл
        Ключ = Запись.Номенклатура + "|" + Запись.Характеристика;
        МассивGTIN = Группы.Получить(Ключ);
        Если МассивGTIN = Неопределено Тогда
            МассивGTIN = Новый Массив;
            Группы.Вставить(Ключ, МассивGTIN);
        КонецЕсли;
        МассивGTIN.Добавить(Запись.GTIN);
    КонецЦикла;
    СтрокиДляCSV = Новый Массив;
    СтрокиДляCSV.Добавить("Номенклатура;Характеристика;Добавленные штрихкоды;Количество");
    Для каждого Элемент Из Группы Цикл
        Ключ = Элемент.Ключ;
        МассивGTIN = Элемент.Значение;
        Разделитель = Найти(Ключ, "|");
        Номенклатура = Лев(Ключ, Разделитель - 1);
        Характеристика = Сред(Ключ, Разделитель + 1);
        СписокШтрихкодов = "";
        Для каждого GTIN Из МассивGTIN Цикл
            Если СписокШтрихкодов = "" Тогда
                СписокШтрихкодов = GTIN;
            Иначе
                СписокШтрихкодов = СписокШтрихкодов + ", " + GTIN;
            КонецЕсли;
        КонецЦикла;
        Количество = МассивGTIN.Количество();
        Строка = Номенклатура + ";" + Характеристика + ";" + СписокШтрихкодов + ";" + Строка(Количество);
        СтрокиДляCSV.Добавить(Строка);
    КонецЦикла;
    ИмяФайла = "F:\Отчет_по_добавленным_GTIN_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".csv";
    ТекстCSV = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.ANSI);
    Для каждого Строка Из СтрокиДляCSV Цикл
        ТекстCSV.ЗаписатьСтроку(Строка);
    КонецЦикла;
    ТекстCSV.Закрыть();
    Сообщить("Отчёт по добавленным GTIN сохранён: " + ИмяФайла);
КонецПроцедуры

// ============================================================
&НаКлиенте
Процедура ВыполнитьНаКлиенте(Команда)
    СоздатьGTINs();
КонецПроцедуры