|
>Private Sub Forom_BeforeInsert(Cancel As Integer)
> If Dcount("*","部品マスタ")= 0 then
> Me.部品番号 = "0000001"
> Else
> Me.部品番号 = Format(DMax("部品番号","部品マスタ") + 1,"0000000")
> End if
>End Sub
>
>ただし、テーブル定義では部品番号は短いテキスト型になっています。テーブルの部品番号の型を数値型にすれば問題ないのですが、型を変更できないとき、どのようにすればよいでしょうか。
当方のアクセスは2003ですが、上記のコード(一部誤字がありますが)で
動きました。
ただ、データ型をシビアに考えていくと、上記のコードには問題がありますね。
問題となるのは、Else以下です。
なお、「部品番号」フィールド中の最大の値が「0123」であるとします。
「部品番号」フィールドはテキスト型ですから、
上記のDMax関数は、テキスト型の値である"0123"を返します。
上記コードでは、"0123"に1を加えようとしていますが、
テキスト型の値に数値をプラスしようとしても、データ型違いというエラーになるはずです。
アクセス2003では、暗黙の型変換というのが行われるのでエラーにはなりません。
つまり、"0123"という文字列を、VBAが勝手に数値と解釈してくれるということです。
2007以降、データ型にはシビアになった、
つまり、暗黙の型変換をあまりやってくれないようになった
と聞いたことがあります。
対策ですが、DMax関数の返り値はテキスト型なので、これを数値型に変えた上で、
1を加えればいいです。
CLng関数を使います。
ただ、「部品番号」フィールドをテキスト型とすることには賛成できません。
おそらく、「部品番号」は、例えば、「1234」ではなく、「0001234」のように表示したい
ということから、テキスト型にしたのだと思いますが、本末転倒です。
第一に、
「部品番号」フィールドは、7桁の数字からなる文字列をその値とするようですから、
それに要するデータ量は、1レコード当たり、2バイト×7字=14バイトとなります。
他方、これを長整数型にすれば、1レコード当たり4バイトで済みます。
データベースは、テーブルに何万レコードも格納しますから、1レコード当たり10バイトの差は、
レコード数が多くなるといろいろと効いてきます。
第二に、コンピュータは、文字列と数値とでは、数値を処理する方が得意です。
第三に、「部品番号」フィールドが長整数型のままでも、
「部品番号」テキストボックスのFormatプロパティをうまく設定してやれば、
テキストボックスに「0001234」のように表示させることは可能です。
なので、少なくとも「部品番号」フィールドは数値型とすべきだと思います。
>また、プレフィックス、部品番号、スァフィックスの組で重複は許されません。
>プレフィックス、部品番号、サフィックスが入力された時点で重複レコードがないかチェックし、あればアラーム、なければ続いて部品名等を入力したいです。
方法としては、2つ考えられます。
第一に、プレフィックス、部品番号、サフィックスの各フィールドで
複合インデックスを作る方法が考えられます。
でも、どこかの本に「重複排除のためだけにインデックスを使うのは好ましくない」
と書かれていましたし、私もそう思うので、おすすめできません。
第二に、然るべきイベントで、DCount関数を使って、
同じ組み合わせが既にテーブルに格納されていないかどうかチェックするという方法です。
使うイベントは、おそらくテキストボックスのBeforeUpdateイベントになると思います。
また、DCount関数の第3引数に設定する条件式をどう書くかというところもポイントとなります。
|
|