powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Pack table для формата dbf
25 сообщений из 54, страница 2 из 3
Pack table для формата dbf
    #33278113
Alex_VC
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lora__k Карабас БарабасЭто немного другой запрос. А озвученный мной запрос не проходит ? (просто нету пока возможности самому попробовать)
Нет, не проходит. Оба запроса переписывают все (в том числе и помеченные на удаление) записи из старой таблицы в новую.
Похоже придется разбираться со структурой dbf файлов, там есть байт, который содержит флаг удаления для каждой записи, его и проверять, короче работать напрямую с файлами...
Ну тады можно сделать через старую Fox'у:
use mytable.dbf
pack
quit

Все это помещается в командный файл (например, pack.prg), и запускается примерно так:
foxprox pack.prg
Можно и интерфейс накрутить (например, выбор файла(файлов))
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33278477
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_VC
Ну тады можно сделать через старую Fox'у:
use mytable.dbf
pack
quit

Все это помещается в командный файл (например, pack.prg), и запускается примерно так:
foxprox pack.prg
Можно и интерфейс накрутить (например, выбор файла(файлов))

Алекс, спасибо, так работает :)
Только, если я правильно понимаю, без Fox'а это все дело работать не будет, чтож мне теперь каждому пользователю на машину FoxPro ставить?... :)
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33278717
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lora__k Alex_VC
Ну тады можно сделать через старую Fox'у:
use mytable.dbf
pack
quit

Все это помещается в командный файл (например, pack.prg), и запускается примерно так:
foxprox pack.prg
Можно и интерфейс накрутить (например, выбор файла(файлов))

Алекс, спасибо, так работает :)
Только, если я правильно понимаю, без Fox'а это все дело работать не будет, чтож мне теперь каждому пользователю на машину FoxPro ставить?... :)
Ну, можне еще немного поизвращаться...
1. Например, уж если речь зашла о "старом фоксе", то он позволял создавать самодостаточные ехе-шники... То есть пишешь фоксовую программу, компилируешь ее в ехе-шник (только надо выбрать Standalone EXE, чтобы не таскать за собой библиотеки поддержки), после этого кидаешь ее тем пользователям, кому это необходимо...
2. Можно еще использовать ODBC драйвер для Visual FoxPro. А на выполнение посылать запрос вида:
Код: plaintext
1.
select * from <old table> where not deleted() into table <new table>
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33278758
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
За умеренную сумму могу написать "сжиматель" в виде ДЛЛ
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33278948
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Карабас БарабасЗа умеренную сумму могу написать "сжиматель" в виде ДЛЛ

Спасибо, но хочу сама разобраться :)

Alex_VC 2. Можно еще использовать ODBC драйвер для Visual FoxPro. А на выполнение посылать запрос вида:
select * from <old table> where not deleted() into table <new table>


При выполнении запроса вылетает ошибка "Ошибка синтаксиса(пропущен оператор) в выражении запроса ' not deleted() into table owners' "
А что это за функция deleted()?
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33278995
Станислав C.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lora__k Alex_VC 2. Можно еще использовать ODBC драйвер для Visual FoxPro. А на выполнение посылать запрос вида:
select * from <old table> where not deleted() into table <new table>


При выполнении запроса вылетает ошибка "Ошибка синтаксиса(пропущен оператор) в выражении запроса ' not deleted() into table owners' "
А что это за функция deleted()?
Вообще-то это я давал ответ...
В Фоксе функция deleted() используется для распознавания помеченных к удалению записей. Поэтому конструкция "not deleted()" в выражении запроса должна вернуть все непомеченные записи...
Перед тем, как предложить решение, я попробовал подобного рода запрос (с "not deleted()") и он не вызвал никаких проблем... Правда я работаю через ADO...
На всякий случай приведу параметры, с которыми я подключался к своему dbf файлу:
Код: plaintext
1.
2.
3.
4.
5.
...
CString strConn = "Driver={Microsoft Visual FoxPro Driver};UID=;PWD=;SourceDB=d:\\temp\\demo;";
strConn += "SourceType=DBF;Exclusive=No;BackgroundFetch=Yes;Collate=Machine;";
strConn += "Null=Yes;Deleted=No;";
...
Кстати, в параметрах подключения уже указано, чтобы удаленные записи не брать...
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33279060
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Станислав C. CВообще-то это я давал ответ...
Станислав, я очень извиняюсь! :)

