Etiquetas - Harbour
Moderador: Moderadores
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Etiquetas - Harbour
Preciso de ajuda.
Decidí fazer a impressão de etiquetas em modo gráfico.
Para isso idealizei que devo guardar as coordenadas de cada etiquetas em pixels numa matriz.
Pretendo utilizar apenas um estilo de fonte "Courrier" (porque mantem a mesma dimensão de largura do caracter) mas com 2 tamanhos diferentes, em folha de A4. Mas não sei como fazer em Harbour.
Alguém pode me dar um exemplo prático, quais as funções, libs que devo utilizar ? E me indicar como compilar em Harbour ?. As coordenadas em pixels irei descobrir no momento dos testes e talvez com ajuda matemática. Mas preciso decolar e não sei como começar. O exemplo pode ser de três linhas para cada etiqueta por 7 colunas de etiquetas.
Se houver algum exemplo peço que me desculpem e anexarei este tópico ao existente no caso.
Conto com a boa ajuda de vocês e da paciência por eu não saber quase nada de Harbour.
Decidí fazer a impressão de etiquetas em modo gráfico.
Para isso idealizei que devo guardar as coordenadas de cada etiquetas em pixels numa matriz.
Pretendo utilizar apenas um estilo de fonte "Courrier" (porque mantem a mesma dimensão de largura do caracter) mas com 2 tamanhos diferentes, em folha de A4. Mas não sei como fazer em Harbour.
Alguém pode me dar um exemplo prático, quais as funções, libs que devo utilizar ? E me indicar como compilar em Harbour ?. As coordenadas em pixels irei descobrir no momento dos testes e talvez com ajuda matemática. Mas preciso decolar e não sei como começar. O exemplo pode ser de três linhas para cada etiqueta por 7 colunas de etiquetas.
Se houver algum exemplo peço que me desculpem e anexarei este tópico ao existente no caso.
Conto com a boa ajuda de vocês e da paciência por eu não saber quase nada de Harbour.
Um clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Re: Etiquetas - Harbour
Bom, no xHarbour eu uso o WIN32PRN para montar alguns informes e o principio será o mesmo para etiquetas. Sei que vc esta querendo para o Harbour, mas acho que a idéia é valida e existe uma função euivalente ao WIN32PRN.
Etiquetas mesmo eu só montei usando o NODOSIMP.
Vou mandar algumas partes. Não posso mandar o fonte inteiro.
Como vc vê abaixo, dá para colocar cordenadas Linha, Coluna. Fica mais fácil do que colocar coordenadas em pixwl pois a resolução da impressora irá influenciar os valores. Já penei por isso tb.
Boa sorte.
Criar
corpo do relatório
Fecha o relatório
Etiquetas mesmo eu só montei usando o NODOSIMP.
Vou mandar algumas partes. Não posso mandar o fonte inteiro.
Como vc vê abaixo, dá para colocar cordenadas Linha, Coluna. Fica mais fácil do que colocar coordenadas em pixwl pois a resolução da impressora irá influenciar os valores. Já penei por isso tb.
Boa sorte.
Criar
Código: Selecionar todos
cprinter := getdefaultprinter()
oprinter:= win32prn():new(cprinter)
oPrinter:Landscape:= .F.
oPrinter:FormType := FORM_A4
oPrinter:Copies := 1
oPrinter:Create()
oPrinter:startDoc()Código: Selecionar todos
oPrinter:SetPrc(linha, 10)
oPrinter:TextOut('Total:')
oPrinter:SetPrc(linha, 40)
oPrinter:TextOut(transform(a_tot[3, 1], '@E 99,999,999,999.99'))
oPrinter:SetPrc(linha, 60)
oPrinter:TextOut(transform(a_tot[3, 2], '@E 99,999,999,999.99'))
oPrinter:SetPrc(linha++, 80)
oPrinter:TextOut(transform(a_tot[3, 3], '@E 99,999,999,999.99'))
...
oPrinter:SetPrc(linha++, 10)
oPrinter:TextOut("CNPJ: 99999999999999999", .T.)
oPrinter:SetPrc(linha++, 10)
oPrinter:TextOut("Informe de Recolhimento de Fornecedores - " + str(m->xano, 4), .T.)Código: Selecionar todos
oprinter:enddoc()
oprinter:destroy()"TRS-80/Sincler/Apple/PC - Clipper Winter 85, tlink 1.0 [pc 10 MHz - 640K] {NEZ 8000 2Kb RAM}"
{POG - Programação Orientada a Gambiarra}
{POG - Programação Orientada a Gambiarra}
- Pablo César
- Usuário Nível 7

- Mensagens: 5312
- Registrado em: 31 Mai 2006 10:22
- Localização: Curitiba - Paraná
Etiquetas - Harbour
Obrigado Gilberto pelas dicas e desculpe não ter retornado antes. De fato sirviram-me em grande parte mas tive bastante trabalho para entender tudo como funciona.
1. Tive sempre o pensamento que tudo que era xHarbour não servia para Harbour. Existem poucas diferenças, nada que não possa ser adaptado de um para o outro. Uma delas neste meu caso é o uso do "WIN32PRN" do xHarbour que substiuí por WIN_PRN para funcionar com Harbour. Essa explicação tem de bastante no fórum.
2. Discordei com a utilização da função TextOut() através de linha e coluna (como no @ lin,col say do Clipper) ora porque eu disse que a minha necessidade estava em fazer em forma gráfica. Claro que fazer a impressão em modo gráfico, não é aconselhável em impressoras matricias, mais ainda pela imprecisão de posição do papel durante a troca de folha soltas (nem sempre é no mesmo lugar), por isso eu ja possuo impressão de etiqueta em formulário contínuo para etiquetas, onde a remalinas ajuda muito no tracionamento e fixação do papel. Daí sim é aconselhável o uso da impressão não gráfica. Mas como agora praticamente as impressoras USBs de jato de tinta e laser estão a um preço mais acessíveis e os formulário de etiquetas não se adequam a impressão não gráfica, isto é, porque o espaçamento de uma etiqueta a outra tem que ser corrigido constantemente e isso ja causou muito problema para meus clientes. Por isso decidí fazer duas formas de impressão, conforme a impressora. Então em lugar do TextOut() coloquei o TextOutAt() no qual posso informar em pixels o que me dá maior precisão no posicionamento de cada etiqueta. Que constem outras funções para impressão como:
3. Você fala de diferentes resoluções entre uma impressora e outra, mas mesmo assim não creio que isso interfira na precisão do posicionamento de cada etiqueta. Pois acredito que quando se trata em definir o tamanho da fonte de acordo o PointSize do SetFont() deva ser para todas as impressoras o mesmo. É dizer um caracter de tamanho 8cpp é igual para todas. Vou ainda fazer testes em jato tinta e laser para constatar essa questão.
4. No seu código exemplo, faltou o essencial: SetFont() e eu me batí muito, pois tinha visto um exemplo de um colega e que estava errado e ainda eu tinha colocado antes do "oPrinter:Create()" daí nunca mudava o tamanho e eu ficava fustrado, até que hoje de manhã percebí o meu erro.
5. Outra coisa que sempre me deixou em dúvidas, é como fazer a compilação para que fique registrado fiz assim:
HBMK2 -lhbwin -lxhb etq1.prg
Eu gosto de relatar a minha experiência, pois é assim que podemos contribuir para esclarecer futuras dúvidas de outros colegas. E por isso estou passando o meu primeiro exemplo de impressão:
Vou ainda melhor este código, com certeza. Um dos pequenos desafios é centralizar o texto, mas não farei com PADC() é dizer não farei pela quantidade de caracteres, farei pelo tamnho em pixels que ocoupa uma determinada string com cada fonte utilizada. Só para efeito de aprendizado, pois fazendo pelo tamanho de string nem sempre fica perfeita a centralização, principalmente com fonte proporcionais não de tamanho fixo como a Courrier e Courrier New.
1. Tive sempre o pensamento que tudo que era xHarbour não servia para Harbour. Existem poucas diferenças, nada que não possa ser adaptado de um para o outro. Uma delas neste meu caso é o uso do "WIN32PRN" do xHarbour que substiuí por WIN_PRN para funcionar com Harbour. Essa explicação tem de bastante no fórum.
2. Discordei com a utilização da função TextOut() através de linha e coluna (como no @ lin,col say do Clipper) ora porque eu disse que a minha necessidade estava em fazer em forma gráfica. Claro que fazer a impressão em modo gráfico, não é aconselhável em impressoras matricias, mais ainda pela imprecisão de posição do papel durante a troca de folha soltas (nem sempre é no mesmo lugar), por isso eu ja possuo impressão de etiqueta em formulário contínuo para etiquetas, onde a remalinas ajuda muito no tracionamento e fixação do papel. Daí sim é aconselhável o uso da impressão não gráfica. Mas como agora praticamente as impressoras USBs de jato de tinta e laser estão a um preço mais acessíveis e os formulário de etiquetas não se adequam a impressão não gráfica, isto é, porque o espaçamento de uma etiqueta a outra tem que ser corrigido constantemente e isso ja causou muito problema para meus clientes. Por isso decidí fazer duas formas de impressão, conforme a impressora. Então em lugar do TextOut() coloquei o TextOutAt() no qual posso informar em pixels o que me dá maior precisão no posicionamento de cada etiqueta. Que constem outras funções para impressão como:
Código: Selecionar todos
oPrinter:textAtFont([<nPosX>] , ;
[<nPosY>] , ;
<cString> , ;
[<cFontName>] , ;
[<nPointSize>] , ;
[<nFontWidth>] , ;
[<nFontWeight>], ;
[<lUnderLine>] , ;
[<lItalic>] , ;
[<lNewLine>] , ;
[<lUpdatePosX>], ;
[<nTextColor>] , ;
[<nTextAlign>] ) --> lSuccess
oPrinter:textOutAt([<nPosX>] , ;
[<nPosY>] , ;
<cString> , ;
[<lNewLine>] , ;
[<lUpdatePosX>], ;
[<nTextAlign>] ) --> lSuccess3. Você fala de diferentes resoluções entre uma impressora e outra, mas mesmo assim não creio que isso interfira na precisão do posicionamento de cada etiqueta. Pois acredito que quando se trata em definir o tamanho da fonte de acordo o PointSize do SetFont() deva ser para todas as impressoras o mesmo. É dizer um caracter de tamanho 8cpp é igual para todas. Vou ainda fazer testes em jato tinta e laser para constatar essa questão.
4. No seu código exemplo, faltou o essencial: SetFont() e eu me batí muito, pois tinha visto um exemplo de um colega e que estava errado e ainda eu tinha colocado antes do "oPrinter:Create()" daí nunca mudava o tamanho e eu ficava fustrado, até que hoje de manhã percebí o meu erro.
5. Outra coisa que sempre me deixou em dúvidas, é como fazer a compilação para que fique registrado fiz assim:
HBMK2 -lhbwin -lxhb etq1.prg
Eu gosto de relatar a minha experiência, pois é assim que podemos contribuir para esclarecer futuras dúvidas de outros colegas. E por isso estou passando o meu primeiro exemplo de impressão:
Código: Selecionar todos
#include "hbcompat.ch"
#define FORM_A4 9
Function Main()
cprinter := GetDefaultPrinter()
oprinter:= win_prn():new(cprinter)
oPrinter:Landscape:= .F.
oPrinter:FormType := FORM_A4
oPrinter:Copies := 1
oPrinter:CharSet(255)
oPrinter:Create()
oPrinter:startDoc()
// sintaxe: oPrinter:setFont(cFontName, nPointSize, nFontWidth, nFontWeight, lUnderline, lItalic, nCharSet)
oPrinter:SetFont('Times New Roman', 06, 0 , , , ,255)
oPrinter:TextOutAt( 30.00, 66.00, 'ABCDEFGHIJKLMNOPQR')
oPrinter:SetFont('Courier New', 18, 0 , , , ,255)
oPrinter:TextOutAt( 30.00, 106.00, '12345')
oPrinter:SetFont('Arial Narrow', 06, 0 , , , ,255)
oPrinter:TextOutAt( 30.00, 116.00, 'ABCDEFGHIJKLMNOPQRST')
oprinter:enddoc()
oprinter:destroy()
return nilUm clip-abraço !
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
- rochinha
- Administrador

