Заказы на доработку 1С (сервис удаленной работы)

Хранилище

База знаний
Неназначенных незавершенных заказов: 1
Бесплатные отчеты, обработки, конфигурации, внешние компоненты для 1С Статьи, описание работы, методики по работе с 1С

Здравствуйте, гость ( Вход | Зарегистрироваться )



> Загрузка прайса из Экселя , Оптимизация          
igmig65 Подменю пользователя
сообщение 23.05.12, 20:08
Сообщение #1

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 614
Из: Донецкая обл
Спасибо сказали: 168 раз
Рейтинг: 140.9

Есть обработка по загрузке прайсов. Но....В прайсе более 30 тыс. позиций. Работает очень медленно, так как приходится работать методом НайтиПоРеквизиту(). Конфигурация доработана. Есть реквизит КодДляЗагрузки, вот по нему и ищем. Если создается новый, то вводится и элемент и несколько подчиненных (ед.изм, цены, категории и т.д.), если находит, то нужно обновлять цену. Интересно можно ли как нибудь оптимизировать решение этой задачи. Может кто сталкивался с подобным. Ведь приходится при получении строки экселя каждый раз запускать поиск по реквизиту по всему справочнику. Интересно, если например сначала выгрузить всю номенклатуру в список значений с представлением - КодомДляЗагрузки, и потом например проверять методом Получить(). Если получит то Найти() иначе Новый(). Даст ли это что нибудь в плане оптимизации....Может кто посоветует что другое. Так как прайсы грузятся в день по нескольку раз, разные, в разные каталоги.

Ardi Подменю пользователя
сообщение 23.05.12, 20:13
Сообщение #2

Живет на форуме
***********
Гений телепатии и социального моделирования
Группа: Пользователи
Сообщений: 4121
Из: Киев
Спасибо сказали: 957 раз
Рейтинг: 0

Даст прирост раз в 50-100. Не больше.


Signature
Услуги 1С программиста 8.2, 7.7 (Плохо, дорого, очередь). Киев.

Спасибо сказали: igmig65,

igmig65 Подменю пользователя
сообщение 23.05.12, 20:19
Сообщение #3

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 614
Из: Донецкая обл
Спасибо сказали: 168 раз
Рейтинг: 140.9

Ну и то дело, а то по 2 часа грузятся

Ardi Подменю пользователя
сообщение 23.05.12, 20:26
Сообщение #4

Живет на форуме
***********
Гений телепатии и социального моделирования
Группа: Пользователи
Сообщений: 4121
Из: Киев
Спасибо сказали: 957 раз
Рейтинг: 0

LOL

А ещё таблицу эксель можно целиком грузить в ТЗ. Хотя это наверно в восьмёрке.

Сообщение отредактировал Ardi - 23.05.12, 20:34


Signature
Услуги 1С программиста 8.2, 7.7 (Плохо, дорого, очередь). Киев.

Домовик Подменю пользователя
сообщение 23.05.12, 20:47
Сообщение #5

Ветеран
Иконка группы
Группа: Местный
Сообщений: 975
Из: Киев
Спасибо сказали: 168 раз
Рейтинг: 0

Интересная идея. не знаю, оптимальнее ли будет. А если загрузить в список, а этот список использовать в условии в запросе?

Сообщение отредактировал Домовик - 23.05.12, 20:57

Ardi Подменю пользователя
сообщение 23.05.12, 20:57
Сообщение #6

Живет на форуме
***********
Гений телепатии и социального моделирования
Группа: Пользователи
Сообщений: 4121
Из: Киев
Спасибо сказали: 957 раз
Рейтинг: 0

А реквизит вообще индексируемый?


Signature
Услуги 1С программиста 8.2, 7.7 (Плохо, дорого, очередь). Киев.

Спасибо сказали: igmig65,

g789 Подменю пользователя
сообщение 24.05.12, 9:38
Сообщение #7

Говорящий
***
Группа: Пользователи
Сообщений: 62
Спасибо сказали: 14 раз
Рейтинг: 0

В качестве офтопа, если есть 1с++ то как-то так:
    Excel = СоздатьОбъект("Excel.Application"); 
    Excel.Displayalerts = 0;//отключить встроенные предупреждения Excel
    
    Excel.Workbooks.Open(СокрЛП(имяФайла));
    Excel.Worksheets(1).Activate();
    Excel.Range("B2").CurrentRegion.Select();//Выделить область
    tbl = Excel.ActiveCell.CurrentRegion;
    str = tbl.AddressLocal();
    str = "$" + СтрЗаменить(str,"$","");
    ListName = Excel.Worksheets(1).Name;
    стр = ListName + str;
    Excel.ActiveWindow.Close();

    Состояние("Считывание файла excel...");
    _база =СоздатьОбъект("ODBCDatabase");
    Если _база.Соединение("DRIVER=Microsoft Excel Driver (*.xls); DBQ=" +СокрЛП(имяФайла)) =0 Тогда
        Предупреждение("Ошибка открытия файла", 60);
        Возврат;
    КонецЕсли;
    _рс =СоздатьОбъект("ODBCRecordSet");
    _рс.УстБД(_база);
    ТекстЗапроса ="
    |select  *
    |from ["+стр+"]
    |";
    
    ит = _рс.ВыполнитьИнструкцию(ТекстЗапроса);

Спасибо сказали: Flexy, igmig65,

Ziam Подменю пользователя
сообщение 24.05.12, 10:16
Сообщение #8

Завсегдатай
Иконка группы
Группа: Местный
Сообщений: 234
Из: Харцызск
Спасибо сказали: 62 раз
Рейтинг: 0

Как вариант, читать файл в таблицу значений. А потом запросом выгребать из справочника инфу. Выиграете на сколько не знаю. Но обращение к базе будет одно, а не каждый раз. Как-то так

Спасибо сказали: igmig65,

igmig65 Подменю пользователя
сообщение 25.05.12, 8:13
Сообщение #9

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 614
Из: Донецкая обл
Спасибо сказали: 168 раз
Рейтинг: 140.9

Всем спасибо, со списком выиграл...но совсем немного. 1с++ неставил. Придется грузить только на серваке, там хоть машина серьезная, 4 ядра, в 4 раза быстрей грузит, чем на моей. Попробую еще сначала выгрузить в ТЗ, потом коды в список и запросом с условием по списку. Результат выложу.

dmiter Подменю пользователя
сообщение 25.05.12, 8:22
Сообщение #10

Завсегдатай
Иконка группы
Группа: Местный
Сообщений: 108
Из: Киев
Спасибо сказали: 16 раз
Рейтинг: 0

1. Файл в таблицу значений - сортировать по реквизиту (или можно отсортировать по реквизиту в Excel);
2. Справочник в таблицу значений - сортировать по реквизиту.
3. Проходим по строкам тз файла (или файлу), если реквизит 1-й строки тз справочника < реквизита файла тогда удаляем строку, если равна устанавливаем цену и удаляем строку с переходом на новую строку тз файла, иначе новый элемент.

При таком алгоритме проходов по справочнику и файлу будет m+n, при поиске элементов m*n.
m-количество строк в файле n - количество элементов справочника
Должно дать эффект.

Сообщение отредактировал dmiter - 25.05.12, 8:23

Спасибо сказали: igmig65,

g789 Подменю пользователя
сообщение 25.05.12, 9:10
Сообщение #11

Говорящий
***
Группа: Пользователи
Сообщений: 62
Спасибо сказали: 14 раз
Рейтинг: 0

igmig65
Можно так, без 1с++ (имяФайла - реквизит формы, тбл - ТаблицаЗначений на форме)
    Если ФС.СуществуетФайл(СокрЛП(имяФайла))=0 Тогда
        Возврат;
    КонецЕсли;
    тбл.Очистить();
    
    Excel = СоздатьОбъект("Excel.Application");
    Excel.Displayalerts = 0;//отключить встроенные предупреждения Excel
    
    Excel.Workbooks.Open(СокрЛП(имяФайла));
    Excel.Worksheets(1).Activate();
    Excel.Range("B2").CurrentRegion.Select();//Выделить область
    tbl = Excel.ActiveCell.CurrentRegion;
    str = tbl.AddressLocal();
    str = "$" + СтрЗаменить(str,"$","");
    ListName = Excel.Worksheets(1).Name;
    стр = ListName + str;
    Excel.ActiveWindow.Close();

    Состояние("Считывание файла excel...");

    СтрокаПодключения ="DRIVER=Microsoft Excel Driver (*.xls); DBQ=" +СокрЛП(имяФайла);

    ТекстЗапроса ="
    |select  *
    |from ["+стр+"]
    |";

    Connection = СоздатьОбъект("ADODB.Connection");
    // Подключение к источнику данных
    Попытка
        Connection.Open(СтрокаПодключения);
    Исключение
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    Command = СоздатьОбъект("ADODB.Command");
    Command.ActiveConnection = СтрокаПодключения;
    Command.CommandText = ТекстЗапроса;
    Command.CommandType = 1;
    // Создание объекта набора записей
    RecordSet = СоздатьОбъект("ADODB.RecordSet");
    // Выполнение и получение набора данных
    RecordSet.Open(Command);
    КоличествоПолей = RecordSet.Fields.Count;
    спИменаПолей = СоздатьОбъект("СписокЗначений");
    Для НомерКолонки = 0 По КоличествоПолей-1 Цикл
        ИмяПоля = RecordSet.Fields.Item(НомерКолонки).Name;
        спИменаПолей.ДобавитьЗначение(ИмяПоля);
        тбл.НоваяКолонка(ИмяПоля);
    КонецЦикла;

    // Перебор данных
    Пока RecordSet.EOF() = 0 Цикл
        тбл.НоваяСтрока();
        Для н=1 По КоличествоПолей Цикл
            тбл.УстановитьЗначение(тбл.НомерСтроки,н,RecordSet.Fields(н-1).Value);
        КонецЦикла;
        RecordSet.MoveNext();
    КонецЦикла;
    RecordSet.Close ();
    Connection.Close();

но так буде медленее, долго заполняется таблица

Спасибо сказали: igmig65,

igmig65 Подменю пользователя
сообщение 28.05.12, 9:40
Сообщение #12

Почти ветеран
Иконка группы
Группа: Местный
Сообщений: 614
Из: Донецкая обл
Спасибо сказали: 168 раз
Рейтинг: 140.9

Сделал: ч-з запрос выгружаю справочник в ТЗ и потом перебирая строки эксель использую ТЗ.НайтиЗначение(). Работает в 40 раз быстрее, единственное это выполнение самого запроса, так как позиций выгружается порядка 30 тыс. Но всеравно результат есть...ВСЕМ СПАСИБО.


Сообщение отредактировал igmig65 - 28.05.12, 9:40

Спасибо сказали: Домовик,

Не нашли ответа на свой вопрос?
Зарегистрируйтесь и задайте новый вопрос.


Ответить Новая тема
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

RSS Текстовая версия Сейчас: 01.11.24, 1:43
1С Предприятие 8.3, 1С Предприятие 8.2, 1С Предприятие 8.1, 1С Предприятие 8.0, 1С Предприятие 7.7, Литература 1С, Общие вопросы по администрированию 1С, Методическая поддержка 1С - всё в одном месте: на Украинском 1С форуме!