0
votes

I'm new to Crystal Reports and trying to maintain someone else's code -- so bear with me. I have a crystal report that is tied to a DataSet with 2 related DataTables.

enter image description here

enter image description here

I'm grouping by JurorProfile.JurorPK. In my Group Header, I display information from the JurorProfile DataTable.

In the report detail, I have RowNumber, JurorQuestionAnswers.Question and JurorQuestionAnswers.Answer.

In my c# code, I'm populating the data like this:


public void SetDataSource(AdoProvider provider, int sessionPK, int jurorPK)
{
   string commandText;
   AdoQuery query;

   commandText = $@"select j.* from Juror j
   where j.JurorPK in (select JurorFK from SessionJurorLink where SessionFK = @sessionId)
   {(jurorPK > 0 ? " and jurorPK = @jurorId" ? "")}
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader jReader = query.ExecuteReader(sessionPK, jurorPK);
   report.Database.Tables["JurorProfile"]
     .SetDataSource((IDataReader)jReader.DataReader);

   commandText = $@"select ... from JurorAnswers ...
   where sessionFK = @sessionId
   {(jurorPK > 0 ? " and jurorFK = @jurorId " : "")}
   order by JurorFK, Rank, ParentFK, QuestionPK
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader qaReader = query.ExecuteReader(sessionPK, jurorPK);
   report.Database.Tables["JurorQuestionAnswers"]
     .SetDataSource((IDataReader)qaReader.DataReader);
}

However, when my report runs, the Group Heading displays and I get a record number printed for each question but the Question and Answer are not displayed.

enter image description here

It would appear, that Crystal Reports is not mapping the data results from my second query to the DataTable.

What's even weirder is that JurorQuestionAnswers DataTable currently has a redundant Lastname and Firstname field. If I include those fields in the detail area (JurorQuestionAnswers.Lastname, JurorQuestionAnswers.Firstname), they actually show up -- the data was properly mapped.

What am I doing wrong?

Update - Image of Links Tab

enter image description here

2
If you inspect the content of report.Database, can you see that the data is really there? I notice you use two different names: JurorAnswers and JurorQuestionAnswers, but I think it is ok - but you want to check if those names must be the same... Third and last, check if you are linking the tables in crystal, in the tab "Link" that is displayed in the second image (this is not THE problem, but it can be ONE problem later).heringer
If I add code to loop through the reader values -- yes, the data is there in the reader. I tried inspecting the content of report.Database. It definitely shows both tables as well as the link between them but I wasn't able to find any kind of property that held data -- for either table.RHarris
Try to inspect the dataset using: dataset.WriteXml(...)heringer
Just to anticipate some thoughts to follow: I'm thinking in these possibilities: (1) the data is not there; (2) the names of columns and tables or types in the dataset are different from those defined for the rpt (do you use XSD file?); (3) something is suppressing the "invisible" fields (did you use the suppress formula?).heringer
I remembered one more thing: may you show the tab "Links" of your "Database Expert"? And what happens when you use the "preview" feature?heringer

2 Answers

1
votes

I finally got this to work. Basically, it involved replacing the DataSet that existed on the report with a new DataSet.

I had to change my code as follows:

public void SetDataSource(AdoProvider provider, int sessionPK, int jurorPK)
{
   string commandText;
   AdoQuery query;
   
   // ** Added Direct Reference to DataSet **//
   var ds = new QuestionAnswersData(); 

   commandText = $@"select j.* from Juror j
   where j.JurorPK in (select JurorFK from SessionJurorLink where SessionFK = @sessionId)
   {(jurorPK > 0 ? " and jurorPK = @jurorId" ? "")}
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader jReader = query.ExecuteReader(sessionPK, jurorPK);

   // ** REPLACED THIS LINE **//
   // report.Database.Tables["JurorProfile"]
   //  .SetDataSource((IDataReader)jReader.DataReader); 

   //** WITH THIS LINE **//
   ds.Tables["JurorProfile"].Load((IDataReader)jReader.DataReader, LoadOption.OverwriteChanges, null);  

   commandText = $@"select ... from JurorAnswers ...
   where sessionFK = @sessionId
   {(jurorPK > 0 ? " and jurorFK = @jurorId " : "")}
   order by JurorFK, Rank, ParentFK, QuestionPK
   ";
   query = provider.CreateQuery(commandText, null
      , provider.CreateParameter("sessionId", DbType.Int32)
      , provider.CreateParameter("jurorId", DbType.Int32)
   );
   AdoReader qaReader = query.ExecuteReader(sessionPK, jurorPK);

   //** REPLACED THIS LINE **//
   //report.Database.Tables["JurorQuestionAnswers"]
   // .SetDataSource((IDataReader)qaReader.DataReader); 

   //** WITH THIS LINE **//
   ds.Tables["JurorQuestionAnswers"].Load((IDataReader}jReader.DataReader, LoadOption.OverwriteChanges, null);

   //** NOW TIE THE DATASOURCE DIRECTLY TO THE REPORT **//
   base.SetDataSource(ds); 
}
0
votes

When you say "JurorQuestionAnswers DataTable currently has a redundant Lastname and Firstname field" I'm curious to know if, when you click on them in the dataset designer and look in the Expression property, you see something like Parent.Firstname (or whether the code contains anything like somedatatable.FirstnameColumn.Expression = "Parent.Firstname").

It's been a long time since I used CR, but my instant assumption is that CR cannot navigate DataRelations and someone worked this out and instead used the built in ability for a DataColumn Expression to reference other tables to conceptually import the parent data into the child table so that CR only has one table of data to deal with. CR will then preform a group on the parent columns itself (and because they reliably repeat the same data they group down to just one value) so you achieve the same effect, you just had to repeat the data

If this is the case, follow the pattern - if you want parent column X in the header, add a datacolumn (in the designer) to the child table, called ParentX (I like to put the word Parent in columns that are derived by relation, so people don't assume theyre redundant, but delberate), set its Experssion to Parent.X and then update/refresh your CR so it sees the new column and group on it