Имя: Пароль:
1C
1С v8
Экспорт из dbf файла в справочник
0 fredrf
 
19.04.12
11:52
Всем привет! (к 8 мой мозг еще не привык и ее почти знает)
В общем история такая, делаю  экспорт записей из файла(записей тыщ 16), пишу обработку на 8.0, процесс занимает секунд 20.
то же самое на 8.2 , уходит МИНУТ 5-7...Вот код 8.2

Процедура Кнопка2Нажатие(Элемент)
   
Диалог =Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
   Диалог.Заголовок = "Выберите файл базы данных";
   Диалог.ПолноеИмяФайла = "";
   Фильтр = "DBF (*.dbf)|*.dbf";
   Диалог.Фильтр = Фильтр;
   Диалог.МножественныйВыбор = Ложь;
   Диалог.Каталог = "С:\";

   Если Диалог.Выбрать() Тогда    
   
       НовыйЭл(Диалог.ПолноеИмяФайла);    //  <---- вот вызываю функцию импорта
           
   КонецЕсли;

   
КонецПроцедуры


&НаСервере  
Функция НовыйЭл(ИмяБД)
           
   Спр    =    Справочники.Прописка;
       
   ДБФ=Новый Xbase();    
   ДБФ.ОткрытьФайл(ИмяБД);    
   ДБФ.Кодировка = КодировкаXBase.OEM;
   всего=ДБФ.КоличествоЗаписей();
   
   ДБФ.Первая();    
   
   Пока ДБФ.ВКонце()=0 Цикл
       
       Эл    =    спр.СоздатьЭлемент();
       
       Эл.Фамилия        =  ДБФ.FIO;
       Эл.Имя            =  ДБФ.NAME;
       Эл.отчество        =  ДБФ.OTCH;
       Эл.ДатаРождения    =  ДБФ.ROD;
       Эл.Дата1        =  ДБФ.PROPIS;
       Эл.Дата2        =  ДБФ.WYP_DAT;
       Эл.ЛицевойКод    =  ДБФ.LIC;
       Эл.ОтНан        =  ДБФ.OTNAN;
       Эл.Улица        =  ДБФ.AD_UL;
       Эл.Дом            =  ДБФ.AD_DOM;
       Эл.Квартира        =  ДБФ.AD_KV;
       
       Эл.Записать();
       
       ном=ДБФ.НомерЗаписи();
       ДБФ.Следующая();

   КонецЦикла;

       ДБФ.ЗакрытьФайл();

   
   КонецФункции
1 aleks-id
 
19.04.12
11:53
иксбейс - зло! юзай запросы
2 Wobland
 
19.04.12
11:53
вводишь путь на клиенте и отдаёшь его (клиентский путь) на сервер? хм
3 fredrf
 
19.04.12
11:55
"водишь путь на клиенте и отдаёшь его (клиентский путь) на сервер? хм", ну да, это то ни как не влияет
4 fredrf
 
19.04.12
11:56
"иксбейс - зло! юзай запросы" - на 8.0 код аналогичный, только в общей процедуре, и выполнение 20 секунд
5 Wobland
 
19.04.12
11:58
(4) ну поюзай запросы, ну что тебе, жалко что-ли? ;)
6 Wobland
 
19.04.12
11:58
(3) вот откуда сервер знает, что у меня в c:\temp лежит? или я чего-то не допонимаю?
7 fredrf
 
19.04.12
12:02
думаю не допонимаешь, переменной путь файла передал, она и работает с ним...столько времени то уходит на ЗАПИСЬ В СПРАВОЧНИКЕ, а не на выборку из базы
8 fredrf
 
19.04.12
12:03
запись в справочник
9 vmv
 
19.04.12
12:05
(0) если на 8.2. то можно через внешние источники, подключить нужный драйвер одибиси что-та вроде майкрософт фоккспро и видишь струкруктуры дбф - грузишь тупо запросом, правда к дбф нужно создать индексный файл.

как-то делал для больших таблиц, код дома
10 Heckfy
 
19.04.12
12:06
А если вместо
Пока ДБФ.ВКонце()=0 Цикл
попробовать
Пока ДБФ.Следующая()=Истина Цикл

?
11 Нуф-Нуф
 
