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


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

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

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

    // Запрос: все уникальные пары (Номенклатура, Характеристика) из регистра штрихкодов
    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ РАЗЛИЧНЫЕ
    |    Штрихкоды.Владелец КАК Номенклатура,
    |    Штрихкоды.Характеристика КАК Характеристика
    |ИЗ
    |    РегистрСведений.Штрихкоды КАК Штрихкоды
    |ГДЕ
    |    Штрихкоды.Штрихкод <> """"";

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

    Выборка = РезультатЗапроса.Выбрать();

    КоличествоХарактеристик = 0;
    КоличествоСEAN13 = 0;
    КоличествоБезEAN13 = 0;
    ВсегоУникальныхEAN13 = 0;
    КоличествоУжеСуществует = 0;
    КоличествоДобавленных = 0;

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

    Пока Выборка.Следующий() Цикл
        НоменклатураСсылка = Выборка.Номенклатура;
        ХарактеристикаСсылка = Выборка.Характеристика;

        КоличествоХарактеристик = КоличествоХарактеристик + 1;

        // Получаем все EAN13 → GTIN
        МассивGTIN = ПолучитьВсеGTINизEAN13(НоменклатураСсылка, ХарактеристикаСсылка);
        Если МассивGTIN.Количество() = 0 Тогда
            КоличествоБезEAN13 = КоличествоБезEAN13 + 1;
            Продолжить;
        КонецЕсли;

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

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

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

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

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

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

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

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

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

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

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

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

// ============================================================
// Функция возвращает МАССИВ всех GTIN из EAN13 (добавлением ведущего нуля)
// ============================================================
Функция ПолучитьВсеGTINизEAN13(НоменклатураСсылка, ХарактеристикаСсылка)

    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    |    Штрихкоды.Штрихкод КАК Штрихкод
    |ИЗ
    |    РегистрСведений.Штрихкоды КАК Штрихкоды
    |ГДЕ
    |    Штрихкоды.Владелец = &Номенклатура
    |    И Штрихкоды.Характеристика = &Характеристика
    |    И Штрихкоды.Штрихкод <> """"";

    Запрос.УстановитьПараметр("Номенклатура", НоменклатураСсылка);
    Запрос.УстановитьПараметр("Характеристика", ХарактеристикаСсылка);

    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
        Возврат Новый Массив;
    КонецЕсли;

    МассивGTIN = Новый Массив;
    Выборка = Результат.Выбрать();
    Пока Выборка.Следующий() Цикл
        Штрихкод = СокрЛП(Выборка.Штрихкод);
        // Только EAN13 (13 цифр)
        Если СтрДлина(Штрихкод) = 13 Тогда
            GTIN = "0" + Штрихкод;
            Если МассивGTIN.Найти(GTIN) = Неопределено Тогда
                МассивGTIN.Добавить(GTIN);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

    Возврат МассивGTIN;
КонецФункции

// ============================================================
// Проверка существования записи по GTIN в регистре "ОписаниеGTINИС"
// ============================================================
Функция НайтиЗаписьПоГТИН(GTIN)

    Запрос = Новый Запрос;
    Запрос.Текст = "
    |ВЫБРАТЬ
    |    ОписаниеGTINИС.GTIN
    |ИЗ
    |    РегистрСведений.ОписаниеGTINИС КАК ОписаниеGTINИС
    |ГДЕ
    |    ОписаниеGTINИС.GTIN = &GTIN";
    Запрос.УстановитьПараметр("GTIN", GTIN);
    Возврат НЕ Запрос.Выполнить().Пустой();

КонецФункции

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

// ============================================================
// Сохраняет плоский список добавляемых GTIN в CSV
// ============================================================
Процедура СохранитьСписокВCSV(СписокЗаписей)

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

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

// ============================================================
// Сохраняет отчёт по добавленным 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();

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