Delphi/C++BuilderのFileOpen関数の戻り値の型が変更されていた

Delphi/C++BuilderのFileOpen関数の戻り値の型が変更されていた。

Delphiでは、Delphi XE2から戻り値の型がInteger(XE以前)からTHandle(XE2以降)に変更されている。

C++Builderではint(XE以前)からunsigned(XE2)、NativeUInt(XE3以降)へと変更されている。

ヘルプを見るとエラーを示す値は-1のままのようで、整合性がとれていない。(THandle型やNativeUInt型は負数にならない)

戻り値が -1 の場合は,エラーが発生したことを示します。

System.SysUtils.FileOpen – RAD Studio API Documentation」より

Delphi

Delphi 2010

function FileOpen(const FileName: string; Mode: Cardinal): Integer;

Delphi XE

function FileOpen(const FileName: string; Mode: LongWord): Integer;

Delphi XE2

function FileOpen(const FileName: string; Mode: LongWord): THandle;

Delphi XE3

function FileOpen(const FileName: string; Mode: LongWord): THandle;

C++Builder

C++Builder 2010

int __fastcall FileOpen(System::UnicodeString FileName, unsigned int Mode);

C++Builder XE

int __fastcall FileOpen(const System::UnicodeString FileName, unsigned Mode);

C++Builder XE2

unsigned __fastcall FileOpen(const System::UnicodeString FileName, unsigned Mode);

C++Builder XE3

NativeUInt __fastcall FileOpen(const System::UnicodeString FileName, unsigned Mode);

C++Builder XEでTJvMonthCalendar2を使ってみる。

TJvMonthCalendar2はJVCLのコンポーネントです。
指定日を太字で表示するなど、標準コンポーネントのTMonthCalendarにはない機能があります。

■Boldプロパティ

指定した日付が太字かどうかを表します。

JvMonthCalendar21->BoldDays->Add("201207=11"); //2012年7月11日は太字
bool bold1 = JvMonthCalendar21->Bold[2012][7][10]; //=> false
bool bold2 = JvMonthCalendar21->Bold[2012][7][11]; //=> true

JvMonthCalendar21->Bold[2012][7][12] = true; //2012年7月12日は太字
bool bold3 = JvMonthCalendar21->Bold[2012][7][12]; //=> true

■BoldDaysプロパティ

太字で表示する日付を設定します。

次の2種類の書式を使用できます。

  1. 0000mm=daylist

    毎年mm月のdaylist日を太字にします。

  2. yyyymm=daylist

    yyyy年mm月のdaylist日を太字にします。

daylistはカンマ区切りで日にちを並べます。

//2012年7月の1日,11日,21日を太字にする
JvMonthCalendar21->BoldDays->Add("201207=1,11,21");

//毎年10月の10日,20日,30日を太字にする
JvMonthCalendar21->BoldDays->Add("000010=10,20,30");

■CircleTodayプロパティ

trueのときは当日の日付を囲みます。

■Colorsプロパティ

コントロールの各部品の色を設定します。

■DateFirstプロパティ、DateLastプロパティ

MultiSelectプロパティがtrueのときは選択されている期間の開始と終了の日付を示します。

JvMonthCalendar21->MultiSelect = true;
JvMonthCalendar21->DateFirst = TDateTime(2012, 8, 10);
JvMonthCalendar21->DateLast = TDateTime(2012, 8, 15);

MultiSelectプロパティがfalseのときはDateFirstプロパティは選択されている日付を示します。

■DateMaxプロパティ、DateMinプロパティ

選択できる期間を示します。

0のときは制限はありません。

JvMonthCalendar21->DateMin = TDateTime(2012, 8, 10);
JvMonthCalendar21->DateMax = TDateTime(2012, 8, 15);

■Daysプロパティ

指定した年月の太字の日にちをカンマ区切り文字列で示します。

//2012年7月の1日,11日,21日を太字にする
JvMonthCalendar21->Days[2012][7] = "1,11,21,31";

//2012年7月の太字に日にちを取得する
UnicodeString days = JvMonthCalendar21->Days[2012][7];
//=> days = "1,11,21"

■FirstDayOfWeekプロパティ

週の始まりの曜日をTJvMonthCalWeekDay型で示します。

JvMonthCalendar21->FirstDayOfWeek = mcTuesday;

■ShowTodayプロパティ

trueのときはコントロールの下部に当日の日付を表示します。

■WeekNumbersプロパティ

trueのときは週数を表示します。

■OnGetDayStateイベント

コントロールが日にちの状態を取得する時に呼ばれます。

引数

  • Date
    要求された最初の日にち。通常は月の初めの日。

  • Count
    要求された月の数。

  • DayStateArray
    日付の状態を示すTMonthDayStateの配列

たとえば2012年7月を表示する時は、2012年6月~2012年8月までの情報が必要になるので、

Date=2012/06/01
Count=3
DayStateArray[0]=6月の太字の日にちのTMonthDayState
DayStateArray[1]=7月の太字の日にちのTMonthDayState
DayStateArray[2]=8月の太字の日にちのTMonthDayState

となります。

TMonthDayStateはDayStatesToString関数で、カンマ区切りの文字列に変換できます。

var
  S: String;
begin
  S := DayStatesToString(DayStateArray[0]); //=> 1,11,21

Delphi XEとC++Builder XEで「々」の動作を確認しました。

.NET Framework 2.0以降では「々」の位置を間違えるらしい。(「愛が重ならない.NET Framework 2.0 – 新日々此何有哉」より。)

Console.WriteLine("{0}", "愛々,1,2,3".IndexOf(",")); //=> 1

Delphi XEとC++Builder XEで動作を確認しました。

# .Net FrameworkのIndexOfはインデックスが0から始まりますが、
# Delphi/C++BuilderのPosはインデックスが1から始まります。

Delphi XEの場合

Writeln(Pos('愛', '愛々,1,2,3')); //=>1
Writeln(Pos('々', '愛々,1,2,3')); //=>2
Writeln(Pos(',', '愛々,1,2,3'));  //=>3
Writeln(Pos('1', '愛々,1,2,3'));  //=>4

C++Builder XEの場合

std::cout << UnicodeString("愛々,1,2,3").Pos("愛") << std::endl; //=>1
std::cout << UnicodeString("愛々,1,2,3").Pos("々") << std::endl; //=>2
std::cout << UnicodeString("愛々,1,2,3").Pos(",") << std::endl; //=>3
std::cout << UnicodeString("愛々,1,2,3").Pos("1") << std::endl; //=>4

Delphi XEとC++Builder XEは問題ないようです。
(.NET Frameworkは詳しくないので、勘違いがあるかもしれません。)

『実践的データモデリング入門』で紹介されているデータモデルパターン

実践的データモデリング入門』で紹介されているデータモデルパターンの一部を紹介します。

このようなパターンを知っていると上手に効率よくモデリングできるのでしょうね。

■履歴モデル

商品の属性内容(コード・単価)の変更が変更される時に、商品を購入した際の履歴を管理するパターンです。
「履歴管理の話の際にとっさにこの2つのパターンが思い浮かべば、業務担当者へのヒアリングも的確なものとなるでしょう。」とのこと。

商品の属性内容を転記する方法

商品自身に適用開始年月日と適用終了年月日を持たせて管理方法

■組織モデル

ピラミッド型の組織階層を表すモデルのパターンです。
「処理特性・データ量・トランザクション量・更新頻度などを見極め、物理モデルで再考すべき」とのこと。

現実の組織を写像したモデル

再帰的に表現したモデル

■ロールモデル

同一企業が、状況によって「顧客」だったり「購買先」だったりするときのパターンです。

■取引モデル

BtoB(企業間の商取引)を汎化したモデル。
販売管理や購買管理のモデルへの応用も可能。