Имя: Пароль:
1C
 
Выгрузка из DBF в Таблицу Значений без перебора записей.
0 FreeFin
 
23.10.06
11:32
Уверен, что должна существовать, в виде драйвера, методики или программного кода, кто встречал?
1 VasilyKushnir
 
23.10.06
11:43
Мож я че не допонял, но по-моему на самом низком уровне любая выгрузка в ТЗ идет не массивом, а отдельными записями. Т.е. перебор записей все-равно наличествует, но где-то очень глубоко запрятан. Другое дело, если не устраивает 1С и реализовать это,  к примеру в ВК на с++.
2 FreeFin
 
23.10.06
11:53
(1) ИМХО, не прав, ТЗ=двухмерный массив, ведь Загрузить и Выгрузить работают без перебора.
Реализовать ессно можно, но зач "велосипед" изобретать?...если он, конечно, есть.
3 SnarkHunter
 
23.10.06
11:56
(2)Ты смотрел сорцы, которые реализуют методы Загрузить и Выгрузить, и это позволяет тебе утверждать, что они работают без перебора?
4 Эльниньо
 
23.10.06
12:06
(2) ТЗ=двухмерный массив ???
Многомерный, однако
5 FreeFin
 
23.10.06
12:07
(3) Не утверждаю, а предполагаю, сырцов не видел (а кто их видел?). И вопрос не в этом. Ведь может тот же Exel или Access "втянуть" в себя dbf-ы, преобразовывая их конверторами в приемлемое время?=могут. И это где-то на уровне "переразметки" а не "построчного считывания". А 1Сина "прожевывает" большой dbf ну неприлично долго. В этом проблема.
6 FreeFin
 
23.10.06
12:09
(4) Тогда вноси исправления в:
http://www.mista.ru/tutor_1c/tz.htm
если не согласен с определением.
Извините, но не о том хотелось бы...
7 КонецЦикла
 
23.10.06
12:09
Даже метод НайтиЗначение() работает по ходу перебором
Напиши запрос может быть
8 Барбариска
 
23.10.06
12:15
"1Сина "прожевывает" большой dbf ну неприлично долго" - каким именно методом?
Если стандартный XBase - действительно неприлично долго
Если приделать Ado.Connection и SQL- запросы - то все летает, хотя и там перебор придется делать.
9 smaharbA
 
23.10.06
12:42
К примеру, но это колекция, а не ТЗ...
...
//*******************************************
Процедура Сформировать()
   Перем Назв;
   Перем Тип;
   Перем Длин;
   Перем Точн;
   Перем Заг;
   ДБФ=СоздатьОбъект("XBase");
   ДБФ.ОткрытьФайл("C:\Temp\Skazy\DH1582.DBF");
   Заг="";
   Для к = 1 По ДБФ.КоличествоПолей()-1 Цикл
       ДБФ.ОписаниеПоля(к, Назв, Тип, Длин, Точн);
       Заг=Заг+"([\s\S\w\W\b\B\t\d\D\n]{"+Длин+"})";
   КонецЦикла;
   ДБФ.ОписаниеПоля(ДБФ.КоличествоПолей(), Назв, Тип, Длин, Точн);
   Заг=Заг+"([\s\S\w\W\b\B\t\d\D\n]{"+(Длин+1)+"})";
   ФСО=СоздатьОбъект("Scripting.FileSystemObject");
   Ширина=32*ДБФ.КоличествоПолей()+32+1;
   ДБФ.ЗакрытьФайл();
   Файл=ФСО.OpenTextFile("C:\Temp\Skazy\DH1582.DBF");
   Сообщить(Ширина);
   Файл.Skip(Ширина);
   Стр=Файл.ReadAll();
   Регуляр=СоздатьОбъект("VBScript.RegExp");
   Регуляр.IgnoreCase=-1;
   Регуляр.Global=-1;
   Регуляр.Pattern=Заг;
   Результат=Регуляр.Execute(Стр);
   Сообщить(Результат.count);
   Для к=0 По Результат.count-1 Цикл
       Стр="";
       Для л=0 По Результат.item(к).SubMatches.count-1 Цикл
           Стр=Стр+Результат.item(к).SubMatches.item(л)+";"
       КонецЦикла;
       Сообщить(Стр);
   КонецЦикла;
КонецПроцедуры
10 smaharbA
 
23.10.06
12:43
+ можна еще ускорить...
11 smaharbA
 
23.10.06
13:10
Я тут можна сказать нещадя живота своего, а они даж и не плюнули...
12 asady
 
23.10.06
13:19
(11) кто не плюнул тот молча скопипастил :)

