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



Пост N: 27
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 09.02.07 14:50. Заголовок: Сохранение массивов в MEM-файле


Товарищи, кто подскажет - я помню, где-то видел, что в Харборе, в отличие от Клиппера, можно сохранять и массивы. А у меня почему-то не работает.
(Используется Harbour Compiler (CVS 2007-01-17 13:50)
Copyright 1999-2007, http://www.harbour-project.org/
Harbour MiniGUI Extended Distribution)
Заранее благодарен.

Спасибо: 0 
Профиль
Ответов - 22 , стр: 1 2 All [только новые]


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


Пост N: 57
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 11.02.07 10:34. Заголовок: Re:


В Клиппере массивы в текстовый файл можно сохранять и восстанавливать , с Мемо полями не пробовал

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


Пост N: 111
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 11.02.07 18:35. Заголовок: Re:


AM пишет:

 цитата:
я помню, где-то видел, что в Харборе, в отличие от Клиппера, можно сохранять и массивы. А у меня почему-то не работает



Вместе с Harbour MiniGUI Extended Distribution распространяется (x)harbour.chm ( см. harbour\doc)

Цитата:

The SAVE command saves public and private memory variables visible within the current procedure or user-defined function to a memory file. The arrays and local and static variables can not be saved to a file.

Vlad04 пишет:

 цитата:
В Клиппере массивы в текстовый файл можно сохранять и восстанавливать



Это реализуется с использованием пользовательской функции. Так можно поступать и в [x]Harbour.
Если не хочется писать самому. можно поискать на http://www.the-oasis.net


Спасибо: 0 
Профиль



Пост N: 28
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 12.02.07 12:18. Заголовок: Re:


Жаль, но где-то я что-то такое видел. Наверно, перепутал с Аляской.

Спасибо: 0 
Профиль





Пост N: 107
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 13.02.07 11:44. Заголовок: Re:


Может это подойдет:

http://www.the-oasis.net/thereef/files/clipper/a2file.zip - Save Clipper Arrays to File.

http://www.the-oasis.net/files/general/arr2fi.zip - Save Clipper arrays to disc, also STOD() function.

Спасибо: 0 
Профиль



Пост N: 29
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 13.02.07 16:52. Заголовок: Re:


Чего-то я по указанным ссылкам не нашёл, вот сам написал:

function saveArr(el) //преобразование массива в строку (для SAVE)
local i,res:=''
DO CASE
CASE VALTYPE(el)='N'
res+='N'+str_t(el)
CASE VALTYPE(el)='L'
res+='L'+IF(el,'T','F')
CASE VALTYPE(el)='C'
res+='C'+str_t(len(el))+':'+el
CASE VALTYPE(el)='D'
res+='D'+DTOS(el)
CASE VALTYPE(el)='U'
res+='U'
CASE VALTYPE(el)='A'
res+='A'+str_t(len(el))+':'
for i=1 to len(el)
res+=saveArr(el)+if(i=len(el),'',',')
next
OTHERWISE
res+='U'
//msay('Недопустимый тип')
ENDCASE
return res

function restArr() //преобразование строки в массив (после RESTORE)
parameters r
private cur_ind:=1
return add_el()
static func add_el()
memvar r,cur_ind
local data_type:=substr(r,cur_ind++,1)
local ret,l,i
do case
case data_type='A'
l=val(substr(r,cur_ind))
do while substr(r,cur_ind++,1)#':'
enddo
ret={}
for i=1 to l
aadd(ret,add_el())
next l
if l=0
cur_ind++
endif
case data_type='C'
l=val(substr(r,cur_ind))
do while substr(r,cur_ind++,1)#':'
enddo
ret=substr(r,cur_ind,l)
cur_ind+=l+1
case data_type='N'
ret=val(substr(r,cur_ind))
do while substr(r,cur_ind++,1)#','.and.cur_ind<len(r)
enddo
case data_type='D'
ret=STOD(substr(r,cur_ind,8))
cur_ind+=9
case data_type='L'
ret=(substr(r,cur_ind,1)='T')
cur_ind+=2
case data_type='U'
cur_ind++
ret=nil
endcase
return ret

Вроде в первом приближении работает.

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


Пост N: 282
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 13.02.07 18:21. Заголовок: Re:


Коллега, позвольте высказать свои критические замечания.
Вместо

VALTYPE( el ) = 'N' // 'C', 'L' etc.

я предпочитаю известные макросы

ISNUMBER( el )
ISCHARACTER( el )
ISLOGICAL( el )
или
ISNIL( el )

то есть код выглядел бы так

DO CASE

CASE ISNUMBER( el )
...
CASE ISCHARACTER( el )
...
CASE ISLOGICAL( el )

На мой взгляд такой текст выглядет более привлекательным.

Не понятно назначение функции restArr(). Она введена только для того, чтобы объявить две PRIVATE переменные r и cur_ind? Зачем это делается? В программе не должно быть НИ одной PRIVATE переменной. Наличие PRIVATE переменной говорит о том, что код неудачно спроектирован.

Да, чтобы не получить GPF, не забудьте проверять, чтобы суммарная длина строки не превосходила максимального значения длины для строк в Clipper.



Спасибо: 0 
Профиль



Пост N: 33
Зарегистрирован: 27.04.06
ссылка на сообщение  Отправлено: 13.02.07 20:03. Заголовок: Re:


А я думал здесь форум [x]Harbour...
заблудился

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


Пост N: 58
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 14.02.07 09:45. Заголовок: Re:


Вот нормальные функции для записи и чтения многомерных массивов в текстовые файлы.
Нашел в толстой книге много лет назад.
/***
Запись и сохранение в текстовом файле МАССИВА
***/
func Asave(NameF,Mas)
Private N:=FCreate(Namef)
if(N #-1,(_save(Mas),Fclose(n)),)
Return N#-1
***
Static Proc _Save(Mas,Alen,tip,i,M)
Alen=Len(Mas)
FWrite(N,"A"+str(Alen,4))
For i:=1 TO Alen
M=Mas;tip=Valtype(M)
tip+=Iif(tip="N",(M:=Ltrim(Str(M)),Str(Len(M),2)+M),;
Iif(tip="C",Str(Len(M),4) +M,Iif(tip="D",dtoc(M),;
Iif(tip="L",Iif(M,"T","F"),""))))
Iif(tip="A",_Save(M),Iif(tip#"B",Fwrite(N,tip),))
NEXT
***
FUNC Arest (NameF,Ret)
Private N:=Fopen(Namef)
if(N #-1,(Fseek(N,1),Ret:=_Rest(),Fclose(N)),Ret:=NIL)
Return Ret
***
Static Func _Rest(Alen,tip,i,M)
Alen =Val(Freadstr(N,4)); M= Array(Alen)
For i:=1 TO Alen
tip = Freadstr(N,1)
M =Iif(tip ="A",_Rest(),;
Iif(tip="C",Freadstr(N,Val(Freadstr(N,4))),;
Iif(tip="N",Val(Freadstr(N,Val(Freadstr(N,2)))),;
Iif(tip="D",CTOD(Freadstr(N,8)),;
Iif(tip="L",Freadstr(N,1)="T",NIL )))))
Next
return M

Все работает и на Клиппере и на Харборе. Ну, а в Мемо записать - еще пару операций добавить.

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




Пост N: 636
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 14.02.07 09:54. Заголовок: Re:


Vlad04 пишет:

 цитата:
Нашел в толстой книге много лет назад


а что это за книга ?

Спасибо: 0 
Профиль



Пост N: 30
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 14.02.07 10:31. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
я предпочитаю известные макросы

ISNUMBER( el )
ISCHARACTER( el )
ISLOGICAL( el )
или
ISNIL( el )


Я их не знал.
Григорьев Владимир пишет:

 цитата:
Не понятно назначение функции restArr().


Для многомерных массивов нужны рекурсивные вызовы, а переменные должны быть одни и те же во всех вызовах. Наверно, можно и как-то иначе, но, главное - работает.
( str_t() - это trim(str()) )
Григорьев Владимир пишет:

 цитата:
В программе не должно быть НИ одной PRIVATE переменной. Наличие PRIVATE переменной говорит о том, что код неудачно спроектирован.


Зачем отказываться от использования возможностей языка? Когда-то я писал на Клиппере и мне было велено обойтись без PUBLIC и PRIVATE переменных. Для процедур, вызываемых асинхронно (по клавишам), при таком ограничении приходилось "вставать на уши". Отмена этого ограничения сделала программирование лёгким и приятным.
Григорьев Владимир пишет:

 цитата:
не забудьте проверять, чтобы суммарная длина строки не превосходила максимального значения длины для строк в Clipper


В Харборе же вроде такое ограничение снято.
Vlad04 пишет:

 цитата:
нормальные функции для записи и чтения многомерных массивов в текстовые файлы.


В общем, примерно как у меня, только пишет в файл. Но в отдельный файл как раз не очень надо, лучше всё вместе в один стандартный .MEM, формат которого можно и не знать.

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


Пост N: 283
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 14.02.07 12:30. Заголовок: Re:


AM пишет:

 цитата:
Для многомерных массивов нужны рекурсивные вызовы, а переменные должны быть одни и те же во всех вызовах. Наверно, можно и как-то иначе, но, главное - работает.



Вы можете легко обойтись без PRIVATE переменных и без дополнительного уровня в виде функции просто вызывая add_el() с параметрами. Например, если add_el() вызывается без параметров, то вы внутри нее сами устанавливаете начальные значения. В остальных случаях эта функция использует значения из параметров. Можно также использовать механизм STATIC переменных, объявленных внутри самой функции.
Я уже давно убедился, что на самом деле важно не то, чтобы "работало", а то, чтобы "правильно" было написано. Тогда "работало" будет простым следствием. А правильно писать - это 1) чтобы код был читабелен любому программисту, который даже не знает Clipper (а это значит, например, не использовать сокращения команд до 4 знаков, как это многие обычно делают в Clipper); 2) не использовать конструкции языка, которые имеют побочные эффекты и чреваты возникновением потенциальных ошибок и трудно сопровождаемые.

Спасибо: 0 
Профиль



Пост N: 31
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 14.02.07 14:08. Заголовок: Re:


Да, возможно, вы правы. Но, как правило, более читабелен более короткий код (я не имею в виду сокращения). Да и для разных людей более читабельно разное, а слишком узкие рамки губительны для творчества - я имею в виду не бедность средств, а необходимость мыслить в определённом ключе. Из-за этого я совершенно не смог работать с 1С, хотя меня сначала сами позвали по старой памяти.

Спасибо: 0 
Профиль





Пост N: 108
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 14.02.07 19:07. Заголовок: Re:


Dima пишет:

 цитата:
Vlad04 пишет:
цитата:
Нашел в толстой книге много лет назад

а что это за книга ?



Может быть, это книга Рика Спенса?
Вот здесь есть много примеров из этой книги, в том числе и по сохранению массивов:
http://ort.ho.com.ua/spense.exe


Спасибо: 0 
Профиль



Пост N: 7
Зарегистрирован: 19.12.06
ссылка на сообщение  Отправлено: 15.02.07 12:05. Заголовок: Re:


А кто знает - как обойти проблему - программа на клиппере сохраняет массив в мемо файле. Та же программа на harbour этот массив при чтении видит как строку. Драйвер баз данных ADS, копался в исходниках - похоже не умеет ADS в harbour читать / писать массивы в мемо файл . Где бы взять хотя-бы формат в котором эти массивы записываются ?

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


Пост N: 284
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 15.02.07 15:58. Заголовок: Re:


k_dima пишет:

 цитата:
Где бы взять хотя-бы формат в котором эти массивы записываются ?


Я думаю, это можно взять в той программе на Clipper, которая их записывает.
Или самому по строке, которая считывается из MEMO поля, определить формат.

Спасибо: 0 
Профиль



Пост N: 8
Зарегистрирован: 19.12.06
ссылка на сообщение  Отправлено: 15.02.07 17:02. Заголовок: Re:


хороший совет - только строка то бинарная - то есть имеется заголовок - наверное длина массива и имеются разделители элементов массива - то же в двоичном виде и вот это как раз расшифровать не удается нужно знать формат, так, чтобы иметь возможность и читать и писать массивы в мемо поле. Причем глюки идут только с драйвером ADS, harbour DBFCDX отрабатывает нормально и возвращает при чтении из мемо поля массив. Попробовал покопаться в исходниках dbfcdx, но силенок не хватает

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


Пост N: 59
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 16.02.07 10:29. Заголовок: Re:


А поподробнее нельзя, что делает ADS с массивом ?
А книга(см.выше) назавалась "CLIPPER & FOXPRO Практикум программирования". Автор Зубов

Спасибо: 0 
Профиль



Пост N: 32
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 16.02.07 11:37. Заголовок: Re: - новое!


k_dima пишет:

 цитата:
то же в двоичном виде и вот это как раз расшифровать не удается нужно знать формат


Чтобы расшифровать двоичный файл, рекомендую посмотреть, чем отличаются результаты при небольших изменениях данных (для поиска отличий можно использовать FC /B ). Для последующего анализа удобно распечатать нужные куски в HEX-формате (чтоб можно было на них черкать). Если не было специально сделано, чтобы затруднить расшифровку, то должно получиться, хотя более сложные случаи могут вылезти потом.

Спасибо: 0 
Профиль



Пост N: 9
Зарегистрирован: 19.12.06
ссылка на сообщение  Отправлено: 16.02.07 15:04. Заголовок: Re:


Подробнее -имеется база данных и мемо файл в который программа на клиппере + ADS в мемо поле пишет массивы - при переводе этой программы на xharbour , драйвер DBFCDX корректно возвращает тип поля "A" и корректно восстанавливает массив, даже если он многомерный, драйвер ADS для harbour возвращает тип данных "C", бинарную строку , и если массив многомерный то выдрать из этой строки многомерный массив не представляется возможным. В исходниках DBFCDX явно видно что мемо поля могут иметь тип HB_IT_ARRAY, в исходниках RDDADS при обработке мемо полей массивы не обрабатываются вообще - все сводится к обработке типа ADS_VARCHAR, ADS_BINARY, ADS_IMAGE. В общем придется отказываться от массивов в мемо - полях - от ADS отказаться не могу.
а разбираться в двоичных строках методом тыка времени нет.
> А поподробнее нельзя, что делает ADS с массивом ?


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


Пост N: 112
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 16.02.07 20:19. Заголовок: Re:


k_dima пишет:

 цитата:
В исходниках DBFCDX явно видно что мемо поля могут иметь тип HB_IT_ARRAY



Где именно ? (файл, строка)


Спасибо: 0 
Профиль
Ответов - 22 , стр: 1 2 All [только новые]
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 11
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет