News combit Dev Blog

dsListLabel - Simplified Xbase++ Integration

Posted: Friday, February 24, 2017 | 2 comment(s)
 
Years ago I started developing a class to simplify the integration of List & Label into Xbase++ which I used for all my client's apps. The range of functionality grew with every new task. By now it supports real data preview which is handled in a separate thread.

As we also offer Addon Libraries for Xbase++ developers (XClass++, AdsClass++, VisualDBU,...) it did not take long until users asked me to share my ideas and code and provide a common class to everyone. Xbase++ developers are used to a high level language and do not really want to deal with API calls.

After consulting with the List & Label team, we decided to share this class and provide it free to everyone. The main approach is to implement sophisticated methods which completely hide the List & Label API. This class will meet most of the demands for everyday reports. It provides callback slots to call all List & Label API functions which are not already wrapped by methods. So there is no limit of individual configuration possibilities.

This is the basic code for creating a report:

FUNCTION Print(oDlg)     // oDlg is calling dialog 
  LOCAL oListLabel 
  LOCAL nError 
 
  oListLabel := dsListLabel():New( oDlg) 
 
  // some error handling
  if oListLabel:Status() == XBP_STAT_FAILURE 
    Msgbox("Cannot load List & Label:"+;
		var2char(oListLabel:Getlasterror())) 
    RETURN false 
  endif 
 
  // report file is searched in :DefaultPath or current directory 
  oListLabel:Report := "order.lst" 
 
  // current workarea is printed in a do-while loop 
  // filter or scopes are respected 
  oListLabel:Connect() 
 
  // register table to be visible in designer and provide data to print 
  oListLabel:DataSetField() 
 
  nError := oListLabel:Print() 
 
  if nError <> 0              // some error handling 
     Msgbox(oListLabel:GetLastMessage(), "Error: "+;
			var2char(oListLabel:GetLastError())) 
  endif 
  oListLabel:Close() 
RETURN nError == 0 

Basic configuration can be set once in the main function like main() and is stored in class members.
dsListLabel():LicensingInfo(<your personal List & Label license>)
dsListLabel():DefaultPath(".\ListLabel")

Little by little this sample can be extended. For example, it is very easy to export the report into a PDF document:
// open export file afterwards, default = .f. 
oListLabel:Showexport := .t. 
 
// instead of :print() 
nError   := oListLabel:SaveAsPdf("c:\tmp\myfile.pdf" )

And sending the report by email is also quite simple:
cCC      := "cc@ds-datasoft.de" 
cBCC     := "bcc@ds-datasoft.de" 
cSubject := "Hello World" 
cBody    := memoread("MailBody.txt")       // for example
 
// instead of :print() 
nError   := oListLabel:SendAsMail(.f., "info@ds-datasoft.de", cCC, cBCC,;
			cSubject, cBody )

So far this looks pretty good. In the next step we will add a report container to support relational data structures, typically used for master-detail printing:
// register tables for designer 
oListLabel:DataSetField(select("Order"), "Order") 
oListLabel:DataSetField(select("OrderItem"), "OrderItem")

// register tables for report container 
// 2nd parameter: symbol name must be identical with 2nd parameter of 
// DataSetField! (case-sensitiv!) 
oListLabel:AddTable("Order", "Order") 
oListLabel:AddTable("OrderItem", "OrderItem") 
 
// register relationen 
// 1st + 2nd parameter: symbol name must be identical with 2nd parameter of 
// DataSetField! 
oListLabel:AddTableRelation("OrderItem", "Order", "Order Items") 

// Codeblock when table changes in report container 
oListLabel:TableChange := {|o,l,c,p| _TableChange(o,l,c,p)} 
 
nError := oListLabel:Print()

Additionally I have added two more features:

  • A callback slot when printing from preview (e.g. to set a print flag)
    // callback, printing
    oListLabel:Callback :=	{|nE,nId,oListLabel|myFunction(nE,nId,oListLabel)}
  • Real data preview in the Designer. To implement this feature a thread is started, the registered tables are moved to the workspace of this thread and the data is passed to List & Label. When finished, the tables are released and moved back to the original workspace.
    // enable once in main()
    dsListLabel:DefaultDesignerPreview(.t.)
    
    That’s it! Once this feature is enabled and you switch to the preview in the Designer you get a preview with real data. All the work is done in the background. This feature requires also to install the OT4XB package from Pablo Botella Navarro which can be downloaded from www.xbwin.com.


The dsListLabel package includes DLLs for List & Label 22 and Visual Xbase++ 2.0. As the source code is also shipped, DLLs for different versions can be created by demand. The component dsListLabel will be included in the next List & Label 22 installation. Or you can download it directly from our website.




Author: Marcus Herz
Partner at DS-Datasoft

Marcus Herz has specialized in Xbase++ development and has created addon libraries from the very beginning of Xbase++. He realizes individual and specific industry solutions and other data-based projects.



RSS
combit Development BlogRSS
What’s this blog for?
A place to share updates about the ongoing development of our products. General musings on the software industry included.
Archive
March 2021 (1)
February 2021 (2)
January 2021 (1)
December 2020 (2)
November 2020 (1)
October 2020 (2)
September 2020 (1)
August 2020 (2)
July 2020 (1)
June 2020 (1)
May 2020 (2)
April 2020 (2)
March 2020 (2)
February 2020 (1)
January 2020 (1)
December 2019 (1)
November 2019 (2)
October 2019 (2)
September 2019 (2)
August 2019 (2)
July 2019 (2)
June 2019 (2)
May 2019 (1)
April 2019 (0)
April 2019 (1)
March 2019 (1)
February 2019 (1)
January 2019 (1)
December 2018 (1)
November 2018 (2)
October 2018 (4)
September 2018 (4)
August 2018 (2)
July 2018 (2)
June 2018 (2)
May 2018 (1)
April 2018 (1)
March 2018 (1)
February 2018 (2)
January 2018 (1)
December 2017 (1)
November 2017 (2)
October 2017 (3)
September 2017 (3)
August 2017 (2)
July 2017 (2)
June 2017 (1)
May 2017 (2)
April 2017 (1)
March 2017 (1)
February 2017 (1)
January 2017 (2)
December 2016 (1)
November 2016 (1)
October 2016 (4)
September 2016 (5)
August 2016 (2)
July 2016 (2)
June 2016 (3)
May 2016 (2)
April 2016 (3)
March 2016 (3)
February 2016 (1)
January 2016 (2)
December 2015 (2)
November 2015 (1)
October 2015 (4)
September 2015 (5)
August 2015 (2)
July 2015 (2)
June 2015 (2)
May 2015 (1)
April 2015 (2)
March 2015 (1)
February 2015 (1)
January 2015 (1)
December 2014 (2)
November 2014 (1)
October 2014 (1)
September 2014 (2)
August 2014 (1)
July 2014 (2)
June 2014 (1)
May 2014 (2)
April 2014 (1)
March 2014 (2)
+1 800 256 3608 (toll-free North America only)