Hola soy corlo
tengo una duda para imprimir list1
el codigo que tengo hasta ahora es el siguiente
Private Sub Command7_Click()
' Imprimir
Dim total As String
Dim total1 As String
Dim total2 As String
Dim i As Integer
Dim factura As Integer
ReDim lbtab(1 To 4) As Long
lbtab(1) = 31
lbtab(2) = 141
lbtab(3) = 278
lbtab(4) = 478
SendMessageArray List1.hwnd, LB_SETTABSTOPS, 4, lbtab(1)
total = Label5.Caption
total1 = Label6.Caption
total2 = Label7.Caption
Printer.FontSize = 18
Printer.CurrentX = 3100
Printer.CurrentY = 0
Printer.Print "Factura Nº:"
Printer.CurrentX = 5000
Printer.CurrentY = 0
Printer.Print Txtnum.Text
Printer.CurrentX = 1000
Printer.CurrentY = 3000
Printer.Print "Cantidad"
Printer.CurrentX = 3500
Printer.CurrentY = 3000
Printer.Print "Producto"
Printer.CurrentX = 7350
Printer.CurrentY = 3000
Printer.Print "Precio"
Printer.CurrentX = 9900
Printer.CurrentY = 3000
Printer.Print "Subtotal"
For i = 0 To List1.ListCount - 1
List1.ListIndex = i
Printer.Print List1.List(i)
Next
List1.Clear
Printer.CurrentX = 8400
Printer.CurrentY = 10000
Printer.Print "Subtotal:"
Printer.CurrentX = 9300
Printer.CurrentY = 10500
Printer.Print "iva:"
Printer.CurrentX = 9000
Printer.CurrentY = 11000
Printer.Print "Total:"
Printer.CurrentX = 10000
Printer.CurrentY = 10000
Printer.Print total
Printer.CurrentX = 10000
Printer.CurrentY = 10500
Printer.Print total1
Printer.CurrentX = 10000
Printer.CurrentY = 11000
Printer.Print total2
Printer.Print
Printer.EndDoc
End Sub
la impresion lo hace bien
como puedo hacer las separaciones del list1 a la hora de imprimir las columnas
el list1 tiene 4 columnas
ReDim lbtab(1 To 4) As Long
lbtab(1) = 31
lbtab(2) = 141
lbtab(3) = 278
lbtab(4) = 478
SendMessageArray List1.hwnd, LB_SETTABSTOPS, 4, lbtab(1)
Básicamente tienes que concatenar el contenido, para formar tú mismo las 4 columnas como una solo string, o bien imprimir en la misma línea reposicionado el cursor...
Puede danrse diferentes casos. Por ejemplo;
- A - Que el ancho de las 4 columnas sea superior al del papel.
- B - Que el ancho de las 4 columnas sea notablemente inferior al del papel
- C - Que una de las columnas sea muy superior al resto y al final las 4 no quepan en el papel.
- D - Que el listbox tenga 4 columnas, pero no tenga ítems suficientes para las 4 columnas (una o más están vacías).
- E - Que el listbox acabe teniendo más de 4 columnas (lo que sucederá cuando añadas más ítems o acortes el alto dle control).
- F - Que en un listbox, con x columnas, la última no tiene porque tener los mismos ítems que las previas ya que un listbox, es una lista que al llegar a cierta cantidad de altura continúa en otra columna, es decir no es un 'grid', donde el número de filas y columnas discurren independientemente.
Lo ideal es tener solución para todos los casos y dado el presente, decidir cuál de ellos se da y qué solución se aplica.
Tratándose de un listbox, el reparto horizontal es automatico sin posibilidad de cambio y distribuye los elementos en columna a medida que tocan el alto del listbox, (requiere tener la propiedad IntegralHeight = TRUE), tampoco hay control sobre qué ancho se le da a la columna, que además es el mismo para todas.
Es decir, nótese que hablamos de una lista (un listbox, técnicamente solo tiene 1 campo a pesar de que se muestre en varias columnas), luego la alineación, fuente, ancho de columna, color de tinta, etc... es solo uno y el mismo para todo), no hablamos de un grid, donde cada columna es un campo y puede tener propiedades distintas... incluído el tipo de datos que aloja (no solo texto).
Lo ideal es repartir proporcionalmente las 4 columnas al ancho del papel (salvo que fueren columnas cuyo ancho textual para cada ítem sea muy corto, en cuyo caso sería preferible añadir más columnas), para ello, hay que crear una función que concatene el número de textos cuyo número de columnas se requiere y que además considere la alineación.
Además por simpliicidad, en vez de proceder como hace VB6, donde deposita (por ejemplo): lunes, martes, miércoles, jueves, viernas, sabado, domingo... debajo uno de otro, es preferible hacer una transposición, y poner en la primera fila: lunes, martes, miercoles jueves, en la segunda viernes, sabado, domingo... etc...
private function ListarEnColumnas(byref lista as listbox, byval numCols as integer, byval MargenIzquierdo as integer, byval AnchoPapel as integer, byval alineacion as AlineacionHorizontal[izquierda, centrada, derecha]) ' entiéndase, no quiero perder tiempo escribiendo una enumeración...
dim filas as long
dim ultimafila as long
dim k as long, j as long, anchocol as integer
dim linea as string
din fuente as stdfont
set fuente = printer.font
printer.fontname = "Courier New" ' una fuente monoespaciada, si no el trabajo es más laborioso...
filas = ((lista.listcount +1) \ numcols)
ultimafila = ((lista.listcount +1) mod numcols) ' columnas que tendrá la última fila.
AnchoCol = ((AnchoPapel - MargenIzquierdo )\numcols)
for k = 0 to filas -1
' obtener la línea de texto en x columnas.
linea = ConcatenarCols(lista, j, NumCols, NumCols, Margen, AnchoCol, Alineacion)
' imprime el texto de la línea
printer.currentx = Margen
printer.currenty = (printer.currenty + printer.textheight("t")) ' el textheight depende de la fuente seleccionada en la impresora, no importa el texto entre paréntesis... es fijo para la fuente.
imprimir linea ' <----- mejor imprimir linea a línea
next
if (ultimafila > 0) luego
' obtener la línea de texto en x columnas (con las columnas que resten).
linea = ConcatenarCols(lista, j, UltimaFila, NumCols, Margen, AnchoCol, Alineacion)
' imprime el texto de la línea
printer.currentx = Margen
printer.currenty = (printer.currenty + printer.textheight("t"))
imprimir linea
end ifi
set printer.font = fuente
end function
private function ConcatenarCols(lista as listbox,indice as long, byval cols as integer, byval maxCols as integer, byval X as integer, byval AnchoCol as integer, byval Alineacion as AlineacionHorizontal) as string
dim k as integer, s as string, cols as string
for k = j to (j+cols)
col = Formatear(lista.list(k), AnchoCol, Alineacion)
s = (s & col)
next
ConcatenarCols = s
end function
' Recordar que usamos una fuente monoespaciada, porque sino el trabajo es mucho más laborioso...
private function Formatear(Texto as string, byval Ancho as integer, byval Alineacion as AlineacionHorizontal) as string
dim k as integer, j as integer, s as string
k = (Ancho - printer.textwidth(texto))
j = (k \ printer.textwidth(" ")) ' siendo monoespaciada, da igual que carácter sea...
if (Alineacion = IZQUIERDA) then
if (k > 0) then ' añadir espacios...
s = (Texto & space$(j))
elseif (K < 0) then ' cortar texto.
s = (left$( Texto, len(texto) + j)) ' j es negativo, luego la suma, resta...
else
s = texto
end if
elseif (alineacion = CENTRO) then
' ' Solo consideor alineación izquierda, el resto quedaría a tu esfuerzo
else ' DERECHA
' ' Solo considero alineación izquierda, el resto quedaría a tu esfuerzo
end if
Formatear = s
end function
Si estás completamente seguro que no se dan los casos etiquetados al comienzo como: 'A' y 'C', puede hacerse más directo (menos código, pero más ineficiente) y en general puede cambiarse cosas aquí y allá según el caso concreto de que se trate...
private function ListarEnColumnas(byref lista as listbox, byval numCols as integer, byval MargenIzquierdo as integer, byval AnchoPapel as integer)
dim filas as long
dim ultimafila as long
dim k as long, j as long, i as integer, n as integer, anchocol as integer
dim linea as string
din fuente as stdfont
set fuente = printer.font
printer.fontname = "Courier New" ' una fuente monoespaciada, si no el trabajo es más laborioso...
filas = ((lista.listcount +1) \ numcols)
ultimafila = ((lista.listcount +1) mod numcols) ' columnas que tendrá la última fila.
AnchoCol = ((AnchoPapel - MargenIzquierdo )\numcols)
for k = 0 to filas -1
n = Margen
for i = 0 to numcols -1
printer.currentx = n ' imprime el texto de la columna 'i'
imprimir lista.list(j+i)
n = (n + AnchoCol)
next
j = (j+NumCols)
printer.currenty = (printer.currenty + printer.textheight("t")) ' el textheight depende de la fuente seleccionada en la impresora, no importa el texto entre paréntesis... es fijo para la fuente.
next
if (ultimafila > 0) then' la última fila tiene 1 o más columnas, pero menos que 'numcols'.
n = Margen
for i = 0 to ultimafila -1
printer.currentx = n ' imprime el texto de la columna 'i'
imprimir lista.list(j+i)
n = (n + AnchoCol)
next
end if
set printer.font = fuente
end function
Todo el código es genérico y requiere adaptación al caso concreto y retocar algunas cosas... por ejemplo es típico tener que pelearse con el 'scalemode'... Margen y AnchoPapel (y por extenson anchoCol) son dependientes de dicho valor, así como TextWidth y TextHeight, CurrentX y CurrentY... Si no se opera para todos con la misma escala, hay desajustes.
editado:
donde ponía: imprimir lista.list(j+n) <---- imprimir, si el objeto es la impresora, sería: printer.print
debe poner: imprimir lista.list(j+i)
Faltaba restablecer la fuente al final d ela función: set printer.font = fuente
Hola Nebire
Gracias por contestar
una pregunta
para ir a la funcion de listar en columnas ¿como se dirige a la funcion , gracias?
Invocándola como cualquier otra función... con su nombre y parámetros obligatorios.
ejemplos:
dim x as integer, v as integer, Total as integer
v= 12
' Llamada con asignación.
x = Sumar(5,v)
' Llamada como subrutina y no como función. 'Total' sería un parámetro pasado por referencia...
Call SumaYSigue(5,v,Total)
' Lllamada como parámetro de otra función:
call Msgbox Sumar(5,v)
x = Restar(sumar(5,v),11)
' Las instrucción 'call' es opcional, pero si se añade, los paréntesis de la función son obligatorias... es decir estas 2 sentencias son equivalentes:
Call SumaYSigue(5,v,Total)
SumaYSigue 5, v, Total
Tú mismo tienes en tú código llamadas a funciones como:
Printer.Print Txtnum.Text
Printer.EndDoc ' 'enddoc' es una función o sub del objeto printer, igual que 'print'
SendMessageArray List1.hwnd, LB_SETTABSTOPS, 4, lbtab(1)
Vamos que sorprende una pregunta así...
He probado la funcion y no funciona
gracias
Tienes que adaptarla... el copy-paste, no siempre va a ser la solución...
Si entiendes lo que hace y conoces un poco el lenguaje no es nada complicado adaptarlo a exactamente lo que necesites según lo que tienes...
* Revisando, se ha escapado un gazapo, que cualquiera que entiende el código lo vería rápido (lo he corregido y comentado en el mensaje más arriba).
gracias por contestar
tu mismo lo dices que hay un error
asi no se solucionan las cosas
yo soy principiante en programacion
gracias por contestar
cierro tema
... mensaje duplicado
Cuando escribes código 'al vuelo', es normal que se escape algún error... en ese punto, lo que importa es escribir y avanzar, sin importar si se ha escapado algún error, es luego cuando lo traslada uno al IDE, que a medida que lo pegas o redactas de nuevo que al tiempo vas repasando el código y los errores o cambios a efectuar saltan rápido a la vista.
Si ves trabajar a un escultor (por ejemplo)... en primera instancia hará un rebaje general que dé forma a la figura que trata de hacer, pero nunca será un acabado (salvo que se trate de una pieza muy pequeña)... tendrá que volver a repasar todo afinando cada detalle que lo precise.
...al programar cuando tengas solvencia, pasa lo mismo, escribes código o pseudocódigo, a veces mezclado, para escribir rápido la idea y cuando lo transcribes a código es cuando repasas cada detalle y lo afinas al caso concreto presente. De hecho a veces es común invocar funciones que ni siquiera has creado, pero cuya funcionalidad queda descrita en su nombre y resulta superfluo en primera instancia perder tiempo en escribirla o describirla... de hecho las funciones 'ConcatenarCols' y 'Formatear' no iba a realizarlas, precisamente porque entiendo que estás aprendiendo, es que las he abordado...
Ya te decía que 'Todo el código es genérico, requiere adaptación al caso concreto y retocar algunas cosas...', porque hay detalles que dependen exclusivamente del caso concreto, y por tanto no hay una solución única válida para todos los casos... y por lo mismo una función générica que pueda ser fácilmente adaptada a cualquier caso, es la mejor opción.
p.d:
De hecho... una vez que todo funciona sin errores, todavía se puede dar un último repaso cuyo cometido es optimizar. Cuando describes una idea no procede pensar en detalles para hacerla óptimo, porque pierdes tiempo, es solo el momento de describir la idea, describir el funcionaiento general, la optimización es la fase final... (en medio es escribir el código y lograr que funcione exactamente como se espera). Los aprendices suelen omitir la primera y última fases, es normal...
Hola nebire
no puedo seguir con el ejemplo que has puesto, porque no consigo separar las columnas
del list1 por impresora
gracias
Básicamente hay que hacer dos cosas (asumiendo todo del modo más simple posible):
1 - Establecer una fuente monoespaciada.
Es necesario para simplificar los cálculos, porque así cualquiera que sea el carácter ocupa el mismo espacio al ser impreso, si cada carácter tiene su medida individual hay que calcular uno a uno, mientras que siendo todos iguales, es una multiplicación.
(al final de imprimir la lista debe ser restablecida la fuente a la que tenía, por eso hay que salvaguardar la fuente previamente usada).
2 - Repartir el ancho del papel entre las columnas a usar y posicionar el cursor en cada comienzo de columna e imprimir ahí el ítem. Damos por hecho que ningún ítem supera el ancho de una columna, de ser así debe invocarse una función que calcule y corte el exceso de caracteres, o reducir el número de columnas, etc... por eso digo asumiendo 'todo lo más simple posible').
Dadas x columnas, se recurre a dividir el ancho disponible del papel entre el número de columnas. Para esto los datos necesarios son: saber los márgenes izquierdo, derecho y ancho del papel.
Entonces en un bucle se recorre de x columnas en x columnas, (es deicr las que caben en una línea son un ciclo de este bucle) y en un bucle interno se recorre desde 0 a x columnas -1 (es decir en el bucle interno se recorre cada columna de la línea y es en éste donde se imprime. el bucle exterior simplemente sirve para preparar la línea.
Ahora imprimes el siguiente ítem del texto en la posición con la que empieza la columna (dando por hecho una alineación izquierda).
Supongamos que el papel mide 10.000 puntos de ancho, que son 5 columnas, que el margen izquierdo son 400 y el derecho 300.... y pongamos que la lista son los meses del año:
el pseudocódigo sería:
set tempfuente = impresora.fuente
impresora.fuente.nombre = "Courier New"
anchoCol = (((anchoPapel - (margenderecho + margenIzquierdo)) / numColumnas)
anchoCol = (((10.000 - (400 + 300)) / 5) = ((10.000-700)/5) = 1.860
bucle Y desde 0 hasta lista.count -1 en pasos de NumColumnas ' desde 0 hasta 11 (pués hay 12 meses)
impresora.PosicionY = (impresora.PosicionY + impresora.altofuente)
Bucle x desde 0 hasta numColumnas -1 ' desde 0 hasta 4 (5 columnas en total)
impresora.PosicionX = (margenizquierdo + (x * anchoCol))
impresora.Imprimir meses(y+x)
siguiente en bucle
siguiente en bucle
' como 5+5 son 10 y hay 12 meses, sobran 2 meses que caben en la última línea:
resto = (lista.Count modulo numCols)
Si (resto > 0) luego
impresora.PosicionY = (impresora.PosicionY + impresora.altofuente)
Bucle x desde 0 hasta resto -1 ' desde 0 hasta ? (? columnas restantes)
impresora.PosicionX = (margenizquierdo + (x * anchoCol))
impresora.Imprimir meses(y+x)
siguiente en bucle
Fin si
set impresora.fuente = tempFuente ' restablecemos la fuente a la que había previamente...
Supongamos que la posición Y actual de la impresora fuera 1.250 y que el alto de la fuente fuera 230 puntos. Estos serían pués los valores que irían arrojando los bucles;
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.250 +230) = 1.480
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(0+0) = "Enero"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(0+1) = "Febrero"
PosicionX para columna 2 = 400 + (2 * 1.860) = 4.120
imprimir lista(0+2) = "Marzo"
PosicionX para columna 3 = 400 + (3 * 1.860) = 5.980
imprimir lista(0+3) = "Abril"
PosicionX para columna 4 = 400 + (4 * 1.860) = 7.840
imprimir lista(0+4) = "Mayo"
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.480 +230) = 1.710
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(5+0) = "Junio"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(5+1) = "Julio"
PosicionX para columna 2 = 400 + (2 * 1.860) = 4.120
imprimir lista(5+2) = "Agosto"
PosicionX para columna 3 = 400 + (3 * 1.860) = 5.980
imprimir lista(5+3) = "Septiembre"
PosicionX para columna 4 = 400 + (4 * 1.860) = 7.840
imprimir lista(5+4) = "Octubre"
LineaActual = posicionY
PosicionY = (LineaActual + altoFuente) = (1.480 +230) = 1.710
PosicionX para columna 0 = 400 + (0 * 1.860) = 400
imprimir lista(10+0) = "Noviembre"
PosicionX para columna 1 = 400 + (1 * 1.860) = 2.260
imprimir lista(10+1) = "Diciembre"
Los puntos 1 y 2 remarcados en negrita son el resumen general (si cambian detalles hay que hacer más o menos funcionalidad para que cumplan todas las expectativas de los detalles).
En el código primero, concatenaba los valores de los items que forman una línea a base añadir los espacios necesarios tras un ítem hasta llegar a la posición de inicio de la siguiente columna, lo cual exigía calcular la cantidad de espacios a añadir o caracteres a cortar (si excedía el ancho de la columna). Y así imprimia toda una línea d euna sola vez... es un código más simple (de hacer y entender) imprimir el dato de cada columna, pero menos eficiente y solo sirve si no hay detalles adicionales que lo compliquen (como otra alineación que no sea izquierda y valores que superen el ancho de la columna).
Gracias
Hola nebire por fin he podido correr el programa
hasta ahora tengo esto
Private Sub Command7_Click()
' Imprimir
Dim factura As Integer
Dim total As String
Dim total1 As String
Dim total2 As String
Dim jk As String
'jk = App.Path & "\facturas\" & Combo2.Text & "\" & Txtnum.Text & ".txt"
Printer.Print Tab(5); "HORA: " & UCase(Format(Now, "hh:mm am/pm"))
Dim i As Integer
Dim aux As String
Printer.FontSize = 18
Printer.CurrentX = 4000
Printer.CurrentY = 0
Printer.Print "Factura Nº:"
Printer.CurrentX = 6000
Printer.CurrentY = 0
Printer.Print Txtnum.Text
Printer.CurrentX = 1000
Printer.CurrentY = 3000
Printer.Print "Cantidad"
Printer.CurrentX = 3500
Printer.CurrentY = 3000
Printer.Print "Producto"
Printer.CurrentX = 7350
Printer.CurrentY = 3000
Printer.Print "Precio"
Printer.CurrentX = 9900
Printer.CurrentY = 3000
Printer.Print "Subtotal"
Printer.CurrentX = 3000
Printer.CurrentY = 3500
listarcolumnas
'Label5.Caption = total
'Label6.Caption = total1
'Label7.Caption = total2
Printer.CurrentX = 8400
Printer.CurrentY = 10000
Printer.Print "Subtotal:"
Printer.CurrentX = 9300
Printer.CurrentY = 10500
Printer.Print "iva:"
Printer.CurrentX = 9000
Printer.CurrentY = 11000
Printer.Print "Total:"
Printer.CurrentX = 10000
Printer.CurrentY = 10000
Printer.Print Label5.Caption
Printer.CurrentX = 10000
Printer.CurrentY = 10500
Printer.Print Label6.Caption
Printer.CurrentX = 10000
Printer.CurrentY = 11000
Printer.Print Label7.Caption
Printer.Print
Printer.EndDoc
End Sub
Private Sub listarcolumnas()
Dim AnchoPapel As Integer
Dim MargenIzquierdo As Integer
Dim numCols As Integer
Dim filas As Long
Dim ultimafila As Long
Dim k As Long, j As Long, i As Integer, n As Integer, anchocol As Integer
Dim linea As String
Dim margen As Integer
Dim fuente As StdFont
Set fuente = Printer.Font
numCols = 4
Printer.FontName = "Courier New" ' una fuente monoespaciada, si no el trabajo es más laborioso...
filas = ((List1.ListCount + 1) \ numCols)
ultimafila = ((List1.ListCount + 1) Mod numCols) ' columnas que tendrá la última fila.
anchocol = ((AnchoPapel - MargenIzquierdo) \ numCols)
For k = 0 To filas - 1
n = margen
For i = 0 To numCols - 1
Printer.CurrentX = n ' imprime el texto de la columna 'i'
Printer.Print List1.List(j + i)
n = (n + anchocol)
Next
j = (j + numCols)
Printer.CurrentY = (Printer.CurrentY + Printer.TextHeight("t")) ' el textheight depende de la fuente seleccionada en la impresora, no importa el texto entre paréntesis... es fijo para la fuente.
Next
If (ultimafila > 0) Then ' la última fila tiene 1 o más columnas, pero menos que 'numcols'.
n = margen
For i = 0 To ultimafila - 1
Printer.CurrentX = n ' imprime el texto de la columna 'i'
Printer.Print List1.List(j + i)
n = (n + anchocol)
Next
End If
Set Printer.Font = fuente
End Sub
y me sale lo siguiente:
la primera fila casi lo hace bien
la segunda fila: primera columna bien segunda columna bien tercera columna mal y cuarta columna mal
faltaria arreglar los datos de la segunda fila
gracias
Hola nebire
el problema esta en la columna producto, porque no siempre tiene los mismos caracteres
como seria el codigo para arreglar la columna producto
Gracias
Puedes mostrar una foto de la impresión, que se vea como va quedando... así me hago cargo del tamaño de los textos, etc...????
p.d.:
Lo que si veo repasando el código, es que a la función ' listarcolumnas', no le has puesto los parámetros necesarios, y por tanto no los recibe, luego parece que simplemente estás imprimiendo un texto detrás del otro, pero sin una consideración correcta de columnas, por eso te está fallando.
Dicho de otro modo... te redacto la función con los parámetros adecuados, ya que parece que no los pasas pero tampoco los inicializas (aunque si el list1)
Private Sub ListarColumnas(byval NumCols as integer, byval MargenIzquierdo as integer, byval AnchoPapel as integer)
Dim AnchoPapel As Integer
'Dim MargenIzquierdo As Integer, numCols As Integer
Dim filas As Long
Dim ultimafila As Long
Dim k As Long, j As Long, i As Integer, n As Integer, anchocol As Integer
Dim linea As String
'Dim margen As Integer
Dim fuente As StdFont
Set fuente = Printer.Font
'numCols = 4 Se recibe por parámetro mejor...
Printer.FontName = "Courier New" ' una fuente monoespaciada, si no el trabajo es más laborioso...
filas = ((List1.ListCount + 1) \ numCols)
ultimafila = ((List1.ListCount + 1) Mod numCols) ' columnas que tendrá la última fila.
anchocol = ((AnchoPapel - MargenIzquierdo) \ numCols)
For k = 0 To filas - 1
n = MargenIzquierdo
For i = 0 To numCols - 1
Printer.CurrentX = n ' imprime el texto de la columna 'i'
Printer.Print List1.List(j + i)
n = (n + anchocol)
Next
j = (j + numCols)
Printer.CurrentY = (Printer.CurrentY + Printer.TextHeight("t")) ' el textheight depende de la fuente seleccionada en la impresora, no importa el texto entre paréntesis... es fijo para la fuente.
Next
If (ultimafila > 0) Then ' la última fila tiene 1 o más columnas, pero menos que 'numcols'.
n = MargenIzquierdo
For i = 0 To ultimafila - 1
Printer.CurrentX = n ' imprime el texto de la columna 'i'
Printer.Print List1.List(j + i)
n = (n + anchocol)
Next
End If
Set Printer.Font = fuente
End Sub
' y la invocas así:
' numero de columnas, margen izquierdo donde empezar, ancho que ocuparán las columnas.
call ListarColumnas(4, 240, printer.width - MargenDerecho)
b]Nota que:[/b]
- MargenIzquierdo y MargenDerecho pueden valer 0, lo que significará que se usará todo el ancho disponible del papel por parte de la impresora (printer.width). Ahora bien si ves que 'queda feo', porque 4 columnas son pocas, puedes o bien añadir alguna columna o utilizar márgenes a ambos lados.
- Puedes omitir el parámetro listbox, si siempre vas a usar un único listbox, pero es acertado que una función reciba por parámetro los datos que utiliza.
Si más adelante copias y pegas la función a otro proyecto, seguirá funcionando porque requerirá el listbox que en dicho proyecto estés usando (se llame como se llame, queda aislado dentro de la función), lo que es mejor que andar renombrando cada aparición del listbox...
Para no liarte visto que ya tienes la función usando el control list1, lo retiro como parámetro, pero es más adecuado que se incluya como tal.
Recuerda que todo lo que se haga con printer.print, printer.line, printer.circle, priter.paintpicture y printer.pset se dibuja a un backbuffer, donde se va recreando la 'imagen' a imprimir, cuando se invoca enddoc, equivale a invocar 'draw' del backbuffer, es decir es cuando se vuelca la imagen completa a la impresora.
aqui te paso un ejemplo
cantidad producto precio subtotal
10 tomates de barbastro 2 20
30 patatas 0,60 18
subtotal: 38
iva: 4,56
total: 42.56
gracias
Me acabo de editar (mientras tu respondías), corrigiéndote la función al completo.... revísa mi mensaje previo y cambia la función en tu código así como la línea que invoca dicha función.
Nota los parámetros que deben ser pasados: si con 4 columnas, pasas 4, si no hay margen izquierdo, pasa 0, etc...
Por cierto, veo que ya le das un valor posicional a cada columna, cuando estableces los valores de currentX, al declarar:
Printer.CurrentX = 1000: Printer.Print "Cantidad"
Printer.CurrentX = 3500: Printer.Print "Producto"
Printer.CurrentX = 7350: Printer.Print "Precio"
Printer.CurrentX = 9900: Printer.Print "Subtotal"
Es decir están a 1000, 3500, 7350 y 9900. es decir lo estableces manualmente y no tienen un reparto equitativo, si quieres que queden con ese mismo reparto, deberías meter dichos valores en un array. Y usarlo como posición para cada columna.
hola nebire
he hecho los cambios de la funcion y el resultado me sale igual
me podrias hacer un ejemplo lo de un array y usarlo como posicion
gracias
hola nebire
he resuelto el tema
en el codigo he modificado declarar la variable prod que es el producto
el prod me acepta 19 caracteres en el list1 a la hora de declarar la variable me lo hace bien
dim prod as string * 19
ahora si
gracias nebire
Me alegro que lo hayas resuelto.
El uso de string de tamaño fijo es otra solución, aunque si por ejemplo decidiras luego cambiar dinámicamente a 5 u otro cualquier número de columnas, habría que cambiar código.
Una rcomendación es en lo posible adoptar soluciones dinámicas, de tal manera que un cambio de valores no suponga un cambio del código, si no simplemente, pasar los valores adecuados en los parámetros.
Una solución basado en un array sería algo como:
Dim PosCols() as integer
dim Headers() as string
' Al inicializar la ventana va bien...
' (dos formas de inicializar un array)
private sub form1_Load()
posCols = Array(1000, 3500, 7350, 9900)
Headers = Split("Cantidad, Producto, Precio, Subtotal", ", ")
end sub
Ya tenemos el array con los valores de inicio de cada columna...
Ahora solo falta imprimir en tales posiciones...
En los headers, remplaza esto:
Printer.CurrentX = 1000: Printer.Print "Cantidad"
Printer.CurrentX = 3500: Printer.Print "Producto"
Printer.CurrentX = 7350: Printer.Print "Precio"
Printer.CurrentX = 9900: Printer.Print "Subtotal"
por esto:
Dim k as integer
printer.CurrentY = 3000
for k = 0 to 3
Printer.CurrentX = posCols(k): Printer.Print Headers(k)
next
Y luego en el bucle interno (el bucle 'i', que aparece dos veces)...
For i = 0 To numCols - 1
Printer.CurrentX = posCols(i)
Printer.Print List1.List(j + i)
Next
Esto invalida la necesidad de 'n', 'anchocol', 'margenizquierdo' y 'anchopapel', aunque insisto en que es preferible parametrizar las funciones, pues les da flexibilidad y puedes reaprovechar código para otros proyectos... el código estático, necesita ser modificado para cada situación. Contradice el paradigma 'orientado a objetos' y favorece el 'código espagueti'...
perfecto
muchas gracias nebire