SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

現役エンジニア直伝! 「現場」で使えるコンポーネント活用術(ActiveReports)

Salesforceに日本の帳票パワーを注入する

  • このエントリーをはてなブックマークに追加

 日本の業務システムには帳票文化という特徴があり、海外製品のレポート機能では実装が無理なくらい細かいものであるといわれています。例えば、プレ印刷された送付届に相手の住所などの情報などを後から印刷、しかも、ミリ単位で印刷位置を合わせないとプレ印刷の枠内からはみ出してしまって印刷不良扱いとなり障害インシデントが発行されてしまうような精度を要求されるのが日本の帳票文化です。

  • このエントリーをはてなブックマークに追加

 そのため、省コストであるとか短納期であるとかいうところに力点が置かれ始めると、必ずしも帳票である必要はなく、レポートでいいのではないかということになります。でも、本当にレポートでいいと思っているのでしょうか。そこには「コストがかかったり納期が延びてしまうなら仕方がない」というあきらめが存在するのではないかと考えます。

 Webアプリでの印刷も状況は同じでしょう。一種の諦めが、レポートで表現できる印刷結果で仕方がないという判断になっているのではないでしょうか。

 では、こう問われたらどうでしょう。「レポートと大きく変わらない納期で帳票出力できますが、レポートと帳票のどちらがよろしいでしょうか」と。

 そこで実際にどのような形で帳票が印刷できるのか、「ActiveReports for .NET 9.0J」と「CData ADO.NET Provider for Salesforce 4J」(以下、ActiveReports + CData)を使って、大企業向けSaaSのトップランナーであるSalesforceから帳票を印刷して確認してみたいと思います。

Salesforceの準備(おさらい)

 今回の内容の説明に入る前に、Salesfoceの準備をおさらいしてみましょう。

Salesforceの利用開始

 CDataでSalesforceに接続するためには、SalesforceのエディションとしてEnterprise EditionまたはUnlimited Editionが必要です。無料トライアルはそれ以外のエディションになるので、無料のDeveloper Editionに申し込みます。

 [サインアップ]ボタンをクリックすると「無料のDeveloper Edition環境にサインアップ」画面が表示されるので、姓名やメールアドレスなどの必要事項を登録します。数分後に登録したメールアドレス宛にSalesforceからメールが届くので、そこに記載されたURLにアクセスすればDeveloper Editionの利用を開始できます。

セキュリティトークンの入手

 手元にセキュリティトークンがあるのならばそれを使用します。ないようであればセキュリティトークンを入手します。入手方法は次の手順になります。

  1. Salesforceにログインし、ヘッダに表示されている自分の名前のドロップダウンメニューを開いて[私の設定]メニューを選択します。
  2. [私の設定]画面が開いたら、サイドメニューから[個人用]メニューを選択、[私のセキュリティトークンのリセット]メニューを選択します。
  3. [セキュリティトークンのリセット]ボタンをクリックします。

 これでセキュリティトークンが登録してあるメールアドレスにメールで届きます。

システム構成

 今回のサンプルで想定しているシステム構成は次のようになります。

図1 WPFアプリのシステム構成
図1 WPFアプリのシステム構成

 WPFアプリではなくWebアプリでということであれば次のような構成も考えられます。

図2 Webアプリのシステム構成
図2 Webアプリのシステム構成

CDataの準備

 CDataのインストールが完了していれば、あとはプロジェクトで参照設定を行えばコードから使うことができます。

 また、サーバーエクスプローラーでデータ接続先に指定しておくと、認証情報の確認やSalesforce上のテーブルの参照が行えるのでお勧めです。

図3 サーバーエクスプローラーにデータ接続追加
図3 サーバーエクスプローラーにデータ接続追加

 今回のサンプルではCampaignテーブルを使います。

図4 Campaingテーブルの項目
図4 Campaingテーブルの項目

データ取得ロジックの作成

 CDataを使ってテーブルの内容を取得するコードを作成します。

リスト1 ReportModel.vb
Imports System.Data.CData.Salesforce
Imports System.Data
 
Namespace Models
    Public Class ReportModel
        Private _DatasetData As New System.Data.DataSet
        Public ReadOnly Property DataSetData() As System.Data.DataSet       '……(1)
            Get
                Return _DatasetData
            End Get
        End Property
 
        Public Sub GetRecords()
            Dim sb = New SalesforceConnectionStringBuilder() With
                     {
                         .User = "mailaddress",
                         .Password = "password",
                         .SecurityToken = "JX55LjThc8A5IUcjtAdEqbsf"}       '……(2)
 
            _DatasetData.Clear()
            Using conn = New SalesforceConnection(sb.ConnectionString)
                Using da = New SalesforceDataAdapter("SELECT * FROM Campaign", conn)
                    da.Fill(_DatasetData, "Campaign")                       '……(3)
                End Using
            End Using
        End Sub
    End Class
End Namespace
  1. 取得結果を参照するためのDataSetを定義
  2. Salesforceとの接続文字列を設定
  3. SELECT文の実行結果をDataSetに設定

 CDataはADO.NET準拠の外部仕様をもっているので、ADO.NETの知識でコードが作成できます。

ActiveReportsの準備

RDLレポートの追加

 ソリューションエクスプローラーでプロジェクトを右クリックして[追加]-[新しい項目の追加]メニューをクリックします。[新しい項目の追加]ダイアログで「ActiveReports 9.0J RDLレポート(XML)」を選択します。名前は「CZ1503rdl.rdlx」とします。

図5 RDLレポートの追加
図5 RDLレポートの追加

ActiveRepots 9.0J レポートエクスプローラの利用

 RDLレポートにデータセットを定義し、データセット上の項目と印字位置を対応付けます。そのためには、まず「ActiveRepots 9.0J レポートエクスプローラ」を起動してデータセットを定義しましょう。

 ActiveRepots 9.0J レポートエクスプローラは、[表示]-[その他のウィンドウ]-[ActiveRepots 9.0J レポートエクスプローラ]メニューから起動します。

図6 ActiveRepots 9.0J レポートエクスプローラの起動
図6 ActiveRepots 9.0J レポートエクスプローラの起動

Dataset Providerの追加

 レポートエクスプローラで「データソース」を右クリックして[データソースの追加]メニューをクリックします。ダイアログで[構成]に「Dataset Provider」を選択して[OK]ボタンをクリックし、データソースを追加します。

図7 レポートデータソースの追加
図7 レポートデータソースの追加

データセットの追加

 レポートエクスプローラで追加したデータソースを右クリックして[データセットの追加]メニューをクリックします。

図8 データセットの追加
図8 データセットの追加

 サーバーエクスプローラーでCampaignテーブルの項目を見ながら必要な項目をフィールドとして定義していきます。

図9 フィールドの定義
図9 フィールドの定義

 今回のサンプルでは、Id、Name、Type、Status、StartDate、EndDateの6つの項目を抜き出してみました。先ほどのCDataが「SELECT * FROM Campaign」として全項目抜き出していたこととの差異を覚えておいてください。

図10 項目込みDataSet定義
図10 項目込みDataSet定義

帳票定義

 準備ができたら帳票定義を行います。RDLレポートにはTableコントロールがあり手軽に一覧表が作成できます。

図11 Tableコントロール
図11 Tableコントロール

 Tableコントロールをレポートデザイナーにドラッグ&ドロップするとヘッダ、詳細、フッターの3行から構成されたグリッドが表示されます。この詳細部分にDataSetに定義したフィールドを割り当てます。

図12 Tableにフィールドを割り当てる
図12 Tableにフィールドを割り当てる

 詳細にフィールドを割り当てると自動的にヘッダにフィールド名が入ります。またセル同士を繋げて一つにしたり、詳細を複数行で定義したりすることもできます。今回のサンプルでは、最終的に詳細を2段にして次のような定義を行いました。

図13 帳票定義の完成
図13 帳票定義の完成

 これにTableのコントロール罫線やLineコントロールを使用して罫線を引いてあげると、より帳票っぽくなるでしょう。

Viewerコンポーネントの設置

 いきなり印刷してしまってもいいのですが、プリンターが手元にない時にも確認ができるように、MainWindowにビューアーを設置してプレビュー表示できるようにしましょう。

 そのためには、まずツールボックスにViewerコンポーネントを追加します。

図14 Viewerコンポーネント
図14 Viewerコンポーネント

 追加できたらWPFデザイナーでWPFウィンドウを表示しておき、ドラッグ&ドロップでViewerコンポーネントを配置してから微調整します。

リスト2 MainWindow.xaml.vb
Imports GrapeCity.ActiveReports
 
Namespace Views
    Public Class MainWindow
        Private Runt As GrapeCity.ActiveReports.Document.PageDocument
 
        Public Sub New()
            ' この呼び出しはデザイナーで必要です。
            InitializeComponent()
 
            ' InitializeComponent() 呼び出しの後で初期化を追加します。
            Me.DataContext = Application.MainVM
            SetReports()                                                     '……(1)
            AddHandler Application.MainVM.PropertyChanged, 
               AddressOf MainVM_PropertyChanged                              '……(2)
        End Sub
 
        Private Sub SetReports()
            Dim fi As New System.IO.FileInfo("CZ1503rdl.rdlx")
            Dim repDef As New GrapeCity.ActiveReports.PageReport(fi)
 
            Me.Runt = New GrapeCity.ActiveReports.Document.PageDocument(repDef)
            AddHandler Me.Runt.LocateDataSource, AddressOf runt_LocateDataSource
        End Sub
 
        Private Sub MainVM_PropertyChanged(sender As Object,
                                           e As ComponentModel.PropertyChangedEventArgs)
            If e.PropertyName = "DataSetData" Then
                Me.CZ1503Viewer.LoadDocument(Me.Runt)                       '……(3)
            End If
        End Sub
 
        Private Sub Runt_LocateDataSource(ByVal sender As Object,
                                          ByVal args As LocateDataSourceEventArgs)
            args.Data = Application.MainVM.DataSetData.Tables("Campaign")   '……(4)
        End Sub
 
    End Class
End Namespace
  1. ActiveReports用の設定を実施
  2. ReportModelが提供するデータが変化した時に発生するイベントを登録
  3. データが取得できたら帳票定義体をローディング
  4. ActiveReportsがデータを必要としたときに呼び出されるプロシージャの中でReportModelが作成したデータを設定

 「args.Data = Application.MainVM.DataSetData.Tables("Campaign")」は、CDataで取得した全項目が入ったDataSetを6つの項目しか定義してなかったRDLレポートのDataSetに代入しています。これによりRDLレポートのDataSetは全項目を持つことになります。

 その状態でも帳票定義体に指定したフィールド名と同一のものを印字します。

図15 実行結果
図15 実行結果

 今回は意図的にCData側で全項目を取得しましたが、メモリ使用効率やデータ転送効率を考えるとCData側でも必要な項目だけを取得するようにしましょう。

まとめ

 もしかしたら、海外では帳票というものの存在を知らないのでレポートで満足していたりしないでしょうか。例えば、お客様の手元に届く請求書や納品書は、日本品質の帳票出力の方がより満足いただける可能性があると考えます。もし、そういった可能性を今まで除外していたとしたら、レポートではなく帳票の可否を検討してみるとよいでしょう。

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8597 2016/03/14 11:37

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング