:: Главная :: Решения :: Статьи :: Проект "Русский help" :: Файловый архив :: Фотоальбом :: Ссылки ::
   Л и с о в о д ы   в с е х   с т р а н,  о б ъ е д и н я й т е с ь !!!  


Форумы  :: FAQ FoxPro

Как восстановить поврежденную таблицу
Дата: 31.08.08 22:02:12 ОтветитьЦитировать

Вопрос

Таблица нормально открывалась. Однако после сбоя питания (не корректного выключения компьютера) при открытии таблицы возникает сообщение об ошибке

Цитата:
"file" is not a table (Error 15)

Как можно починить таблицу?

Причина

Файл DBF можно рассматривать как обычный текстовый файл. Просто текст. Но такой текст, который имеет определенную внутреннюю структуру. Т.е. любая информация всегда находится по определенному "адресу". В определенном месте этого файла. Грубо говоря, в файле DBF значение вот этого поля из вот этой строки должно находится вот в этом месте.

Что и где должно находится, так сказать, "оглавление", записывается в самом начале файла. В так называемой "заголовочной части". Это просто самое начало файла. После которого идет само содержание файла. Данные.

Естественно "оглавление" должно соответствовать определенному "стандарту", зависящему от версии FoxPro, а также должно соответствовать "содержанию". И некоторые из таких соответствий можно проверить. Т.е. посмотреть действительно ли в указанном месте находится соответствующие данные? Что, собственно, и делает FoxPro при открытии файлов DBF.

Чем старше версия FoxPro, тем большее количество параметров проверяется при открытии файла DBF. Если какой-то параметр не соответствует тем значениям, которые должны быть, то FoxPro выдает сообщение об ошибке

Решение

Прежде чем попытаться "исправить" файл DBF, не важно, каким способом, желательно сделать резервную копию. Пусть и поврежденного файла. Как бы "лечение" не сделало хуже!

Помните, что таблица - это совокупность трех файлов с одинковым именем и с расширениями

DBF - собственно таблица
FPT - содержимое мемо-полей
CDX - структурный индексный файл

Это значит, что делать резервную копию надо всех трех файлов. Разумеется, если они есть.

Теоретически, можно самостоятельно проверить соответствие структуры таблицы ее реальному содержанию. В Help по FoxPro достаточно подробно описана структура таблицы и ее заголовочной части. Оглавления. Это статья с названием

Table File Structure (.dbc, .dbf, .frx, .lbx, .mnx, .pjx, .scx, .vcx)

А для мемо-полей, которые хранятся в отдельном файле с расширением FPT это статья с названием

Memo File Structure (.FPT)

Для проверки можно открыть таблицу любым низкоуровневым текстовым редактором. Например, Norton Commander, Disco Commander, FAR-manager и т.п. Далее проанализировать значения в заголовочной части и в области с данными.

Проблема только в том, что при больших размерах файла такой анализ может занять очень много времени. А ручное исправление ошибок очень утомительный процесс.

Тем не менее, просмотреть поврежденный файл в низкоуровневом редакторе бывает полезно. Как правило, при этом можно сделать некоторые общие выводы. Например, а есть ли в файле вообще какая-либо информация. Не заполнен ли файл каким-либо "мусором".

Если стоит задача "спасти" информацию текстового содержания из мемо-полей, то ее можно просто скопировать из файла FPT, поскольку она хранится в нем "как есть". Да и информацию из полей таблицы можно прочитать напрямую. Правда, не всегда "как есть". Иногда требуются некоторые преобразования.

-------------------------------------------------------------------------------------

Есть некоторые способы, позволяющие в простых случаях "привести в чувство" испорченную таблицу.

Если таблицу все-таки удалось открыть, например, отключив проверку структуры настройкой

SET TABLEVALIDATE TO 0

Или же открыв таблицу в младшей версии Visual FoxPro. То можно попробовать выполнить следующие действия:


  1. При помощи команды COPY TO скопировать содержимое таблицы в другой файл. Команда COPY TO создаст таблицу корректной структуры.
  2. Очистить содержимое испорченной таблицы при помощи команды ZAP или просто пересоздать таблицу заново, если ничто не помогает
  3. Заполнить пустую таблицу командой APPEND FROM данными, сохраненными ранее в копии, при помощи команды COPY TO.


Иногда, помогает использование команды PACK.

Если повреждения коснулись ссылок на мемо-поля, то иногда помогает создание нового мемо-поля с последующим его удалением. Дело в том, что факт создания нового мемо-поля заново обновляет все ссылки. Хотя, скорее всего, это приведет к потере данных, записанных в мемо-полях. Но их можно будет достать напрямую, открыв файл FPT как текстовый файл.

--------------------------------------------------------------------------------

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

Если в старших версиях FoxPro это рассогласование вызовет сообщение об ошибке в момент открытия, то в младших версиях FoxPro это соответствие не проверяется. Как следствие, при открытии таблицы Вы увидите меньше записей, чем есть на самом деле. Или больше. Но в последнем случае, эти "лишние" записи будут заполнены "мусором".

Собственно, довольно просто проверить это соответствие самостоятельно. Достаточно посмотреть, как именно формируется "оглавление" в файле DBF. Т.е. посмотреть в HELP структуру файла DBF. Или поискать в интернете различные "фиксеры", которые исправляют некоторые повреждения структуры файла DBF.

Только следует с осторожностью использовать "фиксеры" найденные в интернете. Учитывая тот факт, что есть отличия в структурах файлов DBF для FoxPro 2.x и Visual FoxPro. Отличия в структуре файлов DBF разных версий Visual FoxPro можно считать не существенным с точки зрения исправления возможных повреждений структуры. Впрочем, и большинство "фиксеров" разработанных для FoxPro 2.x могут успешно исправить и повреждение таблиц Visual FoxPro.

Еще раз напомню, прежде чем попытаться "исправить" файл DBF при помощи сторонней утилиты, желательно сделать резервную копию. Пусть и поврежденного файла. Как бы "лечение" не сделало хуже!

-------------------------------------------------------------------------

Ниже приведен один из вариантов исправления

  
 *********************************************************************  
 * Назначение : 	Приведение в соответствие значение количества записей   
 *		в заголовке таблице и реального количества записей  
 * Автор : 	Владимир Максимов  
 * Дата : 	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
Ratings: 0 negative/0 positive


Тема Просмотров Написано Написано
  Работа с данными 5940 Владимир Максимов 01.03.05 21:04
  Выбрать из дочерней таблицы записи с максимальной датой 19279 Владимир Максимов 15.06.05 20:08
  Выбрать записи с повторяющимися (дублирующими) значениями поля 11273 Владимир Максимов 27.06.05 20:21
  Как выполнить восстановление поврежденных индексов 9275 Владимир Максимов 29.06.05 20:04
  Как изменить значения в одной таблице данными из другой 10930 Владимир Максимов 29.06.05 20:40
  Запрос с GROUP BY выдает сообщение о синтаксической ошибке 10687 Владимир Максимов 20.07.05 16:47
  При работе в сети иногда не открывается таблица 5260 Владимир Максимов 20.07.05 17:36
  Как получить программный код создания структуры базы данных 7599 Владимир Максимов 18.09.05 10:14
  Как восстановить поврежденную таблицу 17737 Владимир Максимов 31.08.08 22:02


Извините, но у вас нет прав для того, чтобы писать в этом форуме.

On-line: 26 Александр Жевелев sphinx  and Guests: 24


© 2006 Fox Club 
Яндекс.Метрика