Надо быть снисходительнее - время прохождения данного сигнала может быть очень продолжительным - особенно для тупых одноэснегов.
13 SnarkHunter
 
23.10.06
13:20
Тьху... :-))
14 smaharbA
 
23.10.06
13:27
(12)
(13) во ... эт уже лучче... а то какие вы нафих мистяне :)
15 FreeFin
 
23.10.06
14:03
(10) Спасиб, что в тему
(типа плюну ))), но на (или сразу после):

Стр=Файл.ReadAll();

//одинэсина "помирает" (вылет без сообщений), пытаясь вгрузить в память файлик размером всего 1,5 мб (((
16 smaharbA
 
23.10.06
14:24
(15) вот тут-то и нада "ускорить" -

//*******************************************
Процедура Сформировать()
   Перем Назв;
   Перем Тип;
   Перем Длин;
   Перем Точн;
   Перем Заг;
   ДБФ=СоздатьОбъект("XBase");
   ДБФ.ОткрытьФайл("C:\Temp\Skazy\DH1582.DBF");
   Заг="";
   Для к = 1 По ДБФ.КоличествоПолей()-1 Цикл
       ДБФ.ОписаниеПоля(к, Назв, Тип, Длин, Точн);
       Заг=Заг+"([\s\S\w\W\b\B\t\d\D\n]{"+Длин+"})";
   КонецЦикла;
   ДБФ.ОписаниеПоля(ДБФ.КоличествоПолей(), Назв, Тип, Длин, Точн);
   Заг=Заг+"([\s\S\w\W\b\B\t\d\D\n]{"+(Длин+1)+"})";
   ФСО=СоздатьОбъект("Scripting.FileSystemObject");
   Стрим=СоздатьОбъект("ADODB.Stream");
   Ширина=32*ДБФ.КоличествоПолей()+32+1;
   ДБФ.ЗакрытьФайл();
   Стрим.type=2;
   Стрим.charset="windows-1251";
   Стрим.Open();
   Стрим.LoadFromFile("C:\Temp\Skazy\DH1582.DBF");
   Стрим.position=Ширина+1;
   Регуляр=СоздатьОбъект("VBScript.RegExp");
   Регуляр.IgnoreCase=-1;
   Регуляр.Global=-1;
   Регуляр.Pattern=Заг;
   Результат=Регуляр.Execute(Стрим.ReadText());
   Сообщить(Результат.count);
   Для к=0 По Результат.count-1 Цикл
       Стр="";
       Для л=0 По Результат.item(к).SubMatches.count-1 Цикл
           Стр=Стр+Результат.item(к).SubMatches.item(л)+";"
       КонецЦикла;
       Сообщить(Стр);
   КонецЦикла;
КонецПроцедуры
17 smaharbA
 
23.10.06
14:28
Загрузил 1SENTRY.DBF == 100М ну долга конечно...
18 FreeFin
 
23.10.06
14:35
(17) Не пошло дальше:
Результат=Регуляр.Execute(Стрим.ReadText());

Может настройки или библиотеки необходимые отсутствуют?

Хотя, увы, без цикла с перебором опять не получается. Где-то надо думать в сторону ЗначениеИзФайла (знать структуру ТЗ в состоянии ЗначениеВФайл), разбирать dbf поколоночно в СпмскиЗначений,...не, можно закопаться на неделю... или пойти кофею накатить?...
19 FreeFin
 
23.10.06
14:41
(0) В связи с нерешенностью вопроса.
Остановился на этом бреде (своём): (поиск неуникальных записей в файле 1sjourn.dbf в колонке IDDOC)

Процедура Сформировать()
   Перем КпЖ,НазвПЖ,ТипПЖ,Длинуха,Точнила;    
   ТЗ.Очистить();
   ДБФ=СоздатьОбъект("XBase");
   ДБФ.ПоказыватьУдаленные(1);
   ДБФ.ОткрытьФайл(FileName,,0);
   Если ДБФ.Открыта()=0 Тогда
       Сообщить("Не удалось открыть файл "+FileName);
   Иначе
       Сообщить("Открыт "+FileName);
       ДБФ.ПоказыватьУдаленные(1);
   КонецЕсли;
   СколькоЗаписей=ДБФ.КоличествоЗаписей();
   СколькоПолей= ДБФ.КоличествоПолей();
   Для КпЖ=1 По СколькоПолей Цикл
       ДБФ.ОписаниеПоля(КпЖ,НазвПЖ,ТипПЖ,Длинуха,Точнила);
       ТЗ.НоваяКолонка(НазвПЖ,ТипПЖ,Длинуха,Точнила);
   КонецЦикла;
   Для КзЖ=1 По СколькоЗаписей Цикл
       ДБФ.Перейти(КзЖ);
       ТЗ.НоваяСтрока();
       Для КпЖ=1 По СколькоПолей Цикл  
           ТЗ.УстановитьЗначение(КзЖ,КпЖ,СокрЛП(ДБФ.ПолучитьЗначениеПоля(КпЖ)));
       КонецЦикла;    
       Состояние("Обработка "+КзЖ+"  из "+СколькоЗаписей);
   КонецЦикла;
   ТЗ.НоваяКолонка("Идекс","Число",2,0);
   ТЗ.Заполнить(1,1,ТЗ.КоличествоСтрок(),"Идекс");
   ТЗПРОВ=ТЗ;
   ТЗ.Свернуть("IDDOC","Идекс");
   ТЗ.Сортировать("+Идекс");
   Стр2="";
   ТЗ.НайтиЗначение(2,Стр2,"Идекс");
   ТЗ.ПолучитьСтрокуПоНомеру(Стр2);
   ТЗ.ТекущаяСтрока(Стр2);
   ЧегоИскали=ТЗ.IDDOC;
   НомерВБД="";
   ТЗПРОВ.НайтиЗначение(ЧегоИскали,НомерВБД,"IDDOC");
   Сообщить("В строке DBF  - "+НомерВБД+ " - Дублируется "+ТЗПРОВ.IDDOC);
КонецПроцедуры
//*******************************************
Процедура ВыбратьПуть()
   ИмяКаталога="";
   ИмяФайла="";
   Если ФС.ВыбратьФайл(0,ИмяФайла,ИмяКаталога,"Выберите файл :","База DBF(1sjourn.dbf)|1sjourn.dbf","DBF")=0 Тогда
       Возврат;
   КонецЕсли;  
   FileName=ИмяКаталога+ИмяФайла;  
КонецПроцедуры

Да и хвост с ним.
20 smaharbA
 
23.10.06
14:46
(19) такбы сразу и говорил...
Это делается\ немного иначе, ставится уникальный индекс, делается пометка на удаление, потом делается инверсия пометки удаления - все, вот вам и неуникальные записи...
21 FreeFin
 
23.10.06
14:52
(20) А не затруднит ли чуть подробнее о:

"ставится уникальный индекс"

(как создавать и использовать индексы в 1с СП И ЖКК не посылать, я там был, давно правда),НО чем будет определятся уникальность, при возможном наличии неуникальных значений и их "связок" по нескольким (индексным) полям в текущем файле?
22 smaharbA
 
23.10.06
14:57
(21) счас... типа такого

//*******************************************
Процедура Сформировать()
   Каталог="";
   Имя="";
   Сп=СоздатьОбъект("СписокЗначений");
   Если ФС.ВыбратьФайл(0,Имя,Каталог,"","ДБФ|*.dbf","dbf")=1 Тогда
       ДБФ=СоздатьОбъект("XBase");
       ДБФ.ОткрытьФайл(Каталог+Имя);
       ДБФ.ПоказыватьУдаленные(1);
       ДБФ.ДобавитьИндекс("ID","ID",1,0,"");
       ДБФ.ДобавитьИндекс("NONE","ID",0,0,"");
       ДБФ.СоздатьИндексныйФайл("ID");
       ДБФ.Переиндексировать();
       ДБФ.ТекущийИндекс("ID");
       ДБФ.Первая();
       Пока ДБФ.ВКонце()=0 Цикл
           Сп.ДобавитьЗначение(ДБФ.НомерЗаписи(),ДБФ.НомерЗаписи());
           ДБФ.Удалить();
           ДБФ.Следующая();
       КонецЦикла;
       Сообщить(Сп.РазмерСписка());
       ДБФ.ТекущийИндекс("NONE");
       ДБФ.Первая();
       ДБФ.Первая();
       Пока ДБФ.ВКонце()=0 Цикл
           Если ДБФ.ЗаписьУдалена()=1 Тогда
               ДБФ.Восстановить();
           Иначе
               ДБФ.Удалить();
           КонецЕсли;
           ДБФ.Следующая();
       КонецЦикла;
       ДБФ.Сжать();
       ДБФ.Записать();
       Сообщить(ДБФ.КоличествоЗаписей());
       ДБФ.ЗакрытьФайл();
   КонецЕсли;
КонецПроцедуры
23 smaharbA
 
23.10.06
14:57
Ну тут тупо конечно удаляются повторяющиеся...
24 smaharbA
 
