Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Доступ через vfpoledb.1 к таблице DBF

v7: Доступ через vfpoledb.1 к таблице DBF
Я
   maestro-72
 
05.10.20 - 09:47
Добрый день!
Столкнулся с проблемой доступа к данным через АДО (ну перепробовал много вариантов ничего не помогает) Смысл в следующем, имеется куча таблиц DBF к ним доступ из сети, пользователи с ними работают через писанную ранее оболочку все здорово, но из этих таблиц нужно быстро сформировать новые. Делал через XBASE все работает, но очень долго. Попробовал через АДО и наткнулся на то что для некоторых таблиц выдается сообщение: имя таблицы has become corrupted. The table will need to be repaired before using again. Все, тупик... Пробовал разные провайдеры, пытался найти консольную утилиту, чтобы исправить заголовок таблицы. Все тщетно. А очень  хочется чтобы решалась задача через запрос из за скорости выполнения последнего. Вивер эти поврежденные таблицы открывает без проблем, после открытия вивером проблем с запросом нет.  Вопрос собственно - как заставить запрос игнорировать данную ошибку (я подозреваю что в заголовке неверно указано количество строк) или посоветуйте утилиту консольную которой можно было бы в случае неудачи поправить заголовок и выполнить запрос повторно.

Делаю так:
База = СоздатьОбъект("OLEDBData");
Соединение="Provider=vfpoledb.1;Mode=ReadWrite;Data Source=" Сок ЛП(ВыбКаталог) "BAZA\" ";Collating Sequence=machine;";
;
Если База.Соединение(Соединение)=0 Тогда
Сообщить("Не соеденились");
Возв ат;
КонецЕсли;
Зап осСКЛ = База.СоздатьКоманду();

Вот тут дальше в цикле

Запрос = "INSERT INTO """ СокрЛП(ТЗСопост.Путь) "\" "BAZA\" СокрЛП(ИмяФ) """ Select * from """ СокрЛП(ПутьФ) СокрЛП(ИмяФ) """ WHERE GRWK in (" СокрЛП(ТЗСопост.СтрGRWK) ")";
Попытка
ЗапросСКЛ.Выполнить(Запрос);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;

Какие то таблицы норм, а на каких то вылетает с верхней ошибкой. Прошу помощи
   Mikeware
 
1 - 05.10.20 - 09:54
а что поправляет вьюер в "битых" таблицах?
   Mikeware
 
2 - 05.10.20 - 09:54
Да, и работу даже через xbase можно сильно ускорить, используя индексы.
   maestro-72
 
3 - 05.10.20 - 10:00
Я не знаю, в индексе нет требуемого выражения, а запрос прекрасно справляется с таблицами без индекса. У некоторых таблиц нет индекса вообще (типа справочники)
   Mikeware
 
4 - 05.10.20 - 10:01
(3) ну так сделай индекс, какой нужно.
   maestro-72
 
5 - 05.10.20 - 10:02
(1) Не знаю что поправляет, но после открытия в DBFWiever таблица прекрасно обрабатывается запросом. А вот фокс ее не открывает (туже ошибку выдает
   maestro-72
 
6 - 05.10.20 - 10:06
(4) Все равно это построчное чтение и запись, скорости далеки от Insert
   Mikeware
 
7 - 05.10.20 - 10:09
(5) ну так посмотри. сделай копию, сравни после открытия сравнивалкой бинарников
   Злопчинский
 
8 - 05.10.20 - 10:09
(5) ну так сравни до и после проблемный дбф.
   Mikeware
 
9 - 05.10.20 - 10:09
(6) а инсерт не построчно делает? :-)
   Андроны едут
 
10 - 05.10.20 - 10:12
(5) что мешает поправить файлы открытием в дбвивере с помощью обработки или батника.
   maestro-72
 
11 - 05.10.20 - 10:15
(9) Построчно, только 1с это делает на порядок медленнее. Я сравнивал скорости чтения при работе в Delphi с DBF и XBASE так вот ощущение, что в XBASE мы в Москву через Пекин добираемся
   maestro-72
 