Станислав C. В Фоксе функция deleted() используется для распознавания помеченных к удалению записей. Поэтому конструкция "not deleted()" в выражении запроса должна вернуть все непомеченные записи...
Перед тем, как предложить решение, я попробовал подобного рода запрос (с "not deleted()") и он не вызвал никаких проблем...
У меня все таки этот запрос не проходит, даже если использовать твою строку соединения...

Станислав C. Правда я работаю через ADO...
Может быть в этом дело?

Станислав C. Кстати, в параметрах подключения уже указано, чтобы удаленные записи не брать...
За это отвечает флаг Deleted? Почему же он тогда не работает?
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33282965
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если кому интересно, то упаковать dbf таблицу можно таким способом, исходя из структуры dbf файла:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
    LPSTR szOldTableName;
    LPSTR szNewTableName
    FILE   *FileBinDbOld;
    FILE   *FileBinDbNew;
    char sdel;
    char list[ 512 ];
    int iRecordCount;
    short shHeaderSize, shRecordSize;
    FileBinDbOld = fopen(szOldTableName,"rb");
    if(FileBinDbOld != NULL){
 		fseek(FileBinDbOld, 4 ,SEEK_SET);
		fread(&iRecordCount,sizeof(int), 1 ,FileBinDbOld);
		fread(&shHeaderSize,sizeof(short), 1 ,FileBinDbOld);
		fread(&shRecordSize,sizeof(short), 1 ,FileBinDbOld);

		FileBinDbNew = fopen(szNewTableName,"wb");
	
		fseek(FileBinDbOld,- 12 ,SEEK_CUR);
		fread(&list,shHeaderSize,  1 , FileBinDbOld);
		fwrite(list,  1 , shHeaderSize, FileBinDbNew );

		int i =  0 ;
		while(i < iRecordCount){
			fread(&sdel,sizeof(char),  1 , FileBinDbOld);
			if(sdel == '*') fseek(FileBinDbOld,shRecordSize- 1 ,SEEK_CUR);
			else{
				fseek(FileBinDbOld,- 1 ,SEEK_CUR);
				fread(&list,shRecordSize,  1 , FileBinDbOld);
				fwrite(list, 1 , shRecordSize, FileBinDbNew );
			}
			i++;
		}

		fclose( FileBinDbNew );
    }
    fclose( FileBinDbOld );
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283182
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, забыла скопировать завершающий символ, вот правильный код :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
   
    LPSTR szOldTableName;
    LPSTR szNewTableName
    FILE   *FileBinDbOld;
    FILE   *FileBinDbNew;
    char sdel;
    char list[ 512 ];
    int iRecordCount;
    short shHeaderSize, shRecordSize;
    FileBinDbOld = fopen(szOldTableName,"rb");
    if(FileBinDbOld != NULL){
 		fseek(FileBinDbOld, 4 ,SEEK_SET);
		fread(&iRecordCount,sizeof(int), 1 ,FileBinDbOld);
		fread(&shHeaderSize,sizeof(short), 1 ,FileBinDbOld);
		fread(&shRecordSize,sizeof(short), 1 ,FileBinDbOld);

		FileBinDbNew = fopen(szNewTableName,"wb");
	
		fseek(FileBinDbOld,- 12 ,SEEK_CUR);
		fread(&list,shHeaderSize,  1 , FileBinDbOld);
		fwrite(list,  1 , shHeaderSize, FileBinDbNew );

		int i =  0 ;
		while(i < iRecordCount){
			fread(&sdel,sizeof(char),  1 , FileBinDbOld);
			if(sdel == '*') fseek(FileBinDbOld,shRecordSize- 1 ,SEEK_CUR);
			else{
				fseek(FileBinDbOld,- 1 ,SEEK_CUR);
				fread(&list,shRecordSize,  1 , FileBinDbOld);
				fwrite(list, 1 , shRecordSize, FileBinDbNew );
			}
			i++;
		}
                      
                  fread(&list, 1 ,  1 , FileBinDbOld);
		fwrite(list,  1 ,  1 , FileBinDbNew );
		fclose( FileBinDbNew );
    }
    fclose( FileBinDbOld );
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283200
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Там в хедере количество записей записано .. я вот не помню, это включая удаленные или нет ... если включая, то надо его корректировать
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283235
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Карабас БарабасТам в хедере количество записей записано .. я вот не помню, это включая удаленные или нет ... если включая, то надо его корректировать


Включая удаленные, я как раз с этой проблемой столкнулась :)
Сейчас исправлю.
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283251
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще: я так понял, ты руками задаешь размеры хедера и записи. В принципе в хедере есть информация по количеству полей, т.о. размер хедера можно вычислить. И про размер записи есть инфа ...
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283409
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Карабас БарабасИ еще: я так понял, ты руками задаешь размеры хедера и записи. В принципе в хедере есть информация по количеству полей, т.о. размер хедера можно вычислить. И про размер записи есть инфа ...

Так я эти значения и беру из структуры хедера:
начиная с 4го байта (размером 4б) там хранится RecordsCount - Количество записей в таблице, я его оттуда считываю и записываю в переменную iRecordCount;
Код: plaintext
fread(&iRecordCount,sizeof(int), 1 ,FileBinDbOld);

дальше в восьмом\девятом байте лежит HeaderSize - Размер заголовка в байтах, а в 10\11 байтах RecordSize - Размер записи в байтах.
их получаю аналогично

Код: plaintext
1.
2.
fread(&shHeaderSize,sizeof(short), 1 ,FileBinDbOld);
fread(&shRecordSize,sizeof(short), 1 ,FileBinDbOld);
А количество полей, если надо, можно вычислить исходя из рамера заголовка:
N=(shHeaderSize - 33)/32;
Разве не так?
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33283480
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просто не вчитался :)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284158
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну вот теперь вроде всё :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
    
    LPSTR szOldTableName;
    LPSTR szNewTableName
    FILE   *FileBinDbOld;
    FILE   *FileBinDbNew;
    char sdel;
    сhar list[ 2048 ];
    int iRecordCount;
    short shHeaderSize, shRecordSize;
    FileBinDbOld = fopen(szTableName,"rb");
    if(FileBinDbOld != NULL){
 		fseek(FileBinDbOld, 4 ,SEEK_SET);
		fread(&iRecordCount,sizeof(int), 1 ,FileBinDbOld);
		fread(&shHeaderSize,sizeof(short), 1 ,FileBinDbOld);
		fread(&shRecordSize,sizeof(short), 1 ,FileBinDbOld);

	
		fseek(FileBinDbOld,shHeaderSize- 12 ,SEEK_CUR);
		int i =  0 ;
		int iCountDel =  0 ;
		while(i < iRecordCount){
			fread(&sdel,sizeof(char),  1 , FileBinDbOld);
			if(sdel == '*'){
				iCountDel++;
			}
			fseek(FileBinDbOld,shRecordSize- 1 ,SEEK_CUR);
			i++;
		}


		FileBinDbNew = fopen(szNewTableName,"wb");
 		fseek(FileBinDbOld,-(shHeaderSize+iRecordCount*shRecordSize+ 1 ),SEEK_END);
		fread(&list, 4 ,  1 , FileBinDbOld);
		fwrite(list,  1 ,  4 , FileBinDbNew );
		int iNewRecCount = iRecordCount-iCountDel;
		fwrite(&iNewRecCount, sizeof(int),  1 , FileBinDbNew );
		fseek(FileBinDbOld, 4 ,SEEK_CUR);
		fread(&list,(shHeaderSize- 8 ),  1 , FileBinDbOld);
		fwrite(list,  1 , (shHeaderSize- 8 ), FileBinDbNew );
		
		i =  0 ;
		while(i < iRecordCount){
			fread(&sdel,sizeof(char),  1 , FileBinDbOld);
			if(sdel == '*') fseek(FileBinDbOld,shRecordSize- 1 ,SEEK_CUR);
			else{
				fseek(FileBinDbOld,- 1 ,SEEK_CUR);
				fread(&list,shRecordSize,  1 , FileBinDbOld);
				fwrite(list, 1 , shRecordSize, FileBinDbNew );
			}
			i++;
		}
		fread(&list, 1 ,  1 , FileBinDbOld);
		fwrite(list,  1 ,  1 , FileBinDbNew );

		fclose( FileBinDbNew );
    }
    fclose( FileBinDbOld );
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284171
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вроде ниче, только непонятно, зачем 2 раза пробегать исходный файл ?

