[libreoffice-users] Invoice automation using macros

2011-04-04 Thread Dag Wieers

Hi,

I have quite simple LibreOffice invoices, one file per invoice. There are 
2 items in each invoice I would like to make dynamic.


 1. Invoice number
 2. Due date

For the invoice number, I created a user field InvoiceNumber and a macro 
UpdateInvoiceNumber, which automatically extracts the invoice number 
from the filename and updates the field when the file is opened. This 
works great as I simply can copy my invoice to the new name 
(invoice--MM-#NR-company) and the document is updated automatically 
with /MM/#NR.


Now for the due date its more simple, but I cannot make it work. I used to 
have 2 fields, invoice date and due date. Both are fixed date fields, the 
second is 30 days off. To update them, I have to open the new invoice 
copy, double-click the invoice date field, disable the 'fixed' (so that 
is shows today's date), then make it fixed again, so it doesn't change the 
next time I may edit it. Repeat the same procedure for the due date 
fields. (twice, because I repeat the due date at the end in bold)


Now, what I intended to do was to create another user field of the due 
date and automatically update both with the date set in the invoice date 
field (which remains a fixed date) and add 30 days.


But the problem is that, contrary to user fields, date fields cannot be 
referenced in Basic (likely because they do not have a name). Or at least 
I cannot find it anywhere.


Below is the code I am using in LibreOffice to update the  InvoiceNumber. 
Can someone tell me how I can get the value of a (fixed) Date field ? Or 
is there an easier way to update dates, and manipulate them elsewhere ?



Sub Main
UpdateInvoiceNumber()
RemUpdateDueDate()
End Sub

Sub UpdateDueDate
Rem Don't know how to get to the invoice date fixed date field in the document
InvoiceDateField = thisComponent.getTextFieldMasters().getByName( 
com.sun.star.text.fieldmaster.InvoiceDate )
end Sub

sub UpdateInvoiceNumber
InvoiceNumberField = thisComponent.getTextFieldMasters().getByName( 
com.sun.star.text.fieldmaster.User.InvoiceNumber )
InvoiceNumberField.Content = InvoiceNumber()
disp = createUnoService(com.sun.star.frame.DispatchHelper)
disp.executeDispatch(thisComponent.CurrentController.Frame, .uno:UpdateFields, 
, 0, Array())
end Sub

Function InvoiceNumber
InvoiceNumber = ERROR
If (Not GlobalScope.BasicLibraries.isLibraryLoaded(Tools)) Then
GlobalScope.BasicLibraries.LoadLibrary(Tools)
End If
InvoiceNumber = FileNameoutofPath(thisComponent.getURL(), /)
InvoiceNumber = Mid(InvoiceNumber, 9, 11)
InvoiceNumber = ReplaceStr(InvoiceNumber, -, /)
End Function

Function ReplaceStr(myString As String, str1 As String, str2 As String)
ReplaceStr = join(split(myString, str1), str2)
End Function


PS Is there an easier way to look at the document object model than using 
a watch in your macro editor ? Preferably something to search. That would 
be so useful !


Thanks for your insights !
--
-- dag wieers, d...@wieers.com, http://dag.wieers.com/
-- dagit linux solutions, i...@dagit.net, http://dagit.net/

[Any errors in spelling, tact or fact are transmission errors]

--
Unsubscribe instructions: E-mail to users+h...@libreoffice.org
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/www/users/
All messages sent to this list will be publicly archived and cannot be deleted



Re: [libreoffice-users] Invoice automation using macros

2011-04-04 Thread Dag Wieers

On Mon, 4 Apr 2011, Dag Wieers wrote:

But the problem is that, contrary to user fields, date fields cannot be 
referenced in Basic (likely because they do not have a name). Or at least I 
cannot find it anywhere.


With some help from the OpenOffice forums I solved this by not using 
fixed date fields, but rather using user fields (variables) with a Date 
format.


The downside is that editing them is editing the number of days since 
Epoch (although it does accept a 2011.04.04 string).


To use the below code as macro in your documents, simply create three user 
fields named InvoiceNumber (string), InvoiceDate (Date formatted) and 
DueDate (Date formatted), and use a filename that matches 
invoice-2001/03/011-customer.odt (year/month/number) or simply modify the 
code to do what you like ;-)


And then link the below event-handlers to their respective event from 
Tools  Customize  Events.



REM For testing purposes
Sub Main
updateInvoiceNumber()
updateDueDate()
End Sub

REM Event handler when opening a document
Sub _Open
updateInvoiceNumber()
End Sub

REM Event handler when a document is being saved
Sub _Save
updateDueDate()
End Sub

REM Event handler when a document is modified
Sub _Modified
updateDueDate()
End Sub

REM Update a user field (DueDate) with the invoice date + 30 days
Sub updateDueDate
DueDate = getDueDate()
DueDateField = thisComponent.getTextFieldMasters().getByName( 
com.sun.star.text.fieldmaster.User.DueDate )
If (DueDateField.Value  DueDate) Then
DueDateField.Value = DueDate
thisComponent.TextFields.refresh()
EndIf
End Sub

REM Retrieve the user field (InvoiceDate) from the document and make 
DueDate = InvoiceDate + 30

Function getDueDate
If (Not GlobalScope.BasicLibraries.isLibraryLoaded(Tools)) Then
GlobalScope.BasicLibraries.LoadLibrary(Tools)
End If
InvoiceDateField = thisComponent.getTextFieldMasters().getByName( 
com.sun.star.text.fieldmaster.User.InvoiceDate )
getDueDate = InvoiceDateField.Value + 30
End Function

REM Update a user field (InvoiceNumber) with a slice of the document name
Sub updateInvoiceNumber
InvoiceNumber = getInvoiceNumber()
InvoiceNumberField = thisComponent.getTextFieldMasters().getByName( 
com.sun.star.text.fieldmaster.User.InvoiceNumber )
If (InvoiceNumberField.Content  InvoiceNumber) Then
InvoiceNumberField.Content = InvoiceNumber
thisComponent.TextFields.refresh()
End If
End Sub

REM Extract the invoice number from the document name (slice 9-20)
Function getInvoiceNumber
If (Not GlobalScope.BasicLibraries.isLibraryLoaded(Tools)) Then
GlobalScope.BasicLibraries.LoadLibrary(Tools)
End If
getInvoiceNumber = FileNameoutofPath(thisComponent.getURL(), /)
getInvoiceNumber = Mid(getInvoiceNumber, 9, 11)
getInvoiceNumber = ReplaceStr(getInvoiceNumber, -, /)
End Function

REM Return a string with str1 replaced with str2
Function ReplaceStr(myString As String, str1 As String, str2 As String)
ReplaceStr = join(split(myString, str1), str2)
End Function


Hope this is useful to you.
--
-- dag wieers, d...@wieers.com, http://dag.wieers.com/
-- dagit linux solutions, i...@dagit.net, http://dagit.net/

[Any errors in spelling, tact or fact are transmission errors]

--
Unsubscribe instructions: E-mail to users+h...@libreoffice.org
Posting guidelines + more: http://wiki.documentfoundation.org/Netiquette
List archive: http://listarchives.libreoffice.org/www/users/
All messages sent to this list will be publicly archived and cannot be deleted