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

Тема в разделе "Lotus - Программирование", создана пользователем OlyaZ, 18 май 2009.

  1. OlyaZ

    OlyaZ Гость

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

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

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

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

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

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

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

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Ну для работы с RT годятся такие методы:
    CopyItemToDocument
    AppendRTItem
     
  3. OlyaZ

    OlyaZ Гость

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

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    А чём проблема-то?
     
  5. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Немного не по теме.
    Есть решение, не требующее сохранения.

    Код (Text):
    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 )
    Ещё важно, чтобы хэндл БД-источника не был закрыт до сохранения документа в целевой БД, иначе вложение будет "битым".
     
  6. Akupaka

    Akupaka А че я?.. О.о

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

    OlyaZ Гость

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

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

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    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(...))

    пример кода:
    Код (Text):
        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
     
  9. TIA

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Попробовал собственный пример и понял, что много воды уже утекло.
    Теперь вполне срабатывает вариант простого копирования RT-поля в новый документ.
    И закрытие БД-источника не приводит к ошибкам. Т.е. нижеследующий код корректен.
    Код (Text):
        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.


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

    OlyaZ Гость

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

    TIA :-)
    Lotus team

    Регистрация:
    15 май 2009
    Сообщения:
    790
    Симпатии:
    0
    Тогда, при условии что из одного Notes-документа с шаблоном в Notes-документ проекта можно скопировать всё содержимое ричтекстового поля (с вложенем), то код Akupaka, как образец, вам подходит. В нём копируется поле с вложениями целиком, а не отдельно взятое вложение.
     
  12. K-Fire

    K-Fire Гость

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

    hosm * so what *

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

    kilcher Гость

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

    Omh Lotus team
    Lotus team

    Регистрация:
    4 июл 2007
    Сообщения:
    2.210
    Симпатии:
    0
    Я бы делал Item.CopyItemToDocument.
    Траблов не помню.
     
  16. Akupaka

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    ты напомни свой случай и какие проблемы были, я помню, что-то с переоткрытием дока мы обсуждали, а с вложениями не помню проблем...
     
  17. kilcher

    kilcher Гость

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

    http://codeby.net/forum/threads/29996.html

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

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    да, действительно... не могу ничего сказать... я с таким глюком не стыкался лично...

    SHIFT удерживай :unsure:

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

    DeleteFile Function (win api)?
    http://msdn.microsoft.com/en-us/library/aa363915(VS.85).aspx

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

    OlyaZ Гость

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

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

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

    Akupaka А че я?.. О.о

    Регистрация:
    4 окт 2007
    Сообщения:
    3.373
    Симпатии:
    2
    мы его узнаем, когда пользователь ткнет
    вот у этого выбранного дока мы унид и возьмем...
    смотри NotesUIWorkSpace.PickListCollection, NotesCollection.GetFirstDocument

    щас пример кода напишу... чего я такой добрый сегодня? ))
     
Загрузка...
Похожие Темы - Attachments Очень нужна
  1. xpro
    Ответов:
    12
    Просмотров:
    1.950
  2. ToxaRat
    Ответов:
    8
    Просмотров:
    4.762
  3. Gor
    Ответов:
    39
    Просмотров:
    12.819
  4. animelubitel
    Ответов:
    0
    Просмотров:
    743
  5. Даниил
    Ответов:
    0
    Просмотров:
    820

Поделиться этой страницей