19.04.12
12:06
щас вроде есть такая фигня как внешние источники данных. попробуй заюзать их.
12 fredrf
 
19.04.12
12:07
Heckfy , разницы нет
13 acsent
 
19.04.12
12:08
подписки? передзаписью?
14 vmv
 
19.04.12
12:08
(10)

Пока ДБФ.Следующая() Цикл

вообще при работе с дбф используют

Пока Истина Цикл

// выход по еоф
КонецЦикла
15 Wobland
 
19.04.12
12:09
коллеги, всё-таки. прихожу я на сервер со строкой "c:\temp\none.dbf". как сервер из такого файла будет данные брать?
16 Heckfy
 
19.04.12
12:10
(14) Монописуально. :)
17 fredrf
 
19.04.12
12:10
vmv и  Нуф-Нуф, на счет внешних источников, дело говорите, но вот уж хочеться с данным кодом ПРАВИЛЬНО разобраться
18 fredrf
 
19.04.12
12:11
Wobland импорт записей проходит хорошо, все правильно, просто ДОЛГО,
19 fredrf
 
19.04.12
12:11
Пока ДБФ.Следующая() Цикл --- щас так попробую
20 fredrf
 
19.04.12
12:12
думаю разницы нет
21 Wobland
 
19.04.12
12:12
(18) да я не спорю, я для себя выясняю другой вопрос ;)
22 vmv
 
19.04.12
12:12
(15) если метод серверный, то путь к файлу рассматривается как серверный. в смысле как брать - открыл дбф и читаешь записи
23 kotletka
 
19.04.12
12:12
считывает скорее всего нормально, тупит на создании и сохранении справочника, посмотри там присоздании что навешано и при записи
24 Wobland
 
19.04.12
12:13
(22) то есть сервер полезет на свой c:\temp?
25 fredrf
 
19.04.12
12:14
kotletka думаю правильно говришь, надо глянуть
26 Wobland
 
19.04.12
12:17
+(23) а неплохо было бы смотреть, что уже в справочнике есть
27 fredrf
 
19.04.12
12:19
как справочник показать, скрин?
28 Wobland
 
19.04.12
12:19
(27) скрины тут выкладываются вовне и даётся ссылка
29 Wobland
 
19.04.12
12:20
(28) хотя, одна девушка во исполнение традиции (неправильно ею понятой) выложила скрин ошибки в ЛК
30 fredrf
 
19.04.12
12:21
ссылку выложу, вот код переделал, ну это просто что бы прогресс был виден... и для Wobland, путь на клиент

&НаКлиенте
Процедура Кнопка2Нажатие(Элемент)
   
   Диалог =Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
   Диалог.Заголовок = "Выберите файл базы данных";
   Диалог.ПолноеИмяФайла = "";
   Фильтр = "DBF (*.dbf)|*.dbf";
   Диалог.Фильтр = Фильтр;
   Диалог.МножественныйВыбор = Ложь;
   Диалог.Каталог = "С:\";

   Если Диалог.Выбрать() Тогда    
       
   ДБФ=Новый Xbase();    
   ДБФ.ОткрытьФайл(Диалог.ПолноеИмяФайла);    
   ДБФ.Кодировка = КодировкаXBase.OEM;
   всего=ДБФ.КоличествоЗаписей();
   
   Удаление();
   
   ДБФ.Первая();    
   
   Пока ДБФ.Следующая()=1 Цикл

   
       Нов= Новый структура("П1,П2,П3,П4,П5,П6,П7,П8,П9,П10,П11");
               
       Нов.П1            =    ДБФ.FIO;
       Нов.П2            =    ДБФ.NAME;
       Нов.П3            =    ДБФ.OTCH;
       Нов.П4            =    ДБФ.ROD;
       Нов.П5            =    ДБФ.PROPIS;
       Нов.П6            =    ДБФ.WYP_DAT;
       Нов.П7            =    ДБФ.LIC;
       Нов.П8            =    ДБФ.OTNAN;
       Нов.П9            =    ДБФ.AD_UL;
       Нов.П10            =    ДБФ.AD_DOM;
       Нов.П11            =    ДБФ.AD_KV;
       
       ном=ДБФ.НомерЗаписи();
       этаформа.Реквизит4=окр(ном/всего*100);
       этаформа.ОбновитьОтображениеДанных();
       НовыйЭл(Нов)
       
       
   КонецЦикла;
   
   ДБФ.ЗакрытьФайл();
   
   КонецЕсли;

   
КонецПроцедуры


&НаСервере  
Функция НовыйЭл(Нов)
           
   Спр    =    Справочники.Прописка;
   Эл    =    спр.СоздатьЭлемент();
       
       Эл.Фамилия        =  Нов.П1;
       Эл.Имя            =  Нов.П2;
       Эл.отчество        =  Нов.П3;
       Эл.ДатаРождения    =  Нов.П4;
       Эл.Дата1        =  Нов.П5;
       Эл.Дата2        =  Нов.П6;
       Эл.ЛицевойКод    =  Нов.П7;
       Эл.ОтНан        =  Нов.П8;
       Эл.Улица        =  Нов.П9;
       Эл.Дом            =  Нов.П10;
       Эл.Квартира        =  Нов.П11;

       
   Эл.Записать();
   
   
   КонецФункции
31 fredrf
 
19.04.12
12:22
по времени тож самое выходит
32 Wobland
 
19.04.12
12:24
(31) а попробуй сравнить время без строчки НовыйЭл(Нов)
33 fredrf
 
19.04.12
12:25
"а попробуй сравнить время без строчки НовыйЭл(Нов)" --без нее махом, в этом случае он не создает элементы справочника
34 Heckfy
 
19.04.12
12:25
(31) Замер производительности что говорит? Где узкое место?
35 Wobland
 
19.04.12
12:26
(33) ну вот тебе и ответ. корень зла в создании и записи элемента справочника
36 fredrf
 
19.04.12
12:27
"Замер производительности что говорит? Где узкое место?"  - не смотрел ,  это при добавлении элементов
37 fredrf
 
19.04.12
12:27
Wobland, да ты прав, как решить эту проблему вот вопрос
38 fredrf
 
19.04.12
12:28
где то галочки тут вешаются на запись?
39 Wobland
 
19.04.12
12:28
(37) замер тебе покажет все долгие места
40 vmv
 
19.04.12
12:29
я бы так оптимизировал цикл, ибо

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

   ДБФ.Первая();    
   
   Пока Истина Цикл
       
       СтруктураСвойств.Очистить();
       
       СтруктураСвойств.Вставить("Фамилия"     , ДБФ.FIO);
       СтруктураСвойств.Вставить("Имя"         , ДБФ.NAME);
       СтруктураСвойств.Вставить("отчество"    , ДБФ.OTCH);
       СтруктураСвойств.Вставить("ДатаРождения", ДБФ.ROD);
       СтруктураСвойств.Вставить("Дата1"       , ДБФ.PROPIS);
       СтруктураСвойств.Вставить("Дата2"       , ДБФ.WYP_DAT);
       СтруктураСвойств.Вставить("ЛицевойКод"  , ДБФ.LIC );
       СтруктураСвойств.Вставить("ОтНан"       , ДБФ.OTNAN);
       СтруктураСвойств.Вставить("Улица"       , ДБФ.AD_UL);
       СтруктураСвойств.Вставить("Дом"         , ДБФ.AD_DOM);
       СтруктураСвойств.Вставить("Квартира"    , ДБФ.AD_KV);
       
       Эл = спр.СоздатьЭлемент();
       ЗаполнитьЗначенияСвойств(Эл, СтруктураСвойств);
       Эл.Записать();
       
       Если Не ДБФ.Следующая() Тогда
           Прервать;
       КонецЕсли;
       
   КонецЦикла;
41 fredrf
 
19.04.12
12:32
vmv, repeat напомнил, тока вот это из за записи
42 fredrf
 
19.04.12
12:39
"нафига какждый раз читать элемент " делал по другому же первый код, разницы нет
43 fredrf
 
19.04.12
12:45
http://www.fayloobmennik.net/1803559, там 31 тыща записей
44 fredrf
 
19.04.12
12:48
и такой же код на 8.0 делает то же самое секуннд за 20
45 vmv
 
19.04.12
12:49
(42) да великоват справочник - переходи на чистый оракл, там по фик такие объемы)

