On-line: tnsr2, гостей 2. Всего: 3 [подробнее..]
АвторСообщение





Пост N: 256
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 16.03.20 19:44. Заголовок: непосредственное изменение имени поля в заголовке dbf


Иногда требуется поменять имя поля без изменения других параметров. Если база 200-300мегов, то обновление занимает долгое время. Есть у кого нибудь опыт изменения имени непосредственно в заголовке DBF что бы не перегонять все данные ?

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 19 [только новые]


постоянный участник




Пост N: 3091
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 16.03.20 23:32. Заголовок: MIKHAIL Функции от ..


MIKHAIL
Функции от Pasha к hb 2.0 Скрытый текст


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 257
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 17.03.20 07:59. Заголовок: SergKis пишет: Fiel..


SergKis пишет:

 цитата:
FieldRename( nPos, FieldNameNew[, FieldTypeNew[, FieldDecNew]] )


А как использовать ? Я правильно понимаю, что нужно сначала открыть файл например через DBFNTX в эксклюзивном режиме (через ADS наверное работать не будет...) ?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7175
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 17.03.20 10:28. Заголовок: MIKHAIL пишет: (че..


MIKHAIL пишет:

 цитата:
(через ADS наверное работать не будет...)


Пробовать надо

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 3092
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 17.03.20 11:10. Заголовок: MIKHAIL пишет Я прав..


MIKHAIL пишет
 цитата:
Я правильно понимаю, что нужно сначала открыть файл например через DBFNTX в эксклюзивном режиме


Именно так. Пробовал с hb 2.0 все ф-ии - работают.
На 3.2 DBDELRECORD стала валить программу.
В использовании остались только
FIELDRENAME - для не больших файлов (определение реальной дробной части и "чужие" имена полей -> в свои)
DBINSERT - для использования в файлах отчета (вставка в нужные места итоговых строк, с учетом групп, подгрупп и т.д.)

С ADS не работаю.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1527
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 17.03.20 11:38. Заголовок: менял тупо открывая ..


менял тупо открывая файл в двоичном режиме ( Fopen() ) и записывая новое название ( и тип если требовалось ) прямо в заголовок
Для dbf длинна имени поля не более 10 , заканчивается нулевым байтом. Меняется только так, мгновенно и без оглядки на размер базы
В ADS может не прокатить только если используются словари - тк структура в них или база зашифрована

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 258
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 17.03.20 16:18. Заголовок: Haz пишет: Fopen() ..


Haz пишет:

 цитата:
Fopen() ) и записывая новое название


чисто теоретически понимаю что можно в бинарном режиме в заголовке вписать новое имя поля, просто на грабли наступать не хочется...
Насколько помню первые 32 байта - заголовок, потом идут по 32 байта описание полей., из которых первые 10 отводятся под имя поля, куда и нужно записать коды символов имени. В бинарном режиме опыта работы мало. Какие коды писать ? нужно ли переводить в другую систему или как есть писать...?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1528
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 17.03.20 16:56. Заголовок: MIKHAIL пишет: Как..


MIKHAIL пишет:

 цитата:
Какие коды писать ? нужно ли переводить в другую систему или как есть писать...?



Все верно , начиная с 32 байта , каждые 32 последующие это описания полей. Описание полей заканчиваются значением 0Dh
Никакая система счисление не требуется , просто пишем новое имя поля латиницей в верхнем регистре. Имя дополняем справа до длинны 10 символом chr(0)
например пишем в качестве имени первого поля NEW_NAME
 
func main()
local cName := space(10)
local n := FOPEN( 'demo.dbf', 2 )

// читаем имя первого поля
fseek( n, 32, 0 )
fread(n, @cName, 10)
? CharRem( chr(0), cName)

// пишем новое имя первому полю
fseek( n, 32, 0 )
cName := PADR( "NEW_NAME" , 10, chr(0) )

fWrite( n, cName, 10 )
fClose(n)
return nil




Спасибо: 1 
ПрофильЦитата Ответить





Пост N: 259
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 17.03.20 23:05. Заголовок: Haz то что надо! Не..


Haz то что надо!
Не могу только разобраться с размером заголовка. По идее он прописан в 8-9 байтах
я считаю:
headersize=8байт+9байт*255
но не всегда выходит нужное число, проверяемое обратным методом:
headersize = кол-во полей * 32 +33
что не так делаю ?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1529
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 17.03.20 23:14. Заголовок: MIKHAIL пишет: что ..


MIKHAIL пишет:

 цитата:
