ドリンクバーゲン会場

文字化け対策 ― 2010年11月04日 15時36分29秒

前回、PDFで出力すると文字化けする状態で、
直接プリンターに出力すれば回避できるのではないかと
思っていたのですが、残念ながらダメでした。

直接プリンターに出力する方法は確認できたのですが、
それでも外字は文字化けする結果となりました。

いろいろ調べてみると、外字の処理をサーバーでさせる場合、
EUDCに外字を登録する必要があるのですが、
ここでは、外字ソフトを使っていて、
EUDCには外字は入っておらず、
サーバーから直接プリントしても外字は表示されないのです。

そこで今回は外字データを使っている氏名や学校名などは、
すべて画像処理することにしました。

外字データが使われている数は登録されているデータのなかで、
100件ほどで、それほど多くなく、学年毎には10~20件ほどで、
それほど多くないので、入学時に作成し外字を使う場合だけ、
画像を呼び出すことにしました。

今まではPCのリースアップで外字ソフトをインストールしなおす必要が
ありましたが、画像にすることで必要なくなりますし、
作業用のPCが増えても追加購入する必要もなくなりコストも抑えられると
思うので、今回は画像を作成しました。

CrystalReportへの抽出データの引き渡し ― 2010年10月27日 11時45分55秒

CrystalReportでの抽出ができるようになったので、
Web画面から抽出条件を引き渡すようにしていきます。
今回は、セッションを使うことにしました。
理由は一番簡単かなと思ったからです。

抽出用の画面を作り、そこから抽出条件を作ります。
抽出条件はクラス全員と個別の2パターンあります。

クラスの場合は、年度とクラスを抽出条件にし、
個別の場合は生徒番号を抽出条件に指定します。

抽出自体はそれほど難しい処理ではないので、
すぐに条件にあったレポートが表示されるようになりました。

ところがここで思っていなかった問題が出てきました。
実は、レポート印刷では、いままで「rpt」ファイルを
VisualStudioのプレビューから印刷していたのですが、

今回Web経由で初めて印刷したところ、
プレビューの時は直接プリントアウトされていたのが、
AdobeReader経由となり、外字が文字化けしてしまうのです。

Web画面上では正常に表示されているのですが、
Reader経由では文字化けになるので何か対策が必要ということになりました。

調べてみると、直接プリンターに出力できるようなので、
これから調査してみます。

印刷データの抽出 ― 2010年10月23日 09時37分19秒

CrystalReportで印刷を行うに当たり、残る一つの問題がデータの抽出です。
現状では全件データが表示されてしまっているので、
印刷したいデータのみ抽出する必要があります。

ネットでいろいろ調べてみたのですが、やっぱりなかなか情報が見つからず、
今回もサンプルを参考にしました。

チュートリアルに「選択式を使用したフィルタ」というのがあったので、
そのサンプルを見てみました。

サンプルでは、フォーム上で抽出する情報をセットし、ボタンのクリックで
更新するようになっていたのですが、
今回私が行いたいのは、CrystalReportに直接抽出条件を引き渡す方法ですが、
このサンプルでできそうだったので、試してみます。

サンプルでは、ボタンのクリック時に処理が発生するのですが、
ConfigureCrystalReports()の中にも初期値を設定していました。
ConfigureCrystalReports()は前回データベース接続の設定を入れた場所ですので、
今回もここに設定を追加することで抽出ができると思い設定を追加しました。

******************************************************
Private Sub ConfigureCrystalReports()
  Dim reportPath As String = Server.MapPath("レポートファイル")
  CrystalReportViewer1.ReportSource = reportPath
   Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
   SetDBLogonForReport(myConnectionInfo)
  myConnectionInfo.ServerName = "サーバー名"
   myConnectionInfo.UserID = "ユーザー名"
   myConnectionInfo.Password = "パスワード"
End Sub
******************************************************

上記が前回作成したConfigureCrystalReports()サブです。
ここに抽出用の条件を追加していきます。

******************************************************
Private Sub ConfigureCrystalReports()
<==== ここから
If Not IsPostBack Then
Dim mySelectFormula As String = "{学籍情報.ID} = '学籍番号'"
CrystalReportViewer1.SelectionFormula = mySelectFormula
End If
ここまで ====>
  Dim reportPath As String = Server.MapPath("レポートファイル")
  CrystalReportViewer1.ReportSource = reportPath
   Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
   SetDBLogonForReport(myConnectionInfo)
  myConnectionInfo.ServerName = "サーバー名"
   myConnectionInfo.UserID = "ユーザー名"
   myConnectionInfo.Password = "パスワード"
End Sub
******************************************************

抽出条件を追加したのが上のソースです。
"{学籍情報.ID} = '学籍番号'"
が抽出条件になります。
'学籍番号'に抽出したい番号を登録します。
今回はテストなので、とりあえず学籍番号は直接設定して動かしてみました。
しかし、抽出されずに全件表示されているようです。

サンプルと同じようにしているのですが、抽出されないので、
なにがおかしいのかよくわかりませんでしたが、
デバッグを続けているうちに、おかしなことに気が付きました。

と言うのも、
CrystalReportViewer1.SelectionFormula = mySelectFormula
で抽出条件をセットしているのに、セットした情報が消えているのです。
ステップ実行すると、確かに最初はセットされているのですが、
そのあとのレポートファイルのセットを行うと内容がクリアされてしまうようです。

サンプルではこの順番で記述されているのですが、
消えているのが原因とすれば逆にしたら抽出条件が消えなくなるのではないかと思い、
やってみました。

******************************************************
Private Sub ConfigureCrystalReports()
<====上に移動
  Dim reportPath As String = Server.MapPath("レポートファイル")
  CrystalReportViewer1.ReportSource = reportPath
ここまで ====>
If Not IsPostBack Then
Dim mySelectFormula As String = "{学籍情報.ID} = '学籍番号'"
CrystalReportViewer1.SelectionFormula = mySelectFormula
End If

この場所から

   Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
   SetDBLogonForReport(myConnectionInfo)
  myConnectionInfo.ServerName = "サーバー名"
   myConnectionInfo.UserID = "ユーザー名"
   myConnectionInfo.Password = "パスワード"
End Sub
******************************************************

逆にレポートファイルの設定が消えるなんてことはないかちょっと心配だったのですが、
実行してみると、今度はちゃんと抽出されていました。
ステップ単位で確認してみても抽出条件は消えずに残っていたので、
やはりレポートファイルを登録する際に、抽出条件をクリアしているようです。

まあ多少のトラブルはありましたが、これで抽出に関しても問題なさそうです。
あとは、抽出条件をどうやってCrystalReportに引き渡すかです。

レポートのログオンを自動化する。 ― 2010年10月21日 15時20分57秒

学籍のレイアウト通りにデータを出力することは
ほぼできました。表示位置の微調整などは必要なのですが、
それはまた行うとして、実装にむけての問題があと2つ残っています。

一つは、CrystalReportで学籍情報を表示する際、パスワードを入力しないと
接続できません。
調べたところ、セキュリティ上の問題から、パスワードは保存できないように
なっているそうです。
でも実運用ではパスワードの入力をその都度行うわけにはいかないので、
パスワードの入力をしなくても動くようにする必要があります。

もう一つは、データの抽出です。
生徒単位の抽出やクラス単位での抽出を行う必要があるのですが、
Web画面からどのように設定するのかを調べる必要があります。

以上の2つを調べる必要があるのですが、まずは一つ目のパスワードの設定を
調べてみました。

相変わらず情報が少なめで苦労したのですが、CrystalReportのサンプルを参考に
解決しました。
もっとも参考というよりも丸ごとコピーなのですが・・・(*^_^*)

学籍印刷用のファイルは、「gakuseki1.aspx」と「gakuseki1.aspx.vb」に
分かれていて、コードは「gakuseki1.aspx.vb」です。

以下はコードの中身です。
*********************************************
  Imports CrystalDecisions.Shared
  Imports CrystalDecisions.CrystalReports.Engine
  Imports CrystalDecisions.Web

  Partial Class _Default
  Inherits System.Web.UI.Page
<=== 追加した内容
   Private Sub ConfigureCrystalReports()
   Dim reportPath As String = Server.MapPath("レポートファイル")
  CrystalReportViewer1.ReportSource = reportPath
   Dim myConnectionInfo As ConnectionInfo = New ConnectionInfo()
   SetDBLogonForReport(myConnectionInfo)
  myConnectionInfo.ServerName = "サーバー名"
   myConnectionInfo.UserID = "ユーザー名"
   myConnectionInfo.Password = "パスワード"
   End Sub

   Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
   ConfigureCrystalReports()
   End Sub

  Private Sub SetDBLogonForReport(ByVal myConnectionInfo As ConnectionInfo)
  Dim myTableLogOnInfos As TableLogOnInfos = CrystalReportViewer1.LogOnInfo
   For Each myTableLogOnInfo As TableLogOnInfo In myTableLogOnInfos
   myTableLogOnInfo.ConnectionInfo = myConnectionInfo
  Next
   End Sub
ここまで  ===>
  End Class
*********************************************

<=== ===>ではさまれている部分が追加したところです。
サンプルをコピーして必要なところを変更しています。

変更箇所は上から2行目
Dim reportPath As String = Server.MapPath("レポートファイル")
カッコ内です。レポートファイルを入力するので、作ったレポートファイルの名前に変更します。
サンプルでは、「NorthwindCustomers.rpt」になっているのですが、作成したファイル名にします。

その下、ビューワーも合わせる必要があります。
CrystalReportViewer1.ReportSource = reportPath
「gakuseki1.aspx」ファイルを確認し、「CrystalReportViewer1」の部分を変更します。
「SetDBLogonForReport」のところも同じように変更します。

あとは、サーバー名、ユーザー名、パスワードを自分の環境に合わせて変更します。

これで実行させれば、レポートがダイレクトに表示されました。

なんとか解決!? ― 2010年10月19日 13時03分50秒

クロス集計で止まっていたのですが、T-SQLを使わずに
表示が出せるようになりました。

正直このようなやり方が良いのかどうか、不安な面もあるのですが、
私の知識ではこれがベターだと思っています。

問題点をおさらいすると、科目ごとに評定と単位を表示するのですが、
指導要録のレイアウトに合わせるためには、教科ごとにデータを作らなければいけません。

クロス集計で学年別にデータを作成すると表にはできるのですが、
問題が出てきます。
例えば、教科によっては2年生の時にしか受けない科目や
1年と3年には受けるが2年の時には受けない科目が出てきます。

それでも、クロス集計を全科目で行えば各学年にそれぞれ1科目は入っているので、
なにも問題はないのですが、科目毎にクロス集計を行う場合には問題が発生します。

例を挙げると、家庭科の授業は2年生の時にしか行っていません。
レイアウトでは、左から1年、2年、3年と順番に表示させるのですが、
家庭科の授業では1年のところに2年の評定と単位が入ってしまいます。

最初はT-SQLの使用も考えていたのですが、ダミーのデータがあれば
いけるはずなので、新規に登録することなくダミーのデータをもぐりこませる
方法はないか考えました。

その結果、在籍データと科目データを使ってダミーのデータを作ることができるようになりました。
在籍データには、学年毎の在籍情報が登録されています。
3年生であれば、1年生から3年生までの3件のデータがあるのですが、
その情報と科目データの情報を組み合わせます。

*****************************************************
SELECT dbo.在籍.年度, dbo.科目.科目コード, dbo.科目.科目名, dbo.在籍.クラス番号, dbo.在籍.学籍番号, 0 AS 平均値, 0 AS 単位, 0 AS 評定, ' ' AS 記録,
LEFT(dbo.科目.科目コード, 2) AS グループ
FROM dbo.履歴 CROSS JOIN
dbo.科目
*****************************************************

こんな感じでビューを作成しました。
ダミーのデータなので、評定や単位は0が入っています。
項目は評定テーブルに合わせているので、
評定テーブルとUNIONクエリーを使い、
合わせたものでサブレポートを作成します。
そうすると、先ほどの例でいえば、家庭科にも1年生と3年生のダミーデータが
存在するので、2年生のところに表示されるようになりました。

そして評定と単位を横に並べて表示する方法も解決しました。
評定と単位を一つのデータにしてしまうという方法をとりました。
SQLServerでビューを作成し、評定と単位をまとめ間にスペースを入れて一つのデータにしました。

*****************************************************
CAST(dbo.評定.評定 AS varchar(12)) + '   ' + CAST(dbo.評定.単位 AS varchar(12)) AS 記録,
*****************************************************
上記のような指定でデータを一つにまとめています。

これでレイアウトに合わせて印刷ができるようになったので、
前に進めるようになりました。