- Mensagens: 4664
- Registrado em: 18 Ago 2003 20:43
- Localização: São Paulo - Brasil
- Contato:
Re: Etiquetas - Harbour
Amiguinho,
Não sei como voce montou o conjunto a ser impresso, mas aqui vai um trecho de um antigo sistema meu onde eu montava as etiquetas em vetores e depois imprimia.
A grande diferença é que as propriedades das etiquetas poderia ser intercambiadas no momento da impressão tornando o mais profissional possivel.
Eu criei um comando extendido para auxiliar:
Exemplo do comando:
Veja que neste momento estou passando os campos que quero e que depois a função fará a avaliação e preenchimento do vetor.
A função:
A função controla até o tamanho da página a fim de me mostrar quando tenho que colocar outra folha, lógico que isto era válido para clientes que usavam matriciais e para não perder nenhuma etiqueta preferiam colocar uma folha por vez.
A partes que estão entre "// INICIO/FIM ******" exemplificam os trechos que voce necessita entender, já que o corpo é uma estrutura normal de relatório.
Acho que tá fácil de entender.
Não sei como voce montou o conjunto a ser impresso, mas aqui vai um trecho de um antigo sistema meu onde eu montava as etiquetas em vetores e depois imprimia.
A grande diferença é que as propriedades das etiquetas poderia ser intercambiadas no momento da impressão tornando o mais profissional possivel.
Eu criei um comando extendido para auxiliar:
Código: Selecionar todos
#command ETIQUETE COM TOPO <lbTOPO> ;
CARREIRAS <lbCARREIRA> ;
LARGURA <lbLARGURA> ;
ALTURA <lbLINHAS> ;
ENTRE <lbENTRE> ;
ESPACOS <lbESPACOS> ;
MARGEM DE <lbMARGEM> ;
[FOLHA <lbFOLHA>] ;
[REPETIR <lbREPETIR>] ;
[CAMPOS <list1,...>] => ;
MALETI(<lbTOPO>,<lbCARREIRA>,<lbLARGURA>,<lbLINHAS>,<lbENTRE>,<lbESPACOS>,<lbMARGEM>,{<list1>},<lbREPETIR>,<lbFOLHA>)
Código: Selecionar todos
ETIQUETE COM TOPO M->lbTOPO ;
CARREIRAS M->lbCARREIRA ;
LARGURA M->lbLARGURA ;
ALTURA M->lbLINHAS ;
ENTRE M->lbENTRE ;
ESPACOS M->lbESPACOS ;
MARGEM DE M->lbMARGEM ;
FOLHA M->lbl_FOL ;
CAMPOS {||NOME} , ;
{||ENDERECO} , ;
{||BAIRRO+' - '+ESTADO}, ;
{||ALLTRIM(CIDADE)+' - '+CEP} , ;
{||' '} , ;
{||' '}
A função:
Código: Selecionar todos
PROCEDURE MALETI( lbTOPO , ;
lbCARREIRA, ;
lbLARGURA , ;
lbLINHAS , ;
lbENTRE , ;
lbESPACOS , ;
lbMARGEM , ;
lbUDF , ;
lbREPETIR , ;
lbFOLHAS , ;
lbUDF2 )
// INICIO *********************************************************************************
M->lbID := lbID
M->lbUDF := lbUDF
M->lbNOME := lbNOME
M->lbLARGURA := lbLARGURA
// Se o numero de campos forem menores que numero de linhas
// o numero de linhas ENTER sera acrescido do restante
M->lbENTRE := lbENTRE // IIF(LEN(lbUDF)<lbLINHAS,lbENTRE+(lbLINHAS-LEN(lbUDF)),lbENTRE)
// Se o numero de campos forem menores que numero de linhas
// o numero de linhas sera igual a numero de campos
M->lbLINHAS := lbLINHAS // IIF(LEN(lbUDF)<lbLINHAS,LEN(lbUDF),lbLINHAS)
M->lbMARGEM := lbMARGEM
M->lbTOPO := lbTOPO
M->lbESPACOS := lbESPACOS
M->lbCARREIRA := lbCARREIRA
M->lbREPETIR := IIF(lbREPETIR=NIL,1,lbREPETIR+1)
M->lb_REPETIR := DIV(M->lbREPETIR,M->lbCARREIRA)
IF (lbFOLHAS = 0 .OR. lbFOLHAS = NIL)
M->lbFOLHAS := 0
M->lb_FOLHAS := 0
ELSE
M->lbFOLHAS := lbFOLHAS+M->lbCARREIRA
M->lb_FOLHAS := INT(DIV(M->lbFOLHAS ,M->lbCARREIRA))
ENDIF
// FIM *********************************************************************************
M->TIPO_PRN="I"
IF MENU_PRN() = NIL
RESTSCREEN(LIN_MENU+1,00,23,79,TELA_PRI)
RETURN
ENDIF
SET DEVI TO PRINT
SETPRC(0,0)
IF M->TIPO_PRN = 'I'
@ PROW()+M->lbTOPO, PCOL() SAY CondOn
IF (lbFOLHAS = 0 .OR. lbFOLHAS = NIL)
M->lbTOPO := 0
ENDIF
ENDIF
DO WHILE .NOT. EOF()
IF INKEY()=27
SET PRINT OFF
SET CONSOLE ON
IF PERG("Continua a impress„o ?")="S"
MENSAGEM("Tecle <ESC> para pausa ou interrup‡„o")
SET PRINT ON
SET CONSOLE OFF
ELSE
SET PRINT ON
SET CONSOLE OFF
EXIT
ENDIF
ENDIF
// INICIO *********************************************************************************
Alabel := {}
FOR TX = 1 TO M->lbCARREIRA // Dependendo de quantas carreiras preenche e libera a continuação
TArray := {}
FOR TY = 1 TO LEN(M->lbUDF)
aadd( TArray, EVAL( M->lbUDF[TY] ) )
NEXT
aadd( Alabel, TArray )
IF lbUDF2 # NIL
EVAL( M->lbUDF2 )
ENDIF
SKIP
IF recco() = 1
GO BOTTOM
ENDIF
NEXT
// FIM *********************************************************************************
DO WHILE .T.
// INICIO *********************************************************************************
// Esta função será a que voce produzirá com comandos Harbour
PrintLabel( Alabel, M->lbLARGURA, M->lbLINHAS, M->lbENTRE, M->lbESPACOS, M->lbMARGEM )
// FIM *********************************************************************************
M->lb_REPETIR = M->lb_REPETIR - 1
IF M->lb_FOLHAS <> 0
M->lb_FOLHAS = M->lb_FOLHAS - 1
IF M->lb_FOLHAS <= 1
//EJECT
SET DEVICE TO SCREEN
SET CONSOLE ON
IF PERG("Nova folha esta pronta ?")="S"
ENDIF
MENSAGEM(' ')
SET CONSOLE OFF
SET DEVICE TO PRINT
M->lb_FOLHAS = INT(DIV(M->lbFOLHAS ,M->lbCARREIRA))
SETPRC(0,0)
@ PROW()+M->lbTOPO, PCOL() SAY CondOn
ENDIF
ENDIF
IF M->lb_REPETIR <= 1
EXIT
ENDIF
ENDDO
IF recco() < 2
EXIT
ENDIF
ENDDO
SET PRINT OFF
SET CONSOLE ON
CLOSE DATABASES
deviceprinter( 250 )
RESTSCREEN(LIN_MENU+1,00,23,79,TELA_PRI)
RETURN
FUNCTION LB_CLI
TArray := {}
aadd( TArray, iif( eof(), '', NOME ) )
aadd( TArray, iif( eof(), '', ENDERECO ) )
aadd( TArray, iif( eof(), '', BAIRRO+' - '+ESTADO ) )
aadd( TArray, iif( eof(), '', CEP ) )
aadd( Alabel, TArray )
RETURN .T.
A partes que estão entre "// INICIO/FIM ******" exemplificam os trechos que voce necessita entender, já que o corpo é uma estrutura normal de relatório.
Acho que tá fácil de entender.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Re: Etiquetas - Harbour
Olá Rochinha,
Muito bom o seu exemplo.
Para ficar completo faltou as seguintes funções:
Mensagem()
Div()
Perg()
DevicePrinter()
Menu_Prn()
PrintLabel()
[]´s
Muito bom o seu exemplo.
Para ficar completo faltou as seguintes funções:
Mensagem()
Div()
Perg()
DevicePrinter()
Menu_Prn()
PrintLabel()
[]´s
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
- rochinha
- Administrador

- Mensagens: 4664
- Registrado em: 18 Ago 2003 20:43
- Localização: São Paulo - Brasil
- Contato:
Etiquetas - Harbour
Amiguinho,
Use o código para modelar a sua idéia. usando a estrutura como base.
As funções não são nada extraordinárias:
Mensagem(), basta um @ ..say com o parametro passado.
Div(), recebe os valores e retorna a divisão somente se os dois forem diferente de zero, já que existe um bug no Clipper relativo a divisão por zero.
As outras funções fazem parte do conjunto gerado por programas como o MIRO e não são interessantes no contexto.
Use o código para modelar a sua idéia. usando a estrutura como base.
As funções não são nada extraordinárias:
Mensagem(), basta um @ ..say com o parametro passado.
Div(), recebe os valores e retorna a divisão somente se os dois forem diferente de zero, já que existe um bug no Clipper relativo a divisão por zero.
Código: Selecionar todos
function div( valorA, valorB )
return iif( valorA=0.or.valorB=0, 0, valorA/valorB )Código: Selecionar todos
FUNCTION PRINTLABEL( PALABEL, PCOLUNAS, PLINHAS, PABAIXO, PENTRE, PMARGEM )
LOCAL TX, TY
SETPRC(0,0)
FOR TX:=1 TO PLINHAS // Linhas dentro da etiqueta
FOR TY:=1 TO LEN(PALABEL) // colunas dentro da etiqueta
@ PROW(),(((PCOLUNAS+PENTRE)*(TY-1))+(TY-1))+PMARGEM SAY SUBSTR(PALABEL[TY][TX],1,PCOLUNAS-PENTRE)
NEXT
DEVPOS(PROW()+1,0)
NEXT
DEVPOS(IIF(PLINHAS=NIL,LEN(PALABEL),PLINHAS+PABAIXO),0)
RETURN NILOPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
@braços : ? )
A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
