コンピュータシステムは意志や感情がないので、通常は指定したとおりに作動する。
ただし、電圧や熱、電波などの影響によりり誤動作を起こす場合がある。いまは話に聞かないが、昔はそれを確認するためデュアルシステムのように、2台のコンピュータで同一の処理を行い、結果を突合するような方法が採られたりもした。
コンピュータ側の処理が正しい場合、入力データの誤りが問題となる。
その対策として、項目によって属性や桁数、体系をチェックしたり、入力者を2重化するなどの対策が採られる。

しかし、わざと間違えたものに関してはコンピュータは誤りを判断できない。いくつか例を挙げてみよう。

社会保険庁の年金の問題。これは、読み仮名をいい加減にしたケース、入力していないケース、企業側が従業員の給与を過少申告したケースなど、いろいろなケースが発覚しているが、すべて人為的な行為である。
なお、コンピュータ側に問題があるとすれば住基ネットの住民票コードのように、国民一人一人にユニークな番号付けができなかったことだ。しかし、国民総背番号制と言う名ではすこぶる不評で、その制度を取り入れられなかったがため、設計上ユニークな番号を符番できなかったことはコンピュータシステム上はやむを得ないことだろう。

医療機関の架空請求の問題。患者から受理する自己負担金が3割だとすると、医療機関は残りの7割を保険組合に請求するのだ。保険が利用できる治療はすべて点数化されており、治療内容はすべてカルテに記載される。
まもなくレセプトの電子請求化が義務づけられるが、カルテは電子化されていない医療機関が多い。つまり、カルテと診療報酬の請求は本来連動するはずであるのに、連動しないがために違った内容で請求できてしまう。また、カルテの内容までは通常患者に公開しないため、してもいない治療を上乗せすることもできてしまう。
これも、間違ったデータを判断することはできない。システムだけではなく、出来心が芽生えない仕組みが必要であろう。

システム単独ではなく、システムも含めた業務全体での視点が必要である。こういう分野は多くのシステム会社では見落とされがちである。
システム監査の観点を持っていれば、どのような危険性があるのかを予め洗い出し、対策を取れるだろう。
Excelではバージョンにより最終行(データの入っている行の最終、ではなくExcel自体の最後の行)が違う。固定値で持つと厄介で、かといっていちいちその場で設定するのも保守性を落とすことになる。

ちなみに最終行は
・Excel 2007 : 1,048,576行
・Excel 2003以前(Excel 5 迄?): 65,536行
である。

そこで、こんな風なプロパティを作ればどうだろう?Excel4以前はVBAに対応していないのでこれでごまかすとして・・。

Public Property Get LAST_ROW() As Long
Dim Val As Long

Val = Application.Version

If Val = 12 Then
LAST_ROW = 1048576
Else
LAST_ROW = 65536
End If


End Property

こういうのも共通処理として、サンプルで配布しようかと思う。


ブログトップへ
ブログ内検索キーワード
  サンプル


VBAには #If というものがある。通常の If ではなく、音楽記号でいうところのシャープが付いているものだ。


Sub dispVer()
Dim iVal As Integeri

iVal = Application.Version

#If iVal = 7 Then
MsgBox 95
#ElseIf iVal = 8 Then
MsgBox 97
#ElseIf iVal = 9 Then
MsgBox 2000
#ElseIf iVal = 10 Then
MsgBox 2002
#ElseIf iVal = 11 Then
MsgBox 2003
#ElseIf iVal = 12 Then
MsgBox 2007
#Else
MsgBox iVal
#End If
End Sub

この例、まともに動作するだろうか?おそらくは Else に流れていってしまうだろう。
#If では通常の If のような判定はできないのである。

では、何が出来るのか?上記を簡単に書き換えると


Sub dispVer()
#Const iVal = 11

#If iVal = 7 Then
MsgBox 95
#ElseIf iVal = 8 Then
MsgBox 97
#ElseIf iVal = 9 Then
MsgBox 2000
#ElseIf iVal = 10 Then
MsgBox 2002
#ElseIf iVal = 11 Then
MsgBox 2003
#ElseIf iVal = 12 Then
MsgBox 2007
#Else
MsgBox iVal
#End If
End Sub


上記の例では #Const で定義した値を判定させているが、リテラル値も可能だ。しかし変数は不可である。
つまり、用途としては


Sub Debugsample()

#Const bDebug = True

Dim iVal As Integer

iVal = 10 + 20

#If bDebug Then
Debug.Print iVal
#End If

End Su


というように、デバッグ時の切り替えか、MacかWin16、Win32かの判定くらいにしか使えない。
ならば If と大差なさそうだが、最大の相違点は「その条件に合わない場合は完全に無視する」ということ。つまり、Macのみ/Winのみでサポートされる命令を記述すると、If であればコンパイル時にエラーが出るが、#If ではエラーが出ないのだ。 つまり、実行時に評価されることになる。

これにより、Mac/Winの独自命令も混在させることができる。

なお、バージョン間の処理の際を吸収するニーズの方が多いだろう。確か、過去にクラスモジュールを使って行った記憶がある(ちょっと怪しい)。それもそのうちに紹介できればと思う。

ブログトップへ

ブログ内検索キーワード
 クラス
 バージョン