- PR -

MDBが更新される前にCrystal Reportが出力される。

投稿者投稿内容
sama
会議室デビュー日: 2006/02/22
投稿数: 4
投稿日時: 2006-02-22 15:14
初めて質問させて頂きます。

VB.NETでアプリケーションの開発をしております。

その中でOleDbConnectionでMDBにデータをINSERTし、CrystalReportを表示しているのですが、MDBにデータが更新される前にCrystalReportが表示されてしまう現象が出ています。
現象は、必ず発生するものではありませんが、頻繁に発生しています。
ちなみに、MDB更新時にはトランザクションをかけています。

どなたか何か分かる方がいらっしゃいましたら、教えてください。
以上、よろしくお願いいたします。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-22 15:19
引用:

samaさんの書き込み (2006-02-22 15:14) より:

その中でOleDbConnectionでMDBにデータをINSERTし、CrystalReportを表示しているのですが、MDBにデータが更新される前にCrystalReportが表示されてしまう現象が出ています。


ここ、どうやって確認されました?
おそらく非同期であると仰るわけですよね?

たとえば、CrystalReports がキャッシュを表示しているだけだとか、
そういった可能性はすべて排除していますでしょうか?

引用:

ちなみに、MDB更新時にはトランザクションをかけています。


とりあえずは一連のロジックを見ないと何とも。
通常、トランザクションを使わなくとも同期は取れてると思うのですが。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
sama
会議室デビュー日: 2006/02/22
投稿数: 4
投稿日時: 2006-02-22 16:01
現在開発している画面は、画面の一覧に表示しているデータの、選択行までをCrystalReportでプレビューするという機能なのですが、
選択行を変更して繰返し実行すると、たまに、前回の選択行までのデータが表示されることがあるので、「MDBにデータが更新される前にCrystalReportが表示されてしまう」
と予想したのですが・・・。
何か確認すべき点はありますでしょうか。

ロジックは以下のとおりです。
非常に長くなってしまって申し訳ありません。

Friend Sub prt_RG001
Dim cn As New Data.OleDb.OleDbConnection
Dim cons As String = "Provider=" & gIniData.MDBVergion & ";Data Source=" & gIniData.MDBPath & gIniData.MDBName
cn.ConnectionString = cons
cn.Open()
Dim trans As Data.OleDb.OleDbTransaction = cn.BeginTransaction()

'一覧の選択行までループする
For i = 0 To maxRow
Dim cmd As OleDbCommand = New OleDb.OleDbCommand(FileIO.LoadAsString("Nikkansaiten.RES", sqlFileName, shiftJis))
cmd.Transaction = oTrans
==パラメータの設定==
ret = com.OleDbCommand.ExecuteNonQuery()
Next

trans.Commit()

cn.close

Dim report As New ReportDocument
report.Load(gIniData.CryRepTmpPath & C_REPORTID_RG001)
report.Refresh()

'CryRepView_Load(report)
Dim frm As New CryRepView
'レポートオブジェクト、レポート名を指定する
gViewRptID.SetReportDoc = report
gViewRptID.SetReportNM = C_REPORTNM_RG001
'CrystalReportViewerを開く
frm.ShowDialog()
END SUB

'=============================
'クリスタルレポートプレビュー画面LOAD
'=============================
Private Sub CryRepView_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
'クリレポのインスタンスを作成
Dim rp As New ReportDocument
Dim tbCurrent As CrystalDecisions.CrystalReports.Engine.Table
Dim tliCurrent As CrystalDecisions.Shared.TableLogOnInfo

rp = gViewRptID.ReportDoc
For Each tbCurrent In rp.Database.Tables
'ログイン情報を取得する
tliCurrent = tbCurrent.LogOnInfo
'ログオンするための接続情報を取得する
With tliCurrent.ConnectionInfo
.ServerName = gIniData.MDBPath & gIniData.MDBName
End With
'DBに接続する
tbCurrent.ApplyLogOnInfo(tliCurrent)
Next tbCurrent
CrystalReportViewer1.ReportSource = rp
End Sub
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-22 16:23
中間を担うコードが少し不足していますので、多少誤解があるかもしれません。

引用:

samaさんの書き込み (2006-02-22 16:01) より:

Dim report As New ReportDocument
report.Load(gIniData.CryRepTmpPath & C_REPORTID_RG001)
report.Refresh()


