Página 2 de 2

Gerador de relatorios?

Enviado: 28 Nov 2016 19:14
por JoséQuintas
A propósito, resolvi assim:

Código: Selecionar todos

METHOD FormataMemo( cMemo, nLarguraPDF ) CLASS hbNFeDaNFe

   LOCAL cNovoTexto := "", cTexto, nPos, nCont

   FOR nCont = 1 TO MLCount( cMemo, 10000 )
      cTexto  := MemoLine( cMemo, 10000, nCont )
      DO WHILE .T.
         nPos       := HPDF_Page_MeasureText( ::oPDFPage, cTexto, nLarguraPDF, .T. )
         IF nPos == 0
            nPos := HPDF_Page_MeasureText( ::oPDFPage, cTexto, nLarguraPDF, .F. )
            nPos := Max( nPos, 2 )
         ENDIF
         cNovoTexto += Substr( cTexto, 1, nPos ) + Chr(13) + Chr(10)
         cTexto     := AllTrim( Substr( cTexto, nPos + 1 ) )
         IF Len( cTexto ) == 0
            EXIT
         ENDIF
      ENDDO
   NEXT
   IF Right( cNovoTexto, 2 ) == Chr(13) + Chr(10)
      cNovoTexto := Substr( cNovoTexto, 1, Len( cNovoTexto ) - 2 )
   ENDIF

   RETURN cNovoTexto
Só passar a string, e a largura que será usada no PDF.
O resultado é o texto que poderá ser trabalhado usado MLCount() e MemoLine()

Código: Selecionar todos

? Memoline( cTexto, 1000, nCont )
Ou seja, na impressão é só imprimir, já vai estar do tamanho certo.

- A primeira medida separando sem "quebrar" palavras
- Se essa falhar, separa do jeito que der.
- Se se essa também falhar, considera 2 letras - só pra evitar travamento em algum caso maluco.

Só como exemplo:
"Aaaaaaaaaaaaaaaaaaaaaaaaaa"
Se precisar dividir isso pra imprimir, com wordwrap on, não divide.
Por isso o teste em seguida com wordwrap off.
E já que é pra evitar erro, a terceira opção com 2 letras.... rs

Gerador de relatorios?

Enviado: 28 Nov 2016 19:28
por JoséQuintas
O trem completo aqui:

https://github.com/JoseQuintas/sefazcla ... dDaNfe.prg

Faz parte dos cálculos:

METHOD Init() - inicializa alguns defaults
METHOD CalculaLayout() - alguns outros defaults, e faz as contas de linhas/páginas e algo mais para o layout
METHOD DefineColunasProdutos() - calcula as colunas
METHOD DefineDecimais()

METHOD LarguraTexto() - calcula o espaço necessário para um texto
METHOD FormataMemo() - Divide a string em linhas pra serem usadas por MLCount() e MemoLine()
METHOD ItensdaFolha() - Calcula quantos itens cabem na folha

Imprimir:

quadro produtos:

METHOD CabecalhoProdutos()
METHOD DesenhaBoxProdutos()
METHOD Produtos()

quadro informações adicionais:

METHOD DadosAdicionais()

Lembrando:
Precisa calcular a quantidade de folhas, por isso acaba existindo um "meio simulado" pra fazer isso no CalculaLayout()

Processa itens primeiro, pra definir os tamanhos das colunas
Processa itens de novo, pra já fazer as contas de páginas, etc.
e Processa itens na hora de imprimir.

Gerador de relatorios?

Enviado: 22 Dez 2016 22:52
por JoséQuintas
E não é que exagerei mais um pouco.
Tem tanta coluna que nem cabe mais no PDF.... rs
18 colunas

Código: Selecionar todos

#define LAYOUT_CODIGO          1
#define LAYOUT_DESCRICAO       2
#define LAYOUT_NCM             3
#define LAYOUT_EAN             4
#define LAYOUT_CST             5
#define LAYOUT_CFOP            6
#define LAYOUT_UNIDADE         7
#define LAYOUT_QTD             8
#define LAYOUT_UNITARIO        9
#define LAYOUT_TOTAL           10
#define LAYOUT_DESCONTO        11
#define LAYOUT_ICMBAS          12
#define LAYOUT_ICMVAL          13
#define LAYOUT_SUBBAS          14
#define LAYOUT_SUBVAL          15
#define LAYOUT_IPIVAL          16
#define LAYOUT_ICMALI          17
#define LAYOUT_IPIALI          18
Agora fiz um processo inverso, pelo menos como quebra-galho.
Depois de tudo definido, o que sai ou não, se o espaço pra descrição ficar muito pequeno, vai cortando colunas.

Código: Selecionar todos

      IF ::aLayout[ LAYOUT_DESCRICAO, LAYOUT_LARGURAPDF ] > 150
         EXIT
      ENDIF
      // Se não sobrar espaço pra descrição, desativa colnas
      DO CASE
      CASE nTentativa == 1 ; ::aLayout[ LAYOUT_EAN, LAYOUT_IMPRIME ]      := LAYOUT_NAOIMPRIME
      CASE nTentativa == 2 ; ::aLayout[ LAYOUT_SUBBAS, LAYOUT_IMPRIME ]   := LAYOUT_NAOIMPRIME
      CASE nTentativa == 3 ; ::aLayout[ LAYOUT_DESCONTO, LAYOUT_IMPRIME ] := LAYOUT_NAOIMPRIME
      CASE nTentativa == 4 ; ::aLayout[ LAYOUT_SUBVAL, LAYOUT_IMPRIME ]   := LAYOUT_NAOIMPRIME
      ENDCASE
Notem que LAYOUT_IMPRIME antes era verdadeiro ou falso, e agora é numérico.
É que quando der vou tentar uma opção da NFE, que é agrupar colunas.
Tem isso no manual: por exemplo, na coluna de código do produto, colocar código encima e NCM embaixo, o que economiza uma coluna (e gasta mais uma linha).
Mas isso vai ficar pra depois, por enquanto basta omitir, já fica igual antes.

EAN não existia antes, aproveitei pra acrescentar, já que não vai atrapalhar.
Acho que tem coluna de lote pra remédios, e outras mais que já dá pra acrescentar também.

Gerador de relatorios?

Enviado: 22 Jan 2017 00:43
por JoséQuintas
Versão preliminar, primeiros testes.
ficha.png
Fonte usado pra gerar esse PDF:

Código: Selecionar todos

   oPDF:SetType( 2 )
   oPDF:Begin()
   oPDF:PageHeader()
   oPDF:DrawImageBox( 1, 0, 7, 20, "logotipo.jpg" )
   FOR EACH oElement IN aCamposList
      nWidth := Max( Len( oElement[ 1 ] ), Len( oElement[ 2 ] ) ) + 2
      nWidth := Max( nWidth, 12 ) * 1.5
      IF oPDF:nCol + nWidth > oPDF:MaxCol()
         oPDF:nCol := 0
         oPDF:nRow += 3.5
      ENDIF
      IF oPDF:nRow < 9 .AND. oPDF:nCol < 22
         oPDF:nCol := 22
      ENDIF
      oPDF:DrawBoxTitleText( oPDF:nRow, oPDF:nCol, oPDF:nRow + 3, oPDF:nCol + nWidth, oElement[ 1 ], oElement[ 2 ], "", HPDF_TALIGN_LEFT, 10, "Helvetica", 8, "Helvetica" )
      // oPDF:nCol += nWidth + 1
   NEXT
   oPDF:End()