Lokutus
Ego sum Lokutus flagellum dei

Na dva kliky
14.09.2007
Lotus Notes

Richtext v Lotus Notes je známá tragédie. Nedá se s ním téměř nic dělat.

V Lotusscriptu je sada tříd, které dokážou pracovat s Notes Richtext formátem, ale řekněme si upřímě, je to naprosto nepoužitelné. Zoufalí uživatelé volají po známých funkcích z MS Word, anebo alespoň nějaké integraci, ale stále nic. Notes Richtext neumí styly. Neumí kontinuální zanořené seznamy. Neumí skoro nic. Máte jakýsi NotesRichTextNavigator, ale koukněte se na seznam druhů elementů, které zvládne najít.  Je jich pět. Jenom pět ze všech možných. Objekty typu picture ignoruje, stejně jako jiné speciální objekty. Takže přenést obsah RT pole i s formátováním třeba do MS Word, nebo naopak se v podstatě nedá.

Nedávno jsem dělal jednoduchou workflow aplikaci pro oběhy ISO dokumentace. Všechny dokumenty jsou napsány v MS Word, nebo OO.o Writer. Požadavek byl jednak možnost uchování attachmentu původního dokumentu, tak i jeho hrubý přepis se základním formátováním do richtext pole. Což znamenalo napsat nějakou směrnici, uložit ji, CTRL+A, CTRL+C, přesun do pole Body a CTRL+V. Pak následovaly úpravy, protože přenosem se ztratila většina formátování, jako třeba číslované seznamy apod.

Anebo také ne. Objevil jsem metodu Import třídy NotesUIDocument, které jsem si nikdy dříve nevšiml. A to v helpu tvrdí, že je implementována už od verze 5. Stačí přesunout kurzor do cílového richtext pole a zavolat tuto metodu s parametrem filter$, což je druh souboru a filename$, tedy cesta k souboru. Výsledné formátování není úplně přesné, ale pořád lepší, než přes copy&paste.

Takže to bychom měli jednu část operace. Ale zbývá další. Je potřeba vložit příslušnou směrnici do jiného RT pole, jako attachment. Nehledě na to, že by bylo fajn už při otevření formuláře pro zadání směrnice nabídnout uživateli ke stažení šablonu příslušné směrnice pro otevření ve Wordu, resp. Writeru. A to celé na jeden, maximálně dva kliky.

Výsledek vypadá následovně:

Uživatel v LWF nastartuje proces pro příslušnou ISO dokumentaci. Otevře se mu formulář s předvyplněnými poli.

LWF attachment

Všiměte si malého wizardu na pravé straně formuláře. Nabádá uživatele k otevření šablony, úpravě obsahu, následnému uložení a přiložení souboru. Na úrovni tohoto formuláře pouze dva kroky.

Tedy v prvním kroku provedeme pouze dvě věci.

  1. Nakonektíme se někam, kde máme uložené šablony, podle klíče, který tvoří třeba název LWF procesu, dohledat příslušnou šablonu, uložit ten attachment do Temp adresáře uživatele do složky s unikátním názvem a otevřít přes asociovaný program.
  2. Uložit si do nějakého dočasného pole ve formuláři cestu k souboru na disku pro pozdější využití. Ale lze využít i notes.ini, či uživatelův profil, pokud ho aplikace používá.

Můj zdroják pro tuto akci vypadá následovně:

  Sub Click(Source As Button)
Dim Sys As New NotesUIBase    ' Pomocna trida pro praci s UI
Dim Kw As New KeywordUI(Sys.Db)  ' API pro praci s ciselniky a ulozistem sablon
Dim File As New FileHandle       ' Trida pro praci se soubory
 Dim UI As NotesUIDocument
 Dim KwRepID As String

Set UI = Sys.Ws.CurrentDocument
If UI.FieldGetText("ISOTitle") = "" Then    ' Nejake validace...
Msgbox "Nejprve vyplňte položku Název!", 16, "Chyba"
Exit Sub
 End If

 Let KwRepID = GetConfigValue(Sys.Db, "CnfKeywordRepID")   ' z konfigurace nacteme replica id databaze sablon
 If KwRepID = "" Then
  Msgbox "Cesta k šablonám ISO není nastavena." & CRLF & "Kontaktujte technickou podporu.", 16, "Chyba"
  Exit Sub
 End If
 If Not Kw.OpenByreplicaID(KwRepID) Then    ' podle zadane rep id otevreme databazi sablon
  Msgbox "Šablony ISO nejsou dostupné." & CRLF & "Kontaktujte technickou podporu.", 16, "Chyba"
  Exit Sub
 End If
 If Not Kw.GetTemplateByCode("", "ISOTEMPLATES", UI.FieldGetText("ISOID")) Then     ' podle typu iso dokumentace najdeme prislusny attachment
  Msgbox "Šablona ISO pro ISO: " & UI.FieldGetText("DocName") & " nebyla nalezena." & CRLF & "Kontaktujte technickou podporu.", 16, "Chyba"
  Exit Sub
 End If
  Call
