ReportViewer y fuentes de datos dinámicas
abril 1, 2009 72 comentarios
Durante las últimas semanas he estado enfrascado en labores de mantenimiento de aplicaciones un poco «viejitas» y entre las tareas está la incorporación de algunos requerimientos hechos por los usuarios de modificaciones a los informes, creación de nuevos, etc. Por los días en que fueron programadas originalmente, solía usar componentes de terceros para la creación de informes, los cuales resultaron muy eficaces y aún hoy están sirviendo informes felizmente. Sin embargo no siempre se obtiene ciento por ciento de compatibilidad con las versiones nuevas de .NET; así las cosas, decidí echar una ojeada a ReportViewer que viene incluído con Visual Studio 2008. A primera vista me pareció un poco frívolo, con pocas posibilidades de personalización, gracias a la manía de Microsoft de ponernos las cosas estúpidamente simples; con el asistente y unos cuantos clicks, es posible en menos de un minuto obtener una forma de Windows o una página web que muestre un informe completamente funcional, eso sí, monolíticamente ligado a una tabla específica o expresión SQL. A continuación intentaré mostrar cómo utilizar ReportViewer para mostrar informes a partir de fuentes de datos creadas dinámicamente en tiempo de ejecución.
Acerca de ReportViewer
A modo de preámbulo, ReportViewer es un control gratis que permite incluir informes en las aplicaciones web y desktop (http://www.gotreportviewer.com/). Posee dos modos de operación: local y remoto. Cuando trabaja en modo remoto, simplemente muestra un informe creado por un Servidor de Informes de SQL Server. En modo local, todo el procesamiento, filtrado u ordenamiento ocurren a nivel de cliente. En este post se asume que estamos trabajando en modo local (propiedad ProcessingMode=local).
Conceptualmente, para completar un informe con ReportViewer son necesarios dos componentes:
- La definición del informe, que en este caso es un documento en formato RDLC (Report Definition Language for Client).
- La fuente de datos, un DataSet.
Uno de los aspectos positivos de ReportViewer es la independencia entre estos componentes; la definición del informe no está ligada a ningún formato específico de base de datos, ni a ninguna base o tabla específica. De ahí la posibilidad de construir una definición sin conocer el origen exacto de los datos; solo es necesario especificar de forma abstracta los nombres de campos que debe incluir una tabla que sirva de fuente de datos al informe y sus tipos de datos.
Usualmente construyo las aplicaciones empleando las tradicionales capas lógicas (tiers) de acceso a datos, negocios e interfaz; uno de los módulos se especializa en la construcción de los DataSets que sirven de base a los informes. Este método me resultó siempre muy útil con los componentes de terceros, pues me permitía cambiar de uno a otro sin modificaciones (o mínimas) en el resto de las capas. Afortunadamente, a ReportViewer le he podido también «enchufar» los DataSets generados por estos módulos previamente construídos. Solamente he tenido que crear nuevamente las definiciones de los informes en el nuevo lenguaje RDL, aunque esto es fácil con las herramientas visuales de Visual Studio.
Obtención del Conjunto de Datos
Para entrar en materia, voy a emplear un ejemplo muy simple: se desea mostrar en una página .aspx un informe que liste los atletas finalistas en unos Juegos Olímpicos. En el sistema real se le permite al usuario seleccionar la edición de los Juegos, el deporte y la modalidad, de ahí que la fuente de datos tenga que ser dinámica. Definiré una función CalcularDataSet() que retorna los finalistas de 100 metros planos en atletismo durante los Primeros Juegos Olímpicos celebrados en Atenas, Grecia en 1896. Esta función es un patrón que simplifica el verdadero cómputo del DataSet, que puede ser todo lo complicado que se desee y generalmente residiría en la capa de acceso a datos o en la capa de negocios. Por tanto, incluyo el código por completitud, pero no es importante para comprender el mecanismo que nos ocupa. El aspecto relevante es que la función devuelve un DataSet que contiene el DataTable que servirá de fuente de datos al informe.
public DataSet CalcularDataSet() { string sql = @" SELECT posiciones.lugar, atletas.nombre, atletas.apellido1, delegaciones.nombre AS Pais, posiciones.resultado, eventos.nombre AS Evento, eventos.sigDeporte FROM atletas INNER JOIN integrantesGrupos ON atletas.idAtleta = integrantesGrupos.idAtleta INNER JOIN posiciones INNER JOIN Competencias ON posiciones.idCompetencia = Competencias.IdCompetencia INNER JOIN eventos ON posiciones.idEvento = eventos.idEvento INNER JOIN Categorias ON Competencias.Categoria = Categorias.IdCategoria ON integrantesGrupos.idResultado = posiciones.idPosicion INNER JOIN delegaciones ON posiciones.idDelegacion = delegaciones.idDelegacion WHERE categorias.idclase=1 AND competencias.categoria=2 AND posiciones.idCompetencia=286 AND eventos.sigDeporte='ATL' AND posiciones.idEvento=14 AND posiciones.idFase=3 AND posiciones.sexo='M' "; string connstr = "Data Source=localhost;Initial Catalog=historia;Integrated Security=True"; SqlConnection conn = new SqlConnection(connstr); SqlCommand cmd = new SqlCommand(sql, conn); SqlDataAdapter da = new SqlDataAdapter(); da.SelectCommand = cmd; conn.Open(); DataSet ds = new DataSet(); da.Fill(ds, "Finalistas"); conn.Close(); return ds; }
Creación de la Definición del Informe (documento RDLC)
El documento RDLC es simplemente un documento XML que cumple con el esquema del lenguaje RDLC. Por tanto, en caso extremo, es posible crearlo con cualquier editor de textos. En la práctica, por supuesto, resulta más conveniente emplear las herramientas visuales que proporciona Visual Studio. Para ello añadimos al proyecto un nuevo item de tipo Report y lo denominaremos Finalistas.rdlc. Ello muestra el diseñador de informes con un informe vacío. Aquí arrastramos desde la barra de herramientas un nuevo Table, añadimos las columnas necesarias y les colocamos sus respectivos títulos en la fila de encabezados (Header).
Si compilamos el proyecto, Visual Studio «protestará» debido a que no se ha definido un DataSource en el informe. Debemos añadir entonces un DataSet nuevo al proyecto. En este momento contamos con al menos dos opciones:
- Estilo bottom-up: construir un DataSet a partir de la base de datos real, suministrando una consulta en SQL a través de un Table Adapter, un procedimiento almacenado, etc.
- Estilo top-down: construir un DataSet «ficticio» con una tabla que solo va a contener los nombres de los campos que vamos a utilizar en el informe. Este es el enfoque que se sigue aquí.
Ambos métodos son igualmente válidos. El verdadero objetivo de este paso es crear una fuente de datos que sea «comprensible» para el diseñador de informes de Visual Studio. De regreso al informe, aparecerá en la ventana «Website Data Sources» el nuevo DataSet creado que denominamos DataSetFinalistas. En el diseñador de DataSets obtuve una tabla que denominé TableFinalistas que luce así:
Para completar la definición del informe solo debemos arrastrar los campos correspondientes desde la ventana «Website Data Sources» hacia la fila de detalles (Detail) de la tabla que insertamos anteriormente y añadir las opciones de formato deseadas.
Luego de guardar el documento, para comprender mejor qué hemos hecho, conviene echar una ojeada al documento RDLC generado. Por cualquiera de los dos métodos señalados, se creó una sección que contiene la definición del DataSet. Por cierto, es curioso notar cierta ambiguedad en el término DataSet en este contexto: para RDLC el DataSet es más bien una tabla o la definición de sus campos, contrario a .NET dónde DataSet es una estructura de datos que contiene tablas (DataTable); nada alarmante pero conviene estar claros de esta sutileza para evitar confusiones. La sección de DataSets del RDLC para nuestro ejemplo, queda de la siguiente forma:
<DataSets> <DataSet Name="DataSetFinalistas_TableFinalistas"> <Fields> <Field Name="lugar"> <DataField>lugar</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="nombre"> <DataField>nombre</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="apellido1"> <DataField>apellido1</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="pais"> <DataField>pais</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="resultado"> <DataField>resultado</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="evento"> <DataField>evento</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> <Field Name="sigDeporte"> <DataField>sigDeporte</DataField> <rd:TypeName>System.String</rd:TypeName> </Field> </Fields> <Query> <DataSourceName>DummyDataSource</DataSourceName> <CommandText /> <rd:UseGenericDesigner>true</rd:UseGenericDesigner> </Query> <rd:DataSetInfo> <rd:DataSetName>DataSetFinalistas</rd:DataSetName> <rd:TableName>TableFinalistas</rd:TableName> </rd:DataSetInfo> </DataSet> </DataSets>
Esto, usando el segundo método. La única diferencia en cuanto a generación entre ambos métodos es que con el primero, se incluye más información en la definición, por ejemplo el comando que se utiliza para generar los datos (CommandText), la cadena de conexión (ConnectString), y otros que en un final son irrelevantes pues todo esto lo vamos a generar en ejecución. Nótese en la sección <Query> la «fuente de datos tonta» (DummyDataSource). Todas estas secciones, Query, CommandText, DataSourceName, son obligatorias y es necesario incluirlas aunque estén vacías si no queremos escuchar las quejas del compilador.
En fin, la elección de uno u otro método es una cuestión de gusto y comodidad, si estamos seguros de los campos que vamos a utilizar, entonces el (2) es más simple; si antes queremos jugar un poco con los datos o crear aquí mismo la consulta entonces (1) es más cómodo. Como quiera, lo único importante para realizar el diseño del informe y crear el correspondiente RDLC, es la definición de los nombres de campos que se van a usar.
Informe = Definición en RDLC + Datos
Ya tenemos una función que genera DataSets (de .NET), o en una aplicación real, todo un componente dentro de la capa de datos; y tenemos un RDLC que contiene la definición del informe. Ahora solo resta buscar la forma de aglutinarlos a ambos.
Muy sencillo, supongamos que nuestro proyecto es una aplicación web en el cual tenemos una página llamada finalistas.aspx en la cual depositamos un ReportViewer llamado rv. Además tenemos un botón «Mostrar finalistas» que carga el informe en el ReportViewer. El código es el siguiente:
protected void MostrarInforme() { ReportDataSource rds = new ReportDataSource(); rds.Name = "DataSetFinalistas_TableFinalistas"; rds.Value = CalcularDataSet().Tables[0]; rv.LocalReport.DataSources.Clear(); rv.LocalReport.DataSources.Add(rds); rv.LocalReport.ReportPath = "Finalistas.rdlc"; rv.LocalReport.Refresh(); }
ReportDataSource es la estructura que permite asociar el DataSet referenciado en la definición del informe con un conjunto de datos (DataTable en este caso) generado dinámicamente en tiempo de ejecución. El punto importante aquí es que debe coincidir el Name del ReportDataSource con el Name del DataSet en el RDLC (en este caso DataSetFinalistas_TableFinalistas).
Un par de temas abiertos
Para terminar me agradaría compartir un par de temas abiertos con los que he tropezado en el trabajo con ReportViewer. El primero es específico a la versión para web. Si fijamos las dimensiones del control en tiempo de diseño, en ejecución se mostrarán barras de desplazamiento automáticamente en caso que el tamaño real sea mayor que el predeterminado. Fijando la propiedad SizeToReportContent a True, es posible indicarle a ReportViewer que ajuste el tamaño del control en tiempo de ejecución al tamaño real del informe. Sin embargo, para que esto funcione, es necesario fijar la propiedad AsyncRendering a False, de lo contrario ni se entera. Pero con esta configuración (AsyncRendering=False y SizeToReportContent=True) no me funciona el páginado, al hacer click para mostrar la siguiente página, sigue mostrando la primera.
He estado experimentando algunas de las variantes en este post para resolver el problema y creo que la solución está por esa vía jugando un poco con los javascripts, aunque honestamente, me ha faltado el tiempo para probarlo con más profundidad. Si alguien lo ha hecho, por favor, me deja un comentario por acá.
El segundo se refiere a la generación dinámica del RDLC, o sea, de la definición del informe. Esto abre una amplia gama de posibilidades, la definición en RDLC es finalmente un XML que podemos construir en tiempo de ejecución. He incluído en mi lista de tareas utilizar esta variante para construir informes basados en consultas cruzadas, en las cuales es imposible predecir en tiempo de diseño la cantidad de campos. Recomiendo descargar la aplicación de ejemplo Dynamic Matrix y este post en el cual se construye el RDLC aplicando una transformación XSLT al esquema del DataSet que contiene el resultado de la consulta
En general, ReportViewer resulta muy útil y fácil de usar y aunque no es nueva la idea de separa definición de datos, me parece muy acertada la idea de emplear este enfoque. Es posible descargar las especificaciones del lenguaje RDL del 2008 desde el sitio de Microsoft de SQL 2008.
Como llamas al reporte rdlc por medio de parametros?
Gran aporte man….. realmente espectacular. Es muy bueno no guiarnos solamente por los wizard y hacer algo mas inteligente… Palmas para ti
si eso ess todo… lo voy a revisar
Realmente usted es el primer ser en este planeta que en realidad muestra algo util, estaba varado, llevo mas de un mes buscando alguien que me luces sobre este tema.
gracias
Algo Adicional:
el metodo seria el mismo para visual basic??????
Hola Arturo, me alegra le haya sido útil esta información. En efecto, es posible implementar el método también en VB pues como cualquier lenguaje sobre .NET, soporta ADO.NET y ReportViewer.
Saludos
Me podría ayudar con algo?
Ya implementé lo que me faltaba pero al momento de presionar el botón «generar reporte» me sigue mandando el mismo mensaje «No se ha proporcionado ninguna instancia de origen de datos para el origen de datos ‘DataSet1’.»
Espero que pueda contestar.
Gracias
Hola, fijate que el nombre que estas enviando desde el código se tiene que llamar de la misma manera que el dataset que utilizas cuando diseñas el rdcl
si cuando diseñaste el rdcl le pusiste DataSet1, cuando le indicars el datasource debes llamarlo de la misma manera….
var reporteDataSource = new ReportDataSource(«DataSet1», (DataTable)dataTable);
Me podría ayudar con algo?
Ya implementé lo que me faltaba pero al momento de presionar el botón «generar reporte» me sigue mandando el mismo mensaje «No se ha proporcionado ninguna instancia de origen de datos para el origen de datos ‘DataSet1’.»
Sólo que yo estoy trabajando con Visual Studio 2012 c#
Espero que pueda contestar.
Gracias
Buenos comentarios yo hes estado desarrolonado 2008 pero tengo para problemillas la de la orientacion del papel y la de impresión del lado del cliente he leido varios post y el que me funcion lo de la impresion es el siguiente:
http://idelabar.blogspot.com/2008/10/problemas-para-imprimir-con-report.html
mucho agradeciari si tienes solicon para el tamaño y orientacion del papel (horizontal)
saludos y felicidades por tus comenarios realmente es algo funcional.
excelente documento solo una preguna hay forma de agregar una columna que genere un numero consecutivo a un reporte rdlc, como en reporte de crystal que es numero de registro?, Gracias
Usando la función RowNumber(Nothing) en la definición de la columna.
mil gracias johnbarquin, llevaba varios dias con esto por no decir semanas jejeje me pondre a estudiar mas acerca de este control feliz y exito 2010
En que parte del reporte defino la funcion RowNumber(Nothing) o donde la configuro?
Excelente, claro y conciso, muchas gracias!!!
Tengo una duda, ojala puedan ayudarme, quisiera saber la manera de combinar la fuente de una caja de texto ej. lettra normal y negrita para no tener que concatenar varios cuadros de texto en un reporte hecho con reportviewer, solo se que podemos usar el fontweight pero no se como usarlo enuna expresion, ojala puedan ayudarme
hola muchas gracias por esta informacion es muy buena para trabajar con reportviewer , tengo solo un problema , hice cada paso pero el reporte no muestra la data , y se que el dataset se esta llenando que puede ser , me asegure que el nombre del datasety del rdlc fuera el mismo que el del calculardataset y todo , no puedo ver que sucede , es como que no hace refrest el reportviewer , puede ser que lo estoy haciendo en windowsform ?
HOLA johnbarquin…
Excelente información, gracias, nada más que al generar el reporte los puntos que tengo en la base de datos me los muestra con comas
Por ejemplo en la BD tengo 5.5 en el reporte me muestra 5,5
Espero y me puedas ayudar, le he cambiado formato pero no he dado con la solución, saludos…..
La consulta es la siguiente: necesito saber si es posible personalizar una tabla dentro de un reporte.
Me explico tengo una tabla que guarda en ella la definicion de las conductas de un individuo, para cada conducta existe una nota obtenida por el sujeto, la que necesito marcar de cierta forma (colorear, ticket) dentro de la columna que corresponda.
CONDUCTA | NO CUMPLE | CUMPLE PARCIALMENTE |CUMPLE TODOS | SOBRESALIENTE
siendo conducta la columna con la definicion de la conducta.
Necesito saber si esto se puede hacer, y de poderse como se realiza, agradeceria mucho su ayuda, ya que me tiene asi cada una (xD).
Desde ya gracias.
pd: trabajo con c#, y cargo los datos de la tabla en un Dataset mediante codigo generado en mi documento aspx.cs
Hi, John.
Lo máximo el tutorial, busqué y busqué hasta que hallé tu tutorial . Lo máximo. Muchas gracias.
Trabajo con Visual Studio 2008 SP1 y framework 3.5 y tengo un problema pues las barras aparecen con el mismo valo (mismo tamaño) a pesar que tienen distintos valores.
Me podrías ayudar con eso, por favor
muy buen ejemplo, aun que dure casi tres dias haciendo que funcionara. porque? pues por que cuando hacia la consulta no usaba AS para que el nombre de la columna que me regresa la consulta coincidiera con la tabla que habia creado en el diseñador. un pequeño detalle que pase por alto. espero que no les pase lo mismo 😀
hola a todos porfa necesito urgente hacer un reporte con filtros utilizando xtrareport con punto. net si alguien tiene sabe como se lo agradecere mucho.
Hola, estube leyendo tu post y me parecio muy bien lo del reporte, quisiera ver si me puedes ayudar, tengo una aplicacion de escritorio y en un formulario quiero mostrar el reporte llamado Rporte1.rdlc ya me muestra los datos de la tabla pero no se como porque razon no hace caso a la consulta sql que le envio y para mas detalle pongo mi codigo para ver si me puedes ayudar, gracias
BindingSource bindingSource1 = new BindingSource();
string consulta = «»;
consulta = «SELECT EMPEÑOS.id_empeño, PRENDAS.id_prenda, PRENDAS.tipo, PRENDAS.subtipo, PRENDAS.descripcion, PRENDAS.calidad, PRENDAS.peso,PRENDAS.mutuo, PRENDAS.avaluo FROM EMPEÑOS INNER JOIN PRENDAS ON EMPEÑOS.prenda1 = PRENDAS.id_prenda WHERE (PRENDAS.tipo = ‘Joyeria’)»;
string cadena = obj.Cadena;
SqlConnection olecn = new SqlConnection(cadena);
SqlCommand olecmd1 = new SqlCommand(consulta, olecn);
DataSet1 ds = new DataSet1();
SqlDataAdapter a = new SqlDataAdapter(olecmd1);
DataTable dt = new DataTable();
a.Fill(dt);
dt = ds.Tables[«PRENDAS»];
bindingSource1.DataSource = dt;
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
dataGridView1.DataSource = bindingSource1;
ReportDataSource datasourse = new ReportDataSource(«DataSet1_PRENDAS», dt);
reportViewer1.LocalReport.DataSources.Add(datasourse);
reportViewer1.RefreshReport();
Prueba quitarle esta linea:
dt = ds.Tables[«PRENDAS»];
pues ya el a.Fill (dt) solamente, debe llenar el DataTable con los datos de tu consulta.
Hola, Quite la linea pero sigue sin funcionar la consulta no se que pueda estar mal en el codigo ya que hace la consulta pero no la muestra en el reporte.
Uhmmm mira, antes de agregar el nuevo ReportDataSource a la colección de DataSources del informe, quizás tengas que vaciarla primero, pues debe estar tomando la implícita que fue la ficticia que pusimos en la definición del informe y que por supuesto no tiene datos. Quedaría asi:
ReportDataSource datasourse = new ReportDataSource(“DataSet1_PRENDAS”, dt);
reportViewer1.LocalReport.DataSources.Clear(); // <<==== AGREGAR ESTA LINEA
reportViewer1.LocalReport.DataSources.Add(datasourse);
Muy buen ejemplo, pero tengo una duda y la quisiera comentar con ustedes:
Estoy trabajando con Visual Basic .net, en visual estudio 2008.
El tema es que el reporte, por algun motivo no se ve. He realizado pruebas, agregando errores forzados, pero aun asi no arroja el error (como por ejemplo poner otra extencion al reporte).
He analizado el codigo y no puedo encontrar el error. Por favor hechenme una mono, gracias.
Public Function RptProve() As DataTable
Dim Sql As String
Sql = «SELECT rutprov,prov,Direprov,ciudad,fonoprov FROM proveedores»
Try
Dim DA As New MySqlDataAdapter(Sql, Cnn)
Dim DS As New DataSet
DA.SelectCommand.CommandType = CommandType.Text
DA.Fill(DS, «Proveedores»)
Return DS.Tables(«Proveedores»)
Catch
MsgBox(«Existen problemas»)
End Try
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim rds As ReportDataSource = New ReportDataSource()
rds.Name = «DSProve_DTProv»
rds.Value = RptProve()
RVProve.LocalReport.DataSources.Clear()
RVProve.LocalReport.DataSources.Add(rds)
RVProve.LocalReport.ReportPath = «ProveRpt.rdlc»
RVProve.LocalReport.Refresh()
End Sub
RVProve.RefreshReport()
Muy bueno este artículo. Excelente. Gracias!!!!
Lo único que me faltaba era el import «Imports Microsoft.Reporting.WebForms»
Una pregunta. Sabrás si se puede capturar el evento click sobre una fila y extraer el valor de algunos campos de la fila?
EXCELENTE EJEMPLO, ESTOY COMENZANDO EN ESTO DE REPORTIN SERVICE, HE SEGUIDO LOS PASOS DEL EJEMPLO, Y TENGO EL SIGUIENTE PROBLEMA:
EN MODO DE DISEÑO DEL SITIO WEB EL INFORME SE CARGA CORRECTAMENTE, PERO AL COMPILAR Y SUBIR AL SITIO WEB, NO CARGA EL INFORME Y NO SE CUAL ES EL ERROR. SI ALGUIEN ME PUEDE AYUDAR LES AGRADESCO
Saludos,
Si alguien me puede ayudar por favor mi problema es el siguiente..
estoy haciendo un reporte con xtrareport y punto net en el cual coloco una imagen cualquiera, la imagen no esta en la base sino en un directorio, en en momento que visualizo el reporte esta la imagen, pero le ato mi reporte a un aspx y la imagen no aparece…
gracias por su ayuda.
nadie responde!!!! de que sirve el foro???
Saludos
Me gusto mucho el tutorial, quisiera saber como se hace lo mismo al utilizar tablas con un join entre 2 tablas !!
Si, de hecho el ejemplo mostrado usa JOINs con varias tablas, la preparación de la fuente de datos (DataSet) para el informe puede ser todo lo complicada que sea necesario; lo importante es la correcta asociación de los campos de este resultado final con los elementos del informe.
para ver sime pueden ayudar:
soy principiante para la realizacion del reportes en visual basic 2008
ya hice la prueba de como funciona el proceso realizando el proceso mediante el asistente de oriegne de datos.
lo que yo quiero es realizar el reporte mediante codigo, he probado con los codigos que algunos compañeros me ha dado pero nada. el error es el siguiente .
Error 1 El objeto ‘table1’ de tipo table se encuentra en el cuerpo del informe, pero el informe no tiene ningún conjunto de datos. No se permiten regiones de datos en informes sin conjuntos de datos. C:\Users\Adminitrador\Desktop\WindowsApplication2\WindowsApplication2\Report1.rdlc WindowsApplication2
adjunto el codigo
‘ espacio de nombres de las librerias
Imports System.Data ‘importa las librerias a trabajar con los datos
Imports System.Data.SqlClient ‘importa el cleinete que trabaja con losdatos
Imports Microsoft.Reporting.WinForms
Public Class Form1
Dim colBotones As New DataGridViewButtonColumn ‘CREO LA VARIABLE DE TIPO DE BOTON EL DATAGRID
Dim imprimir As New BindingSource
Dim sql As String
Dim imp As SqlCommand
Dim datos As SqlDataAdapter
Dim datos1 As DataSet
Dim datasourse As ReportDataSource
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
sql = «select Nom_Paciente from tbl_paciente»
imp = New SqlCommand
imp.CommandType = CommandType.Text
imp.CommandText = sql
imp.Connection = Cn
datos = New SqlDataAdapter(imp)
datos1 = New DataSet
datos.Fill(datos1, «tbl_paciente»)
imprimir.DataSource = datos1
datasourse = New ReportDataSource(«DataSet1», datos1)
ReportViewer1.LocalReport.DataSources.Clear()
ReportViewer1.LocalReport.DataSources.Add(datasourse)
ReportViewer1.RefreshReport()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call ConectarDB()
ReportViewer1.LocalReport.ReportPath = «Report1.rdlc»
Me.ReportViewer1.RefreshReport()
End Sub
End Class
espero una colaboracion por parte de ustedes.
Hola amigo excelente tutorial pero por favor podrias indicar como hacer un reporte con parametros
gracias
Hola, muy bueno elaporte de verdad, a mi me sirvio muchisimo la aplicacion con matrices. creo que ahora he aprendido muchisomo de report viewer, pero tengo una pregunta y ojala puedan contestarmela lo mas rápido posible, resulta que hice mi aplicacion en asp.net 2005 y c# con reportes en report viewer, eso en win 2003 server me funciona barbaro, pero en linux centos 5.4 como le hago para que funciones los reportes hechos con reportviewer, si hay alguien que me pueda ayudar, se lo agradecería.
Tambien respondiendo a la pregunta de VHSO, solo te vas al menu dentro del reporte, y seleccionas report parameters y añades los parametros que desees por ejemplo docente (nombre del parametro) seleccionas el tipo de parametro y listo ahora, para pasarle desde asp.net con codigo c# lo ago asi
ReportParameter param1 = new ReportParameter(«docente», ddlProfesor.SelectedItem.ToString());
ReportParameter[] p1 ={ param1 };
rpvNotasHQ1.LocalReport.SetParameters(p1);
ddlProfesor es el control desde donde paso el parametro y listo ya solo debes añadir un textbox y
agregar esta linea en el
=Parameters!docente.value
ojala sea de ayuda
En que parte del reporte defino la funcion RowNumber(Nothing) o donde la configuro?
Disculpa soy nuevo con el manejo de este control. Es posible colocar en cajas de texto datos distribuidas sobre mi repote datos que obtengo de una consulta?
a mi da un problemita, yo quiero mostrarlo en una aplicacion desktop, pero no reconoce la funcion ReportDataSource rds = new ReportDataSource(); me dice que no puede hayarlo, me falta alguna directiva para que lo reconozca???
esto es lo que estoy haciendo, pero no me esta cargando los datos y no logro identificar que es lo que esta mal, es con una base de datos en acces
co-> es un objeto de una clase conexion donde se conecta a la base de datos
public DataSet Calculardataset()
{
string cadenainstruccionSQL = «select * from Acta_Consumo where Acta_Consumo.Id=4»;
co.oconectar.Open();
co.ocomando = co.oconectar.CreateCommand();
co.ocomando.CommandText = cadenainstruccionSQL;
OleDbDataAdapter adapter = new OleDbDataAdapter(co.ocomando);
DataSet datareport = new DataSet();
adapter.Fill(datareport, «tablareport»);
co.oconectar.Close();
return datareport;
}
no logro encontrar la parte de sección de DataSets del RDLC
Tengo un problema no reconoce la funcion ReportDataSource rds = new ReportDataSource(); me dice que no puede hayarlo
Muy buen aporte… gracias… pero necesito unas ayudas adicionales,pues tengo una aplicación web la cual cuenta con reportes, por favor necesito ejemplos sobre el Microsoft ReportViewer pero usando parametros, en este caso que el parametro se obtenga de un DropDownList.
La aplicación está en 3 capas.
Gracias nuevamente.
Gracias. Buen post. Me ha sido util
Juan Pedro, realmente tu aporte ha sido muy valioso y me dio lo que realmente quería hacer.
Lo único a lo que no le pude llegar fue a hacer el DataSet “ficticio”, así que esto lo hice de una forma mucho más complicada, pero que al final también me funcionó.
Si alguien pudiera darme un enlace de un video para entender bien como se hace el DataSet «ficticio» lo agradecería mucho. Yo uso C# 2010, por aquello de que este dato sea importante.
Con respecto a la pginacion cuando le cambias la propiedad de AsyncRendering=False y SizeToReportContent=True para que no halla problema con la paginacion debes colocar llamar al metodo protected void MostrarInforme() en el evento init del reportviewer
HOLA A TODOS
COMO PUEDO PASAR UN INFORME.RDLC A U PRINTPREVEWDIALOG Y UN PRINTDOCUMENT
Muy buen material, excelente, ahora bien, el ejemplo que usas es los reportes locales (.rdlc), ahora bien, ¿hay alguna manera de realizar misma funcionalidad, pero para un reporte remoto?, es decir un archivo .rdl, que esta alojado en un servidor de informe, y se requiere que el origen de datos cambie dinamicamente. Gracias de antemano.
hay alguna manera de que el usuario seleccione los campos que quiere que aparecen en el informe desde un form de visual studio………….
Buenoas, estoy teniendo un problema y no se bien como solucionarlo.
Realize una aplicacion Web que necesita mostrar un formulario para imprimir. Para ello completa un formulario y al enviar habro otra pagina web con un reportViewer. En en load de la pagina de reporte seteo el reporte que es de tipo LocalReport, ya que por un solo reporte me parecia mas complicado configurar un Servidor de Informes.
El problema que el reporte que quiero generar es de Solicitud de Usuario, entonces esta dentro de una seccion del Sitio Web donde no necesita loguearse. El problema es el siguiente: Con el codigo que copio abajo cuando ejecuto el reporte no termine de generarse nunca y aveces me pide (en el reporte!) usuario y contraseña:
ReportViewer1.ShowCredentialPrompts = false;
// Habilitar hipervínculos para manejar clic en el ID del cliente
// Necesario ya que la imagen del logotipo
ReportViewer1.LocalReport.EnableExternalImages = true;
ReportViewer1.LocalReport.ExecuteReportInCurrentAppDomain(System.Reflection.Assembly.GetExecutingAssembly().Evidence);
ReportViewer1.LocalReport.SetParameters(rp);
ReportViewer1.LocalReport.Refresh();
en cambio si le agrego la siguiente linea funciona correctamente donde ‘2035425435244’ es el id de usuario que corrresponde con el CUIT
-FormsAuthentication.SetAuthCookie(«2035425435244», false);
Obviamente debe ser un tema de Seguridad pero no se como resolverlo, ya que con la solución que le encontré(lo de agregar esa línea) luego entra al sitio a la parte donde no debería entrar si no tiene autorización.
Ademas en el web.config tengo la exclusion.
Si alguien puede ayudarme. Muchas gracias
Juan criei um dataset com xml e queria no report vincular esse dataset sendo que quando no report seleciono reportdata new dataset esse dataset nao aparece, criei esse dataset no projeto na pasta relatorio/xds.
Ou só posso vincular o dataset vindo de um tableadapter ?
Hola que tal, estoy haciendo un proyecto en Visual Studio 2010, donde tendo un reporte rdl creado con ReportBuilder 2.0 en ProcessingMode=Local. Mi App es en WinForms, el tema es el siguiente:
Ej: tengo un datatable con clientes como filas, y tengo que generar un reporte por cada linea del datatable, el problema es que cuando el asigno al ReportViewer el datatable solo me un reporte con los datos del primer cliente. Yo quisiera que me genere tanto reportes como filas tenga el datatable y despues mandar a imprimir.
Alguna sugerencia?? no logro dar con la solucion.
Muchas Gracias
Buen dia, excelente post, pero tengo un problema, estoy trabajando con windows form, cuando carga el reporte no muestra nada, ni dice que se esta generando el reporte. Utilice la segunda opcion creo el archivo xml con un sp de la base de datos que contendra la extructura donde estaran los datos, Ya verifique y si esta llegando el dataset con la informacion que necesito. Sin embargo no lo muestra. Podrian ayudarme por favor. Muchas gracias.
Mi problema es el siguiente, necesito que en el reportviewer los objetos se los pueda ubicar en diferente posició per en tiempo de ejecución, ya que en crystal reports si hay como hacer eso, alguien podría ayudarme?
Saludos tienes un ejemplo por favor
Hola
A alguien no le salio un error como error al procesar el informe. Dataset1
hola, teng un problema, el informe sale con los titulos pero los datos no se llenan, no sabras que pueda ser??
Por favor ayudenme, al cargar el reporte sale en blanco y solo aparece «No se ha proporcionado ninguna instancia de origen de datos para el origen de datos «DataSet1», a que se puede deber esto???
Estimado amigo es posible que pueda imprimir el reporte desde un botón ajeno a reportviewer?
Hola, tengo un proyecto Web con .Net 2008, cuando ejecuto el ReportViewer en modo Local me muestra los datos pero cuando lo subo al servidor me muestra el reporte pero sin datos. No me muestra ningún mensaje de error. Si me pueden ayudar lo agradecería mucho!
Att: Cesar Osorio
Solucionado, el administrador del servidor tenia los reportes bloqueados.
Realice un Reporte con ReportsPreviewer me genera y todo me sale perfecto pero al momento de crear algun filtro no me visualiza los metodos.
este codigo lo estoy ingresando en un boton para visualizar y agregar parametros.
Me.SqlDataSource1
Me.ReportViewer1.
Muchas gracias Brother, me has salvado la semana
Gracias por la publicación, yo aplique el segmento de código MostrarInforme() para crear y cargar en tiempo de ejecución los rdlc, generar pdfs y exportarlos, utilice un SP para asignarlo al .value del ReportDataSource.
Una ayuda, tengo un report viewer, estoy manejando imagenes en barrido, osea meto una imagen en un lisp y el reporte me salen 3 fotos hacia abajo y esta bien ahora habra una forma de que el barrido no sea habia abajo, si no lateral, ya le he buscado y no encuentro nada, gracias
Hola johnbarquin,
Muy bueno tu aporte !!!!.
Estoy desarrollando una aplicación WinForm con ReportViewer para datos dinámicos y tengo el siguiente problema :
Dentro del archivo .rdlc inserto un objeto tabla, coloco el nombre de las columnas.
No entiendo bien donde debo colocar el dataset, si es dentro del informe ó dentro del form que contiene al objeto reportviewer. Porque cuando lo coloco dentro del informe no lo enlazo a ningún origen de datos porque lo hago desde el form pero no puedo compilar el proyecto porque falta el origen de datos.
Muchas gracias.
Muy buen aporte
Una pregunta si por algun motivo se requiere mas de una consulta por ejemplo 2 consultas(Cabezera y Detalle), tendria 1 DATASET con 2 DATATABLES, entonces como prodria hacerle para asignarle al LocalReport.DataSources el «dataset» y NO el datatable(0) o tedria que agregar los 2 datatables datatable(1) y datatable(2) ???
Para ver si me puedes ayudar y explicar un poco mas ya que la experiencia que tengo es muy poca.
Gracias
Interesante Codigo lo pruebo para hacer una dll para reportes si todo sale bien retroalimento
saludos
Saludos, compañeros:
Seguí los pasos de esta entrada para un reporte con la versión de Visual Studio 2012, pero no me está funcionando. Se muestra el viewer en blanco, aun cuando el DataTable que le asigno tiene datos y el DataSet tiene el mismo nombre en el reporte. Alguna Idea:
Public Sub CargaReporteTickets(Tick_Grupo As String)
Try
Dim ObjTicket As New clTicket
Dim ds As New DataSet
ds = ObjTicket.ConsultarTicket(Tick_Grupo)
Dim rds As New ReportDataSource()
rds.Name = «SP_ReporteTicket»
ds.Tables(0).TableName = «SP_ReporteTicket»
rds.Value = ds.Tables(0)
RV.LocalReport.DataSources.Clear()
RV.LocalReport.DataSources.Add(rds)
RV.LocalReport.ReportPath = «ReporteTickets.rdlc»
RV.LocalReport.Refresh()
Catch ex As Exception
MessageBox.Show(«Ha ocurrido un error cargando los tickets.» + ex.Message())
End Try
End Sub
Saludos,
me sale este error alguien que pueda ayudarme a resolverlo
Se ha producido un error durante el procesamiento local de informes.
No se ha especificado la definición del informe ‘ReportP’
Referencia a objeto no establecida como instancia de un objeto.