что не так делаю ?

эавтра с компа пример сброшу. С телефона неудобно

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 7176
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.03.20 09:55. Заголовок: может это поможет ht..

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 6603
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 18.03.20 11:01. Заголовок: Всем привет ! Я не с..


Всем привет !
Я не совсем понимаю зачем нужно переименовывать поле в базе ?
Просто интересно.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1530
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 18.03.20 11:05. Заголовок: MIKHAIL пишет: я сч..


MIKHAIL пишет:

 цитата:
я считаю:
headersize=8байт+9байт*255


длинна заголовка в байтах получается так (
 
fSeek( n, 8)
cBuf := Space(2)
fRead( n, @cBuf, hb_BLen(cBuf) )
? "Header size :" , Bin2L( cBuf )


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 260
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 18.03.20 11:20. Заголовок: Dima пишет: может э..


Dima пишет:

 цитата:
может это поможет http://www.realcoding.net/articles/struktura-dbf-failov-dlya-neprodvinutykh.html


Это я знаю, тут то же самое:

 цитата:
Этот же размер можно извлечь из 8,9 байтов заголовка - HeaderSize


У меня значения байтов не сходиться почему то. Наверное не правильно вычисляю размер...

Andrey пишет:

 цитата:
Я не совсем понимаю зачем нужно переименовывать поле в базе ?


Потребность возникла при обновлении больших сетевых фалов, если требуется изменить имя поля. Обычно создается новая структура и туда перегоняются данные. Это очень медленно. Если можно изменить имя поля в заголовке, без изменения структуры данных, это очень быстро. Причины для изменения могут быть у каждого свои.... Я например сделал имя которое в дальнейшем начало конфликтовать с другими подсистемами, и мне проще его поменять в заголовке чем гонять данные...

Haz пишет:

 цитата:
Bin2L( cBuf )


Попробую, спасибо.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 3924
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 18.03.20 20:17. Заголовок: MIKHAIL пишет: head..


MIKHAIL пишет:

 цитата:
headersize=8байт+9байт*255



Умножать надо на 256. А лучше считать 2 байта и передать их функции Bin2I. Bin2L это для 4-х байт

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1531
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 18.03.20 20:31. Заголовок: Pasha пишет: Bin2L ..


Pasha пишет:

 цитата:
Bin2L это для 4-х байт


Да, упустил. Всё верно Bin2I

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 261
Зарегистрирован: 05.10.06
ссылка на сообщение  Отправлено: 19.03.20 15:43. Заголовок: Haz пишет: Всё вер..


Haz пишет:

 цитата:
Всё верно Bin2I



Все работает, только почему то расчет кол-ва полей отличается от описанной структуры dbf
кол-во полей получается по формуле (headersize-34)/32
А символ окончания заголовка - chr(13) находится по адресу headersize - 2

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1532
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 19.03.20 16:25. Заголовок: MIKHAIL пишет: А си..


MIKHAIL пишет:

 цитата:
А символ окончания заголовка - chr(13) находится по адресу headersize - 2


В некоторых источниках то что хранится в в 08-09 называют адресом первой записи.
Может в этом дело , да и счет начинается с нулевого адреса ( а по сути он первый )
PS
не проверял но вроде сходится
Пусть имеем 100 полей тогда
сам заголовок 32 байта + 100 дескриптор полей по 32 + терминатор =
32 + 100*32 + 1 = 3233 ( занято )
тогда в 8-9 должен быть записан адрес первой записи как 3234

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1533
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 19.03.20 16:43. Заголовок: Haz пишет: не прове..


Haz пишет:

 цитата:
не проверял но вроде сходится


проверил по какой то dbf c двумя полями в 8-9 записано 98
считаем
32 + 2*32 + 1 = 97
значит первая запись начнется с 98

Спасибо: 1 
ПрофильЦитата Ответить
Администратор




Пост N: 3925
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 20.03.20 10:23. Заголовок: MIKHAIL пишет: Все ..


MIKHAIL пишет:

 цитата:
Все работает, только почему то расчет кол-ва полей отличается от описанной структуры dbf
кол-во полей получается по формуле (headersize-34)/32



Немного не так, формула (headersize-32)/32

Посмотрите класс для низкоуровневой работы c dbf, там разбираются разные форматы, и можно обращаться к полям по имени:

oDbf:FieldName

Ссылка на класс:
https://cloud.mail.ru/public/458B/4hTkEJg3a

PS Функцию WinToDos замените на HB_ANSITOOEM

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 647
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет