レコードセットをttxファイルを介してCrystal Reportのフィールドにマッピング

レコードセットのフィールド値をttxファイルを介してCrystal reportのフィールド定義にマッピング

作業テーブルをAccessにエクスポートして現品票を発行したいと思ったのですが、簡単にできるのかと思ったら結構手こずりました。

古いですがCrystal report 9にはParameter Fieldがあるので、VBからPassing Parameterするのかと思いきやRecord Setを放り投げると勝手にフィールドから値を取ってくれるので、Crystal Report Viewerという無償のActiveXコンポーネントビューアーの中にレポートを表示できます。

    CrRep.Database.SetDataSource rs, 3, 1
    CRViewer91.ReportSource = CrRep
    CRViewer91.ViewReport

それがこの部分。3番目の引数1がTable Numberを表します。

    '選択されたコンボのORDERCODを取得
    result = Combo1.List(Combo1.ListIndex)

    'Passing parameter from VB6 to CR using CRAXDRT
    Dim CrApp As CRAXDRT.Application
    Dim CrRep As CRAXDRT.Report

    'ORDERTBLからORDERCODのレコードセットを取得
    Dim conn As New ADODB.Connection
    Dim rs As ADODB.Recordset

    Dim mySQL As String

    cn.Open _
        "Provider = Microsoft.Jet.OLEDB.4.0; " & _
            "Data Source = " & CurDir & "\NNA.mdb"

    Set CrApp = New CRAXDRT.Application
    Set CrRep = CrApp.OpenReport(App.Path & "\reports\TravelSheet.rpt", & _
                    crOpenReportByTempCopy)

    CrRep.DiscardSavedData

    If result <> "ALL" Then
        mySQL = "SELECT * FROM OPERATIONTBL WHERE ORDERCOD='" & _
            Combo1.Text & "' ORDER BY ORDERCOD"
    Else
        mySQL = "SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD"

    End If
    With rs
        .ActiveConnection = cn
        .CursorLocation = adUseServer
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Properties("IRowsetIdentity") = True

        .Open mySQL
    End With
    CrRep.Database.SetDataSource rs, 3, 1
    CRViewer91.ReportSource = CrRep
    CRViewer91.ViewReport

ところがCrystal Report ViewerのようなWin7での標準以外のコンポーネントを使った開発アプリはXPで問題起こす可能性大であり、crviewer9.dllが古いPCで問題起こしまくりなので、まずCR8.5にダウングレードした上で、以下にコード変更。

CR8.5はフォームレイアウトだけに限定させるために、ttxファイルにフィールド定義を行いVBからレコードセットを投げてttxファイルのField Definitionに従ってフォームにはめ込む。

Dim result As String

    '選択されたコンボボックスのORDERCODを取得
    result = Combo1.List(Combo1.ListIndex)

    'ORDERTBLからORDERCODのレコードセットを取得
    Dim conn As New ADODB.Connection
    Dim rs As ADODB.Recordset

    Dim mySQL As String

    cn.Open _
        "Provider = Microsoft.Jet.OLEDB.4.0; " & _
            "Data Source = " & CurDir & "\DNN.mdb"

    If result <> "ALL" Then
        mySQL = "SELECT * FROM OPERATIONTBL WHERE ORDERCOD='" & _
                    Combo1.Text & "' ORDER BY ORDERCOD"

    Else
        mySQL = "SELECT * FROM OPERATIONTBL ORDER BY ORDERCOD"

    End If

    rs.Open mySQL, cn, adOpenKeyset, adLockOptimistic

    With rptControl
        .WindowTitle = "Travel Sheet"
        .ReportFileName = App.Path & "\Reports\TravelSheet.rpt"

        .SetTablePrivateData 0, 3, rs
        .WindowShowPrintBtn = True
        .WindowShowPrintSetupBtn = True

        .RetrieveDataFiles
        .WindowState = crptMaximized
        .Destination = crptToWindow
        .Action = 1
    End With

CRファイルのReport Expertでttxファイル(rpt.ttx)を指定してあげると、コード内のレコードセットのフィールド値が自動的にCRファイルのフィールドにマッピングされます。

reportexpert

ttxファイルにタブ区切りでフィールド名、属性、長さを定義するやり方は日本では既に古典の部類に入る手法でしょうが、インドネシアではまだまだ現役です。

ORDERCOD	string	100
PROCNO	number
RESOURCE	string	100
ITEM	string	100
QTY	number
STARTDATE	string	100
ENDDATE	string	100
WORKTIME	string	100
PARENTITEM	string	100
CLASS	number