Автоматизация бизнеса

Установка, настройка, внедрение и сопровождение любых конфигураций на платформе 1С:Предприятие. 

e-mail: info@programmist1c.ru

Минимальный объем работ от 50 000 рублей
  •   Удаленный админ
  •   Карта сайта
  •   Контакты


  • Поиск
     

    v8: Алгоритм синхронизации двух таблиц (по текстовому полю)

    Алгоритм синхронизации двух динамических таблиц (по текстовому полю) без использования вложенного цикла
    Автор статьи: vde69 | Редакторы: Гений 1С, Волшебник
    Последняя редакция №6 от 10.01.07 |


    Ключевые слова: синхронизация, динамических, таблиц, алгоритм


    В процессе обмена данными часто возникает вопрос синхронизации двух динамических таблиц по одному полю. Для небольших  объемов информации вполне подходит и простой перебор всех вариантов (двойной цикл, или рекурсия). Но для больших массивов (более 10 000 элементов) это становиться очень медленно. Предлагаю использовать другой алгоритм, основанный на одном цикле, в моем случае это дало ускорение в х800!!!

    Для начала рассмотрим общий принцип:

    1.    Надо получить две таблицы (в моем случае ДанныеФайла и ВсеТовары), процесс получения таблиц здесь не рассматривается
    2.    Предварительная обработка строк индекса, приведение к одному регистру, удаление пробелов, другое форматирование, это здесь тоже не рассматривается
    3.    Сортировка таблиц по индексу
    4.    Параллельная обработка двух таблиц

    Теперь собственно пример:

    // сравнивает по символьно строки, возвращает истина если 
    // Строка1 больше чем Строка2
    Функция СтрокаБольше(Строка1, Строка2)
        Результат = Ложь;
        
        Длина = Макс(СтрДлина(Строка1),СтрДлина(Строка2));
        Для Индекс = 1 По Длина Цикл
            Если Индекс > СтрДлина(Строка2)Тогда
                // если дошли до сюда, значит строка1 длинее строки2
                Результат = Истина;
                Прервать;
            ИначеЕсли Индекс > СтрДлина(Строка1)Тогда
                // ну а в этом случае короче, а значит меньше
                Результат = Ложь;
                Прервать;
            КонецЕсли;
            
            // сравнение по коду символа не работает, поэтому сравниваем по символьно
            // символ можно получать и по другому, 
    // но этот вариант у меня работает быстрее
    
            Код1 = Символ(КодСимвола(Строка1, Индекс));
            Код2 = Символ(КодСимвола(Строка2, Индекс));
            Если Код1 < Код2 Тогда
                // все, дальше можно не смотреть, попался больший символ
                Результат = Ложь;
                Прервать;
            ИначеЕсли Код1 > Код2 Тогда
                // все, дальше можно не смотреть, попался меньший символ
                Результат = Истина;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Возврат Результат;
    КонецФункции
    
    
    
    Процедура Выполнить()
        
        ВсеТовары.Сортировать  ("Артикул Возр");
        ДанныеФайла.Сортировать("Артикул Возр");
    
                 
        Результат = Новый ТаблицаЗначений;
        Результат.Колонки.Добавить( "Номенклатура", Справочники.Номенклатура);
    
        ИндексВсеТовары = 0;       // это указатели на текущую позицию
        ИндексДанныеФайла = 0;
        
        Пока Истина Цикл // а вот и главный цикл
            ОбработкаПрерыванияПользователя( );
            Попытка    
                ЭлементВсеТовары = ВсеТовары[ИндексВсеТовары];
                ЭлементДанныеФайла = ДанныеФайла[ИндексДанныеФайла];
            Исключение
                // обработка закончена, это выход из цикла
                Прервать;
            КонецПопытки;
            
            Если ЭлементВсеТовары.Артикул = ЭлементДанныеФайла.Артикул тогда
                ИндексВсеТовары = ИндексВсеТовары + 1;
                ИндексДанныеФайла = ИндексДанныеФайла + 1;
                
                // Добавляем строку с ценой в результат
                НоваяСтрока = Результат.Добавить( );
                НоваяСтрока.Номенклатура = ЭлементВсеТовары.Номенклатура;
            ИначеЕсли СтрокаБольше(ЭлементДанныеФайла.Артикул, ЭлементВсеТовары.Артикул) Тогда
                // Двигаем товары
                ИндексВсеТовары = ИндексВсеТовары + 1;
            ИначеЕсли СтрокаБольше(ЭлементВсеТовары.Артикул, ЭлементДанныеФайла.Артикул) Тогда
                // Двигаем файлы
                ИндексДанныеФайла = ИндексДанныеФайла + 1;
            Иначе
                // если сюда попали, значит беда (сделано только для отладки условий)
                Сообщить("Ошибка алгоритма 2");
                Прервать;            
            КонецЕсли
            
        КонецЦикла;
    КонецПроцедуры
    


    Вот собственно и все.
    21.02.18 | 10:31


    30.11.16 | 20:25


    28.11.16 | 09:22


    26.11.16 | 08:19


    22.11.16 | 20:17


    19.11.16 | 10:14


    18.11.16 | 20:09




    Внедрение 1С Автоматизация 1С Доработка 1С Сопровождение 1С Обслуживание 1С Программирование 1С 8 Hастройка 1С Карта сайта Контакты