23.10.06
14:58
+ Да СписокЗначений тут даже лишний
25 FreeFin
 
23.10.06
15:04
(24) (качает головой) это почти в два раза дольше, чем в (19) ...Пока ДБФ.ВКонце()*2, но с тем же результатом. Но как пример=понято, спасибо.

Еще тут мулю накопал, dbf, открытый в Access, проверяет на уникальность записей в колонке вообще тремя строками, может через него открывать-проверять? (в виде дурноватого предположения)))
26 smaharbA
 
23.10.06
15:14
Может быть, но тута просто "ремонт" файлов DHXXXX или SCXXXX
27 dk
 
23.10.06
16:46
В ToySQL есть загрузка из DBF в таблицу значений, да и не только из DBF.
Очень шустро загружает, например, лист Excel'я
28 Babay
 
23.10.06
16:53
С помощью 1с++:
1) Подключится к dbf, используя Прямой доступ через ODBC или OLEDB
2) Использовать метод:
ВыполнитьИнструкцию(ТекстSQL)

Параметры:
ТекстSQL - тип: Строка. SQL-выражение.
Возвращает: тип: ТаблицаЗначений. Результат запроса в виде таблицы значений. Колонки таблицы значений будут типизированы соответствующими значениями.

Описание: выполняет SQL-выражение и возвращает результат в виде таблицы значений. Если результат запроса пустой, то возвращается таблица значений с типизированными колонками. В случае возникновения ошибки, будет сгенерировано исключение с описанием ошибки.
29 Babay
 
23.10.06
16:55
Плюс этого метода - использование текста на языке SQL
30 FreeFin
 
23.10.06
17:34
(29) А зачем ToySQL и 1С++?
Или в виндузях уже отменили что-то типа:

ADO = CreateObject("ADODB.Connection");
Base= CreateObject("ADODB.Recordset");
ADO.Open("DRIVER=Microsoft FoxPro VFP Driver (*.dbf); Exclusive=No;SourceType=DBF;SourceDB="+ПутьДоФайла);
Base.Open(ТекстЗапроса);

Вопрос по-сути: как/какой изящный ТекстЗапроса, с группировкой по индексируемым полям DBF и получением размера в группировке "состряпать" и результат понять/обработать.
31 Babay
 
24.10.06
09:55
1
32 Babay
 
24.10.06
09:56
(30) Тебе ж надо было СРАЗУ в ТЗ
33 Babay
 
24.10.06
09:56
(30) А ты по конкретнее можешь сказать что тебе надо?
34 FreeFin
 
24.10.06
12:29
(All) То что мне надо сотворил сам.

Как быстро найти дублирующиеся записи в 1sjourn.dbf :

ИмяКаталога="D\Temp\"; //или определяется походу процедур (см выше в (19))
ИмяФайла="1sjourn.dbf";

ADO = CreateObject("ADODB.Connection");
Base= CreateObject("ADODB.Recordset");
ADO.Open("Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source="+ИмяКаталога+";Extended Properties=""DBASE IV;"";");
ТекстЗапроса="select IDDOC from "+ИмяФайла+" group by IDDOC having count(*)>1;";
Base.Open(ТекстЗапроса,ADO);
//Выбрано=ADO.Execute(ТекстЗапроса); //если без Recordset
Пока Base.EOF=0 Цикл //Цикл по выбранным записям из 1sjourn.DBF
Дупль=Base.Fields("IDDOC").value;
Сообщить(""+Дупль);
Base.MoveNext();    
КонецЦикла;
Base="";
ADO.Close();


Отакот, хлопцы )))
ЗЫ виндузячий драйвер FoxPro эту функцию (having count) не "слопал".
35 smaharbA
 
24.10.06
12:49
(34) у меня была задача тока 1С... :)
36 FreeFin
 
24.10.06
12:56
(35) А здесь и есть "тока 1С", "Windows" и база/ы в dbf формате. Ни каких "не стандартов" sql-ей, ВК и прочего=нет.) Но работает? )))
Мне оно надо было для быстренькой проверки удаленных баз на эту бяку (я им чо SQL Server ставить буду?). Одна простенькая внешняя обработочка и вопрос снят!
37 smaharbA
 
24.10.06
12:59
А я вот стал "исправляться", как неадинэснегом стал :)
38 FreeFin
 
24.10.06
13:03
(37) Да ладно (недоверчиво), и не совмещаешь полезное с приятным (кроме пива с...)? Не верю!..неадинэснег...се равно, что матрос без корабля )))

ЗЫ Сам админ, но без адинэса=скучаю )
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.