Attachments, Очень нужна помощь!

  • Автор темы OlyaZ
  • Дата начала
O

OlyaZ

Всем-всем доброго времени суток!

Уважаемые, очень нужна помощь в таком вопросе: необходимо скопировать embedded object из поля Rich text item одного Notes документа DB1 в другое поле Rich text item другого документа DB2.

Если конкретнее говорить, то имеется база данных шаблонов документов и база данных проектов.
в бд проектов необходимо реализовать возможность копировать размещенное в бд шаблонов вложение. причем вид в представлении д.б следующим:

- Проект 1
>файл1
>файл2...

- Проект 2
> файл3....

В курсе, что можно предварительно необходимый шаблон сохранить на диске, а потом его уже загружать в необходимый Notes документ. а какой скрипт для этого использовать?????

Подскажите, кто знает. Заранее, огромное спасибо!
 
O

Omh

Ну для работы с RT годятся такие методы:
CopyItemToDocument
AppendRTItem
 
O

OlyaZ

А КАК их можно использовать в моем случае? подскажите, плз!!!
 
T

TIA

В курсе, что можно предварительно необходимый шаблон сохранить на диске, а потом его уже загружать в необходимый Notes документ. а какой скрипт для этого использовать?????

Немного не по теме.
Есть решение, не требующее сохранения.

Код:
Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim doc As NotesDocument, forward As NotesDocument
Dim uidoc As NotesUIDocument
Dim sourcebody As NotesRichTextItem
Dim resultbody As NotesRichTextItem
Dim resultbody1 As NotesRichTextItem

Set uidoc = ws.CurrentDocument
Set doc = uidoc.Document
'Set db = doc.ParentDatabase
Set db = New NotesDatabase("", "")
call db.OpenMail

'Обновление RichText из интерфейса в back-end
If uidoc.EditMode Then Call uidoc.Refresh(True) 

Set sourcebody = doc.getfirstitem ( "Body" )
Set forward = New Notesdocument ( db )
Set resultbody1 = sourcebody.copyitemtodocument ( forward, "TMP" ) 
Set resultbody = New NotesRichTextItem ( forward, "Body1" )
Call resultbody.addnewline (1) 
Call resultbody.appendtext ( "----- Start Forward -----")
Call resultbody.addnewline (1)
Call resultbody.appendrtitem ( resultbody1 )
Call resultbody1.remove

'Это необходимо, чтобы показать RichText без сохранения
Call resultbody.CopyItemToDocument( forward,"Body")
Call resultbody.remove

forward.Form = "Memo"
forward.Subject = doc.Subject ( 0)
Call ws.editdocument ( True, forward )

Ещё важно, чтобы хэндл БД-источника не был закрыт до сохранения документа в целевой БД, иначе вложение будет "битым".
 
A

Akupaka

Ещё важно, чтобы хэндл БД-источника не был закрыт до сохранения документа в целевой БД, иначе вложение будет "битым"
а подробнее, что и как происходит? :)
знаю о баге когда объект NotesDocument пропадает в памяти, если выходит за рамки области видимости объекта БД из которой он был получен (часто ошибка вылазит при использовании функций, кот возвращают док из какой-то БД, которая открывается в той же функции)
но твое утверждение я не понял, не встречался, видать... не похоже на то о чем я написал выше?.. хотя, возможно суть в том же...
 
O

OlyaZ

А чём проблема-то?

Проблема в том, что хотелось бы поподробнее узнать, как в моем случае использовать эти методы

Немного не по теме.
Есть решение, не требующее сохранения.
...
Ещё важно, чтобы хэндл БД-источника не был закрыт до сохранения документа в целевой БД, иначе вложение будет "битым".

Уважаемый TIA, прокомментируйте, пожалуйста, приведенный код. базы данных как-то должны быть связаны?
 
A

Akupaka

OlyaZ, я бы предложил тебе почитать справку по классам
NotesSession, NotesDatabase, NotesDocument, NotesItem, NotesRichTextItem

в твоем случае код сводится приблизительно к такому:
есть две БД: БД1 (db1.nsf), БД2 (db2.nsf)
в БД1 есть документ srcDoc с некоторым заведомо известным нам унидом, например (srcDocUnid)
нужно создать в БД2 документ dstDoc по форме "Form2" с вложениями из поля "Body" документа srcDoc

для этого надо:
- открыть обе БД (NotesSession.GetDatabase(...))
- найти srcDoc (NotesDatabase.GetDocumentByUnid(...))
- создать новый документ (dstDoc) в БД2 (NotesDatabase.CreateDocument)
- достать итем Body, хранищий вложения (NotesDocument.GetItem)
- скопировать итем в dstDoc (NotesItem.CopyItemToDocument)
- сохранить новый документ в БД (NotesDocument.Save(...))

