Помогите получить реферал на BLOB

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Аватара пользователя
Aragorn
Активист
Сообщения: 113
Зарегистрирован: 11 Июль 2005, 12:40
Откуда: Москва

Помогите получить реферал на BLOB

Сообщение Aragorn »

Умоляю, не могу справиться с проблемой:
Пытаюсь написать универсальную программку, позволяющую перезаливать содержимое одного tps-файла в ему подобный.
Для этого написал шаблончик, который при перекомпиляции создает описания-зеркала всех таблиц, содержащихся в .dct. Файлы создаются с именами X_&имя_файла (соответственно префиксы, ключи и пр.пр.пр.). Глобальная очередь имя таблицы-реферал.
Может я и велосипед изобретаю, если что не так - подскажите, как лучше решить эту задачку.
Но все вроде работает, за исключением следующего утыка: структура RECORD перезальется через what/who/where, MEMO я так понимаю через file{Prop:Value, -X}, а вот как перезалить BLOBЫ?!?!?!
file{prop:blobs} дает количество blobov в таблице, и че?! как мне с ними быть?
в хелпе по 5.5 кларе есть примерчик примерно такого плана

Код: Выделить всё

ABlob &Blob
...
...
ABlob &= file{Prop:Blob, X#}
...
...ABlob{Prop:Label}...
когда я эту красоту применяю, прога падает насмерть на последнем операторе из примера.

Код: Выделить всё

If ABlob &= Null Then Stop('Null') End
выводит стоп...
ХЕЛП!!! Нужен реферал на БЛОБ!!!

Circumstances
C55 (Patch up to 7), ABC
-------------------------------
В истинном золоте блеска нет...
Аватара пользователя
Aragorn
Активист
Сообщения: 113
Зарегистрирован: 11 Июль 2005, 12:40
Откуда: Москва

Сообщение Aragorn »

Честное слово, ну очень надо!..
-------------------------------
В истинном золоте блеска нет...
Аватара пользователя
Admin
Администратор
Сообщения: 4010
Зарегистрирован: 05 Июль 2005, 15:59
Откуда: Хабаровск
Благодарил (а): 53 раза
Поблагодарили: 33 раза
Контактная информация:

Сообщение Admin »

попробуй вот так делать присвоение:

TO:FieldLabel{PROP:Size} = FROM:FieldLabel{PROP:Size}
TO:FieldLabel[0 : FROM:FieldLabel{PROP:Size} - 1] = FROM:FieldLabel[0 : FROM:FieldLabel{PROP:Size} - 1]
Аватара пользователя
Aragorn
Активист
Сообщения: 113
Зарегистрирован: 11 Июль 2005, 12:40
Откуда: Москва

Сообщение Aragorn »

А что есть FieldLabel? Если это имя конкретного BLOBa, то это не пойдет. Фокус в том, что я не должен знать, есть они в таблице, в каком количестве и с какими именами. Мне надо получать последовательно ссылки на все блобы, имеющиеся в таблице, и там с помощью prop:handle и prop:size их записывать в новую структуру...

а может, я не очень понял, что вы написали? можно поподробнее? пожалуйста...
-------------------------------
В истинном золоте блеска нет...
Аватара пользователя
Олег
Ветеран движения
Сообщения: 122
Зарегистрирован: 16 Июль 2005, 2:35
Откуда: Москва
Контактная информация:

Сообщение Олег »

Получить легально реферал на BLOB можно только в C6x
В младших версиях свойство PROP:Blob не работает для файловых блобов и используется ТОЛЬКО для OLE.
Но! Можно самому сформировать реферал на нужный BLOB:

refGrp GROUP
Blob &BLOB
END
ptrGrp GROUP,OVER(refGrp)
BlobFile &FILE
BlobNo SHORT
END
SourceBlob &BLOB
TargetBlob &BLOB

! Предполагаем, что в процедуру получаем рефералы на файлы через параметры _SourceFile и _TargetFile.
! Следует иметь в виду, что номера блобов и мемо-полей имеют сквозную нумерацию, поэтому перебирать их необходимо в одном цикле с проверкой типа и применением соответствующего алгоритма обработки

Blobs# = _SourceFile{PROP:Memos} + _SourceFile{PROP:Blobs}
Loop Blob# = 1 to Blobs#
if _SourceFile{PROP:Type,-Blob#} = 'MEMO'
! Код обработки MEMO-полей
else
ptrGrp.BlobFile &= _SourceFile
ptrGrp.BlobNo = Blob#
SourceBlob &= refGrp.Blob

ptrGrp.BlobFile &= _TargetFile
ptrGrp.BlobNo = Blob#
TargetBlob &= refGrp.Blob

! Код обработки BLOB-полей SourceBlob и TargetBlob
end
End

В вышеприведенном коде сделано еще одно допущение, что кол-во и порядок следования MEMO- и BLOB-полей совпадают в обоих файлах. В противном случае код получается несколько более сложным.

В качестве небольшой рекламки - все это и много другого уже давно реализовано в библиотеке DynaLib, которая имеет практически одинаковый функционал для всех последних версий C50/C55/C6x.
Фришную версию этой либы (с некоторыми ограничениями по сравнению с полной версией) вместе с примерами ее использования можно взять на сайте http://dynalib.narod.ru
Среди примеров, кстати, есть и простенький пример организации озвученной тобой задачи. Причем - без использования дополнительных шаблонов. Работа только с одним рефералом на исходный файл - в результате получаешь универсальную функцию создания бэкапов любых файлов. Кстати, среди методов либы есть и такие макрометоды, которые подобные задачи решают одним вызовом. Причем подобная задача для них - самая простая:))

Удачи!
Аватара пользователя
Aragorn
Активист
Сообщения: 113
Зарегистрирован: 11 Июль 2005, 12:40
Откуда: Москва

Сообщение Aragorn »

Сделал - ПОЛУЧИЛОСЬ!!! Большое спасибо!
Но!... Я теперь хочу знать:
- как это работает?! Указываем номер БЛОБа и все? Получаем реферал? Да, получаем.
А как к этому прийти самому? Где написано, как это делать? Общие принципы? Как именно Вы, Олег, к этому пришли? Не у велосипедистов же спросили? Где-то увидели, прочитали? Поделитьесь, пожалуйста, опытом - где про это почитать, и, буду совсем наглым, как работает именно этот вышеприведенный пример? Принципы там какие?
Очень жду ответа...
-------------------------------
В истинном золоте блеска нет...
Аватара пользователя
Олег
Ветеран движения
Сообщения: 122
Зарегистрирован: 16 Июль 2005, 2:35
Откуда: Москва
Контактная информация:

Сообщение Олег »

Дело в том, что реферал на BLOB представляет собой группу, состоящую из двух полей - реферала на файл и номер BLOB-а в этом файле. Этой информации для RTL Клариона достаточно, что-бы получить полный доступ к заданному BLOB-полю.
В Кларионе, кстати, это не единственный случай, когда под рефералом "скрывается" группа. К примеру, реферал на строку &STRING, так-же является группой - адрес области памяти, которая выделена под строку и размер этой области. Или реферал на группу, который состоит из трех полей - адреса области памяти, выделенной под эту группу, размера группы и адреса области памяти, в которой описана вся структура группы (метки/типы/размеры полей).

Как я об этом узнал? Ну, люблю иногда "прокручивать" программки под отладчиком с анализом асм-кода!:)) А по другому - никак! Если только не "одолжить" у SV исходники или хотя-бы заголовчные файлы RTL!:)
Ответить