эээ и файлик с обенника грохай - за разглашение персональных данных 3 года в хате, если за разглашенные подадут в суд
46 Heckfy
 
19.04.12
12:50
(44) Конфы то разные. Смотри что отрабатывает в ПередЗаписью() и ПриЗаписи()
47 fredrf
 
19.04.12
12:50
я ж фамилии убрал))
48 fredrf
 
19.04.12
13:21
В общем код, когда один вызов функции, минуты за две выполняется, один фиг медленнее, всем в общем спасибо, я делал так , потому что хотел отображать прогресс операции, как с этим кодом это сделать?

&НаКлиенте
Процедура Кнопка2Нажатие(Элемент)
   
   Диалог =Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
   Диалог.Заголовок = "Выберите файл базы данных";
   Диалог.ПолноеИмяФайла = "";
   Фильтр = "DBF (*.dbf)|*.dbf";
   Диалог.Фильтр = Фильтр;
   Диалог.МножественныйВыбор = Ложь;
   Диалог.Каталог = "С:\";

   Если Диалог.Выбрать() Тогда    
       Удаление();
       НовыйЭл(Диалог.ПолноеИмяФайла);        
   КонецЕсли;

   
КонецПроцедуры


&НаСервере  
Функция НовыйЭл(имя)
   
   
   Спр    =    Справочники.Прописка;

   ДБФ=Новый Xbase();    
   ДБФ.ОткрытьФайл(имя);    
   ДБФ.Кодировка = КодировкаXBase.OEM;
   всего=ДБФ.КоличествоЗаписей();
 
   ДБФ.Первая();    
   
   Пока ДБФ.Следующая()=1 Цикл

   Эл    =    спр.СоздатьЭлемент();
       
       Эл.Фамилия        =  ДБФ.FIO;
       Эл.Имя            =  ДБФ.NAME;
       Эл.отчество        =  ДБФ.OTCH;
       Эл.ДатаРождения    =  ДБФ.ROD;
       Эл.Дата1        =  ДБФ.PROPIS;
       Эл.Дата2        =  ДБФ.WYP_DAT;
       Эл.ЛицевойКод    =  ДБФ.LIC;
       Эл.ОтНан        =  ДБФ.OTNAN;
       Эл.Улица        =  ДБФ.AD_UL;
       Эл.Дом            =  ДБФ.AD_DOM;
       Эл.Квартира        =  ДБФ.AD_KV;
       
   
   Эл.Записать();
   КонецЦикла;

       ДБФ.ЗакрытьФайл();
       
   КонецФункции
49 fredrf
 
19.04.12
13:22
просто есть дбф файлы по гигабайту, видеть хочеться сколько еще ждать))
50 Wobland
 
19.04.12
13:24
(48) а то, что время на отображение прогресса тратится будет, ты не задумывался? Сообщить() в цикле, к примеру, весьма неплохо добавляет времени к обработке
51 fredrf
 
19.04.12
13:25
Wobland, без сообщить бы хотелось
52 Wobland
 
19.04.12
13:25
(49) как-то порционно можно обновлять. как вон ВыгрузкаЗагрузкаДанныхXML работает - в состояние по сотне говорит
53 fredrf
 
19.04.12
13:25
54 Wobland
 
19.04.12
13:25
ну и Индикаторы никто ещё не отменял
55 fredrf
 
19.04.12
13:26
это про нынешние замеры производительности
56 Wobland
 
19.04.12
13:26
(53) я не хочу картинки качать ;)
57 fredrf
 
19.04.12
13:27
"ну и Индикаторы никто ещё не отменял", вот то что надо, как передать значение на клиент, щас вся обработка на сервере же идет
58 Wobland
 
19.04.12
13:29
(57) тут извини, готового у меня нет, а ты производишь впечатление человека, способного сомостоятельно с этим справиться.

сервер возвращает количество обработанных, клиент смотрит на него и в нужный момент что-нибудь рисует на форме. как-то так, наверное
59 Heckfy
 
19.04.12
13:30
(57) Запили еще функцию, куда передавай кол. обработанных и общее количество. А в ней уже индикатор двигай. Как то так.....
60 fredrf
 
