Merge di documenti Word

‘ Grazie alla libreria OpenXml SDK di Microsoft, inclusa dalla release 2015.05b della piattaforma

‘ web QWay/QualiWare, è possibile con poche righe di codice aggiungere il contenuto di uno o più documenti Word all’interno di un altro documento Word esistente.

‘ Il seguente frammento di codice inserisce in un documento Word diversi documenti presenti in un’altra
‘ categoria documentale, e il cui codice è specificato in 3 listbox.
‘ I documenti vengono inseriti in corrispondenza di 3 segnalibri, uno per listbox.
dim i as integer
dim items as dbarray
dim tipo_cont,numero as string
dim q as qwtable
dim a as dbarray
dim msg as string=””
dim QWSess as QWSession=form.page.session(“QWSess”)
dim s as string
dim listboxes as dbarray
dim l as integer
dim segnalibri as dbarray
 
dim path_doc as string
dim path_scheda as string
 
q=new qwtable
q.database=form.form_state.dmd_ref.DB
q.requestlive=false
q.allowallrecords=false
 
‘ Recupera il percorso del documento corrente
q.sql=”select DIRECTORY,NOMEFILE from DOCUMENT d join TIPI_DOC t on d.TIPO=t.TIPO where d.TIPO=’POSDOC’ and d.TIPO_CONT=:TIPO_CONT and d.NUMERO=:NUMERO and d.IND_REV=:IND_REV”
q.params(“TIPO_CONT”)=form.findcontrol(“TIPO_CONT”).Value
q.params(“NUMERO”)=form.findcontrol(“NUMERO”).Value
q.params(“IND_REV”)=form.findcontrol(“IND_REV”).Value
q.active=true
 
if not dbdollar(“.DOCX”,upper(q.rowset.fields(“NOMEFILE”).value)) and not dbdollar(“.DOCM”,upper(q.rowset.fields(“NOMEFILE”).value))
   msg=”Il documento del POS deve essere in formato DOCX o DOCM”+chr(13)
else   
‘ Recupera il percorso del documento corrente
path_doc=QWSess.Q95_NOME_DIR_DOCUM+”\”+q.rowset.fields(“DIRECTORY”).value+”\”+QWSess.DESCRITT.rowset.fields(“DIR_ATTESA”).value+”\”+q.rowset.fields(“NOMEFILE”).value
 
q.active=false
 
if not file(path_doc) then
  form.alert(“File del documento non presente. Contattare l’amministratore”)
else
  q.active=false
  q.sql=”select NOMEFILE,DIRECTORY from DOCUMENT d join TIPI_DOC t on t.TIPO=d.TIPO where d.TIPO=’POSSCH’ and d.PUBBLICATO=1 and d.OBSOLETO=0 and d.TIPO_CONT=:TIPO_CONT and d.NUMERO=:NUMERO order by d.IND_REV desc”
 
  Dim myDoc As DocumentFormat.OpenXml.Packaging.WordprocessingDocument = DocumentFormat.OpenXml.Packaging.WordprocessingDocument.Open(path_doc, True)
  Dim mainPart As DocumentFormat.OpenXml.Packaging.MainDocumentPart = myDoc.MainDocumentPart
  ‘ Scorre su tutte le listbox utilizzando la stessa logica
  listboxes=new dbarray(form.findcontrol(“Notebook1”).controls(3).findcontrol(“ATTIVITA”),form.findcontrol(“Notebook1”).controls(4).findcontrol(“ATTREZZATURE”),form.findcontrol(“Notebook1”).controls(5).findcontrol(“MEZZI”))
  segnalibri=new dbarray(“ATTIVITA”,”ATTREZZATURE”,”MEZZI”)
  
  for l=1 to listboxes.size
  items=listboxes(l).GetItems()
 
  for i=1 to items.size
s=left(items(i),at(” -“,items(i))-1)
a=string2array(s,”|”)
tipo_cont=a(1)
numero=a(2)
‘ Cerca tutti i files che fanno riferimento all’oggetto inserito
q.params(“TIPO_CONT”)=tipo_cont
q.params(“NUMERO”)=numero
q.active=true
if q.rowset.first()
    if not dbdollar(“.DOCX”,upper(q.rowset.fields(“NOMEFILE”).value)) and not dbdollar(“.DOCM”,upper(q.rowset.fields(“NOMEFILE”).value))
  msg+=”Il documento relativo a “+items(i)+” non è in formato DOCX o DOCM”+chr(13)
else   
      path_scheda=QWSess.Q95_NOME_DIR_DOCUM+”\”+q.rowset.fields(“DIRECTORY”).value+”\”+QWSess.DESCRITT.rowset.fields(“DIR_IN_VIG”).value+”\”+q.rowset.fields(“NOMEFILE”).value
 
                       try
  ‘ Verifica se il documento è già presente cercando un segnalibro avente come nome il codice del documento
  dim BookmarkStart=myDoc.MainDocumentPart.Document.Body.Descendants(Of DocumentFormat.OpenXml.Wordprocessing.BookmarkStart)().FirstOrDefault(Function(x) x.Name = tipo_cont+numero)
  If BookmarkStart Is Nothing Then                          
‘ Il documento non esiste ancora: cerca il segnalibro del gruppo e aggiunge il documento alla fine
BookmarkStart=myDoc.MainDocumentPart.Document.Body.Descendants(Of DocumentFormat.OpenXml.Wordprocessing.BookmarkStart)().FirstOrDefault(Function(x) x.Name = segnalibri(l))
if not BookmarkStart is nothing then
  Dim altChunkId As DocumentFormat.OpenXml.StringValue = tipo_cont+numero ‘ Deve essere unico
  Dim chunk As DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPart = mainPart.AddAlternativeFormatImportPart(
  DocumentFormat.OpenXml.Packaging.AlternativeFormatImportPartType.WordprocessingML, altChunkId)
  Using fileStream As System.IO.FileStream = System.IO.File.Open(path_scheda, System.IO.FileMode.Open)
chunk.FeedData(fileStream)
  End Using
 
  Dim altChunk As New DocumentFormat.OpenXml.Wordprocessing.AltChunk()
  altChunk.Id = altChunkId
  
  BookmarkStart.Parent.InsertAfterSelf(altChunk)
 
‘ Inserisce un segnalibro per identificare la scheda appena aggiunta
dim bkmStart as DocumentFormat.OpenXml.Wordprocessing.BookmarkStart= new DocumentFormat.OpenXml.Wordprocessing.BookmarkStart()
bkmStart.Name=tipo_cont+numero
bkmStart.Id=tipo_cont+numero
dim bkmEnd as DocumentFormat.OpenXml.Wordprocessing.BookmarkEnd = new DocumentFormat.OpenXml.Wordprocessing.BookmarkEnd()
bkmEnd.Id=tipo_cont+numero
myDoc.MainDocumentPart.Document.Body.InsertBefore(bkmStart, altChunk)
myDoc.MainDocumentPart.Document.Body.InsertAfter(bkmEnd, altChunk)
 
else
  dim e as string=”Segnalibro “+segnalibri(l)+” non presente nel documento. Non è possibile aggiungere le relative schede”+chr(13)
  if not dbdollar(e,msg) then
 msg+=”Segnalibro “+segnalibri(l)+” non presente nel documento. Non è possibile aggiungere le relative schede”+chr(13)
  end if  
end if
end if
catch e as exception
   msg+=e.message+chr(13)
end try
end if   
else
  msg+=”Documento relativo a “+items(i)+” non esistente o non pubblicato”+chr(13)
end if   
q.active=false
if msg<>”” then
  exit for
end if
next
 
if msg<>”” then
  exit for
end if
next
if msg=”” then
  mainPart.Document.Save()
end if   
myDoc.Close()
 
end if
end if
 
if msg<>”” then
   form.alert(msg)
else
   form.alert(“Il documento è stato aggiornato.”)
end if