I'm developing a cashier application using Delphi 7 and QuickReport 3.0.9.
The problem is the printing module is limited to the size of the component length in the form, so when the user prints a very long list of item, some of the items will get cut off. The printer is a special printer for cashiers (I don't know the correct name for this printer) that uses a roll of paper, so the printout length should be unlimited.
How do I set the printout length to unlimited? I already emptied the QuickRep1 - Page - Length property but it's still cut off at some point.
Unfortunately you cannot do it with QuickReport v3.0.9.
Support for continuous paper has been introduced with QuickReport v5 update:
Continuous paper. A new property of TPage, Continuous adds support for printing from rolls
When you set the Continuous property to true, the report should not contain any newpage commands.
Related
How is this technique implemented?
I noticed that they(like Bartender) don't directly concatenate commands like ZPL (etc.).
And also they don't use bitmap(GDI,GDI+ images) transfer to printer-driver.
Printer-based Serialization In print jobs that include serial numbers, many printers can accept a starting value and the incremental
step size. When you use this printer-based serialization, you can
print a large number of serialized items without having to send any
data after the first label.
Printer-based Barcodes Printers that have built-in barcode functionality make it possible for software programs to request
complex barcodes by using simple text strings (such as “1234”). This
process is much faster than sending bitmap images (or pictures) of
barcodes that consume hundreds or thousands of extra bytes per printed
item. (When you use software other than BarTender, our driver fonts
give you some limited functionality.)
Printer-based barcodes are, as you mention, barcodes that have the symbology / definition stored in the printer firmware. Much like a DLL that you give "12345" and as a result gets a bitmap, an SVG file etc etc.
Many modern label printers know a bunch of common symbologies such as EAN, DM, QR, UPC and similar.
The benefit is obviously that it makes transfer of data much more efficient. Instead of sending a (large) image for every print, the software just sends initial definition (layout, symbology choice and options, ..) + the value needed. Taken to the next level, the printer could receive metadata such as "take this layout, make 500 labels, and in the barcode start at 1, increase 1 every label".
Some disadvantages are
is that the appearance is left to the firmware designer of the printer firmware
There may be less coordination between what's being designed and what's being printed, although typically the driver for the printer should adress this.
The printer firmware may not be updated if the barcode symbology specifications has been updated
The printer firmware may contain only a subset of the barcode definition
In short, simplificy vs freedom of parameters and appearance.
How it is technically implemented (at printer end, from receiving the number to drawing the actual barcode) is probably out of scope for this forum.
Example specification (in newer printer model)
Looking at a random Zebra Printer (ZT600) the built-in barcodes covers nearly every use:
1D symbologies
Code11, Code39, Code93, Code128 (all subsets),
UCC, ISBT, UPC, EAN 8 / 13, UPC/EAN extensions,
Plessey, Postnet, 2of5, Logmars, MSI, Codabar and Planet Code
2D symbologies
codablock, PDF417, Code49, Datamatrix,
QR, TLC39, MicroPDF, RSS14 +composite and Aztec.
When you print an element on a label (barcode or text) you can do that by sending a graphic field or by instructing the printer to pick up the element internally and build the element with the configuration you need.
For example, in case you want to print a text, the ZPL command will include the font you want to use, vertical and horizontal size, position of the text and so on.
In the case of a barcode, the barcode selector contained in the ZPL command, will automatically recall the .BAR file stored in the Z memory, which contains the instructions for the printer to build the barcode, then, in the same command and likewise for the text, you have also provide the size of the barcode (usually it's a ratio between the narrow and the bold line), the position, the human readable line and so on.
The graphic method is used for example when a font which is not stored on the printer memory is used: the printer doesn't recognize the font and so it can't build the text, so the print can happen only after a conversion of the text field into a graphic field. This works well with text fields, but the barcodes can have quality issues as, due to how a thermal printers physicall works, the lines of a barcode can be printed like a sort of saw. Moreover you can't see or edit the data since the code is basically unreadable, that's why it's impossible to send serialized data, unless you use a software.
The element printing is not affected by this type of quality issues and allows you to edit the data.
If you want to see the difference, try to use zebradesigner and print to file a label with a barocode. When you select a barcode, you can choose to print it as a graphic or to use the printer element and you'll see that the .prn files will contains different data.
This is what you get using the printer element (128 barcode containing 123456789012)
https://justpaste.it/66gvp
and this is the same barcode printed as graphic field
https://justpaste.it/27abu
I'm developing a Windows application in WPF, which uses the "link-os" SKD to print a large amount of tickets over a USB connection with a Zebra GC420t. The problem is that during printing, the printer apparently loses the detection of the black mark and begins to print the content in a wrong position relative to the top of the ticket.
Important points:
My software build a ZPL string in runtime and sends it to the printer;
I'm using the "GC420t" driver (non EPL);
Before starting the print job, I send to the printer some print settings:
"~SD15~TA000~JSN^XA^SZ2^PW639^LL799^PON^PR2,2^PMN^MNM^LS0^MTT^MMT,N^MPE^XZ^XA^JUS^XZ"
At the beginning, the printer is correctly calibrated. Sometimes, when the problem reported in this post happens, the printer becomes uncalibrated.
Below, a ZPL sample code, and the link to a video that demonstrates exactly the moment the error happens. Every help is welcome.
Video: Zebra GC420t error while printing
Zpl String:
~DYE:LOGO1,P,P,34149,,89504E470D0A1A0A0000000D49484452...(Intentionally truncated)
^XA^LS0^LT0^XZ
The statement below is repeated for each label:
^XA
^FO70,0^IME:LOGO1.PNG^FS
^FO57,230^GB533,0,2^FS
^FT0,261^A0N,31,31^FB620,1,0,C^FDEVENTO TESTE^FS
^FO57,272^GB533,0,2^FS
^FT0,294^ACN,18,10^FB620,1,0,C^FD^FS
^FT0,316^ACN,18,10^FB620,1,0,C^FD01/09/2019^FS
^FT0,379^AAN,18,10^FB620,1,0,C^FD^FS
^FT0,431^AAN,27,15^FB620,1,0,C^FDR$ 10.00^FS
^FT0,529^AAN,18,10^FB620,1,0,C^FD^FS
^FT0,510^AAN,18,10^FB620,1,0,C^FD^FS
^FT0,492^AAN,18,10^FB620,1,0,C^FDInformau00e7u00f5es sobre o seu evento!^FS
^FT564,475^ABB,11,7^FH^FD008403615029^FS
^FT0,356^ABN,25,14^FB620,1,0,C^FDREFRIGERANTE^FS
^FT67,569^ABN,11,7^FH^FDPDV: TICKET SIMPLES ESC. 29/12/2018 00:50^FS
^FO57,582^GB533,0,2^FS
^FT0,649^ABN,22,12^FB655,1,0,C^FDREFRIGERANTE^FS
^BY3,3,61^FT172,717^BCN,,Y,N^FD>;008403615029^FS
^FT76,472^BQN,2,4^FH^FDLA,008403615029^FS
^XZ
The above statement is repeated for each label.
Thank you all!
Apparently the problem was solved when I set a more precise value for the label size.
I was setting the height of the label to 100mm, when in fact it measures 107mm.
After I made the adjustment, the problem did not happen again.
[EDIT]
Although the procedure described above has considerably reduced the occurrence of errors, even at a lower frequency, it persists. In contact with Zebra's support, we discovered another possible cause: the texts and logos on the back of the ticket are confusing the sensors of the printer (black mark). We're working on the redesign of the label. I will update this thread again soon.
We have an application that prints 2 invoice copies - 1 on white (for the cust) and 1 on blue (for us).
We print a LOT of these so we are getting a printer with 3 big trays. One tray (tray 5) holds 4000 sheets and the other two (trays 3 and 4) are a tandem set holding 1600 and 2000 sheets. The application automatically generates the invoice and sends one document to the tray with the white paper and one to the tray with the blue paper.
The user has no input in this process.
Now, my problem is this - if I specifically send the blue copy to tray 3 and there is no paper in tray 3, the job will go on hold until someone loads it up even though tray 4 has 2000 more sheets ready to go. On the other hand, if I tell the printer to print on Blue 8 1/2x11" paper, it is smart enough to know that that type of paper is in both trays and to pull from either one until they are both empty. So, I want to change our application to select a paper type/size and color instead of a specific tray.
The program is written in Delphi and I have been looking at the DEVMODE structure returned by TPrinter.GetPrinter. The DEVMODE structure has a memory size in dmDriverExtra that indicates how much extra data the print driver is adding to the structure for its own storage.
Does anyone know of anyway to access this data and make changes to it? If you have examples in other languages, I can probably adapt it to Delphi so anything will help.
There are actually two different items in the questions:
How to set the pater size and type:
PaperSize would be stored in dmPaperSize (value DMPAPER_LETTER)
PaperType is a bit more difficult. I'd guess that it's in dmMediaType (use DeviceCapabilities to retrieve available media types and their names)
How to access / edit "DriverExtra" data:
In short: don't!
A bit longer: dmDriverExtra is described as "Contains the number of bytes of private driver-data that follow this structure". So this data is private to the driver (which means that you need very good documentation for the driver to actually know the format and content of this data. It's not guaranteed that different versions of the driver use the same format).
So the only thing you can do is to use a print dialog, retrieve the DevMode structure and store it for further use (however as I said: If the driver changes, this data may become invalid...)
I don't have any background in programming and this is my first shot. I wrote a Delphi program that is supposed to print on a result sheet. I work in an institute and we have to establish hundreds of result sheets every 2 months. It's really difficult to do that and different handwriting is also an important issue. I have this code:
if PrintDialog.Execute() then
begin
with MyPrinter do
begin
MyPrinter.BeginDoc();//Start Printing
//Prints First Name
MyPrinter.Canvas.TextOut(FirstNameX,FirstNameY,EditFirstName.Text);
//Prints Last Name
MyPrinter.Canvas.TextOut(LastNameX,LastNameY,EditLastName.Text);
//Prints Level
MyPrinter.Canvas.TextOut(LevelX,LevelY,EditLevel.Text);
//Prints Date
MyPrinter.Canvas.TextOut(DateX,DateY,MEditDate.Text);
//Prints Student Number
MyPrinter.Canvas.TextOut(StdNumX,StdNumY,EditStdnumber.Text);
....
MyPrinter.EndDoc();//End Printing
end;
end;
I can't get the right coordinates to print properly. Am I missing something? How can I set the right coordinates? You know TPrinter uses pixels to get the coordinates but papers are measured in inches or centimeters.
I'm really confused. I appreciate any help.
#Milad I recommend you use a report component like Quick Report (comes with the oldies versions of delphi and is very easy to use) or FreeReport (it's free) to make your task easier.
for more info check theses links
QuickReports Tutorial
QuickReports Documentation, Knowledge Base and FAQ
if you want to print directly from delphi without components here I leave a couple of links that can help.
Printing Directly from Delphi
Delphi - Printing via the TPrinter Canvas
While using a reporting tool is a good idea, if you really do want to do it yourself, you can. I do this for printing to custom paper in our licensing application. The key is to know the size of your paper, and work it out from that using the printer PageHeight and PageWidth properties. For A4 paper I chose to use 297mm by 210mm, and from that I was able to calculate where I wanted things to be. The calculation is done thus:
nStartPos := 210-141;
nUserColX := muldiv(localPrinter.PageWidth, 187, 297);
nUserColY := muldiv(localPrinter.PageHeight, nStartPos, 210);
The nStartPos variable is done to start on a particular place, and then nUserColY is used to move down a line at a time as here:
nUserColY := nUserColY - localPrinter.canvas.font.height - (localPrinter.canvas.font.height div 8);
This then allows more than one line at a time to fit nicely.
This is not complete, but should be a good start for custom printing.
Using ReportBuilder 7.X
Question
Is it possible to Control Print to File.
I need to change the Length of a field at print time
Example:
label2
In the setup - I set its length to 800 which is the max possible this field should ever be.
However, in many cases the record is less than that and i need to set it to the calculated size before printing to file.
Is this possible?
Is it possible to control any portions of this Print to file...at print time (before Print, after print)?
Are the objects avaiable?
We are registered users of the 10.x and above i believe, but have still not gotten around to recompiling are application in Delphi 2009 and the new ReportBuilder....so, that is not an option at this point.
Thanks
Shane
You can try to use the OnDataChange event of the tDataSource that you are using to link your data to your report. This event fires when the current record in the associated dataset changes. In that event, adjust your label to the size for the current record.
i solved this! Each control has a saveLength property. I can just use a global variable that can change at any time (controlling length of entire record). Then just before i print he label, i can set its saveLength property
thanks to all who responded though