File.Save(Kw.Template)   ' ulozime na disk
 Let FilePath = File.Path
 Let UI.Document.FilePath = FilePath   ' ulozime si cestu do smluvniho pole ve formulari
 Call UI.Document.Save(True, False)    ' ulozime uidocument
 Call UI.Refresh     ' pro jistotu ho zaktualizujeme
 Call File.Drop      ' aby nam nas soubor destruktor tridy file nezlikvidoval – jsme totiz cistotni a obvykle po sobe uklizime
 If Not File.Open Then    ' pokusime se otevrit soubor pres asociovany program
  Msgbox "Šablony ISO nejsou dostupné." & CRLF & "Kontaktujte technickou podporu.", 16, "Chyba"
  Exit Sub
 End If
End Sub

Pro otevření souboru přes asociovaný program postačí známá funkce:

Function ShellExecuteA Lib "shell32.dll" _
(Byval hwnd As Any, Byval operation As Any, Byval filename As String, _
Byval parms As Any, Byval defdir As Any, Byval show As Integer) As Long

Pokud se podaří a soubor se otevře, nic nebrání uživateli jej zeditovat a uložit. Následně se přesune do našeho formuláře a použije druhý odkaz, Přiložit soubor, který naimportuje obsah souboru do Body a spustí agenta:

  Sub Click(Source As Button)
Dim Ws As New NotesUIWorkspace
 Dim UI As NotesUIDocument
  Dim Doc As NotesDocument
 Dim RTI As NotesRichTextItem
 Dim Ag As NotesAgent

 Set UI = Ws.CurrentDocument
 If UI.FieldGetText("FilePath") = "" Then
  Msgbox "Nejprve musíte otevřít šablonu!", 16, "Chyba"
   Exit Sub
 End If
  Call
UI.GotoField("Body")
 Call UI.Import("Microsoft Word", FilePath)
 Call UI.Save
 Call UI.Close
 Set Doc = UI.Document
 Let Doc.SaveOptions = "0"
 Call Doc.Save(True, False)
 Set Ag = Ws.CurrentDatabase.Database.GetAgent("ISOAddAttachment")
 If Ag.Run(Doc.NoteID) <> 0 Then
  Msgbox "Nepodařilo se přiložit soubor."
 End If
End Sub

Nakonec se rozjede agent, který v backendu přiloží attachment a otevře dokument zpět do frontendu, neboť jak známo, ve frontendu nelze tuto operaci skriptem provést.

  Sub Initialize
  Dim Sys As New NotesUIBase
 Dim Ag As NotesAgent
 Dim cDb As NotesDatabase
 Dim cDoc As NotesDocument
 Dim UI As NotesUIDocument
 Dim cRTI As NotesRichTextItem

 Set Ag = Sys.Ses.CurrentAgent
 Set cDb = Sys.Ses.CurrentDatabase
 Set cDoc = cDb.GetDocumentByID(Ag.ParameterDocID)
 Set cRTI = cDoc.GetFirstItem("ISOAttachment")
 Call cRTI.EmbedObject(EMBED_ATTACHMENT, "", cDoc.FilePath(0))
 Let cDoc.FilePath = ""
 Call cDoc.Save(True, False)
 Set UI = Sys.Ws.EditDocument(True, cDoc)
End Sub

A nakonec je potřeba ošetřit pole SaveOptions:

  Sub Postopen(Source As Notesuidocument)
If Source.Document.HasItem("SaveOptions") Then
   Call Source.Document.RemoveItem("SaveOptions")
   Call Source.Document.Save(True, False)
 End If
End Sub

A to je vše. Uživatel ušetří několik operací.

linkuj.cz vybrali.sme.sk

Komentáře



Přidání komentáře...


Vaše jméno:


Váš e-mail:


URL vašich stránek:


Nadpis:


Text: