Книга знаний

1С:Предприятие / v8 / Приемы программирования / Обмен данными, УРБД

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

Алгоритм синхронизации двух динамических таблиц (по текстовому полю) без использования вложенного циклаАвтор статьи:
Последняя редакция №1 от 28.03.06
URL: http://kb.mista.ru/article.php?id=129

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


В процессе обмена данными часто возникает вопрос синхронизации двух динамических таблиц по одному полю. Для небольших  объемов информации вполне подходит и простой перебор всех вариантов (двойной цикл, или рекурсия). Но для больших массивов (более 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;
           
           // Добавляем строку с ценой в результат
           НоваяСтрока = Результат.Добавить( );
           НоваяСтрока.Номенклатура = ЭлементВсеТовары.Номенклатура;
       ИначеЕсли СтрокаБольше(ЭлементДанныеФайла.Артикул, ЭлементВсеТовары.Артикул) Тогда
           // Двигаем товары
           ИндексВсеТовары = ИндексВсеТовары + 1;
       ИначеЕсли СтрокаБольше(ЭлементВсеТовары.Артикул, ЭлементДанныеФайла.Артикул) Тогда
           // Двигаем файлы
           ИндексДанныеФайла = ИндексДанныеФайла + 1;
       Иначе
           // если сюда попали, значит беда (сделано только для отладки условий)
           Сообщить("Ошибка алгоритма 2");
           Прервать;            
       КонецЕсли
       
   КонецЦикла;
КонецПроцедуры

Вот собственно и все.

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика