Работа с RTF полем

  • Автор темы Chernom0r
  • Дата начала
Статус
Закрыто для дальнейших ответов.
C

Chernom0r

#1
Здравствуйте!
Вот столкнулся с проблемой, которую сам решить уже отчаялся :)

Есть некоторая форма с RTF полем Body, которое содержит текст и приаттаченные файлы. Необходимо избавиться от текста и оставить только аттачи. С текстовым полем проблем нет, но применительно к RTF полю я не знаю как поступить.
В принципе возможен вариант с созданием нового поля и помещением в него только аттачей ($File), а потом удалением поля Body

Заранее спасибо за ответы..
 
V

Veselinka

#2
1. Получаешь
To get: notesEmbeddedObjectArray = notesRichTextItem.EmbeddedObjects
2. Экстрактишь на файлуху:
Call notesEmbeddedObject.ExtractFile( path$ )
3. Удаляешь этот РТитем и создаешь его заново
4. Эмбедишь в него детачнутые файлы
Set notesEmbeddedObject = notesRichTextItem.EmbedObject( type%, class$, source$, [ name$ ] )

Идеологически - описала, на практике в принципе могут быть сюрпризы - так что надо пробовать

Это не совсем то что ты говорил, потому что не всегда создается поле $File, часть атачей лежит в самом ртфполе.
Вообще я бы не рискнула работать с РТФами и их структурой не пользуясь стандарным лотусовым API, а извращаясь с $file Полем, так как результат для меня - непредсказуем.
 
N
#3
Привет, Chernom0r.
Пусть документы по форме "temp1" содержат rich text field с некоторым текстом и некоторыми присоединенными файлами (attachments) в нем. Следующий код помогает "избавиться от текста и оставить только аттачи..." в rich text field. Код проверен на работоспособность.

Код:
(Declarations)
Dim session As NotesSession
Dim ws As NotesUIWorkspace
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim collection As NotesDocumentCollection
Dim rtitem As NotesRichTextItem

(Initialize)
Sub Initialize

Set session = New NotesSession
Set ws = New NotesUIWorkspace
Set db = session.CurrentDatabase  

End Sub

Sub Click(Source As Button)	
Dim temp_dir As String
Dim obj_arr() As String
Dim i As Integer
Dim file_path As String
Dim search_str As String

i = 0
Redim obj_arr(i)	
temp_dir = Environ("Temp")
search_str = "Form = ""temp1"""
Set collection = db.Search(search_str, Nothing, 0)
For k = 1 To collection.Count
 Set doc = collection.GetNthDocument(k)
 Set rtitem = doc.GetFirstItem("body")
 If rtitem.Type = RICHTEXT Then
 	Forall obj In rtitem.EmbeddedObjects
   If obj.Type = EMBED_ATTACHMENT Then
   	Call obj.ExtractFile(temp_dir + "\" + obj.Name)
   	i = i + 1
   	Redim Preserve obj_arr(i)
   	obj_arr(i) = obj.Name    
   End If
 	End Forall  
 End If
Next	

Call rtitem.Remove	
Call doc.Save(True, True)
Set rtitem = New NotesRichTextItem(doc, "body")
If Ubound(obj_arr) > 0 Then
 For i = 1 To Ubound(obj_arr)
 	file_path = temp_dir + "\" + obj_arr(i)
 	Call rtitem.EmbedObject(EMBED_ATTACHMENT, "", file_path)
 	Kill file_path
 Next  
End If

Call doc.Save(True, True)

End Sub
 
C

Chernom0r

#4
Спасибо за ответы.
2 nor:
Скрипт красивый, но он у меня не проходит. Вываливается с сообщением "Type mismatch" вот здесь:

Код:
Forall obj In rtitem.EmbeddedObjects
 
N
#5
Привет, Chernom0r.
Мог бы и сам уже давно разобраться с этой ошибкой. Я просто не предусмотрел вариант, когда rtf не содержит никакого attachment, а только текст, например. Поэтому, в мой код, перед командой Forall obj In rtitem.EmbeddedObjects необходимо внести сверхэлементарную проверку на существование attacments в rtf, и уже от результата этой проверки нужно решить тебе, как обрабатывать rtf.
Я думаю ты сам разберешься, если не получится, то спроси, как.
 
N
#6
Chernom0r, перед тем как выложить сюда код, я его проверял, что бы никаких ошибок не было. У меня 6 релиз лотуса и домино. Работоспособность кода проверялась на rtf с текстом и несколькими attachments.
 
C

Chernom0r

#7
Хм...
Дело в том, что аттачметнт существует :\
@AttachmentNames, например, вполне правдиво показывает, что это 11111.tif
@AttachmentLengths показывает его действительный размер.

Спасибо за наводку. Сейчас посмотрю что мне по этому поводу Lotus Skript выдаст.
P.S. У меня Lotus Domino & Notes R5
 
C

Chernom0r

#8
Простая проверка на наличие EmbeddedObject проходит.

Код:
If doc.HasEmbedded Then
  Messagebox ( "Doc contains an object, link, or attachment" )
End If
Messagebox вываливается с нужным сообщением.
Значит файл таки присудствует и Лотус его видит.
 
C

Chernom0r

#9
Хм..
Вобщем ситуация оказалась таковой, что прое Body не содержит EmbeddedObject'ов (выяснилось путем дебага скрипта и изучения результатов). Судя по всему приаттаченный файл хранится в поле $File.
-----------------------------------------------------
Попытаюсь обьяснить суть проблемы подробнее.

Есть #!/bin/sh скрипт на FreeBSD, который шлет письмо с аттачем определенному почтовому пользователю. Письмо кладется в базу.
Само письмо содержит subject (который меня интересует мало, т.к. я его сам и формирую как хочу), Body с некоторой полезной информацией, которую я достаю при помощи FieldGetText и обрабатываю потом в текстовом поле ,а также приаттаченные файлы.
Всю текстовую информацию я рассовываю по нужным мне полям на основании которых далле будут приниматься некоторые решения.
В итоге должен появиться документ в базе с некоторыми видимыми полями и файлами.
Дело в том, что поле Body оставить в том виде котором оно есть я не могу, т.к. в нем присудствует много мусора не нужного конечному пользователю. И вытащить файл при помощи Call notesEmbeddedObject.ExtractFile( path$ ) тоже не могу, т.к. такого обьекта нет.

Как мне лучше поступить?
 
V

Veselinka

#10
можно работать не с конкретным полем, а с документом вообще:
notesEmbeddedObjectArray = notesDocument.EmbeddedObjects

попробуй получить атачи прямо с документа, экстрактить их, а сложить потом уже в боди
 
N
#11
Действитльно, обращайся напрямую к attachments документа, а не конкретного поля, может это поможет.
 
V

Veselinka

#12
Chernom0r - сейчас сама с твоей проблемой столкнулась - при сохранении документа с веб - надо был аплоаженный файл в конкретное поле перекинуть... у меня тоже все время Has Embedded был тру, а атачментов в документе - массив был пустой и все падало.
Я нашла на интертрастовском форуме вот такое решение - оно немного хакерское и я еще не проверяла - как оно работает если атачей больше чем один, но с 1 атачментом оно работает:

Function WebMoveAttachment1 ( doc As NotesDocument, Byval moveToFieldName As String )
Dim session As New NotesSession
Set v2File = doc.GetFirstItem ( "$File" )
fileName = v2File.Values(0)
Set inputAttachment = doc.GetAttachment ( fileName )

tempDirectory = session.GetEnvironmentString ( "Directory", True )
filePath = tempDirectory + "\" + fileName
Call inputAttachment.ExtractFile ( filePath )
Call doc.RemoveItem ( "$File" )

If doc.HasItem ( moveToFieldName ) Then
Set rtItem = doc.GetFirstItem ( moveToFieldName )
Else
Set rtItem = New NotesRichTextItem ( doc, moveToFieldName )
End If
Set inputAttachment = rtItem.EmbedObject ( EMBED_ATTACHMENT, "", FilePath )
Kill FilePath
End Function
 
V

Veselinka

#13
С несколькими атачментами оно не работает...
Попробовала пройтись вот таким образом по полям $file, но иногда один атач по нескольки полям раскидан, поэтому приведенный ниже код работает не стабильно и только в случае, если в одном итеме - 1 атач.
Function WebMoveAttachment1 ( doc As NotesDocument, Byval moveToFieldName As String )
Dim session As New NotesSession
tempDirectory = session.GetEnvironmentString ( "Directory", True )

i=1

While doc.HasItem( "$File" )
Set v2File = doc.GetFirstItem ( "$File" )
fileName = v2File.Values(0)
filePath = tempDirectory + "\" + fileName

Set inputAttachment = doc.GetAttachment ( fileName )
Call inputAttachment.ExtractFile ( filePath )
Call v2File.remove
Redim Preserve pathes(1 To i) As String
pathes(i)=filePath
i=i+1
Wend

If doc.HasItem ( moveToFieldName ) Then
Set rtItem = doc.GetFirstItem ( moveToFieldName )
Call rtitem.remove
Set rtItem = New NotesRichTextItem ( doc, moveToFieldName )
Else
Set rtItem = New NotesRichTextItem ( doc, moveToFieldName )
End If

Forall p In pathes
Call rtItem.EmbedObject ( EMBED_ATTACHMENT, "", p )
Kill p
End Forall



End Function
 
N
#14
to Veselinka
как один этач может быть раскидан по нескольким полям?!???
в одном итеме $FILE всегда хранится ссылка на один attachment, на сколько я помню... поэтому твой код должен работать надежно
у меня аналогичный скрипт уже сколько работает в рабочей бд и никаких нареканий я не слышал...
 
G

Guest

#15
а у меня - не работает! Часть файлов - все нормально, а вот если встречается мега файл больше чем на 5-6 мегабайт - все ломается. Ошибки скрипт не выдает, но перекинутые атачи - поломатые.
 
N
#16
никогда не пробовал присоединять такие большие файлы
 
Статус
Закрыто для дальнейших ответов.