ItextSharp locks all files - itext

I used itext sharp to merge some pdf. After that, i want to delete them.
However itextsharp doesn't close the file, and File.Delete throws and exception.
This is my code:
Dim mergedPdf As Byte() = Nothing
Using ms As New MemoryStream()
Using document As New Document()
Using copy As New PdfCopy(document, ms)
document.Open()
'_listaPath is a List (of String) with the paths off all pdf to merge
For i As Integer = 0 To _listaPDF.Count - 1
Dim reader As New PdfReader(_listaPDF(i))
' loop over the pages in that document
Dim n As Integer = reader.NumberOfPages
Dim page As Integer = 0
While page < n
copy.AddPage(copy.GetImportedPage(reader, System.Threading.Interlocked.Increment(page)))
End While
Next
End Using
End Using
mergedPdf = ms.ToArray()
End Using
File.WriteAllBytes(fileexplorer.FileName, mergedPdf)
For Each pdfTMP In _listaPDF
If File.Exists(pdfTMP) Then
File.Delete(pdfTMP)
End If
Next
_listaPDF = New List(Of String)

I found the problem.
This line
Dim reader As New PdfReader(_listaPDF(i))
Should be
Using reader As New PdfReader(_listaPDF(i))
Conclusion, I need more coffee

Related

Is there a way to count the number of actual replaces when using replaceAll in OO Basic?

Considering the example for search & replace of specific uk-to-us words from the Editing Text Documents OO Wiki:
Dim I As Long
Dim Doc As Object
Dim Replace As Object
Dim BritishWords(5) As String
Dim USWords(5) As String
BritishWords() = Array("colour", "neighbour", "centre", "behaviour", _
"metre", "through")
USWords() = Array("color", "neighbor", "center", "behavior", _
"meter", "thru")
Doc = ThisComponent
Replace = Doc.createReplaceDescriptor
For I = 0 To 5
Replace.SearchString = BritishWords(I)
Replace.ReplaceString = USWords(I)
Doc.replaceAll(Replace)
Next I
Question: is there a way to get the count of actual replacement that has been made ? (if any) I don't mind the individual count for each term, but just globally – i.e. if, say, the original text included 2 occurences for 'colour' and 1 for 'behaviour', in the end to get the number 3 (purpose: to report this number to user as info via MsgBox).
As shown in the example at https://www.openoffice.org/api/docs/common/ref/com/sun/star/util/XReplaceable.html, the number found is returned.
Dim TotalFound As Long
TotalFound = 0
...
TotalFound = TotalFound + Doc.replaceAll(Replace)
Next I
MsgBox "Replaced " & TotalFound & " occurrences"
Result: Replaced 3 occurrences

LibreOffice Draw -add hyperlinks based on query table

I am using draw to mark up a pdf format index map. So in grid 99, the text hyperlinks to map99.pdf
There are 1000's of grid cells - is there a way for a (macro) to scan for text in a sheet that is like
Text in File | Link to add
99|file:///c:/maps/map99.pdf
100|file:///c:/maps/map100.pdf
and add links to the relevant file whenever the text is found (99,100 etc).
I don't use libre much but happy to implement any programatic solution.
Ok, after using xray to drill through enumerated content, I finally have the answer. The code needs to create a text field using a cursor. Here is a complete working solution:
Sub AddLinks
Dim oDocument As Object
Dim vDescriptor, vFound
Dim numText As String, tryNumText As Integer
Dim oDrawPages, oDrawPage
Dim oField, oCurs
Dim numChanged As Integer
oDocument = ThisComponent
oDrawPages = oDocument.getDrawPages()
oDrawPage = oDrawPages.getByIndex(0)
numChanged = 0
For tryNumText = 1 to 1000
vDescriptor = oDrawPage.createSearchDescriptor
With vDescriptor
'.SearchString = "[:digit:]+" 'Patterns work in search box but not here?
.SearchString = tryNumText
End With
vFound = oDrawPage.findFirst(vDescriptor)
If Not IsNull(vFound) Then
numText = vFound.getString()
oField = ThisComponent.createInstance("com.sun.star.text.TextField.URL")
oField.Representation = numText
oField.URL = numText & ".pdf"
vFound.setString("")
oCurs = vFound.getText().createTextCursorByRange(vFound)
oCurs.getText().insertTextContent(oCurs, oField, False)
numChanged = numChanged + 1
End If
Next tryNumText
MsgBox("Added " & numChanged & " links.")
End Sub
To save relative links, go to File -> Export as PDF -> Links and check Export URLs relative to file system.
I uploaded an example file here that works. For some reason your example file is hanging on my system -- maybe it's too large.
Replacing text with links is much easier in Writer than in Draw. However Writer does not open PDF files.
There is some related code at https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=1401.

How can I find a text in a spreadsheet using OObasic?

On OpenOffice documentation [1], I found a replace example. But I didn't find a search example.
Dim Doc As Object
Dim Sheet As Object
Dim ReplaceDescriptor As Object
Dim I As Integer
Doc = ThisComponent
Sheet = Doc.Sheets(0)
ReplaceDescriptor = Sheet.createReplaceDescriptor()
ReplaceDescriptor.SearchString = "is"
ReplaceDescriptor.ReplaceString = "was"
For I = 0 to Doc.Sheets.Count - 1
Sheet = Doc.Sheets(I)
Sheet.ReplaceAll(ReplaceDescriptor)
Next I
And better: Where can I find the docs that list the range/cell possible methods?
[1] http://wiki.openoffice.org/wiki/Documentation/BASIC_Guide/Editing_Spreadsheet_Documents
first of all: https://wiki.openoffice.org/wiki/Extensions_development_basic is a good starting point. In particular the XRAY tool is very helpfully.
The following code shows a search example:
Dim oDoc As Object
Dim oSheet As Object
Dim oSearchDescriptor As Object
Dim i As Integer
oDoc = ThisComponent
oSheet = oDoc.Sheets(0)
oSearchDescriptor = oSheet.createSearchDescriptor()
oSearchDescriptor.SearchString = "is"
For i = 0 to oDoc.Sheets.Count - 1
oSheet = oDoc.Sheets(i)
oResults = oSheet.findAll(oSearchDescriptor)
'xray oResults
if not isnull(oResults) then msgbox oResults.AbsoluteName
Next i
If you have XRAY installed, you can inspect every object with it and you have access to the related API docs.
Greetings
Axel

extract track changes information (inserted deleted text) from docx file

I'm looking to extract the inserted and deleted text from a word document after it's been reviewed. I've been able to extract the comments using the following macro:
Sub ExportComment()
Dim s As String
Dim cmt As Word.Comment
Dim doc As Word.Document
Dim workBk As Word.Document
Set workBk = ActiveDocument
Set doc = Documents.Add(Visible:=True)
Dim myRange As Range
Set myRange = doc.Range(0, 0)
Dim myTable As Table
Set myTable = doc.Tables.Add(Range:=myRange, NumRows:=workBk.Comments.Count, NumColumns:=6)
Dim i As Integer
i = 1
For Each cmt In workBk.Comments
myTable.Cell(i, 1).Range.Text = cmt.Index
myTable.Cell(i, 2).Range.Text = cmt.Scope.Information(wdActiveEndPageNumber)
myTable.Cell(i, 3).Range.Text = cmt.Initial
myTable.Cell(i, 4).Range.Text = cmt.Scope
myTable.Cell(i, 5).Range.Text = cmt.Range.Text
i = i + 1
Next
End Sub
But can't seem to figure out how to also get the inserted and deleted text from the tracked changes. Any ideas?
Thanks!
Just as you used the Comments collection in your sample code, you will want to use the Revisions Collection (for example, Dim rev as Word.Revision). Unlike Comments, Revisions has a Type property that you can use to identify different varieties of Track Changes. Here are some revision types:
If you want to see example VBA code that extracts revisions, go to
http://www.thedoctools.com/downloads/basTrackChanges_Extract.shtml
which is referenced on the below page while discussing the issue of extracting revisions:
http://www.thedoctools.com/index.php?show=mt_trackchanges_extract

Loop through fields of recordset to populate form?

I'm trying to use a For loop to loop through the fields in a single record recordset to populate the fields on a form. I was hoping to find a way that is neater/reusable than typing out half a dozen lines of txtField.value = rs!Field.
When I look at the code during runtime both variables have the correct information in them, it just isn't displaying them on the form. Any help would be greatly appreciated.
Dim strClient As String
Dim rsClient As dao.Recordset
Dim tfield As String
Dim ffiend As String
Dim fld As dao.Field
Set dbs_Current = CurrentDb()
strClient = "Select * from tblClient where pk_client_id = " & gbl_Client_ID
Set rsClient = dbs_Current.OpenRecordset(strClient)
For Each fld In rsClient.Fields
On Error Resume Next
tfield = "txt" & fld.Name & ".value"
ffield = "rsClient!" & fld.Name
tfield = ffield
Next fld