И еще: я бы при помощи файлов, проецируемых в память делал, и быстрее работать будет, на порядок, и ... логичнее, да и проще.
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284254
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Карабас БарабасНу вроде ниче, только непонятно, зачем 2 раза пробегать исходный файл ?
Так первый раз, чтобы получить количество записей помеченных на удаление, отсюда получаю новое количество записей в файле, потом подправляю хедер и перезаписываю файл уже без удаленных записей, а как ещё? :)

Карабас Барабас
И еще: я бы при помощи файлов, проецируемых в память делал, и быстрее работать будет, на порядок, и ... логичнее, да и проще.

Можно об этом поподробнее?
Я конечно и сама поищу, но буду благодарна, если подскажешь :)
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284263
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. можно один раз пробежаться, считая реально скопированные записи, потом в новом файле вернуться в заголовок и записать правильное значение числа записей.

2. CreateFile, CreateFileMapping, MapViewOfFile ....... Рихтер в помощь
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284285
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Карабас Барабаспотом в новом файле вернуться в заголовок и записать правильное значение числа записей.

А разве можно перезаписывать файл частично?
Карабас Барабас
2. CreateFile, CreateFileMapping, MapViewOfFile ....... Рихтер в помощь

спасибо, я с этим поразбираюсь :)
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284307
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lora__kА разве можно перезаписывать файл частично?а ты попробуй :) зачем тогда все эти Seek ?
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284336
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И правда можно :)
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33284686
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lora__kА количество полей, если надо, можно вычислить исходя из рамера заголовка:
N=(shHeaderSize - 33)/32;
Разве не так?
Вообще-то не так.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
iHeaderSize = Data[ 8 ] | (Data[ 9 ]<< 8 );
iRecordSize = Data[ 10 ] | (Data[ 11 ]<< 8 );
switch(bufHeader[ 0 ]) {
  case 0x03: case 0x83: case 0x8B: case 0xF5:
     iCountOfFields = (iHeaderSize -  34 ) >>  5 ;
     break;
  case 0x30:
    iCountOfFields = (iHeaderSize -  294 ) >>  5 ;
  case 0x04: case 0xF4:
    iCountOfFields =  0 ;
    while (Data[ 68  + (iCountOfFields *  48 )] != 0x0d) iCountOfFields++;
  default:
    iCountOfFields =  0 ;
}
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33285194
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl!
А зачем так сложно?
И в чем я не права? :) Ведь DBF-файл состоит из двух частей: хедер и сами записи.
хедер включает в себя 32 бита загололовка dbf файла и описания полей - N раз по 32 байта, плюс завершающий символ - 1 байт. Таким образом размер хедера DBF-файла в байтах составляет: (32+32xN+1) байт. Этот же размер можно извлечь из 8\9 байтов заголовка - iHeaderSize
Следовательно количество полей равно:
N:=(iHeaderSize-33)/32 байт.
Я во все это дело влезла совсем недавно, поэтому буду благодарна, если ты мне объяснишь, что не так :)
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33286288
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Видимо, наш ночной белый друг имел в виду, что форматов dbf-а много , и у них разные заголовки.
...
Рейтинг: 0 / 0
Pack table для формата dbf
    #33286447
Lora__k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivВидимо, наш ночной белый друг имел в виду, что форматов dbf-а много , и у них разные заголовки.
То есть он предложил универсальный подход, а у меня частный случай.
Понятно, спасибо :)
...
Рейтинг: 0 / 0
25 сообщений из 54, страница 2 из 3
Форумы / C++ [игнор отключен] [закрыт для гостей] / Pack table для формата dbf
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]