ここで Refresh メソッドですか...

引用:

gViewRptID.SetReportDoc = report
gViewRptID.SetReportNM = C_REPORTNM_RG001[/code]


g プレフィクスから始まるのはグローバル変数ですか... orz
Preview を表示する Form に直接渡せば良いと思います。

引用:

'クリレポのインスタンスを作成
Dim rp As New ReportDocument[/code]
''' (省略) '''
rp = gViewRptID.ReportDoc


インスタンス化する必要がないですよね。
gViewRptID (おそらくはグローバル変数) に渡したものに上書きされます。

引用:

CrystalReportViewer1.ReportSource = rp


Refresh メソッドはこの直前か直後に呼び出すべきなのではないでしょうか?

それと、本件とは関係ないところですが、データベースの処理のところ、
ちゃんと Try 〜 Finally で Close と Dispose を保証してあげてください。

  オブジェクトの破棄を保証する

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
sama
会議室デビュー日: 2006/02/22
投稿数: 4
投稿日時: 2006-02-22 17:51
返信ありがとうございます。
以下の箇所を修正してみましたが、結果は変わりませんでした。

==ReportDocumentをNEWしない。
'Dim rp As New ReportDocument
→Dim rp As ReportDocument

==Refreshの場所を変更
rp.Refresh()
rp.SetParameterValue("JigyoshoNm", gIniData.JigyoshoNm())
CrystalReportViewer1.ReportSource = rp
(この直後にRefreshをすると、パラメータを聞かれてしまうので、できませんでした。)

また、クリスタルレポートのレポートオプションの
「最初の最新表示時に照合」をチェックOFFからONに直しましたが、こちらも結果は変わりませんでした。

尚、ご忠告頂いた、Try 〜 Finally の処理は、書込みが長くなってしまうと思い、省いて貼り付けてしまいました。ありがとうございました。




じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-02-22 19:53
引用:

samaさんの書き込み (2006-02-22 17:51) より:

以下の箇所を修正してみましたが、結果は変わりませんでした。


すいません。(;_ _)

とりあえず、MDB 更新後に Thread.Sleep(1000) などを入れて、(秒数は調整してください)
何パターンか、何度か試してみて頂けますでしょうか?

これで再現しない場合は、同様のパターンを Thread.Sleep メソッドを抜いた状態で試して頂けますか?
後者だけで再現するのであれば、非同期になっているということになるでしょう...

# こういうのって ADODB 時代の頃だけかと思っているのですが...

あとは... OleDbConnection_StateChange イベントで Close 後に、
レポートのソースを生成しているかどうかを見るくらいしか思いつきません...

要所要所に Console.WriteLine メソッドをおいて、Closed の後に、
順番どおりに帳票の生成に取り掛かっているかどうかを見るわけです。

お力になれず、申し訳ないです。(;_ _)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-02-22 21:15
引用:

じゃんぬねっとさんの書き込み (2006-02-22 15:19) より:

とりあえずは一連のロジックを見ないと何とも。


じゃんぬさんにじゃなくて。

 ロジック != ソースコードでお願いします。アジャイルでなくても、一読の価値ありです。→第1回 アジャイル開発ではドキュメントを書かないって本当?
 特に、4ページ目をお読みください。自分のコードが自分がしたいことを表現しているかどうか、それを検証すれば、たいていの問題は自力で解決できます。

〆 written by Jitta@わんくま同盟 on 2006/02/22
sama
会議室デビュー日: 2006/02/22
投稿数: 4
投稿日時: 2006-02-23 12:41
Thread.Sleep(3000)で、現象は出なくなり、Thread.Sleepをはずすと現象が再現してしまいます。

取りあえずは(今は時間が無いもので・・)この方法で回避しておこうと思います。

ありがとうございました。

時間が開いたらOleDbConnectionのcloseについても確認したいと思います。


引用: --------------------------------------------------------------------------------

じゃんぬねっとさんの書き込み (2006-02-22 15:19) より:

お力になれず、申し訳ないです。(;_ _)

--------------------------------------------------------------------------------
なんて、とんでもないです。感謝感謝です。

また、何かありましたら、よろしくお願いいたします。



Jittaさん
ありがとうございます。参考にさせていただきます。

スキルアップ/キャリアアップ(JOB@IT)