пример кода:
Код:
	On Error 4091 Resume Next ' чтобы перехватить исключение метода NotesDatabase.GetDocumentByUNID, если унид неверный
Dim s As NotesSession
Dim srcDb As NotesDatabase
Dim dstDb As NotesDatabase
Dim srcDoc As NotesDocument
Dim dstDoc As NotesDocument
Dim bodyItem As NotesItem
Dim srcDocUnid As String

Set s = New NotesSession()
Set srcDb = s.GetDatabase("ServerName", "db1.nsf", False) ' пытаемся открыть БД1
Set dstDb = s.GetDatabase("ServerName", "db2.nsf", False) ' пытаемся открыть БД2

' проверяем открылись ли БД, если нет, то заканчиваем работу
If Not(srcDb.IsOpen) Then
Msgbox "Source Db not open"
Exit Sub
End If
If Not(dstDb.IsOpen) Then
Msgbox "Dest Db not open"
Exit Sub
End If

' начинаем работать
' устанавливаем унид и пытаемся достать документ из базы
srcDocUnid = "%SourceDocUnid%"
Set srcDoc = srcDb.GetDocumentByUNID(srcDocUnid)
If Not(srcDoc Is Nothing) Then
' документ получен
' достаем итем
Set bodyItem = srcDoc.GetFirstItem("Body")
If Not(bodyItem Is Nothing) Then
' итем получен, можем создавать документ-приемник
Set dstDoc = dstDb.CreateDocument()
' станавливаем форму документа
Call dstDoc.ReplaceItemValue("Form", "Form2")
' копируем итем в документ
Call bodyItem.CopyItemToDocument(dstDoc, "Body")
' сохраняем документ
Call dstDoc.Save(True, False, False)
End If
End If
 
T

TIA

а подробнее, что и как происходит? :)
знаю о баге когда объект NotesDocument пропадает в памяти, если выходит за рамки области видимости объекта БД из которой он был получен (часто ошибка вылазит при использовании функций, кот возвращают док из какой-то БД, которая открывается в той же функции)
но твое утверждение я не понял, не встречался, видать... не похоже на то о чем я написал выше?.. хотя, возможно суть в том же...

Попробовал собственный пример и понял, что много воды уже утекло.
Теперь вполне срабатывает вариант простого копирования RT-поля в новый документ.
И закрытие БД-источника не приводит к ошибкам. Т.е. нижеследующий код корректен.
Код:
	Dim ws As New NotesUIWorkspace
Dim db As NotesDatabase
Dim doc As NotesDocument, forward As NotesDocument
Dim uidoc As NotesUIDocument
Dim sourcebody As NotesRichTextItem

Set uidoc = ws.CurrentDocument
Set doc = uidoc.Document
Set db = New NotesDatabase("", "")
Call db.OpenMail

'Обновление RichText из интерфейса в back-end
If uidoc.EditMode Then Call uidoc.Refresh(True) 

Set sourcebody = doc.getfirstitem ( "Body" )
Set forward = db.CreateDocument
if IsValidItem(sourcebody) then Call sourcebody.copyitemtodocument( forward, "Body" )

forward.Form = "Memo"
forward.Subject = doc.Subject ( 0)
Call ws.editdocument ( True, forward )

А причину старой баги всё же расскажу, т.к. многим может оказаться полезным.
Многие знают, что физически вложения не хранятся в самой ноте. Нота имеет лишь ссылку (в виде RRV) на системную ноту (object), в которой и располагаются вложения. При копировании вложений, нотес не выполняет сразу перенос вложения (зачастую весьма объёмного), а как-бы запоминает ссылку на источник. За счёт чего сама операция копирования (например CopyItemToDocument) выполняется быстро. Ссылки бывают на файловую систему, на другую ноту другой или текущей БД, на буфер обмена (точнее тоже на ноту в локальной спец-БД, в файле вида C:\Temp\notesD80BDD\~editclp.ncf). При сохранении ноты с новым вложением, нотес по ссылке получает источник вложения и копирует его в новую внутреннюю ноту для вложения. При закрытии хэндла БД, закрываются и полученные через него хэндлы нот. Т.е. описанная Akupaka ситуация с пропаданием NotesDocument. Так вот, если ссылка была на ноту-источник из другой БД, и эта БД закрыта, то ссылка не может разрешиться, т.к. нота-источник теперь тоже закрыта.

Думаю, что исправление баги заключалось в том, что раньше ссылка на ноту-источник была в виде хэндла, а теперь, наверно, в виде RRV. RRV -- это что-то типа NoteId.


Если конкретнее говорить, то имеется база данных шаблонов документов и база данных проектов.
в бд проектов необходимо реализовать возможность копировать размещенное в бд шаблонов вложение. причем вид в представлении д.б следующим:

- Проект 1
>файл1
>файл2...

- Проект 2
> файл3....

OlyaZ, а вы все-таки расскажите подробнее о своей задаче. Понял, что есть документ-шаблон с вложениями. Что нужно каким-то образом пренести вложения из шаблона в БД проектов. Каким образом?
Сколько Notes-документов в вашем примере создано в БД проекты - 2? По какому принципу определяется, какое вложение в какой документ-проект должно попасть? Или всё совсем не так?
 
O

OlyaZ

OlyaZ, а вы все-таки расскажите подробнее о своей задаче. Понял, что есть документ-шаблон с вложениями. Что нужно каким-то образом пренести вложения из шаблона в БД проектов. Каким образом?
Сколько Notes-документов в вашем примере создано в БД проекты - 2? По какому принципу определяется, какое вложение в какой документ-проект должно попасть? Или всё совсем не так?

Спасибо всем за ответы, буду пробовать и разбираться.
А суть моей задачи такая: Решается проблема документационной поддержки процесса ИТ-аудита. для этого создана бд1 - ХРАНИЛИЩЕ ШАБЛОНОВ, в которой хранятся шаблоны-"образцы" используемых документов; и бд2 - собственно проектов ИТ-аудита. проблема возникла, когда стало необходимым реализовать возможность прикрепления к проекту ИТ-аудита файла шаблона для последующей правки в соответствии с конкретным проектом. в бд1 есть форма для шаблонов, в которой аттачится файл шаблона. необходимо, работая в бд2, аттачить файл шаблона из первой базы на форме добавления документа к проекту и работать с ним дальше. на этой форме (бд2) могу пока тока выбрать название нужного шаблона (выводится окно выбора из представления бд1 нужного названия шаблона), а сам файл необходимо предварительно сохранять на диске, что крайне нежелательно.
 
T

TIA

А суть моей задачи такая: ....

Тогда, при условии что из одного Notes-документа с шаблоном в Notes-документ проекта можно скопировать всё содержимое ричтекстового поля (с вложенем), то код Akupaka, как образец, вам подходит. В нём копируется поле с вложениями целиком, а не отдельно взятое вложение.
 
K

K-Fire

А почему крайне нежелательно сохранять на диске вложение? Папка доступная пользователю на запись есть всегда (локальная папка Data, либо виндозный темп), записать, потом удалить файл из кода нет никаких проблем. Есть конечно особые траблы в висте, но это все решаемо.
 
H

hosm

А не лень уточнить кратенько, что в висте за траблы появились: с доступом к файловой системе, там что-то в секьюрити поменяли?
На моей памяти от клиентов пробегали 1-2 случайные, привязанные, похоже, именно к настройкам ОС на конкретных паре рабочих мест ошибки, которые у нас не повторяются. Вроде в итоге админы на местах разрулили всё :)
 
K

kilcher

Я что-то не пойму.Так как лучше всего делать копирование? С помощью Copyitem,или все таки выкладывать на диск а потом цеплять?
В моем случае были проблемы как раз с Copyitem и append. А когда стала выкладывать файл на диск, все вроде работает.
 
O

Omh

Я бы делал Item.CopyItemToDocument.
Траблов не помню.
 
K

kilcher

Вот здесь мы обсуждали

https://codeby.net/threads/29996.html

Так вот,изменила там Copyitem на "выкладывание и прикрепление" и больше пока проблем не возникало.
Только вот еще вопрос как удалить временный файл мимо корзины?
 
A

Akupaka

Вот здесь мы обсуждали
да, действительно... не могу ничего сказать... я с таким глюком не стыкался лично...

Только вот еще вопрос как удалить временный файл мимо корзины?
SHIFT удерживай :unsure:

Kill fileName в корзину удаляет?..

DeleteFile Function (win api)?


либо java-решение поищи...
 
O

OlyaZ

в твоем случае код сводится приблизительно к такому:
есть две БД: БД1 (db1.nsf), БД2 (db2.nsf)
в БД1 есть документ srcDoc с некоторым заведомо известным нам унидом, например (srcDocUnid)
нужно создать в БД2 документ dstDoc по форме "Form2" с вложениями из поля "Body" документа srcDoc
...

что-то у меня совсем ничего не получается :)
Люди, разложите, плз, все по полочкам мне-чайнику!!!сама что-т никак не втыкну, что почем и куда....
что значит "заведомо известным нам унидом"? как он будет известен,м?

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

Подскажите, вразумите плз!!!!
 
A

Akupaka

что значит "заведомо известным нам унидом"? как он будет известен,м?
мы его узнаем, когда пользователь ткнет
кнопочка ..., кот откроет вьюху из бд шаблонов для выбора нужного дока
вот у этого выбранного дока мы унид и возьмем...
смотри NotesUIWorkSpace.PickListCollection, NotesCollection.GetFirstDocument

щас пример кода напишу... чего я такой добрый сегодня? ))
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!