Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2009年05月12日] [更新 2013年11月20日] ワード操作フォームEx
ワード操作フォームEx
テストプログラム EnterSheet
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro + Word 2010







テキストボックスを使用した帳票入力


あらかじめヘッダフッタ部に帳票の元を作成し,さらに入力位置にテキストボックスを配置した文書を用意してあります.
この文書にワード操作フォームからデータを入力して表示するものです.実は,このテスト用文書の元帳票は,ワードで作成してメタファイルとして保存した図形を使っています.
入力コントロールは [Enter] で移動し,[Shift] + [Enter] で前のコントロールへ移動するように設定してあります.もちろん,[Tab] と [Shift] + [Tab] も有効です.


図1
実行中の画面
  • [帳票元図の印刷] をチェックすると背景の帳票元図も印刷

リスト1
メインフォームのコード
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses EnterSheetUnit;

{$R *.DFM}

//=============================================================================
//  ワード操作フォームEx(の継承フォーム)を生成して使用
//  plWordFormEx2は自動実行から外しておく
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  plWordFormEx2 := TplWordFormEx2.Create(Self);

  //フォーム表示の時に表示する文書
  plWordFormEx2.wdfFileFullPath := '帳票入力の例.doc';

  try
    plWordFormEx2.ShowModal;
    Update;
  finally
    plWordFormEx2.Free;
  end;
end;

end.


リスト2
ワード操作フォームEx の (継承フォームの) コード
unit EnterSheetUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, plWordEx, StdCtrls, Buttons, ToolWin, ComCtrls, ExtCtrls;

type
  TplWordFormEx2 = class(TplWordFormEx)
    CheckBox1: TCheckBox;
    Panel1: TPanel;
    Edit1: TEdit;
    Panel2: TPanel;
    Edit2: TEdit;
    GroupBox1: TGroupBox;
    Panel4: TPanel;
    Panel5: TPanel;
    Panel6: TPanel;
    Panel7: TPanel;
    Panel8: TPanel;
    Panel9: TPanel;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    procedure Edit1Change(Sender: TObject);
    procedure Edit1Enter(Sender: TObject);
    procedure Edit1Exit(Sender: TObject);
    procedure Edit1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
    procedure btnPrintClick(Sender: TObject);
    procedure btnFileSaveClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  plWordFormEx2: TplWordFormEx2;

implementation

{$R *.dfm}

//=============================================================================
//  ワード操作フォームExのOnActiveイベント処理
//  ワード操作フォームExがActiveになった後に実行
//=============================================================================
procedure TplWordFormEx2.FormActivate(Sender: TObject);
begin
  //元のOnFormActivateを実行
  //必ず必要
  inherited;

  //初期値を設定
  Edit1.Text := '31500';
  Edit2.Text := 'ボーランドジャパン株式会社';
  Edit3.Text := '151-8583';
  Edit4.Text := '東京都渋谷区笹塚1-50-1';
  Edit5.Text := '笹塚NAビルディング';
  Edit6.Text := '□□□□ソフト株式会社';
  Edit7.Text := '□□ □';
  Edit8.Text := '03-1234-5678';

  Edit1.SetFocus;
end;

//=============================================================================
//  編集内容の表示
//  Editに入力した内容をワードの該当位置に表示
//  このイベントはEdit1~Edit8までのOnChangeで共有
//=============================================================================
procedure TplWordFormEx2.Edit1Change(Sender: TObject);
var
  StrText : String;
  Kingaku : Integer;
begin
  if wdfWordApp.Documents.Count=0 then exit;

  //金額
  if (Sender = Edit1) then begin
    Kingaku := StrToIntDef(Edit1.Text,0);
    if Kingaku > 0 then StrText := '\' + IntToStr(Kingaku) else StrText := ' ';
    wdfPutTextBox(1, StrText);
    wdfPutTextBox(8, StrText);
  end;

  //加入者名
  if (Sender = Edit2) then begin
    wdfPutTextBoxEx(4, 12, 12, 'MS Pゴシック', 2, Edit2.Text);
    wdfPutTextBoxEx(5, 12,  9, 'MS Pゴシック', 2, Edit2.Text);
  end;

  //郵便番号
  if (Sender=Edit3) then begin
    wdfPutTextBox(9,Edit3.Text);
  end;

  //住所1,住所2,団体名,氏名
  if (Sender = Edit4) or (Sender = Edit5) or
     (Sender = Edit6) or (Sender = Edit7) then begin

    //何故か空白は全角でないと文字サイズが反映されない
    StrText := Edit4.Text + ' ' +
               Edit5.Text + sLineBreak +
               Edit6.Text + sLineBreak + '   ' +
               Edit7.Text;

    wdfPutTextBoxEx(2, 10, 8, 'MS 明朝', 1, StrText);

    StrText := Edit4.Text + sLineBreak +
               Edit5.Text + sLineBreak +
               Edit6.Text + sLineBreak+ '     ' +
               Edit7.Text;
    wdfPutTextBox(6, StrText);
  end;

  //電話番号
  if (Sender = Edit8) then begin
    wdfPutTextBox(7, Edit8.Text);
  end;

  wdfWordDoc.Saved := True;
end;

//=============================================================================
//  コントロールにフォーカスが来た時の処理
//  背景色を変更しているだけ
//=============================================================================
procedure TplWordFormEx2.Edit1Enter(Sender: TObject);
begin
  TEdit(Sender).Color := $00FFFDBF;
end;

//=============================================================================
//  コントロールがフォーカスを失った時の処理
//  背景色を変更しているだけ
//  ワードにフォーカスを移動してもこのOnExitは発生しない
//=============================================================================
procedure TplWordFormEx2.Edit1Exit(Sender: TObject);
begin
  TEdit(Sender).Color := clWhite;
end;

//=============================================================================
//  入力は[Enter]で確定し,次の入力コントロールにフォーカス移動
//  [Shift]+[Enter]で前のコントロールにフォーカス移動
//=============================================================================
procedure TplWordFormEx2.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = VK_RETURN) then begin
    if (Sender = Edit1) and (ssShift in Shift) then begin
      Edit8.SetFocus;
    end else if (Sender = Edit8) then begin
      if (ssShift in Shift) then begin
        Edit7.SetFocus;
      end else begin
        Edit1.SetFocus;
      end;
    end else begin
      //[Enter]で次の,[Shift]+[Enter]で前のタブコントロールに移動
      //もちろん[Tab],[Shift]+[Tab]も有効
      keybd_event( VK_TAB, MapVirtualKey(VK_TAB, 0), 0 , 0 );
      keybd_event( VK_TAB, MapVirtualKey(VK_TAB, 0), KEYEVENTF_KEYUP , 0 );
    end;
    Key:=0;
  end;
end;

//=============================================================================
//  [Enter]での処理はKeyDownで処理するので無効に
//  郵便番号と電話番号は数値と-記号と[BackSpace]のみ入力可能に
//
//  このコードはDelphiのバージョンによって異なる
//=============================================================================
procedure TplWordFormEx2.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Ord(Key) = VK_RETURN) then begin
    Key := Chr(0);
  end else begin
    //#8は[BackSpace]
    if (Sender = Edit1) then begin
      if not (CharInSet(Key, ['0'..'9', Chr($8)])) then Key := Chr(0);
    end;
    if (Sender = Edit3) or (Sender = Edit8) then begin
      if not (CharInSet(Key,['0'..'9', '-', Chr($8)])) then Key := Chr(0);
    end;
  end;
end;

//=============================================================================
//  印刷
//  [帳票元図の印刷]にチェックがあれば背景の帳票も印刷
//  wdfHeaderFooterPrintプロパティはヘッダフッタ部の印刷有無フラグ
//=============================================================================
procedure TplWordFormEx2.btnPrintClick(Sender: TObject);
begin
  wdfHeaderFooterPrint := False;
  if CheckBox1.Checked then wdfHeaderFooterPrint := True;

  //継承元の[印刷]ボタンクリックを実行
  inherited;
end;

//=============================================================================
//  文書保存時の処理
//  保存ダイアログ表示前に保存文書名を加工
//=============================================================================
procedure TplWordFormEx2.btnFileSaveClick(Sender: TObject);
var
  S : String;
begin
  S := FormatDateTime('yyyy"年"mm"月"dd"日_"', Now);
  SaveDialog1.FileName := S + '帳票入力の例';

  //継承元のボタンクリックを実行
  inherited;
end;

end.


OnEdit1KeyPress のコードは Delphi のバージョンによって違います.Delphi 2009 以降は Unicode 対応に伴い,キーコードの取得に CharInSet を使用します.それより前のバージョンでは以下のコードを使用してください.


リスト3
OnEdit1KeyPress のコード (Delphi 2009 より前のバージョン用)
//=============================================================================
//  [Enter]での処理はKeyDownで処理するので無効に
//  郵便番号と電話番号は数値と-記号と[BackSpace]のみ入力可能に
//
//  このコードはDelphiのバージョンによって異なる
//=============================================================================
procedure TplWordFormEx2.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if (Ord(Key) = VK_RETURN) then begin
    Key := Chr(0);
  end else begin
    //#8は[BackSpace]
    if (Sender = Edit1) then begin
      if not ((Key in ['0'..'9']) or (Key=#8)) then Key := #0;
    end;
    if (Sender = Edit3) or (Sender = Edit8) then begin
      if not ((Key in ['0'..'9', '-']) or (Key = #8)) then Key := #0;
    end;
  end;
end;