12 - 05.10.20 - 10:16
(10) Да, хочу консольное приложение блабла.EXE таблица.DBF поправил и запрос к ней сделал, не нашел нигде, везде либо виверы либо надо через приложение открывать таблицу интерактивно
   maestro-72
 
13 - 05.10.20 - 10:17
Как то прям грустно, механизм есть, а такой капризный к таблицам и путей обхода не наблюдается
   Злопчинский
 
14 - 05.10.20 - 10:19
Не суетись.
все получится.
   tgu82
 
15 - 05.10.20 - 10:28
(0) Когда-т о на турбопаскале писал программку которая записывала реальное количество строк в заголовлк ДБФ. Интересно что Clipper чихл на эти ошибки с высокой колокольни а вот фохпро ругался
   maestro-72
 
16 - 05.10.20 - 10:34
(15) Вот! Проблема Clipper. Не сохранилось ничего из наработок
   maestro-72
 
17 - 05.10.20 - 10:47
А 1с77 как то с  битами и байтами работает, я подумал может просто через XBASE запросить количество строк в таблице, и поправить в заголовке. Ну может через ADODB.Streem... ?
   Злопчинский
 
18 - 05.10.20 - 11:22
(17) внешними способами через FSO и прочие объекты ОС
   maestro-72
 
19 - 05.10.20 - 11:29
(18) Поискал, но чет не нашел примеров для замены байта. не соображу никак
   tgu82
 
20 - 05.10.20 - 11:37
*********************************************************************  
 * Назначение :     Приведение в соответствие значение количества записей   
 *        в заголовке таблице и реального количества записей  
 * Автор :     Владимир Максимов  
 * Дата :     31.08.2008  
 * Версия FoxPro: Visual FoxPro с 3 по 9  
 *        Возможно, этот код будет работать и в версиях FoxPro 2.x  
 *        если убрать объявления LOCAL и MessageBox()   
 *        Но это не проверялось  
 *********************************************************************  
    
* Пользователь выбирает файл для проверки  
* 5 параметр в функции GetFile() был введен только в версии Visual FoxPro 6  
 * для младших версий FoxPro его надо удалить  
  Local lcFileName  
  lcFileName = GetFile("DBF","","",0,"Выбор файла для проверки количества записей")  
  If Empty(m.lcFileName)  
     * Файл не был выбран  
      Return  
  EndIf  
    
 * Открываю файл и запоминаю его дескриптор (идентификатор)  
  Local lnFD  
  lnFD = Fopen(m.lcFileName,12)  
  If m.lnFD < 0  
      MessageBox("Не удалось открыть файл" + Chr(13) + ;  
          m.lcFileName + Chr(13) + ;  
          "Возможно, он открыт другим приложением")  
  EndIf  
    
 * Теоретически, здесь хорошо бы добавить проверку на тот факт,   
 * что данный файл - это DBF-таблица (анализ первого байта)  
 * Но в данном случае предполагается, что пользователь понимает, что он делает  
 * Если, тем не менее, Вы хотите создать универсальную утилиту, то  
 * посмотрите код программы CPZERO.PRG из поставки FoxPro.  
 * Эта программа находится в каталоге TOOLS\CPZERO корневой папки FoxPro  
    
 * Определяю количество записей записанное в заголовке файла  
 * байты с 4 по 7  
  LOCAL lnReccount  
  =FSEEK(m.lnFD,4)  
  lnReccount =    ASC(FREAD(m.lnFD,1)) + ;  
          ASC(FREAD(m.lnFD,1)) * 256 + ;  
          ASC(FREAD(m.lnFD,1)) * 256 * 256 + ;  
          ASC(FREAD(m.lnFD,1)) * 256 * 256 * 256  
                
 * Определяю позицию, с которой начинается собственно данные (первая запись)  
 * байты с 8 по 9  
  LOCAL lnDataStart  
  lnDataStart =     ASC(FREAD(m.lnFD,1)) + ;  
          ASC(FREAD(m.lnFD,1)) * 256  
    
 * Определяю количество символов в одной записи, включая метку на удаление  
 * байты с 10 по 11  
  LOCAL lnRecLength  
  lnRecLength =    ASC(FREAD(m.lnFD,1)) + ;  
          ASC(FREAD(m.lnFD,1)) * 256  
    
 * Определяю общий размер файла, через порядковый номер последнего байта  
  LOCAL lnFileSize  
  =FSEEK(m.lnFD,0,0)  
  lnFileSize = FSEEK(m.lnFD,0,2)  
    
 * Определяю значение самого последнего байта файла  
  LOCAL lnEndByte  
  =FSEEK(m.lnFD,-1,1)  
  lnEndByte = ASC(FREAD(m.lnFD,1))  
    
 * И реальное количество записей в файле  
  LOCAL lnFaktCount  
  DO CASE  
  CASE m.lnFileSize = m.lnDataStart  
     * Т.е. в таблице вообще нет информации  
      lnFaktCount = 0  
  CASE m.lnEndByte = 26  
     * Если последний байт файла имеет ASCII код 26 (0x1A),   
     * то общее число информационных байтов надо уменьшить на 1  
      lnFaktCount = (m.lnFileSize - m.lnDataStart - 1) / m.lnRecLength  
  OTHERWISE  
      lnFaktCount = (m.lnFileSize - m.lnDataStart) / m.lnRecLength  
  ENDCASE  
    
    
  LOCAL lnResult  
 * Анализ полученных результатов  
  DO CASE  
  CASE INT(m.lnFaktCount) <> m.lnFaktCount  
    
     * Есть дробная часть. Т.е. выделить целое количество записей невозможно  
     * повреждения более существенные, чем разница в количестве записей  
     * лучше ничего не трогать  
      lnResult = -1  
      =Fclose(m.lnFD)  
        
      MessageBox("Выделить целое количество записей невозможно"+Chr(13) + ;  
                  "Повреждения более существенные, чем разница в количестве записей")  
    
  CASE m.lnFaktCount <> m.lnReccount  
    
     * Записанное и фактическое количество записей отличаются  
     * корректирую записанное количество записей  
      =FSEEK(m.lnFD,4,0)  
      FOR lnI=1 TO 4  
          =FWRITE(m.lnFD,CHR(MOD(INT(m.lnFaktCount / 256**(m.lnI-1)),256)))  
      ENDFOR  
    
      lnResult = 1  
      =Fclose(m.lnFD)  
    
      MessageBox("Значение количества записей исправлено")  
    
  OTHERWISE  
    
     * Ошибки в определении количества записей не обнаружено  
      lnResult=0  
      =Fclose(m.lnFD)  
    
      MessageBox("Ошибки в количестве записей не обнаружено")  
    
  ENDCASE  
    
 * Результат возвращается на случай, если есть необходимость в подобном анализе  
  RETURN m.lnResult
   tgu82
 
21 - 05.10.20 - 11:37
вот что-то нашел
   tgu82
 
22 - 05.10.20 - 11:38
   tgu82
 
23 - 05.10.20 - 11:39
   Ёпрст
 
24 - 05.10.20 - 11:59
(0)
Запрос.Выполнить("Exec('SET TABLEVALIDATE TO 0')")
   Ёпрст
 
25 - 05.10.20 - 12:00
сделай перед инсертом
   maestro-72
 
26 - 05.10.20 - 12:01
(21) Ага, это я видел, не подходит, потому что надо чтобы было чтоб это автоматом шло из проги (23) этот тоже читал
   maestro-72
 
27 - 05.10.20 - 12:01
(24) Сейчас попробую
   maestro-72
 
28 - 05.10.20 - 12:02
Пока как вариант решения сложной проблемы. Неисправную таблицу просто копирую отдельно, делаю сжатие методом XBASE и потом все по ней отрабатывает на ура.
   maestro-72
 
29 - 05.10.20 - 12:08
(24) Отлично, жму руку! Тема закрыта, все получилось!


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