Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
26 мая 2024, 19:10

как сопоставить номенклатуру 2-ух разных баз или нечеткий поиск

Автор Св Ч, 03 янв 2019, 00:04

0 Пользователей и 1 гость просматривают эту тему.

Св Ч

Добрый День!
Задача сопоставить номенклатуру 2-ух разных баз (1-база по документам бухгалтерским, 2-ая база по фактическому товару склада, обе изначально заполняли справочник номенклатуры параллельно , в 1-ой базе - заполнял бухгалтер по документам контрагентов, во 2-базе заполнял кладовщик по физическому соответствию)
вот вроде бы накатала 2-ве функции, которые призваны сопоставить номенклатуру этих баз (в ручную сопоставлять некому, коды номенклатуры пока не ведутся, при сопоставлении в екселе сходится 20%, в бухгалтерской базе номенклатура на украинском в основном, в базе кладовщика на русском в основном).

Функция ФункцияПреобразованияНоменклатуры(Строка_Номенклатуры)
    RegExp = Новый COMОбъект("VBScript.RegExp");// создаем объект для работы с регулярными
    RegExp.MultiLine = ложь;  // истина — текст многострочный, ложь — одна строка
    RegExp.Global = Истина;     // истина — поиск по всей строке, ложь — до первого совпадения
    RegExp.IgnoreCase = Истина; // истина — игнорировать регистр строки при поиске
    Разделитель=" ";
    RegExp.Pattern = "[^\" + Разделитель + "]+";
    Matches = RegExp.Execute(Строка_Номенклатуры);

    ВидНоменкл="";
    Маркер="";
   
    НоменклатурныйЭлемент = Новый Структура;
    // пара ключ (имя переменной) - значение (произв. типа)
             
         //выделяем размер -параметры числовые     
    СтрокаЧисел = "";
         Для Индекс = 1 По СтрДлина(Строка_Номенклатуры) Цикл
            Символ = Сред((Строка_Номенклатуры), Индекс, 1); // Перебираем все сиволы из нашей строки
            Если ((КодСимвола(Символ) >= 42 И КодСимвола(Символ) <= 59) или   (КодСимвола(Символ)=92)или   (КодСимвола(Символ)=1093)или (КодСимвола(Символ)=32)) Тогда // Код нуля - 48, код 9-ки - 57
                Если (СтрДлина(СтрокаЧисел) = 0) и ((КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57)) тогда
                    СтрокаЧисел = СтрокаЧисел + Символ;
                иначеесли (СтрДлина(СтрокаЧисел)> 0)    тогда
                    СтрокаЧисел = СтрокаЧисел + Символ;
                конецесли;       
             КонецЕсли;
          КонецЦикла;
        kk= СтрДлина(СтрокаЧисел);
        Пока   kk >= 0 Цикл
           Символ = Сред((СтрокаЧисел), kk, 1); // Перебираем все сив
             если ((КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57)) тогда
                 прервать
             конецесли;
        kk = kk - 1;
       КонецЦикла;
       Если СтрДлина(СтрокаЧисел) > 0 Тогда
           
             НоменклатурныйЭлемент.Вставить("Размер", Лев(СокрЛП(СтрокаЧисел), kk));
          КонецЕсли;
        СтрокаЧисел = "";

         
       Для Сч = 0 По Matches.Count()-1 Цикл
         
           Если Сч=0 Тогда
                 
                   НоменклатурныйЭлемент.Вставить("Наименов_кор_руск",(Matches.Item(Сч).Value));

           Иначе
                 СтрокаМаркировки = "";   
                  СтрокаЧис  = "";
                  Символ2 =  "";
                  Индекс1 = 0;
                  Для Индекс1 = 1 По СтрДлина(Matches.Item(Сч).Value) Цикл
                      Символ2 = Сред((Matches.Item(Сч).Value), Индекс1, 1); // Перебираем все сиволы из нашей строки
                      Если      (КодСимвола(Символ2) >= 48 И КодСимвола(Символ2) <= 57) тогда      //не содержит цифр
                                  СтрокаЧис=  СтрокаЧис  + Символ2;

                      иначеЕсли      ((КодСимвола(Символ2) >= 65 И КодСимвола(Символ2) <= 90)      //англ рег
                             или   (КодСимвола(Символ2) >= 97 И КодСимвола(Символ2) <= 122)      //англ м
                             или   (КодСимвола(Символ2) >= 1040 И КодСимвола(Символ2) <= 1071)      //руск рег
                             ) тогда        //руск рег
                                 СтрокаМаркировки = СтрокаМаркировки  + Символ2;
                      конецесли;       
                     
                  КонецЦикла;//по символьный цикл разбора слова
                 
                  Если СтрДлина(СтрокаМаркировки) >= 1 Тогда
                              Маркер= Маркер+" "+СокрЛП(СтрЗаменить(Matches.Item(Сч).Value,НоменклатурныйЭлемент.Размер,""));
                  ИначеЕсли (СтрДлина(СтрокаЧис) = 0) и (СтрДлина(СтрокаМаркировки) = 0) Тогда
                        если   СтрДлина(СокрЛП(Matches.Item(Сч).Value)) >=1 тогда
                             ВидНоменкл=ВидНоменкл+" "+СокрЛП(СтрЗаменить(Matches.Item(Сч).Value,НоменклатурныйЭлемент.Размер,""));
                        конецесли;
                         
                  КонецЕсли;
               КонецЕсли;
         
                 
         
         
       КонецЦикла;
       
   
             НоменклатурныйЭлемент.Вставить("Вид_номенклатуры", СокрЛП(ВидНоменкл));
             НоменклатурныйЭлемент.Вставить("Маркеровка_производ",СокрЛП(Маркер));

   
    Возврат НоменклатурныйЭлемент;
КонецФункции

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

            Выборка0 = Запрос.Выполнить().Выбрать();
         если Выборка0.Количество()=0 тогда

     
     
           Номенклатура = ФункцияПреобразованияНоменклатуры(СокрЛП(ПолеВвода1));
         
           Сообщить("Наименов_кор_руск"+" "+Номенклатура.Наименов_кор_руск);
           Сообщить("Вид_номенклатуры"+" "+Номенклатура.Вид_номенклатуры);

           Сообщить("Маркеровка_производ"+" "+Номенклатура.Маркеровка_производ);

           Сообщить("Размер"+" "+Номенклатура.Размер);

            Запрос = Новый Запрос;                             
            Запрос.УстановитьПараметр("Наименов_кор_руск","%" + Номенклатура.Наименов_кор_руск+ "%");
            Запрос.УстановитьПараметр("Вид_номенклатуры","%" + Номенклатура.Вид_номенклатуры+ "%");
            Запрос.УстановитьПараметр("Маркеровка","%" + Номенклатура.Маркеровка_производ+ "%");
            Запрос.УстановитьПараметр("Размер","%" + Номенклатура.Размер+ "%");

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

            Выборка = Запрос.Выполнить().Выбрать();
         
            если Выборка.Количество()>0 тогда
                Пока Выборка.Следующий() Цикл
                    //сверяешь маркировку и размер среди найденных
                    Сообщить("родитель"+" "+Выборка.РодительНаименование);
                    Сообщить("наименование"+" "+Выборка.Наименование);
                КонецЦикла;
             конецесли;

         иначеесли Выборка0.Количество()>0 тогда
                Пока Выборка0.Следующий() Цикл
                    //сверяешь маркировку и размер среди найденных
                    Сообщить("родитель"+" "+Выборка0.РодительНаименование);
                    Сообщить("наименование"+" "+Выборка0.Наименование);
                КонецЦикла;
             конецесли;


вроде бы работает , правда в конвертации пока не тестировала.
Может у кого-то есть более оптимальные предложения?

но как вставить их в алгоритмы конвертации, как к ним обратиться и как задать параметры?
а главное, как выгрузить результат в событие "после загрузки"?



Сергей Соболев9

Добры вечер. Расскажу свой опыт (исходников к сожалению не сохранилось). Создавал обработку для того, чтобы номенклатура в двух базах была одинаковой. Для примера поиска использовал механизм поиска дублей (во многих конфигурациях он есть), им искал похожую номенклатуру и кидал её в таблицу соответствий, после в таблице отмечал какую номенклатуру исправлять, и запускал исправление. Всё делалось через COM-соединение.

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск