My recommendation would be to first concentrate on getting the data input portion of the code working the way the users want it to. During this phase, just save the data to a tab-delimited text file. This format is easy to generate, easy to read and (if you implement it in the form of one VI that reads a dataset and another that writes datasets) easy to upgrade to something better later.
Once the data entry portion is working the way users want, create the print routine. All you have to do is create a VI with a white front panel and place on it indicators to display the data you want printed. You then use the VI server functionality to tell the VI to print itself. The only thing to remember is that you have to have at least one property node on the diagram of the "print" VI. This causes LV to update the VI's front panel even if it's not open. Normally LV doesn't update a subVIs front panel unless it's open, however the presence of a property node overrides this behavior. Again, I can send you an example of this type of operation...
When the printing is working the way you want, you can come back to the data management piece and replace your two IO routines with versions that fetch the information from a database or whatever you want.
Now, the reader version of the program would be the same as the regular version but without the screen that allows the user to modify/enter data. Again, if you structure the code right, generating the "data reader" version of your application is simply a matter of reconfiguring your standard code base to use one display screen rather than another one--or possibly setting an input that in the reader version of the software, disables all the data input fields and turns them (essentially) into indicators.
There are a bunch of ways of doing this sort of thing. I have also developed systems that used software plugins to vary the application's functionality.
Hopefully this hasn't confused you. We can as you like, cover each piece in more detail.
Mike...
mporter@arielcorp.com