powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / отключить dbf от контейнера
14 сообщений из 14, страница 1 из 1
отключить dbf от контейнера
    #34416253
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
задача: отключить dbf от контейнера не открывая его.
вроде все понятно: найду в заголовку место где написано что подключен к контейнеру (после описания структуры полей) и впишу первый байт из них 0 и файл стал свободным,
смещения можно найти или исходя из количества поле, или из смещения начало данные,
но не получается получить эти цифры из заголовка dbf
функции filetostr() fread() после прочтения данных преобразуют их в печатные символы и asc() уже не возвращает истинного числа записаного в определенном байте.
что посоветуете?
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34416280
Sergey Sizov.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Покажи как это делалось. Что-то не верится.
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34416493
Burn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>что посоветуете?
Преобразовывать считаные байты в числа - ты считываешь последовательность байт, которые фокс интепритирует как символы. Хотя для сброса признака контейнера достаточно проверить чему равен байт - скорее всего Chr(1) и записать на его место новый - Chr(0)
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34416508
Burn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В контейнере - Chr(4)
Есть мемо - Chr(2)
Есть cdx- Chr(1)
Ну и там комбинации - Chr(5)->Chr(1),Chr(6)->Chr(2),Chr(7)->Chr(3)
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417212
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Sergey Sizov.Покажи как это делалось. Что-то не верится.
да в том то и дело что не получается.
а задумано так:
tables_dbf="C:\ASUP21\dbf\v0301.dbf"
fff=fopen(tables_dbf, 12)
if fff>0
=FSEEK(fff, 8, 0) && байты 8-9 начало данных s=fread(fff,1)
fc=asc(s)
s=fread(fff,1)
fc=asc(s)*256+fc
fc=fc-263 && с этой позиции вписано dbc
=FSEEK(fff, fc, 0)
=fwrite(fff,s,chr(0)) && зачистить dbc
=fclose(fff)
else
wait window time 3 "неполучилось" endif
вычисленная FC несоотвествует нужной. присвоение
fc=asc(s)
оказываются неверным - если считанный символ оказывается непечатным, то он превращается в пробел
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417213
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Burn>Преобразовывать считаные байты в числа - ты считываешь последовательность байт, которые фокс интепритирует как символы.
ну я тоже так думал, но считанные быйты уже в момент считывания искажаются
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417216
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BurnВ контейнере - Chr(4)
Есть мемо - Chr(2)
Есть cdx- Chr(1)
Ну и там комбинации - Chr(5)->Chr(1),Chr(6)->Chr(2),Chr(7)->Chr(3)

Chr(4) в позиции 28 означает что сам dbf является контейнером, а не входит в него
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417279
Burn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>ну я тоже так думал, но считанные быйты уже в момент считывания искажаются
Первый раз такое слышу - в свое время еще для FPD 2.6 писал процедурку исправления заголовка и ничего с тех пор не искажалось

Код: 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.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
FUNCTION NOT_DBF
PARAMETERS file_name

*   Размер файла
=ADir(a_file, file_name)
file_size=a_file( 1 , 2 )

*   Множетели для перевода
DIMENSION a_mult( 4 ), a_byte( 4 )
a_mult( 1 )= 1 
a_mult( 2 )= 256 
a_mult( 3 )= 65536 
a_mult( 4 )= 16777216 
a_byte= 0 

file_hand=FOpen(file_name, 2 )

*   Невозможно открыть файл
IF file_hand = - 1 
   RETURN TO opendbf .f.
ELSE
*   Пустой файл
   =FSeek(file_hand,  0 ,  0 )
   IF FEOF(file_hand)
      IF .not.FClose(file_hand)
         CLOSE ALL
      ENDIF
      RETURN TO opendbf .f.
   ELSE
*   Не DBF-фовский файл
      m_byte=FRead(file_hand, 1 )
      IF m_byte <> Chr( 3 ).and.;
         m_byte <> Chr( 131 ).and.;
         m_byte <> Chr( 139 ).and.;
         m_byte <> Chr( 245 )
         IF .not.FClose(file_hand)
            CLOSE ALL
         ENDIF
         RETURN TO opendbf .f.
      ELSE
*   Перевод в десятичные числа количества записей
         m_count= 0 
         FOR i= 0  TO  3 
            =FSeek(file_hand,  4 +i,  0 )
            m_byte=FRead(file_hand,  1 )
            m_count=m_count+ASC(m_byte)*a_mult(i+ 1 )
         ENDFOR
         
*   Перевод в десятичные числа длинны заголовка
         m_hand= 0 
         FOR i= 0  TO  1 
            =FSeek(file_hand,  8 +i,  0 )
            m_byte=FRead(file_hand,  1 )
            m_hand=m_hand+ASC(m_byte)*a_mult(i+ 1 )
         ENDFOR
         
*   Перевод в десятичные числа длинны записи
         m_size= 0 
         FOR i= 0  TO  1 
            =FSeek(file_hand,  10 +i,  0 )
            m_byte=FRead(file_hand,  1 )
            m_size=m_size+ASC(m_byte)*a_mult(i+ 1 )
         ENDFOR
         
*   Размер файла
         m_file_size=m_count*m_size+m_hand+ 1 
         
         IF file_size <> m_file_size
*   Реальная и расчетная длинна файлов не совпадает
            IF file_size > m_file_size
*   Если расчетная длина больше расчетной то файл усекаем            
               =FChSize(file_hand, m_file_size)
            ELSE
*   Если расчетная больше, то корректируем заголовок
               IF Mod(file_size-(m_hand+ 1 ), m_size) =  0 
*   Если нет в конце лишних байт, то просто в заголовке уменьшаем
*   число записей
                  m_new_count=(file_size-(m_hand+ 1 ))/m_size
                  