19.04.12
13:33
всем спасибо !!! каша в голове вроде прозрачней стала, может даже съедобней))
61 fredrf
 
19.04.12
13:35
код конечно простой, просто привыкнуть пока не могу к "НаСервереНаКлиенте"
62 fredrf
 
19.04.12
14:54
вот прогресс выполнения из сервера в клиент, может кто улучшение предложит)



&НаКлиенте
Процедура Кнопка2Нажатие(Элемент)
   
   Диалог =Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
   Диалог.Заголовок = "Выберите файл базы данных";
   Диалог.ПолноеИмяФайла = "";
   Фильтр = "DBF (*.dbf)|*.dbf";
   Диалог.Фильтр = Фильтр;
   Диалог.МножественныйВыбор = Ложь;
   Диалог.Каталог = "С:\";

   Если Диалог.Выбрать() Тогда    
       Удаление();
       Этаформа.Реквизит2="Удалено!";
       Этаформа.ОбновитьОтображениеДанных();
       тек=1;
       Пока НовыйЭл(Диалог.ПолноеИмяФайла, тек)=1 Цикл
           Этаформа.ОбновитьОтображениеДанных();
            тек=тек+1000;
       КонецЦикла;
       
   КонецЕсли;
         
               
КонецПроцедуры


&НаСервере  
Функция НовыйЭл(имя, тек)
   
   Спр    =    Справочники.Прописка;

   ДБФ=Новый Xbase();    
   ДБФ.ОткрытьФайл(имя);    
   ДБФ.Кодировка = КодировкаXBase.OEM;
   всего=ДБФ.КоличествоЗаписей();
 
   ДБФ.Перейти(тек);    
   ном=0;
   Пока ДБФ.Следующая()=1 Цикл

   Эл    =    спр.СоздатьЭлемент();
       
       Эл.Фамилия        =  ДБФ.FIO;
       Эл.Имя            =  ДБФ.NAME;
       Эл.отчество        =  ДБФ.OTCH;
       Эл.ДатаРождения    =  ДБФ.ROD;
       Эл.Дата1        =  ДБФ.PROPIS;
       Эл.Дата2        =  ДБФ.WYP_DAT;
       Эл.ЛицевойКод    =  ДБФ.LIC;
       Эл.ОтНан        =  ДБФ.OTNAN;
       Эл.Улица        =  ДБФ.AD_UL;
       Эл.Дом            =  ДБФ.AD_DOM;
       Эл.Квартира        =  ДБФ.AD_KV;
       
       ном=ном+1;
       Этаформа.Реквизит4=окр((ном+тек)/всего*100);
       Эл.Записать();
       
       Если ном=1000 тогда возврат 1; КонецЕсли;
   КонецЦикла;

       ДБФ.ЗакрытьФайл();
       
       
   КонецФункции
63 fredrf
 
19.04.12
14:56
с сервера просто нельзя обновлять форму
64 Heckfy
 
19.04.12
14:59
Этаформа.Реквизит4=окр((ном+тек)/всего*100);

Если ном=1000 тогда возврат 1; КонецЕсли;
   КонецЦикла;

Замени на

Если ном%1000=0 тогда
ФункцияОбновленияФормы(ном);
КонецЕсли;
   КонецЦикла;

И сделай ФункцияОбновленияФормы(ном) отдельно. Как то так.....
65 Wobland
 
19.04.12
14:59
(62) почти не глядел. контроль уникальности элементов справочника прикрутил?
66 Heckfy
 
19.04.12
15:00
+ (64) и Всего еще можно в функцию передать.
67 fredrf
 
20.04.12
06:28
"ном%1000=0" это аналог "ном div 1000=0"?
68 fredrf
 
20.04.12
06:29
"ном mod 1000=0" то есть так
69 Wobland
 
20.04.12
06:29
(67) % остаток от деления. див вроде отсутствует в 1С. только так: Цел(а/б)
70 fredrf
 
20.04.12
06:30
понятно
71 fredrf
 
20.04.12
06:57
"Если ном%1000=0 тогда
ФункцияОбновленияФормы(ном);
КонецЕсли;"

я бы что то вроде этого и сделал, но не получаецца на сервере клиентскую функцию вызвать, разве как то можно ?
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.