Establecer márgenes de informes con Visual Basic

Informe Access - Márgenes

Hace ya tiempo que suelo establecer los márgenes de todos los informes de mis aplicaciones al abrirlos ya que suele ocurrir que al utilizarlos distintos usuarios, o simplemente al cerrarlos y volver a abrirlos, se descuadran completamente.

Generalmente cuando las aplicaciones que desarrollo son simples y los usuarios tienen acceso total a los datos, las suelo dejar en .mdb o ahora en .accdb, ya que suelen ser usuarios de mi servicio y no tienen motivo (ni ganas) de andar tocando donde no deben (en cualquier caso tendrían no ocurriría nada ya que suelen ser sencillitas).

Para este tipo de aplicaciones, siempre he utilizado el código que colgó en su día Eduardo Olaz en la web del Búho:

Hay que utilizar la propiedad PrtMIP del informe. Esta propiedad es una cadena de 28 bytes en la que se almacena la configuración de la página:
Márgenes, Columnas, Tamaño, etc… Léete la ayuda.

En tiempo de ejecución, por ejemplo en los eventos Al imprimir, etc… es de sólo lectura. En tiempo de diseño es de lectura y escritura. Los pasos que hay que seguir son:
Mediante código, abrir el informe en modo diseño
Establecer la propiedad PrtMIP del informe
Abrir el informe en modo Normal (Se imprimirá)
Cerrar el informe sin grabarlo

La instrucción:
ImprimirAjustandoMargenes “rptVentas”, 3, 2, 1.5, 2
Imprimirá el informe rptVentas con un margen izquierdo de 3 cms, un margen
derecho de 2 cms, un margen superior de 1,5 cms y un margen inferior de 2
cms.

Créate un módulo con este código:

Option Explicit
Type CadenaPrtMip
strConfiguracion As String * 28
End Type
' la estructura TipoPrtMIP se pasa a la cadena
' strConfiguracion, y ésta a la propiedad PrtMIP
' de un informe para configurar sus propiedades
' mediante VBA en modo diseño.
' PrtMIP es de sólo lectura en tiempo de ejecución

Type TipoPrtMIP
MargenIzquierdo As Long
MargenSuperior As Long
MargenDerecho As Long
MargenInferior As Long
SoloDatos As Long
Ancho As Long
Alto As Long
TamañoPredeterminado As Long
Columnas As Long
EspacioColumna As Long
EspacioFila As Long
DiseñoElemento As Long
FastPrinting As Long
Datasheet As Long
End Type

Public Sub ImprimirAjustandoMargenes( _
ByVal Informe As String, _
Optional ByVal MargenIzq As Single = 2.54, _
Optional ByVal MargenDch As Single = 2.54, _
Optional ByVal MargenSup As Single = 2.54, _
Optional ByVal MargenInf As Single = 2.54)
' Este procedimiento abre un informe
' le aplica los márgenes, lo imprime y lo cierra
' para aplicarle los márgenes usa la propiedad
' (de sólo lectura en ejecución) prtMip del informe
' Primera versión 19/10/2002
' Eduardo Olaz eduardo@olaz.net
' Los márgenes están en centímetros
' strConfiguracion será la cadena de 28 byts que
' pasaremos a la propiedad PrtMip del informe
' conTwipsCentimetro Coeficiente de conversión
' de Centímetros a Twips

' Aquí deberías poner una rutina de errores
On Error GoTo HayError
Const conTwipsCentimetro As Long = 567
' Los márgenes se pasan en Twips
Dim PrtMipString As CadenaPrtMip
Dim TPrtMip As TipoPrtMIP
Dim rpt As Report
DoCmd.OpenReport Informe, acDesign
Set rpt = Reports(Informe)
' Ya que tenemos una cadena en el PrtMip
' del informe gravado la usamos como base
PrtMipString.strConfiguracion = rpt.PrtMip
LSet TPrtMip = PrtMipString
With TPrtMip
.MargenIzquierdo = MargenIzq * conTwipsCentimetro
.MargenSuperior = MargenSup * conTwipsCentimetro
.MargenDerecho = MargenDch * conTwipsCentimetro
.MargenInferior = MargenInf * conTwipsCentimetro
End With
LSet PrtMipString = TPrtMip ' Actualiza la propiedad.
rpt.PrtMip = PrtMipString.strConfiguracion
' Abrimos el informe para imprimirlo
DoCmd.OpenReport Informe, acViewNormal
' Cerramos el informe sin grabarlo
DoCmd.Close acReport, Informe, acSaveNo
Set rpt = Nothing
Salir:
Exit Sub

HayError:
MsgBox "Se ha producido el Error Nº " & Err.Number _
& vbCrLf _
& Err.Description _
& vbCrLf _
& "Al tratar de imprimir el informe: " _
& Informe, _
vbCritical + vbOKOnly, _
"Procedimiento ImprimirAjustandoMargenes"
Set rpt = Nothing
Resume Salir
End Sub

Como bien dice el propio Eduardo, en tiempo de ejecución no podríamos modificar la propiedad PrtMIP de los informes así que hasta ahora tenía que modificar el código de todos mis informes cuando las aplicaciones eran ya más complicadas (o los usuarios menos de fiar…) y tenía que compilar a .mde o .accde (últimamente entrego todo en accdr, me gusta más y se puede ejecutar solo con el Run-Time, pero de eso ya hablaré en otro artículo).

Como siempre en este tipo de casos, empecé a buscar información sobre gente a la que le ocurría lo mismo, pero siempre encontraba la misma solución, el post de Eduardo Olaz y la imposibilidad de modificar los informes en tiempo de ejecución.

Pues bien, el otro día encontré una solución que además de ser bastante más sencilla que la de Eduardo Olaz, funciona en tiempo de ejecución tanto con archivos de Access 2000/2003 (mde) como con archivos de Access 2007/2010 (accde). Se trata de las propiedade TopMargin, BottomMargin, LeftMargin, RightMargin de un objeto Printer. Se suponía que se podían modificar en tiempo de ejecución.

El siguiente paso era saber cómo funcionaba todo esto, pero en vez de tener que probar una y mil veces distintas soluciones (como suele pasar casi siempre), me funcionó a las primera, sin saber muy bien a qué objeto printer le asigna las propiedades. El caso es que funciona.

Aqui os paso el procedimiento que ejecuto antes de imprimir cada informe. Para utilizarlo hay que crear un módulo en el que pegáis el siguiente código, y se le llama antes de abrir un informe (o en algún evento de los informes):

'***************************************************************************************
Public Sub AjustarMargen(Arriba As Integer, Abajo As Integer, Izquierda As Integer, Derecha As Integer)
'***************************************************************************************
'Procedimiento para ajustar márgenes antes de imprimir un informe en tiempo de ejecución
'Funciona en archivos mde y en accde</span>
'Arkaitz Arteaga - www.programadordepalo.com</span>
'Llamar antes de imprimir el informe de la siguiente manera (para por ejemplo margen  superior 1cm, abajo 2cm, izquierda 3 cm, derecha 4cm):
'AjustarMargen(1,2,3,4)
'****************************************************************************************
With Printer
.TopMargin = Arriba * 567 'Ajusto el tamaño entre centimetros y twips
.BottomMargin = Abajo * 567
.LeftMargin = Izquierda * 567
.RightMargin = Derecha * 567
End With
End Sub
'***************************************************************************************

Así que ya sabéis, si necesitáis modificar los márgenes en tiempo de ejecución, aquí tenéis una posible solución.

The following two tabs change content below.
Arkaitz Arteaga
Llevo más de 10 años programando, sobre todo en Visual Basic y con bases de datos Access. Para mí, VBA y Access siguen siendo herramientas muy potentes. He desarrollado varios proyectos con PHP y MySql. Si sumo las webs que he tenido, probablemente pasaría de 100. Ahora prefiero dedicar todo mi esfuerzo a este blog (aunque sigo manteniendo unas cuantas...). Trabajo en la administración pública (si, soy funcionario), pero he trabajado en pequeñas empresas e incluso en una "grande" de las telecomunicaciones. Ultimamente estoy bastante metido en abrirme nuevos horizontes con C# y .NET. Renovarse o morir!

Una respuesta a Establecer márgenes de informes con Visual Basic

  1. Una duda sobre márgenes en informes de access:
    ¿Existe la forma de proporcionar márgenes diferentes según se trate de una página par o impar?
    Tengo un informe que se imprime de manera que aparece un único registro por página, y me gustaría que cada página tuviera un margen concreto según fuera par o impar.
    Gracias.

Deja un comentario