*   Перевод числа записей в шестнадцатиричные
                  IF m_new_count >= a_mult( 4 )
                     a_byte( 4 )=Int(m_new_count/a_mult( 4 ))
                     m_new_count=Mod(m_new_count, a_mult( 4 ))
                  ENDIF
                  IF m_new_count >= a_mult( 3 )
                     a_byte( 3 )=Int(m_new_count/a_mult( 3 ))
                     m_new_count=Mod(m_new_count, a_mult( 3 ))
                  ENDIF
                  IF m_new_count >= a_mult( 2 )
                     a_byte( 2 )=Int(m_new_count/a_mult( 2 ))
                     m_new_count=Mod(m_new_count, a_mult( 2 ))
                  ENDIF
                  a_byte( 1 )=m_new_count
                  
*   Запись в файл
                  FOR i= 0  TO  3 
                     m_byte=Chr(a_byte(i+ 1 ))
                     =FSeek(file_hand,  4 +i,  0 )
                     =FWrite(file_hand, m_byte,  1 )
                  ENDFOR
               ELSE
*   Определяем число лишних байт и усекаем файл
                  m_diff=Mod(file_size-(m_hand+ 1 ), m_size)
                  =FChSize(file_hand, file_size-m_diff)
                  
*   Уменьшаем в заголовке число записей
                  m_new_count=(file_size-m_diff-(m_hand+ 1 ))/m_size
                  
*   Перевод числа записей в шестнадцатиричные
                  IF m_new_count >= a_mult( 4 )
                     a_byte( 4 )=Int(m_new_count/a_mult( 4 ))
                     m_new_count=Mod(m_new_count, a_mult( 4 ))
                  ENDIF
                  IF m_new_count >= a_mult( 3 )
                     a_byte( 3 )=Int(m_new_count/a_mult( 3 ))
                     m_new_count=Mod(m_new_count, a_mult( 3 ))
                  ENDIF
                  IF m_new_count >= a_mult( 2 )
                     a_byte( 2 )=Int(m_new_count/a_mult( 2 ))
                     m_new_count=Mod(m_new_count, a_mult( 2 ))
                  ENDIF
                  a_byte( 1 )=m_new_count
                  
*   Запись в файл
                  FOR i= 0  TO  3 
                     m_byte=Chr(a_byte(i+ 1 ))
                     =FSeek(file_hand,  4 +i,  0 )
                     =FWrite(file_hand, m_byte,  1 )
                  ENDFOR
               ENDIF
            ENDIF
         ELSE
*   Файл невозможно исправить
            RETURN TO opendbf .f.
         ENDIF
         
         IF .not.FClose(file_hand)
            CLOSE ALL
         ENDIF
      ENDIF
   ENDIF
ENDIF
RETURN .t.

>Chr(4) в позиции 28 означает что сам dbf является контейнером, а не входит в него
Ну, значит невнимательно читал хелп
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417338
alex11100
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
убивает в заголовке привязку к контейнеру
Код: 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.
FUNCTION EraseByteInStru
LPARAMETERS fullctablename, ismodidbffile
IF EMPTY(fullctablename)
     RETURN .F.
ENDIF
dbfopenhandle = FOPEN(fullctablename,  12 )
IF dbfopenhandle <  0 
     RETURN .F.
ENDIF
= FSEEK(dbfopenhandle,  27 )
cdxmemodbcbyte = FREAD(dbfopenhandle,  1 )
IF ASC(cdxmemodbcbyte) >=  4  .AND. ismodidbffile = .T.
     newcdxmemodbcbyte = CHR(ASC(cdxmemodbcbyte) -  4 )
     = FSEEK(dbfopenhandle,  27 )
     = FWRITE(dbfopenhandle, newcdxmemodbcbyte)
ENDIF
isintablechr13 = .F.
FOR forfscan =  1  TO  10000 
     IF FREAD(dbfopenhandle,  1 ) = CHR( 13 )
          isintablechr13 = .T.
          EXIT
     ENDIF
ENDFOR
IF isintablechr13 = .T.
     IF ismodidbffile = .T.
          FWRITE(dbfopenhandle, REPLICATE(CHR( 0 ),  263 ))
          = FCLOSE(dbfopenhandle)
     ELSE
          dbflinktodbc = FREAD(dbfopenhandle,  263 )
          = FCLOSE(dbfopenhandle)
          RETURN dbflinktodbc
     ENDIF
ELSE
     = FCLOSE(dbfopenhandle)
     RETURN .F.
ENDIF
RETURN .T.
ENDFUNC
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417373
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex11100убивает в заголовке привязку к контейнеру
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
...
isintablechr13 = .F.
FOR forfscan =  1  TO  10000 
     IF FREAD(dbfopenhandle,  1 ) = CHR( 13 )
          isintablechr13 = .T.
          EXIT
     ENDIF
ENDFOR
IF isintablechr13 = .T.
...
ENDIF

исходит из того что в блоке описания поле не может встретится байт 13 - а это не верно - это может быть размер поля
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417433
alex11100
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну найдите конец заголовка (начало записей по-умному)
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417501
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
дак вот пытаюсь найти - немогу понять почему она искажает байты при чтении?
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417543
Алексей О
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ой. прошу прощения у всех участвовавших
все работает так как и задумывалось - только не с тем сверял
...
Рейтинг: 0 / 0
отключить dbf от контейнера
    #34417763
Burn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
исходит из того что в блоке описания поле не может встретится байт 13 - а это не верно - это может быть размер поля
Действительно косяк. Синкс.
Но тогда не нарывался. А сейчас это не актуально. Так храню как пример работы
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / отключить dbf от контейнера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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