Bem vamos nos aprofundar em Dynamic Crystal Reports de C#Normalmente Crystal Reports e gerado com colunas pre-definidas,Ou seja, os campos mostrados no Crystal Reports estao selecionados atraves de um assistente na hora do Crystal Report design .O programa a seguir descreve como gerar um cristal report em C # com dynamic columns no momento da geracao de relatorios. Ou seja, nao estamos selecionando qualquer coluna da tabela do banco no momento do Crystal Report Design. Em vez de que estamos passando uma consulta SQL string e obter o Crystal Report dinamicamente em tempo de execucao em C #. A partir da imagem abaixo voce pode entender como ele funciona.Strongly Typed Dataset. Aqui estamos limitando em cinco colunas, mas voce pode adicionar qualquer numero de coluna de acordo com suas necessidades de relatorios.Proximo passo e criar um projeto de Cristal Reports da Strongly Typed dataset. Voce tem que adicionar um Crystal Report em seu projeto e como data source selecione Strongly Typed dataset.Selecione todas as 5 colunas de Strongly Typed dataset :Clique no botao Concluir,Entao voce pode ver os campos selecionados no Crystal Reports .Organize os campos de acordo com seus criterios.Aqui estamos indo passar as instrucoes SQL para o Crystal Reports em runtime de C #. Por que temos que analisar a instrucao SQL antes de passa-lo para o Crystal Reports. Entao nos criamos uma funcao para analisar instrucoes SQL no programa C #.ProcesSQL Funcao Publica () As StringVoce tem que incluir CrystalDecisions.CrystalReports.Engine em seu codigo-fonte C #.using CrystalDecisions.CrystalReports.Engine;using CrystalDecisions.Shared;using System;using System.Windows.Forms;using CrystalDecisions.CrystalReports.Engine;using CrystalDecisions.Shared;using System.Data;using System.Data.SqlClient ;namespace WindowsApplication1{ public partial class Form1 : Form { CrystalReport1 objRpt = new CrystalReport1(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { SqlConnection cnn ; string connectionString = null; string sql = null; connectionString = "data source=SERVER NAME;initial catalog=crystaldb;user id=USER NAME;password=PASSWORD;"; cnn = new SqlConnection(connectionString); cnn.Open(); sql = procesSQL(); SqlDataAdapter dscmd = new SqlDataAdapter(sql, cnn); DataSet1 ds = new DataSet1(); dscmd.Fill(ds, "Product"); objRpt.SetDataSource(ds.Tables[1]); crystalReportViewer1.ReportSource = objRpt; crystalReportViewer1.Refresh(); } public string procesSQL() { string sql = null; string inSql = null; string firstPart = null; string lastPart = null; int selectStart = 0; int fromStart = 0; string[] fields = null; string[] sep = { "," }; int i = 0; TextObject MyText ; inSql = textBox1.Text; inSql = inSql.ToUpper(); selectStart = inSql.IndexOf("SELECT"); fromStart = inSql.IndexOf("FROM"); selectStart = selectStart + 6; firstPart = inSql.Substring(selectStart, (fromStart - selectStart)); lastPart = inSql.Substring(fromStart, inSql.Length - fromStart); fields = firstPart.Split(','); firstPart = ""; for (i = 0; i <= fields.Length - 1; i++) { if (i > 0) { firstPart = firstPart + ", " + fields[i].ToString() + " AS COLUMN" + (i + 1); firstPart.Trim(); MyText = (TextObject) objRpt.ReportDefinition.ReportObjects[i+1]; MyText.Text = fields[i].ToString(); } else { firstPart = firstPart + fields[i].ToString() + " AS COLUMN" + (i + 1); firstPart.Trim(); MyText = (TextObject)objRpt.ReportDefinition.ReportObjects[i+1]; MyText.Text = fields[i].ToString(); } } sql = "SELECT " + firstPart + " " + lastPart; return sql; } }}OBS : connectionString = "data source=SERVER NAME;initial catalog=crystaldb;user id=USER NAME;password=PASSWORD;"; Voce precisa preencher as informacoes necessarias para conectar o database atraves da Connection String. A