Вход | Регистрация

1С:Предприятие ::

Метки:

Ускорение обработки 2-х ТаблицЗначений

Я
   §
31.07.04 - 14:13
Суть обработки такая:
1 таблица - это остатки по регистру Остатки товара(артикул,цвет,размер - остаток)
2 таблица - это остатки по регистру Инвентаризация
(артикул,цвет,размер - остаток)

где-то по 3000 наименований (обрабатывает - около часа);
Можно ускорить в десятки раз (знаю как, но не знаю как сделать в 1с :))

обе таблицы в идеале должны быть идентичны, на самом деле 146 отличий.
См коментарии в процедуре

Процедура Выполнить()
    ЗаполнитьДанными();
    Для К = 1 по Остатки.КоличествоСтрок() Цикл
        Остатки.ПолучитьСтрокуПоНомеру(к);
        Артикул = Остатки.ПолучитьЗначение(к,"Артикул");
        Цвет = Остатки.ПолучитьЗначение(к,"Цвет");
        Размер = Остатки.ПолучитьЗначение(к,"Размер");
        Остаток = Остатки.ПолучитьЗначение(к,"Остаток");
        Код = Остатки.ПолучитьЗначение(к,"Код");
        КолСтрок = Инвентаризация.КоличествоСтрок();
        
        НенашелАрт = 1;
        НенашелЦв = 1;
        НенашелРазм = 1;
        N = 0;
        Для А = 1 по КолСтрок Цикл 
            Инвентаризация.ПолучитьСтрокуПоНомеру(А);  
            АртикулИнв = Инвентаризация.ПолучитьЗначение(А,"Артикул");
            ЦветИнв = Инвентаризация.ПолучитьЗначение(А,"Цвет");
            РазмерИнв = Инвентаризация.ПолучитьЗначение(А,"Размер");
            ОстатокИнв = Инвентаризация.ПолучитьЗначение(А,"Остаток");
            РознЦена = Инвентаризация.ПолучитьЗначение(А,"Цена");
            КодИнв = Инвентаризация.ПолучитьЗначение(А,"Код");
            Если Артикул <> АртикулИнв Тогда
                Продолжить;
                НенашелАрт = 0;    
            ИначеЕсли Цвет <> ЦветИнв Тогда
                Продолжить;
                НенашелЦв = 0;    
            ИначеЕсли Размер <> РазмерИнв Тогда
                Продолжить;
                НенашелРазм = 0;
            ИначеЕсли ОстатокИнв <> Остаток Тогда
                НенашелАрт = 0;
                НенашелЦв = 0;
                НенашелРазм = 0;
                    Спрв = СоздатьОбъект("Справочник.Товары");
                    Спрв.НайтиПоКоду(Код);
                    Справ = СоздатьОбъект("Справочник.Товары");
                    Справ.ИспользоватьДату(ПолучитьДатуТа());
                    Справ.ВыбратьЭлементы();
                    Пока Справ.ПолучитьЭлемент() = 1 Цикл
                        Если Справ.ТекущийЭлемент().ЭтоГруппа() = 1 Тогда
                            Продолжить;
                        КонецЕсли;
                        Если Справ.ТекущийЭлемент().ПринадлежитГруппе(Спрв.ТекущийЭлемент()) = 1 Тогда
                             РознЦена=Справ.Опт_Цена+Окр(Справ.Опт_Цена*ПроцентНДС(Справ.СтавкаНДС)/100,2);
                        КонецЕсли;
                    КонецЦикла;    
                АктСверки.НоваяСтрока();
                АктСверки.N = N+1;
                АктСверки.Артикул = Артикул;
                АктСверки.Цвет = Цвет;
                АктСверки.Размер = Размер;
                АктСверки.Цена = РознЦена;
                АктСверки.Остаток = Остаток;
                АктСверки.Факт = ОстатокИнв;
                АктСверки.Разница = ОстатокИнв - Остаток;
                АктСверки.СуммаРасч = РознЦена*Остаток;
                АктСверки.СуммаФакт = РознЦена*ОстатокИнв;
                АктСверки.СуммаРазн = РознЦена*ОстатокИнв-РознЦена*Остаток;
                АктСверки.Код = Код;
            Иначе 
// - Вот сдесь надо удалить эту строку (потому что эта строка идентична строке в первой таблице, чтобы он по ней не бегал еще 3000 раз.) Если написать Инвентаризация.Удалить строку() Тогда в следующем цикле он пишет Инвентаризация.ПолучитьСтрокупоНомеру(А)- Номер за пределами значения. В этом и вся проблема   


                НенашелАрт = 0;
                НенашелЦв = 0;
                НенашелРазм = 0;
                Продолжить;
            КонецЕсли;
        КонецЦикла;
        Если (НенашелАрт = 1) или (НенашелЦв = 1) или (НенашелРазм = 1) Тогда
                Спрв = СоздатьОбъект("Справочник.Товары");
                Спрв.НайтиПоКоду(Код);
                Справ = СоздатьОбъект("Справочник.Товары");
                Справ.ИспользоватьДату(ПолучитьДатуТа());
                Справ.ВыбратьЭлементы();
                Пока Справ.ПолучитьЭлемент() = 1 Цикл
                    Если Справ.ТекущийЭлемент().ЭтоГруппа() = 1 Тогда
                        Продолжить;
                    КонецЕсли;
                    Если Справ.ТекущийЭлемент().ПринадлежитГруппе(Спрв.ТекущийЭлемент()) = 1 Тогда
                         РознЦена=Справ.Опт_Цена+Окр(Справ.Опт_Цена*ПроцентНДС(Справ.СтавкаНДС)/100,2);
                    КонецЕсли;
                КонецЦикла;    
            АктСверки.НоваяСтрока();
            АктСверки.N = N+1;
            АктСверки.Артикул = Артикул;
            АктСверки.Цвет = Цвет;
            АктСверки.Размер = Размер;
            АктСверки.Цена = РознЦена;
            АктСверки.Остаток = Остаток;
            АктСверки.Факт = 0;
            АктСверки.Разница =-1*Остаток;
            АктСверки.СуммаРасч = РознЦена*Остаток;
            АктСверки.СуммаФакт = 0;
            АктСверки.СуммаРазн = -1*РознЦена*Остаток;
            АктСверки.Код = КодИнв;
        КонецЕсли;    
    КонецЦикла;
 
  Рекламное место пустует
   aka graham
 
1 - 31.07.04 - 14:44
А если попробовать сделать цикл "пока A<=тз.количествострок()", в случае удаления строки счетчик А остается прежним, если нет - увеличиваем на 1.
   Орк
 
2 - 31.07.04 - 20:08
А можно еще попытаться использовать сл. код :
Инвентаризация.ВыбратьСтроки();
Пока Инвентаризация.ПолучитьСтроку()=1 Цикл
    //Чо-хотим удалим

КонецЦикла;
   romix
 
3 - 31.07.04 - 20:09
Две таблицы надо слить в одну.
Остатки - количество со знаком плюс, инвентаризация - с минусом.
Свернуть (делается почти мгновенно) по графам "Товар", "Количество".
Останутся только различия.
   Guk
 
4 - 31.07.04 - 20:11
(0) А нельзя не вываливать весь код, а локализовать проблему?
Волшебнику: Ну и как это называется?...
   romix
 
5 - 31.07.04 - 20:31
(+3) Слияние таблиц тоже можно сделать быстро -
1) изменением (увеличением) числа строк у первой таблицы
2) копированием второй таблицы в первую в диапазоне строк.

(4) Остатки ему надо сравнить с инвентаризацией. Правильно что вывалил весь код. :-) Правильное решение - строк 20 :-) и работает мгновенно.
   427
 
6 - 31.07.04 - 21:05
первое. Убрать ПолучитьЗначение. Напрямую обращаться к полям...

Второе - послать в .опу реализованный алгоритм...

а сделать -
Выгрузка Остатков из запроса в ТЗ
добавить колонку ОстатокИнвентаризации (и нужные - какие понадобятся... но правильно добавить надо, чтобы при свертке не проколоться)...

добавить в эту ТЗ строки из Инвентаризации, при этом Остаток по Инвентаризации пишется в свою колонку, остальные колонки - теже, что и в запросе Товар/Артикул, цвет, размер, етс. Колонка Остаток - при добавлении строк из инвентаризации - остается нулевой

Затем свернуть ТЗ по
Товар, цвет, размер с суммированием по Остаток и ОстатокИнтентаризации...

В полученной тз - каждая комбинация представлена только 1 строкой...
Товар, размер, цвет - и есть две колонки Остаток и ОстатокПоИнвентаризации

ОДИН раз бежишь по полученной ТЗ и просматриваешь строки, сравнивая колонки
Остаток и ОстатокПоИнвентаризации

в зависимости от условий несколько действий в операторе
Если (Остаток - ОстатокИнвнтаризации)= 0

иначеесли (Остаток - ОстатокИнвнтаризации)> 0

иначеесли (Остаток - ОстатокИнвнтаризации)< 0


Никаких поисков. Никаких сравнений... Полетит....
   427
 
7 - 31.07.04 - 21:09
Во.... пока через pcAny.... с клиента базу сливал, уже все ответили....


Список тем форума
Рекламное место пустует   Рекламное место пустует
Читай всё полезное и впитывай, а нападки игнорируй. Здесь так принято. aka AMIGO
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Ветка сдана в архив. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует