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





Пост N: 117
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 08.04.08 16:47. Заголовок: Чтение массива из мемо-поля


Всем привет!
В мемо-полях записаны массивы такого типа:
{111,{1,"HK"},"AAA",{{1,"55"},{"2","77"}},123,{.T.,STOD("20080201")}}
Т.е. в массиве очень разнородные значения плюс куча вложенных массивов.
Если длина поля меньше 512 - делаю макро & и все ок.
Но при длине > 512 - Ошибка BASE/1513 Operation too complex: &
Пожалуйста, помогите с функцией чтения такого массива.
Может где-то есть готовое решение?

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


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


Пост N: 81
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 09.04.08 13:23. Заголовок: Сорри, накорябал на ..


Сорри, накорябал на скорую руку. Вроде работает. Попробуй.


LOCAL cStr := "{ 111, { 1, 'HK' }, 'AAA', { { 1, '55' }, { '2', '77' } }, 123, { .T., Date() } }"
LOCAL nPos := 1
LOCAL aRes := {}




aRes := ArrayFromStr( cStr, nPos )

QUIT


FUNCTION ArrayFromStr( cStr, nPos )


LOCAL i
LOCAL c
LOCAL cItem := ""
LOCAL xItem
LOCAL aSubArr



FOR i := nPos TO Len( cStr )
c := SubStr( cStr, i, 1 )

IF c == "{"
i++
IF ISNIL( aSubArr )
aSubArr := AClone( ArrayFromStr( cStr, @i ) )
ELSE
AAdd( aSubArr, AClone( ArrayFromStr( cStr, @i ) ) )
END // IF
ELSEIF c == "," .or. c == "}"
IF ISNIL( aSubArr )
aSubArr := {}
END // IF
cItem := AllTrim( cItem )
IF ! Empty( cItem )
xItem := &( cItem )
AAdd( aSubArr, xItem )
END // IF
cItem := ""
xItem := NIL
IF c == "}"
nPos := i+1
RETURN aSubArr
END // IF
ELSE
cItem += c
END // IF

NEXT

RETURN aSubArr


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





Пост N: 118
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 09.04.08 14:57. Заголовок: Спасибо, PSP ! Я под..


Спасибо, PSP !
Я подозревал, что без рекурсивных вызовов здесь не обойтись.
Сегодня обязательно попробую!

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


Пост N: 82
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 09.04.08 16:52. Заголовок: ort пишет: Спасибо,..


ort пишет:

 цитата:
Спасибо, PSP !


Не за что! :)

ort пишет:

 цитата:
Я подозревал, что без рекурсивных вызовов здесь не обойтись.


Очень удобная штука. Проверь пример, пжалста, прежде, чем использовать.

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




Пост N: 113
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 10.04.08 07:54. Заголовок: ort пишет: Может гд..


ort пишет:

 цитата:
Может где-то есть готовое решение?



1. clipper 5.2e from SUV - мощность макроподстановки 2048 символов

насчет "512 символов и все ок" - я бы не стал заблуждаться. Насколько помню, емкость буфера для пикода, получаемого из компиляции строки - 256 символов, если буфер переполняется - то это не всегда отслеживается и тупо трутся системные переменные (или иногда отслеживается и даже генерируется runtime-ошибка , но переменные все равно трутся и корректность дальнейшего выполнения программы под очень большим вопросом)

2. хранение массивов в SIxMemo

3. arrayFromStr (c) psp. Странно, что ты "подозревал про рекурсию". В общем случае без нее не обойтись не только при получении из строки массива, но и при исходной операции - конвертировании нативного массива в строку. "C"-значения-то у тебя откуда берутся, б-г даёт что ли?

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





Пост N: 120
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 10.04.08 12:00. Заголовок: suv2 пишет: clipper..


suv2 пишет:

 цитата:
clipper 5.2e from SUV - мощность макроподстановки 2048 символов


Можете поделиться таким решением?

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




Пост N: 117
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 10.04.08 14:27. Заголовок: попробуй это. http..


попробуй это.

http://slil.ru/25674557

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


Пост N: 112
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 11.04.08 06:53. Заголовок: Храню массивы в тек..


Храню массивы в текстовых файлах.Нет проблем с размером

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





Пост N: 121
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 11.04.08 10:13. Заголовок: suv2 пишет: попробу..


suv2 пишет:

 цитата:
попробуй это.


Попробывал. Спасибо, работает!

Vlad04 пишет:

 цитата:
Храню массивы в текстовых файлах.Нет проблем с размером


Проблема возникает не при хранении, а при чтении.

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





Пост N: 122
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 11.04.08 11:58. Заголовок: PSP пишет: Проверь ..


PSP пишет:

 цитата:
Проверь пример, пжалста, прежде, чем использовать.


На данном примере работает.
Но на таком простом cStr := "{{{4444,88}}}"
выдает такой результат: {4444,88,{4444,88}}
Никак не могу понять почему?
Вот функция для проверки результата:
Function StrFromArray(aArr) 
LOCAL j, cStr := ""

cStr := "{"
FOR j=1 TO Len(aArr)
IF ValType(aArr[j]) == 'A'
cStr += StrFromArray(aArr[j])
ELSE
IF ValType(aArr[j]) == 'N'
cStr += TrimStr(aArr[j])
ELSEIF ValType(aArr[j]) == 'L'
cStr += '.'+LTOC(aArr[j])+'.'
ELSEIF ValType(aArr[j]) == 'D'
cStr += 'STOD("'+DTOS(aArr[j])+'")'
ELSEIF ValType(aArr[j]) == 'C'
cStr += '"'+aArr[j]+'"'
ENDIF
ENDIF
IF j < Len(aArr) ; cStr += "," ; ENDIF
NEXT
cStr += "}"
RETURN cStr



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


Пост N: 83
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 11.04.08 12:47. Заголовок: Я ж говорю, не прове..


Я ж говорю, не проверял. Вот так вроде правильней...

 
LOCAL cStr := "{{{123,456,789}}}"
LOCAL nPos := 1
LOCAL aRes := {}


aRes := ArrayFromStr( cStr, nPos, .F. )

QUIT



FUNCTION ArrayFromStr( cStr, nPos, lRecurs )


LOCAL i
LOCAL c
LOCAL cItem := ""
LOCAL xItem
LOCAL aSubArr := {}



FOR i := nPos TO Len( cStr )
c := SubStr( cStr, i, 1 )

IF c == "{"
i++
IF lRecurs
AAdd( aSubArr, AClone( ArrayFromStr( cStr, @i, .T. ) ) )
ELSE
aSubArr := AClone( ArrayFromStr( cStr, @i, .T. ) )
END // IF

ELSEIF c == "," .or. c == "}"
cItem := AllTrim( cItem )
IF ! Empty( cItem )
xItem := &( cItem )
AAdd( aSubArr, xItem )
END // IF
cItem := ""
xItem := NIL
IF c == "}"
nPos := i
RETURN aSubArr
END // IF
ELSE
cItem += c
END // IF

NEXT


RETURN aSubArr



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





Пост N: 123
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 11.04.08 15:01. Заголовок: PSP пишет: Я ж гово..


PSP пишет:

 цитата:
Я ж говорю, не проверял.


Я без претензий, просто очень хотелось довести работу до конца.
Я все подкручивал и подкручивал - а результата не было...
Спасибо!
Теперь ей по зубам ЛЮБОЙ массив!

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


Пост N: 84
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 12.04.08 09:11. Заголовок: Рад, что пригодилось..


Рад, что пригодилось. Пользуйся на здоровье! :)

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




Пост N: 118
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 13.04.08 15:55. Заголовок: ort пишет: Попробыв..


ort пишет:

 цитата:
Попробывал. Спасибо, работает!



Ограничения все равно есть.

Нельзя использовать длинные строковые константы (больше 256 символов). А именно, нельзя вычислять &'[abcde......(очень много символов)......]'. Напоминаю, что квадратные скобки [] - это такой же полноправный ограничитель строковых констант, как одинарный ' или двойной " апостроф и в данном примере он выбран для улучшения читаемости. Пример можно было написать так
&["abcde......(очень много символов)......"]
или так &'"abcde......(очень много символов)......"'
или так &"'abcde......(очень много символов)......'"


Нельзя использовать длинные выражения фильтра (больше 256 символов).

С массивами все тоже непросто, я даже не могу сформулировать четкие ограничения, но тем не менее при достаточно длинном (сложном?) массиве всё падает. Например, при ста элементах {"A","A","A","A",......}. Тем не менее, я могу вычислить такое

{"aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa","aaaaaaa"}

Тут 99 элементов и 991 символ. Какие ограничения будут с многомерными массивами - надо экспрериментировать.

Итого - с помощью моего macro.obj можно только вычислять длинные макровыражения. То есть "A=1.and.B=2.and.C=3.......(очень много условий)....", а также можно компилировать длинные блоки кода &"{|| A:=1,B:=2,C:=3...... }"

Подходить близко к 256 (в выражении фильтра и в длине строковой константы) вообще опасно, длина примерная. Например, при компилировании выражения фильтра длина пи-кода в байтах получается примерно равной длине выражения фильтра и никто не даст гарантии, что при выражении длиной 240 символов скомпилированный пи-код не превысит свой максимум и не затрет при этом системные переменные. То же самое касается длинных строковых констант в макроподстановке. Если такое выражение вычислилось и без выпадения программы по GPF или internal error, это абслютно не означает, что все прошло гладко. Скорее всего при этом всё потёрлось и очень скоро программа начнет выкидывать чудовищные глюки.

Разумеется, всё это верно и при оригинальном macro.obj, мой вариант только лишь увеличивает длину макровыражения, а длину фильтра, строковых констант и сложность массивов я так и не победил.

Так что пожалуй, мой macro.obj твою проблему всё же не решает. Храни в сикс-мемо или компилируй сам (парсинг выражения)

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




Пост N: 119
Зарегистрирован: 24.09.05
ссылка на сообщение  Отправлено: 13.04.08 15:58. Заголовок: Интересно, почему дл..


Интересно, почему длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- длинные- строки в сообщении не переносятся?

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





Пост N: 124
Зарегистрирован: 06.06.06
ссылка на сообщение  Отправлено: 13.04.08 22:38. Заголовок: suv2 пишет: Так что..


suv2 пишет:

 цитата:
Так что пожалуй, мой macro.obj твою проблему всё же не решает. Храни в сикс-мемо или компилируй сам (парсинг выражения)


Буду пользоваться функцией ArrayFromStr(), написанной PSP.
suv2, спасибо за внимание и толковые разъяснения.

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


Пост N: 114
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 15.04.08 10:37. Заголовок: ort пишет: Проблема ..


ort пишет:

 цитата:
Проблема возникает не при хранении, а при чтении.


Нет проблем ни при записи, ни при чтении, ни при хранении. Все на них построено. В массивах хранятся настройки форм для просмотре таблиц , редактирования, печати.
Все ок.

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

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