Имя: Пароль:
1C
1С v8
Как быстро загрузить данные из dbf-файла?
,
0 Азат
 
16.11.11
09:53
Размер файла = примерно 100 000 записей.
Штатный ХВАСЕ работает очень уж долго, а

Книга знаний: Пример работы с файлами DBF по интерфейсу ADO

выдает ошибку: "Произошла исключительная ситуация (JET Engine): Строка D:\BASE\738E~1\price.dbf задает ошибочный путь. Проверьте, что путь задан правильно"

Файл существует, штатным ХВАСЕ
1 Азат
 
16.11.11
09:53
+ (0) открывается и читается без проблем...
2 Wobland
 
16.11.11
09:53
много букв в пути?
3 Азат
 
16.11.11
09:55
путь нормализую с помощью fso+shortpath
4 ptiz
 
16.11.11
09:56
(0) Замер делал? Какая именно команда тормозит?
5 Азат
 
16.11.11
10:00
(4) замер не делал, подождал минуты полторы - был в районе первых 5000, после чего грохнул код.... считывал просто последовательно через Пока не дбф.вконце() цикл
6 vmv
 
16.11.11
10:08
мне удалось заюзать внешние источники для работы с dbf, все работает делаю к ним запросы и гружу как хочу.

есть два важных момента

1. в источниках одибиси нужно инсталировать драйвер визуал фокспро дбф, скачав с сайта мягких

2. Своим умом или через хбейс 1С создать индексный файл для дбф-файла.

Все, кидаешь строку подключения, указав папку с дбф-файлами и работаешь с ними, как с родными объектами 1С, показывая формы списков, элементов, выполняя запросы, загрузки и пр.
7 Mikeware
 
16.11.11
10:10
(6) ему индекс не нужен, он просто тупо перебирает в цикле. с индексом в этом случае будет даже медленнее...
8 ptiz
 
16.11.11
10:13
Проверил скорость Xbase на паре файлов:

Обработано 2 805 788 записей за 51 сек.
Обработано 1 528 693 записей за 31 сек.


Или быстрее надо?
9 vmv
 
16.11.11
10:17
(8) это обходы?

а если в каждой итерации, при получении записи нужно делать анализ состава ее свойств и уходить на "продолжить" или выполнять инициализаю свойств своего объекта, то невожномжность обработать записи без запроса - эта минус.

Другое дело получаешь запросом выборку записей дбф по своей логике группировки свойств и тулишь куда надо. хбейс это не умеет, увы.

но я согласен померяться производительностью обходов)
10 ptiz
 
16.11.11
10:18
(9) Ну он утверждает, что именно Xbase тормозит, в чем я очень сомневаюсь.
11 Нуф-Нуф
 
16.11.11
10:18
щас вроде 14 платформа умеет запросы к дбф делать
12 vmv
 
16.11.11
10:22
(10) наверно неправильно изложил проблему

кратко суть. Допустим у меня есть дбв "Клиенты", где по булевому признаку вид существует деление

Вид = 1, это юрлицо
Вид = 0, это физлицо.

Если мне нужно обновить у себя юрлиц, то через хбейс я вынужден делать обход всех записей, устанвливая в теле интерайии цикла
Если Вид = 0 Тогда
Продолжить;
КонецЦикла;

через внешние источники я просто выбираю запросом готовую выборку и не делаю холостых итераций
13 aka AMIGO
 
16.11.11
10:23
как часто приходится перекачивать? если разово - так пусть иксбэйс тормозит, Бог с ём..
14 НЕА123
 
16.11.11
10:27
(0)
>Штатный ХВАСЕ работает очень уж долго,
точно он?
15 НЕА123
 
16.11.11
10:29
(5)
понятно. не в XBASE дело.
16 vmv
 
16.11.11
10:30
(14) если в таблице дбв 100 полей "S(255)", то вероятно будет долго

ищем тестера обхода дбф через 1с для входных данных

2КК записей, со 100 стринговыми максимальными колонками без индексного файла)
17 Amiralnar
 
16.11.11
10:35
(12) я создам индекс по этому полю и обойду его за один проход, не считывая лишних записей.
18 ptiz
 
16.11.11
10:36
(16) Не влезет в 2 гб.
19 Valerik0101
 
16.11.11
10:41
150474 записи в дбф, 14 полей (строки и числа поровну) - загрузка в ТЗ занимает 66 секунд и отжирает примерно метров 200 памяти
(строки ограниченной длинны)
20 Азат
 
16.11.11
12:17
66 секунд - это оч долго...
21 Азат
 
16.11.11
12:24
(15) и в чем же дело, если не в ХВАСЕ?
22 Азат
 
16.11.11
13:03
Спецом для знатоков:

Код:

ДБФ = Новый XBase(Стр.ИмяФайла,, Истина);
Если НЕ ДБФ.Открыта() Тогда
   ДБФ.ОткрытьФайл(Стр.ИмяФайла);
КонецЕсли;
ДБФ.Первая();
Пока НЕ ДБФ.ВКонце() Цикл
   Если К % 1000 = 0 Тогда
   Сообщить("Записей " + К + " за " + ТекущаяДата());
   КонецЕсли;
   КодНом = ПолучитьУКонтрагента(Стр.Контрагент, "КодНом");
   НаимНом = ПолучитьУКонтрагента(Стр.Контрагент, "НаимНом");
   Производитель = ПолучитьУКонтрагента(Стр.Контрагент, "Производитель");
   Цена = ПолучитьУКонтрагента(Стр.Контрагент, "Цена");
   Колво = ПолучитьУКонтрагента(Стр.Контрагент, "Колво");
           
   Структура = Новый Структура("КодНом, НаимНом, Производитель, Цена,    Колво", КодНом, НаимНом, Производитель, Цена, Колво);
   Массив.Добавить(Структура);
               
   К = К + 1;
   ДБФ.Следующая();
КонецЦикла;
23 Азат
 
16.11.11
13:05
Вот примерный результат обработки:

Старт 16.11.2011 14:34:02
Записей 1 000 за 16.11.2011 14:35:22 //1 мин 20 сек
Записей 2 000 за 16.11.2011 14:36:42 //1 мин 20 сек
Записей 3 000 за 16.11.2011 14:38:02 //1 мин 20 сек
Записей 4 000 за 16.11.2011 14:39:21 //1 мин 20 сек
Записей 5 000 за 16.11.2011 14:40:41 //1 мин 20 сек
Записей 6 000 за 16.11.2011 14:42:01 //1 мин 20 сек
Записей 7 000 за 16.11.2011 14:43:21 //1 мин 20 сек
Записей 8 000 за 16.11.2011 14:44:41 //1 мин 20 сек
Записей 9 000 за 16.11.2011 14:46:19 //1 мин 18 сек
Записей 10 000 за 16.11.2011 14:47:43  //1 мин 24 сек
Записей 11 000 за 16.11.2011 14:49:07  //1 мин 24 сек
Записей 11 987 за 16.11.2011 14:50:27  //1 мин 20 сек
24 ptiz
 
16.11.11
13:06
Замер производительности сделай, что занимает больше всего времени?
25 Ахиллес
 
16.11.11
13:11
(22) А теперь так:

ДБФ = Новый XBase(Стр.ИмяФайла,, Истина);
Если НЕ ДБФ.Открыта() Тогда
   ДБФ.ОткрытьФайл(Стр.ИмяФайла);
КонецЕсли;
ДБФ.Первая();
Пока НЕ ДБФ.ВКонце() Цикл
   Если К % 1000 = 0 Тогда
   Сообщить("Записей " + К + " за " + ТекущаяДата());
   КонецЕсли;
   //КодНом = ПолучитьУКонтрагента(Стр.Контрагент, "КодНом");
   //НаимНом = ПолучитьУКонтрагента(Стр.Контрагент, "НаимНом");
   //Производитель = ПолучитьУКонтрагента(Стр.Контрагент, "Производитель");
   //Цена = ПолучитьУКонтрагента(Стр.Контрагент, "Цена");
   //Колво = ПолучитьУКонтрагента(Стр.Контрагент, "Колво");
           
   //Структура = Новый Структура("КодНом, НаимНом, Производитель, Цена,    Колво", КодНом, НаимНом, Производитель, Цена, Колво);
   //Массив.Добавить(Структура);
               
   К = К + 1;
   ДБФ.Следующая();
КонецЦикла;

И удивись :-)
26 Начинающий Программер
 
16.11.11
13:20
(22) А где тут обращение к значениям полей в ДБФ?
27 Buster007
 
16.11.11
13:24
(22) а что такое ПолучитьУКонтрагента()?
28 Buster007
 
16.11.11
13:25
+(27) неизвестная переменная еще Стр.Контрагент
29 Азат
 
16.11.11
13:32
(26) а, точна, спасиб, ваще туплю
30 rutony
 
16.11.11
13:37
Тоже в свое время была проблема скорости работы с дбф, все было решено оптимизацией кода, а именно в первую очередь:
- убиение ненужных сообщить/состояния, они очень просаживают производительность
- для градусников сделать отображение прогресса не для каждого элемента, а для кратного N
- так же очень просаживает производительность обращение через 3 точки к реквизитам, за это вообще по хорошему нужен расстрел

Судя по коду в (22) присутствует все самые тяжелые косяки оптимальности кода
31 Азат
 
16.11.11
13:52
(30) насчет сообщить / состояния - согласен, но сам терпеть не могу сидеть и пялиться в пустой экран, лучше уж пусть оно хоть какую-то ерунду пишет...
32 Ахиллес
 
16.11.11
14:36
(30) Тяжкое наследие клюшек? "Состояние" кстати на производительность практически не влияло там никак. А вот если окошко со служебными сообщениями расширить на 3/4 экрана и "сообщить" активно начать пользоваться... семёрка тогда подыхала и ползала, как таракан которого Дихлофосом потравили. И опять же, если окошко с сообщениями сжать до минимальной высоты, тогда и на "сообщить" тоже по фигу, ничего не отражалось на производительности.
33 acsent
 
16.11.11
14:39
(12) У хбэйс есть индексы