Форум » Clipper » Чтение массива из мемо-поля » Ответить

Чтение массива из мемо-поля

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

Ответов - 16

PSP: Сорри, накорябал на скорую руку. Вроде работает. Попробуй. 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

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

PSP: ort пишет: Спасибо, PSP ! Не за что! :) ort пишет: Я подозревал, что без рекурсивных вызовов здесь не обойтись. Очень удобная штука. Проверь пример, пжалста, прежде, чем использовать.


suv2: ort пишет: Может где-то есть готовое решение? 1. clipper 5.2e from SUV - мощность макроподстановки 2048 символов насчет "512 символов и все ок" - я бы не стал заблуждаться. Насколько помню, емкость буфера для пикода, получаемого из компиляции строки - 256 символов, если буфер переполняется - то это не всегда отслеживается и тупо трутся системные переменные (или иногда отслеживается и даже генерируется runtime-ошибка , но переменные все равно трутся и корректность дальнейшего выполнения программы под очень большим вопросом) 2. хранение массивов в SIxMemo 3. arrayFromStr (c) psp. Странно, что ты "подозревал про рекурсию". В общем случае без нее не обойтись не только при получении из строки массива, но и при исходной операции - конвертировании нативного массива в строку. "C"-значения-то у тебя откуда берутся, б-г даёт что ли?

ort: suv2 пишет: clipper 5.2e from SUV - мощность макроподстановки 2048 символов Можете поделиться таким решением?

suv2: попробуй это. http://slil.ru/25674557

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

ort: suv2 пишет: попробуй это. Попробывал. Спасибо, работает! Vlad04 пишет: Храню массивы в текстовых файлах.Нет проблем с размером Проблема возникает не при хранении, а при чтении.

ort: PSP пишет: Проверь пример, пжалста, прежде, чем использовать. На данном примере работает. Но на таком простом cStr := "{{{4444,88}}}" выдает такой результат: {4444,88,{4444,88}} Никак не могу понять почему? Вот функция для проверки результата: [pre]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[/pre]

PSP: Я ж говорю, не проверял. Вот так вроде правильней... [pre] 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 [/pre]

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

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

suv2: 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 твою проблему всё же не решает. Храни в сикс-мемо или компилируй сам (парсинг выражения)

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

ort: suv2 пишет: Так что пожалуй, мой macro.obj твою проблему всё же не решает. Храни в сикс-мемо или компилируй сам (парсинг выражения) Буду пользоваться функцией ArrayFromStr(), написанной PSP. suv2, спасибо за внимание и толковые разъяснения.

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



полная версия страницы