ちょっと脇道にそれまして...

ちょっと頼まれモノ
今までだったらFileMakerとかでちょちょいと済ませるのだけど、ちょうどいいネタだったのでVB.NET+VB-Reportでやってみた。

作成したのは合計請求書(請求書の表紙)を印刷する簡単なプログラム


・帳票レイアウトの作成
Excelを使って使う帳票レイアウトを作成する。
今回はこんな感じ


・Formを作成する
VisualStudioでプロジェクトを作ってFormを作成する。


・コードを書く
コード書く前に下準備として
「参照の追加」で
  • VBReport.dll
  • VBReport.XlsCrt.dll
  • VBReport.XlsPDF.dll
  • VBReport.XlsReportCtrl.dll
を追加

「追加」-「既存の項目」で
  • msvcr71.dll
を追加

「追加」-「既存の項目」で作成したExcelの帳票レイアウトファイルを追加する。
[ビルドアクション]を[埋め込まれたリソース]にする。
をやっておく

次のコードをFormに書く
  Public Class FormMain
    Private Sub FormMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      '-----予期しない例外はトラップして継続実行させる-----
      AddHandler Application.ThreadException, AddressOf CommonLib.ErrorTrap_ApplicationError_Resume
      '----------------------------------------------------
  
      AddHandler tb今回請求金額.Validating, AddressOf CommonLib.tb_Validating_Integer
  
      AddHandler tb1行目.Enter, AddressOf CommonLib.tb_Enter
      AddHandler tb2行目.Enter, AddressOf CommonLib.tb_Enter
      AddHandler tb今回請求金額.Enter, AddressOf CommonLib.tb_Enter
  
      AddHandler tb1行目.Leave, AddressOf CommonLib.tb_Leave
      AddHandler tb2行目.Leave, AddressOf CommonLib.tb_Leave
      AddHandler tb今回請求金額.Leave, AddressOf CommonLib.tb_Leave
  
      Call FormClear()
    End Sub
  
    Private Sub FormMain_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
      Me.KeyPreview = True
      Call FormClear()
    End Sub
  
    Private Sub FormKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
      'Enterキーで次のコントロールにフォーカスする
      If e.KeyCode = Keys.Enter Then
        Me.ProcessTabKey(True)
      End If
    End Sub
  
    Private Sub btn発行_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn発行.Click
      Call 出力_合計請求書()
    End Sub
  
    Private Sub btnクリア_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnクリア.Click
      Call FormClear()
    End Sub
  
    Private Sub FormClear()
      cb月限.SelectedIndex = 0
  
      dtp発行日.Value = System.DateTime.Today
  
      tb1行目.Text = ""
      tb2行目.Text = ""
  
      tb今回請求金額.Text = ""
  
      tb1行目.Visible = False
  
      tb2行目.Focus()
    End Sub
  
    Private Sub 出力_合計請求書()
      '-----和暦の処理-----
      Dim Japan As New System.Globalization.JapaneseCalendar
      '--------------------
  
      '-----ルート名前空間を取得する-----
      '埋め込まれたリソース(印刷用レイアウトファイル)を利用するために必要
      Dim AppNameSpace As String
      Dim type As System.Type
      type = Me.GetType()
      AppNameSpace = type.Namespace
      Dim EmbedFileName As String = AppNameSpace & ".PrintForm.xls"
      '----------------------------------
  
      Dim rptCtrl As New VBReport.XlsReportCtrl.XlsReportCtrl
      Dim srmExcelFile As System.IO.Stream = Nothing
  
      Dim str出力プリンタ As String = ""
  
      Try
        '印刷用Layout定義
        rptCtrl.CtrlMode = VBReport.XlsReportCtrl.xlCtrlMode.cmHide
        rptCtrl.Option.ExcelMode = True
        rptCtrl.Printer.ColorMode = True
        rptCtrl.Option.ProgressDialog = False
  
        '埋め込まれたリソースの使用
        Dim asmExcelFile As System.Reflection.Assembly
        asmExcelFile = System.Reflection.Assembly.GetExecutingAssembly
        srmExcelFile = asmExcelFile.GetManifestResourceStream(EmbedFileName)
  
        'プリンタ設定
        If rptCtrl.Option.SetPrinter(True, "") = False Then
          Exit Sub
        End If
  
        'ページを開始
        rptCtrl.Start.Embed(srmExcelFile)
        rptCtrl.Page.Begin("合計請求書", "1")
  
        If cb月限.Text.Length = 0 Then
          '何もしない
        Else
          rptCtrl.Cell("D5").Value = " " & cb月限.Text & "月限"
        End If
  
        rptCtrl.Cell("AZ5").Value = "平成 " & Japan.GetYear(dtp発行日.Value) & " 年 " & dtp発行日.Value.Month.ToString.PadLeft(2) & " 月 " & dtp発行日.Value.Day.ToString.PadLeft(2) & " 日"
  
        rptCtrl.Cell("D7").Value = tb1行目.Text & vbNewLine & tb2行目.Text
  
        rptCtrl.Cell("P12").Value = "\" & CDec(tb今回請求金額.Text).ToString("#,##0") & "."
  
        '印刷する
        rptCtrl.Page.End()
        rptCtrl.Out.DoPrint("合計請求書")
  
      Catch ex As Exception
        MsgBox(ex.Message)
      Finally
        rptCtrl.Dispose()
  
        ' 読み込んだリソースを閉じる
        srmExcelFile.Close()
      End Try
  
    End Sub
  
    Private Sub tb2行目_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles tb2行目.Validated
      If tb2行目.Text.Length >= 14 Then
        If MsgBox("印刷すると文字が切れてしまうかもしれません。" & "2行に分けますか?", DirectCast(MsgBoxStyle.Information + MsgBoxStyle.YesNo, MsgBoxStyle), "") = MsgBoxResult.Yes Then
          tb1行目.Visible = True
          tb1行目.Text = tb2行目.Text.Substring(0, 14)
          tb2行目.Text = tb2行目.Text.Substring(13)
          tb2行目.Focus()
        End If
      End If
    End Sub
  End Class

・ビルドして配布
あとはビルドして、プロジェクトのフォルダの中の\bin\Releaseをコピーして実行環境にコピーするだけ
Installerを書くまでもなし

・まとめ
慣れると意外と簡単(レイアウト作成も含めて約1時間)
少し手を入れたらmdbファイルか、XMLファイルに発行履歴も簡単に残せるんだけど、お金にならないのであまり手間をかけないのをモットーに