![]() |
|
1С:Предприятие
:: 1С:Предприятие 7.7 и ранее
|
|
| ||
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 | https://yandex.ru/search/?text=восстановить%20заголовок%20dbf%20файла&lr=10&src=suggest_T
Вот такой адрес поискового запроса | ||
Ёпрст 24 - 05.10.20 - 11:59 | |||
Ёпрст 25 - 05.10.20 - 12:00 | сделай перед инсертом | ||
maestro-72 26 - 05.10.20 - 12:01 | |||
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) Отлично, жму руку! Тема закрыта, все получилось! |
|
Список тем форума
|