Resumen Manejo de textos largos (memos)

Saludos listeros.

Después de comentarlo particularmente con Jorge Serrano, de la News de
Visual Basic de IberNet, os remito dos funciones :

MemoLinesSinCRLF( sTexto as string ) as collection,
que recibe un texto largo, con retornos de carro y devuelve una colección
con las líneas que contiene ese texto.

MemoLines( sTexto as string , sngLongitud as single , iLinea as integer ,
oObject as variant , bLineasEnBlanco as boolean ) as Variant.
Función que recibe un texto y lo divide en líneas de sngLongitud, en
milímetros. Puede devolver una colección de líneas de la longitud
especificada o bien, si así se indica mediante iLinea, una línea en
concreto de toda la colección.
oObject puede ser el objeto printer, un Form o bien un PictureBox, de
manera que podemos calcular la anchura de las líneas para pantalla o
impresora.
bLineasEnBlanco define si deseamos que se nos retornen y/o cuenten las
líneas totalmente en blanco o no.

No son nada del otro mundo pero quizá os puedan ayudar en algo.
Si las utilizais y encontrais algún 'bug' o comentario digno de mención,
hacédmelo saber para poder mejorarlas.

Saludos.
ORZO, <orzo@orzo.com>



Attribute VB_Name = "Memos"
'
' Memos
' Módulo para la división de textos largos en líneas.
' Fecha : 7/12/97
' De Francisco Javier Rodríguez Arévalo para ORZO, S.C.P. (c) 1997
' Uso y distribución gratuitos
'

' Variables declaradas explícitamente.
Option Explicit

' Constantes de Retorno para MemoLines.
Const MEMO_TODAS = -1

Public Function MemoLines(ByVal sTexto As String, ByVal sngLongitud As Single, Optional ByVal iLineaARetornar As Variant, Optional ByVal oObject As Variant, Optional ByVal bLineasEnBlanco As Variant) As Variant
  ' Retorna una línea en concreto contenida en el texto pasado, según una
  ' longitud dada, en un objeto concreto. La escala viene dada por el
  ' propio objeto. Los objetos pueden ser del tipo Form, PictureBox o
  ' Printer

  Dim oLineasSinCRLF As New Collection ' Colección que representa el texto
                                        ' sin retornos de carro.
  Dim oLineasSinSPACES As New Collection ' El texto dividido en líneas
                                          ' ajustadas al tamaño especificado.
  Dim sLineTmp As String

  ' Por omisión, se retornarán todas las líneas.
  If (IsMissing(iLineaARetornar)) Then
    iLineaARetornar = MEMO_TODAS
  End If
  ' Por omisión, el objeto es la impresora.
  If (IsMissing(oObject)) Then
    Set oObject = Printer
  End If
  ' Por omisión, Se devuelven las líneas en blanco, también.
  If (IsMissing(bLineasEnBlanco)) Then
    bLineasEnBlanco = True
  End If

  Dim iSPACE As Integer ' Posición de un nuevo espacio.
  Dim iPosAnterior As Integer ' Guarda la última posición válida.
  Dim iContador As Integer ' Para recorrer la colección de líneas.
  Dim bForzar As Boolean ' En condiciones especiales, fuerza la
                            ' asignación de la línea y el fin del bucle.

  ' Sea cual sea el objeto, las medidas siempre se entenderán en milímetros.
  oObject.ScaleMode = vbMillimeters

  ' Quita los espacios inútiles.
  sTexto = Trim$(sTexto)
  ' Si hay texto y se ha especificado una longitud mínima para el texto de
  ' retorno ...
  If ((Len(sTexto) <> 0) And (sngLongitud > 0)) Then
    ' Se extraen los retornos de carro del texto original, de manera que
    ' nos quede una colección de líneas puras.
    Set oLineasSinCRLF = MemoLinesSinCRLF(sTexto)
    ' Recorreremos todas las líneas, una a una.
    For iContador = 1 To oLineasSinCRLF.Count
      ' Toma la línea que toca.
      sLineTmp = oLineasSinCRLF(iContador)
      ' Si la línea tiene longitud 0 ...
      If (Len(sLineTmp) = 0) Then
        ' ... es que es una línea en blanco.
        If (bLineasEnBlanco) Then
          ' y se añade a la colección de retorno sólo si así se ha
          ' indicado.
          oLineasSinSPACES.Add Key:=CStr(oLineasSinSPACES.Count + 1), Item:=""
        End If
      Else
        ' Iniciamos el bucle de fragmentación.
        iPosAnterior = 0
        Do While (Len(sLineTmp) <> 0)
          ' Busca el primer espacio en la cadena ...
          iSPACE = InStr(iPosAnterior + 1, sLineTmp, Chr$(32))
          ' Determina si la nueva posición es válida.
          If (iSPACE = 0) Then
            ' Se ha alcanzado un final de línea sin espacio.
            If (oObject.TextWidth(sLineTmp) > sngLongitud) Then
              ' La longitud de la línea excede el máximo permitido.
              ' Se divide en dos nuevas líneas.
              oLineasSinSPACES.Add Key:=CStr(oLineasSinSPACES.Count + 1), Item:=Trim$(Left$(sLineTmp, iPosAnterior))
              oLineasSinSPACES.Add Key:=CStr(oLineasSinSPACES.Count + 1), Item:=Trim$(Mid$(sLineTmp, iPosAnterior + 1))
            Else
              ' La longitud de la línea es válida.
              oLineasSinSPACES.Add Key:=CStr(oLineasSinSPACES.Count + 1), Item:=sLineTmp
            End If
            sLineTmp = ""
          Else
            ' Hay un espacio.
            If ((oObject.TextWidth(Trim$(Left$(sLineTmp, iSPACE))) > sngLongitud)) Then
              ' La posición actual queda fuera del margen de impresión permitido.
              ' Guarda la línea hasta la siguiente posición válida.
              oLineasSinSPACES.Add Key:=CStr(oLineasSinSPACES.Count + 1), Item:=Trim$(Left$(sLineTmp, iPosAnterior))
              sLineTmp = Trim$(Mid$(sLineTmp, iPosAnterior + 1))
              iPosAnterior = 0
            Else
              ' Movemos el puntero sobre la cadena ...
              iPosAnterior = iSPACE
            End If
          End If
        Loop
      End If
    Next iContador
  End If

  If (iLineaARetornar = MEMO_TODAS) Then
    ' Si no se ha especificado ninguna línea en concreto, asigna la
    ' colección completa de líneas extraídas para su retorno.
    Set MemoLines = oLineasSinSPACES
  Else
    ' Asigna la línea en concreto para su retorno.
    MemoLines = oLineasSinSPACES(iLineaARetornar)
  End If
End Function

Public Function MemoLinesSinCRLF(ByVal sTexto As String) As Collection
  ' Devuelve una colección de cadenas que corresponden a las líneas
  ' contenidas en el Texto pasado como parámetro.
  Dim iCRLF As Integer ' Nuevo CRLF localizado.
  Dim oLineas As New Collection ' Colección de líneas a devolver.
  ' Eliminamos los posibles espacios sobrantes.
  sTexto = Trim$(sTexto)
  ' Vamos a recorrer todo el texto ...
  Do While (Len(sTexto) <> 0)
    ' Busca el primer retorno de carro en la cadena.
    iCRLF = InStr(1, sTexto, vbCrLf)
    If (iCRLF = 0) Then
      ' Si no lo encuentra el texto pasa a ser la última línea de la
      ' colección.
      oLineas.Add Key:=CStr(oLineas.Count + 1), Item:=Trim$(sTexto)
      sTexto = ""
    Else
      oLineas.Add Key:=CStr(oLineas.Count + 1), Item:=Trim$(Left$(sTexto, iCRLF - 1))
      sTexto = Mid$(sTexto, iCRLF + 2)
    End If
  Loop
  ' Retornamos las líneas en forma de colección, sin retornos de carro.
  Set MemoLinesSinCRLF = oLineas
End Function



Resumen Resumen

Visual Basic Página de Visual Basic

Página principal Página principal

www.jrubi.com