• Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Discover the Error of Your Ways

Q: How does a program determine errors after calling a UNIX-type API?

— Gene Gaunt This email address is being protected from spambots. You need JavaScript enabled to view it.

A: The code in Figure 1 shows how to retrieve the error value when calling UNIX-type APIs.

— Carsten Flensburg This email address is being protected from spambots. You need JavaScript enabled to view it.

H debug

D errno Pr 10i 0

D strerror Pr 128A


D fclose Pr extproc('fclose')

D parm * value

D errnbr s 10i 0

D errtxt s 46A noopt


C callp fclose (*NULL)

C eval errnbr = errno

C errnbr dsply

C eval errtxt = strerror

C errtxt dsply

C dump


C seton lr


P errno B

D errno Pi 10I 0

D sys_errno Pr * ExtProc('__errno')

D errnbr S 10I 0 Based(errptr)

D errptr S *


C Eval errptr = sys_errno

C Return errnbr




P strerror B

D strerror Pi 128A

D sys_strerror Pr * ExtProc('strerror')

D 10I 0 Value

D errtxt S 128A Based(txtptr) Noopt

Figure 1: This code fragment finds the error value when you call UNIX-type APIs.

Don’t Be So Quick to Pull the Trigger

Many AS/400 programmers have taken advantage of database triggers to let OS/400 protect their data integrity. For example, they use triggers to validate data when a record is added and to ensure that, if a record is deleted, any other business rules that should be in effect for related records are also enforced. For the most part, this technique works great. However, there is at least one instance when database triggers cannot protect your data. If someone runs Clear Physical File Member (CLRPFM) over a database file being protected by a trigger, that trigger is not fired, because triggers act at the row level, not the file level. That is, the trigger is not activated unless the deletion is performed one row at a time (for example, using the DELETE operation in RPG or pressing F23, the Delete function key, while in the DFU).

— Chuck Pence This email address is being protected from spambots. You need JavaScript enabled to view it.

Changing the Code Page of AS/400 IFS Files

For those who have used a PC-based tool such as Microsoft Word or Excel or Lotus 1-2-3 to view the contents of an AS/400 Integrated File System (AS/400 IFS) file created using Copy to Import File (CPYTOIMPF), the file probably appeared to contain gibberish. This was probably because the PC-based program expected the file to be ASCII and the file contained EBCDIC characters. One way to remedy this is to set the code page of the AS/400 IFS files to ASCII before using CPYTOIMPF to load the file with data. This translates the data being placed in the file to ASCII. Follow these six steps to create an ASCII code page AS/400 IFS file that can be used as a base to set the code page of new AS/400 IFS files:

1. CRTPF lib/temp rcdlen(1) (Add a record to this file by using a utility program such as DFU.)

2. CD DIR(‘/qdls/foldername’)


4. MOV OBJ(‘temp’) TOOBJ(‘CCSID00367’) TOCODEPAGE(00367)

5. Copy the ASCII code page file to create the output AS/400 IFS file for your CPYTOIMPF command when you first use an output AS/400 IFS file. Issue the following command to replace myASCIIfile.csv with the name of the file you are specifying on the CPYTOIMPF command:

CPY OBJ(‘CCSID00367’) TOOBJ(‘myASCIIfile.csv’)

When you specify your new AS/400 IFS file on the CPYTOIMPF command, the data is translated to ASCII as it is copied to the output AS/400 IFS file.


— David Morris This email address is being protected from spambots. You need JavaScript enabled to view it.

What’s the Deal with INST?

Q: How do you map to a source line number from a job log’s INST column? I know the INST number is hexadecimal. However, I think the hexadecimal number is not a source line number but a compile listing STMT number. I used the Win95 calculator (in Scientific view) to enter the hexadecimal number to convert it to decimal. I then compiled the source to get the STMT numbers, making sure the source change date and time agreed with the program object. I knew I was looking for some kind of I/O function, because the job log message I was trying to track down was about a record lock, but the steps I took did not get me to an I/O source line. The program was not ILE, and the default GENOPT option *NOOPTIMIZE was used.

— Paul Roubekas This email address is being protected from spambots. You need JavaScript enabled to view it.

A: Here’s one method you can use. The INST column in the job log shows MI statement numbers. Follow these steps to determine the SEU line number:
1. Recompile the program and specify GENOPT(*LIST).
2. Look near the end of the compiler listing for a section of MI code. Look for the INST column, the second column from the left. Find the number in this column that appears in your job log.
3. Look in the far left column on the line matching your instruction number. This is the SEU line number (e.g., 12300).

— Gene Gaunt This email address is being protected from spambots. You need JavaScript enabled to view it.

Editor’s Note: Of course, you could always just look at the job log. It specifies the line number in error in the message text.

Finding Numeric Values in Packed Fields

Q: I have a program that writes to and updates packed decimal fields. Because of the way the program is structured, I’m not always sure that the data going into that field is valid for the data type. When invalid data goes into the field, it causes problems, such as decimal data errors if other programs try to access the data in that field. Is there a method I can use to test for valid data in packed decimal fields before I write it to a file?

— Edwin Yang This email address is being protected from spambots. You need JavaScript enabled to view it.

A: TESTN tests only zoned fields. To test a packed field, you could use Check/Check Right (CHECK/CHECKR) to test a character view of the field. Figure 2 shows a program I wrote that checks whether the program parameter contains a valid packed number. Call the program and pass it a packed field, the number of bytes in the packed field, and an “ok” field.

If the “ok” field returns a value of 1, the field contains valid packed data. You can easily modify this little program and include it as either a subroutine or a subprocedure in your programs.

— Barbara Morris

IBM Toronto Lab RPG Compiler Development

* =============================================================== *

* To compile: *

* *


* SRCMBR(BM000R1) *

* *

* =============================================================== *

d valBegin c X'+

d 00010203040506070809+

d 10111213141516171819+

d 20212223242526272829+

d 30313233343536373839+

d 40414243444546474849+

d 50515253545556575859+

d 60616263646566676869+

d 70717273747576777879+

d 80818283848586878889+

d 90919293949596979899'

d valLast c x'+

d 0A0B0C0D0E0F+

d 1A1B1C1D1E1F+

d 2A2B2C2D2E2F+

d 3A3B3C3D3E3F+

d 4A4B4C4D4E4F+

d 5A5B5C5D5E5F+

d 6A6B6C6D6E6F+

d 7A7B7C7D7E7F+

d 8A8B8C8D8E8F+

d 9A9B9C9D9E9F'

d lastByte s 1a


c PARM charView 16

c PARM len 5 0

c PARM ok 1

* Check the last byte for digit (0-9) + sign (A-F)

C 1 SUBST charView:len lastByte

c valBegin CHECK lastByte 11=FD

* Check the first n-1 bytes for digits (0-9) in both nibbles

c EVAL len = len - 1

c valLast CHECKR charView:len 10=FD


c EVAL ok = NOT (*IN10 OR *IN11)

c IF ok = '0'

c 'invalid' DSPLY


c 'ok' DSPLY




Figure 2: This program tests for numeric values in packed variables.

Separate Test and Production Environments

We often have separate test and production environments with separate copies of application database files. A problem I encounter when running a test or production program against the test database is that test results accidentally go to a production printer, thus confusing users, or that a test run in the test system accidentally triggers an EDI communication. The first problem is caused by the hardcoding of production OUTQs in CL programs, a simple way of getting output to an OUTQ other than the job’s default OUTQ. I added permanent code to the CL programs so the program uses production facilities (such as printers or EDI) if run in production but bypasses these facilities automatically if run in test. The code I added is shown in Figure 3.

In my example, “filename” is the name of a file found in either your test or your production database library. You find the name and type of that library to test whether you are using a test or production library. For this technique to work, you must ensure that all your database libraries are correctly classified as either TEST or PROD. This library type is easy to set:


Note that IBM has introduced a bit of inconsistency. With Change Library (CHGLIB), you must prefix TEST and PROD with an asterisk, but Retrieve Library Description (RTVLIBD) returns the library type without an asterisk.

— Richard Leitch This email address is being protected from spambots. You need JavaScript enabled to view it.





OVRPRTF FILE(printfile) OUTQ(production)
ELSE CMD(DO) /* You are in test */


Figure 3: Add this code to your applications to ensure that your programs run in the correct environment.

Who Hosts That Address?

Looking for a way to determine, via a program, which TCP/IP host name is assigned to which TCP/IP address? File QATOCHOST in library QUSRSYS contains host table entries added using option 10 from the Configure TCP/IP (CFGTCP) menu. QATOCHOST contains IP addresses, host names, and descriptions. You can create a query or RPG program to generate a report of this information, which would be an improvement over the OS/400 TCP/IP Host Table Entries Information report, which you create via F6 from the Work with TCP/IP Host Table Entries panel. You can also use the Client Access file transfer function to download this information into the HOSTS file on your PC.

— Tim Cortez Worley Warehousing, Inc. This email address is being protected from spambots. You need JavaScript enabled to view it.

Editor’s Note: To the best of our knowledge, this is not a supported interface. Be aware that IBM may rename this file or store this information in another object in a future release of OS/400.

Using SQL to Merge Files

In years past, the RPG cycle and MR indicator allowed RPG programmers to merge the contents of files based on common keys. This technique was commonly known as matching records processing. Lately, however, the RPG cycle (and matching records processing in particular) has fallen out of favor, but the need to merge the contents of files still exists.

For those who have SQL on their AS/400s, there is an alternative to matching records processing. The trick is to use a union to merge data via a left join combined with an exception join. The left join selects all records from the primary file; the exception join picks up unmatched records from the secondary file. Using ORDER BY on the last union presents merged records in order.

You enter the SQL statement as shown in Figure 4. I have used this technique with IBM-supplied output files to match related information. For example, you can merge the output of the Display Object Description (DSPOBJD) command with corresponding Display File Description (DSPFD) *MBR information and use the merged information to generate reports via SQL (see Figure 5).

After you run these two commands, you can run the SQL statement shown in Figure 6 to merge the object and member creation information generated by the commands. The output of the SQL statement is a list of objects and their corresponding source members. You can run this statement interactively or run it within an SQL program. To handle null values returned for unmatched records when this statement is embedded in an SQL program, you must define a null indicator area or surround the field names with an

IFNULL function. For character fields, use IFNULL(FldNam, ‘ ‘); for numeric fields, use IFNULL(FldNam, 0).

— David Morris This email address is being protected from spambots. You need JavaScript enabled to view it.

SELECT Table1.Column1, Table2.Column2... From Table1
Left Join Table2 On Table1.Column1 = Table2.Column1
SELECT Table1.Column1, ifnull(Table2.Column2, ' ')... From Table2
Exception Join Table1 On Table1.Column1 = Table2.Column1
Order By Table1.Column1, Table2.Column2
Figure 4: These SQL statements perform the matching record function.


Figure 5: This command loads a list of all objects in a given location to an *OUTFILE.

SELECT odlbnm, odobnm, mblib, mbfile, mbname, ... * From obj Left Join mbr On odsrcl = mblib And odsrcf =
mbfile And odsrcm = mbname Where Substr(odobnm,1,1) ¨= 'Q'
UNION ALL Select odlbnm, odobnm, mblib, mbfile, mbname ... From mbr Exception Join obj On mblib = odsrcl
And mbfile = odsrcf And mbname = odsrcm Where mbname ¨= ' ' Order By odlbnm, odobnm, mblib, mbfile,

Figure 6: These SQL statements merge the object and member creation information generated by the previous commands.

TESTN Negative

If you use the test numeric (TESTN) operation in your RPG programs, you should be aware of how negative numbers are tested. To review, TESTN determines whether a character field contains all numeric data, numeric data with leading spaces, all spaces, or none of the above. When stored in a character field, negative numbers encode the sign into the rightmost character.

Uppercase letters J through R represent -1 through -9, respectively (hexadecimals D1 through D9), and the right brace (}) represents zero in a negative number (hexadecimal D0). Consequently, a field defined as 5a with a value of 1234} becomes -12340 when moved to a numeric field defined as 5.0. This means that your character field turns on the HIGH indicator in a TESTN operation, indicating all numeric data. Furthermore, if the rightmost character is an uppercase letter from A through I (hexadecimals C1 through C9) or the left brace ({) (hexadecimal C0) and all other characters are numeric, this field also tests as all numeric data. Try it yourself. Uppercase letters A through I translate to positive 1 through 9, respectively, and the left brace ({) becomes zero when moved to a numeric field.

Suppose your system receives an electronic data interchange (EDI) purchase order from your trading partner and one of the fields received is an order quantity sent to you in a mutually agreed upon character field. In addition, suppose your batch RPG program always edits this field for actual numeric data before moving the character field to a numeric field, subsequently creating a sales order. Would receiving a value of 1000A cause a problem? A TESTN on this field passes, and congratulations! You’ve just ordered 10,000 widgets for your trading partner when they wanted only 1,000. Imagine the surprise if a shipment actually hits their receiving dock.

Fortunately, the workaround for this particular situation is simple, as shown in the code fragment in Figure 7. Just move your character field left into a bigger character field before the TESTN statement. Make certain that the rightmost character of the bigger field is a number from 0 through 9, and TESTN will work as you expect. Another solution would be to use the CHECK operation to scan explicitly for just the numbers 0 through 9.

— Chris Ringer This email address is being protected from spambots. You need JavaScript enabled to view it.

* =============================================================== *

* To compile: *

* *


* SRCMBR(CR000R1) *

* *

* =============================================================== *

D CharQty s 5a Inz('1000A')

D IntQty s 5s 0

D Char30 s 30a

D Wk0to9 c Const('0123456789')

* Using TESTN HiLoEq

C move *ZEROS Char30

C movel CharQty Char30

C testn Char30 50

C If (*IN50 = *On)

C move CharQty IntQty

C else

* ..not numeric

C endif

* Using CHECK

C Wk0to9 Check CharQty 50

C If (*IN50 = *Off)

C move CharQty IntQty

C else

* ..not numeric

C endif

Figure 7: This code fragment tests for numeric values in negative numbers.



Support MC Press Online





  • White Paper: Node.js for Enterprise IBM i Modernization

    SB Profound WP 5539

    If your business is thinking about modernizing your legacy IBM i (also known as AS/400 or iSeries) applications, you will want to read this white paper first!

    Download this paper and learn how Node.js can ensure that you:
    - Modernize on-time and budget - no more lengthy, costly, disruptive app rewrites!
    - Retain your IBM i systems of record
    - Find and hire new development talent
    - Integrate new Node.js applications with your existing RPG, Java, .Net, and PHP apps
    - Extend your IBM i capabilties to include Watson API, Cloud, and Internet of Things

    Read Node.js for Enterprise IBM i Modernization Now!


  • Profound Logic Solution Guide

    SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation.
    Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects.
    The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the companyare not aligned with the current IT environment.

    Get your copy of this important guide today!


  • 2022 IBM i Marketplace Survey Results

    Fortra2022 marks the eighth edition of the IBM i Marketplace Survey Results. Each year, Fortra captures data on how businesses use the IBM i platform and the IT and cybersecurity initiatives it supports.

    Over the years, this survey has become a true industry benchmark, revealing to readers the trends that are shaping and driving the market and providing insight into what the future may bring for this technology.

  • Brunswick bowls a perfect 300 with LANSA!

    FortraBrunswick is the leader in bowling products, services, and industry expertise for the development and renovation of new and existing bowling centers and mixed-use recreation facilities across the entertainment industry. However, the lifeblood of Brunswick’s capital equipment business was running on a 15-year-old software application written in Visual Basic 6 (VB6) with a SQL Server back-end. The application was at the end of its life and needed to be replaced.
    With the help of Visual LANSA, they found an easy-to-use, long-term platform that enabled their team to collaborate, innovate, and integrate with existing systems and databases within a single platform.
    Read the case study to learn how they achieved success and increased the speed of development by 30% with Visual LANSA.


  • The Power of Coding in a Low-Code Solution

    LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed.
    Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

    • Discover the benefits of Low-code's quick application creation
    • Understand the differences in model-based and language-based Low-Code platforms
    • Explore the strengths of LANSA's Low-Code Solution to Low-Code’s biggest drawbacks



  • Why Migrate When You Can Modernize?

    LANSABusiness users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.
    In this white paper, you’ll learn how to think of these issues as opportunities rather than problems. We’ll explore motivations to migrate or modernize, their risks and considerations you should be aware of before embarking on a (migration or modernization) project.
    Lastly, we’ll discuss how modernizing IBM i applications with optimized business workflows, integration with other technologies and new mobile and web user interfaces will enable IT – and the business – to experience time-added value and much more.


  • UPDATED: Developer Kit: Making a Business Case for Modernization and Beyond

    Profound Logic Software, Inc.Having trouble getting management approval for modernization projects? The problem may be you're not speaking enough "business" to them.

    This Developer Kit provides you study-backed data and a ready-to-use business case template to help get your very next development project approved!

  • What to Do When Your AS/400 Talent Retires

    FortraIT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators is small.

    This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn:

    • Why IBM i skills depletion is a top concern
    • How leading organizations are coping
    • Where automation will make the biggest impact


  • Node.js on IBM i Webinar Series Pt. 2: Setting Up Your Development Tools

    Profound Logic Software, Inc.Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. In Part 2, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Attend this webinar to learn:

    • Different tools to develop Node.js applications on IBM i
    • Debugging Node.js
    • The basics of Git and tools to help those new to it
    • Using as a pre-built development environment



  • Expert Tips for IBM i Security: Beyond the Basics

    SB PowerTech WC GenericIn this session, IBM i security expert Robin Tatam provides a quick recap of IBM i security basics and guides you through some advanced cybersecurity techniques that can help you take data protection to the next level. Robin will cover:

    • Reducing the risk posed by special authorities
    • Establishing object-level security
    • Overseeing user actions and data access

    Don't miss this chance to take your knowledge of IBM i security beyond the basics.



  • 5 IBM i Security Quick Wins

    SB PowerTech WC GenericIn today’s threat landscape, upper management is laser-focused on cybersecurity. You need to make progress in securing your systems—and make it fast.
    There’s no shortage of actions you could take, but what tactics will actually deliver the results you need? And how can you find a security strategy that fits your budget and time constraints?
    Join top IBM i security expert Robin Tatam as he outlines the five fastest and most impactful changes you can make to strengthen IBM i security this year.
    Your system didn’t become unsecure overnight and you won’t be able to turn it around overnight either. But quick wins are possible with IBM i security, and Robin Tatam will show you how to achieve them.

  • Security Bulletin: Malware Infection Discovered on IBM i Server!

    SB PowerTech WC GenericMalicious programs can bring entire businesses to their knees—and IBM i shops are not immune. It’s critical to grasp the true impact malware can have on IBM i and the network that connects to it. Attend this webinar to gain a thorough understanding of the relationships between:

    • Viruses, native objects, and the integrated file system (IFS)
    • Power Systems and Windows-based viruses and malware
    • PC-based anti-virus scanning versus native IBM i scanning

    There are a number of ways you can minimize your exposure to viruses. IBM i security expert Sandi Moore explains the facts, including how to ensure you're fully protected and compliant with regulations such as PCI.



  • Encryption on IBM i Simplified

    SB PowerTech WC GenericDB2 Field Procedures (FieldProcs) were introduced in IBM i 7.1 and have greatly simplified encryption, often without requiring any application changes. Now you can quickly encrypt sensitive data on the IBM i including PII, PCI, PHI data in your physical files and tables.
    Watch this webinar to learn how you can quickly implement encryption on the IBM i. During the webinar, security expert Robin Tatam will show you how to:

    • Use Field Procedures to automate encryption and decryption
    • Restrict and mask field level access by user or group
    • Meet compliance requirements with effective key management and audit trails


  • Lessons Learned from IBM i Cyber Attacks

    SB PowerTech WC GenericDespite the many options IBM has provided to protect your systems and data, many organizations still struggle to apply appropriate security controls.
    In this webinar, you'll get insight into how the criminals accessed these systems, the fallout from these attacks, and how the incidents could have been avoided by following security best practices.

    • Learn which security gaps cyber criminals love most
    • Find out how other IBM i organizations have fallen victim
    • Get the details on policies and processes you can implement to protect your organization, even when staff works from home

    You will learn the steps you can take to avoid the mistakes made in these examples, as well as other inadequate and misconfigured settings that put businesses at risk.



  • The Power of Coding in a Low-Code Solution

    SB PowerTech WC GenericWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed.
    Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

    • Discover the benefits of Low-code's quick application creation
    • Understand the differences in model-based and language-based Low-Code platforms
    • Explore the strengths of LANSA's Low-Code Solution to Low-Code’s biggest drawbacks



  • The Biggest Mistakes in IBM i Security

    SB Profound WC Generic The Biggest Mistakes in IBM i Security
    Here’s the harsh reality: cybersecurity pros have to get their jobs right every single day, while an attacker only has to succeed once to do incredible damage.
    Whether that’s thousands of exposed records, millions of dollars in fines and legal fees, or diminished share value, it’s easy to judge organizations that fall victim. IBM i enjoys an enviable reputation for security, but no system is impervious to mistakes.
    Join this webinar to learn about the biggest errors made when securing a Power Systems server.
    This knowledge is critical for ensuring integrity of your application data and preventing you from becoming the next Equifax. It’s also essential for complying with all formal regulations, including SOX, PCI, GDPR, and HIPAA
    Watch Now.

  • Comply in 5! Well, actually UNDER 5 minutes!!

    SB CYBRA PPL 5382

    TRY the one package that solves all your document design and printing challenges on all your platforms.

    Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product.

    Request your trial now!

  • Backup and Recovery on IBM i: Your Strategy for the Unexpected

    FortraRobot automates the routine tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:
    - Simplified backup procedures
    - Easy data encryption
    - Save media management
    - Guided restoration
    - Seamless product integration
    Make sure your data survives when catastrophe hits. Try the Robot Backup and Recovery Solution FREE for 30 days.

  • Manage IBM i Messages by Exception with Robot

    SB HelpSystems SC 5413Managing messages on your IBM i can be more than a full-time job if you have to do it manually. How can you be sure you won’t miss important system events?
    Automate your message center with the Robot Message Management Solution. Key features include:
    - Automated message management
    - Tailored notifications and automatic escalation
    - System-wide control of your IBM i partitions
    - Two-way system notifications from your mobile device
    - Seamless product integration
    Try the Robot Message Management Solution FREE for 30 days.

  • Easiest Way to Save Money? Stop Printing IBM i Reports

    FortraRobot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing.
    Manage your reports with the Robot Report Management Solution. Key features include:

    - Automated report distribution
    - View online without delay
    - Browser interface to make notes
    - Custom retention capabilities
    - Seamless product integration
    Rerun another report? Never again. Try the Robot Report Management Solution FREE for 30 days.

  • Hassle-Free IBM i Operations around the Clock

    SB HelpSystems SC 5413For over 30 years, Robot has been a leader in systems management for IBM i.
    Manage your job schedule with the Robot Job Scheduling Solution. Key features include:
    - Automated batch, interactive, and cross-platform scheduling
    - Event-driven dependency processing
    - Centralized monitoring and reporting
    - Audit log and ready-to-use reports
    - Seamless product integration
    Scale your software, not your staff. Try the Robot Job Scheduling Solution FREE for 30 days.