Visual basic5.0への移植 〜その理想と現実〜

16bitアプリケーションからのコンバート

真崎理人 MASAKI,Rihito
有限会社リヒトシステムズ rihito@mail.dddd.ne.jp

はじめに

 ご覧のとおり今回の特集は「Visual Basic(以降VB)トラブル処方箋」です.なんだか消毒液のにおいとあの待合い室独特の喧噪が聞こえてきそうですね.筆者自身は大の“注射嫌い”ですから,めったなことでは病院には近づかないようにしているのですが,本日は“VB移植科”の専任ドクターとして,最近巷で多発している16bit版VBから32bit版への“コンバート(移植)作業にまつわるエトセトラ”と“VB5へのお気楽コンバート”へのアプローチ法をご紹介しましょう.
 なお,この記事はVisual Basic2.0J(以降VB2J)からVisual Basic5.0(同VB5)への移植を想定して書いていますが,同じ16bit版VBであるVisual Basic3.0(同VB3)やVisual Basic4.0 16bit版(同VB4-16)から32bit版VBへのコンバートを考えている読者は,対応するVBに置き換えてお読みください(残念ながらVB1やVB for DOSは対象としていません).


● 目指すは32bit

 今年の3月,まばゆいばかりのVB5のリリースを前にした明るい話題の陰で,一つのニュースが筆者の元にも届きました − 「VB用カスタムコントロールの大手ベンダーがVBX製品の販売とサポートを終了すると発表」,栄華をきわめたWindows3.1(以降Win3.1)+VB2J+VBXの時代も盛者必衰の例外ではなくここに終焉を迎えたわけです(注1).もちろん,今までどおりVB2J+VBXでの開発を続けることができなくなったわけではありませんが,その製品とライセンスを手に入れることが原則的にできなくなったことは,開発チームの増員や(カスタマイズ用)ソースコード付きのVBアプリケーションの配布ができなくなる事を意味します.たしかにVB4-16は継続販売されていますが,VB5に16bit版が添付されなかったこともからも,新規アプリケーション開発を16bit版VBで行うことは無謀といってよいでしょう.
 今となっては,Windowsファミリーにおいての標準プラットフォームはWindows95(以降Win95)やWindowsNT4.0(以降WinNT4.0)などの32bit Operating System(OS)であることに疑いの余地はありません.これからの新規開発は,32bit版VBであるVB5(またはVB4-32)が唯一の選択肢なのです.さあ目指すは32bitです!(注2)


注1:Windows3.1は現在も販売されている.また,VB2はVB4の発売ととに,昨年すでに発売を終了している.
注2:もしエンドユーザのハードウェア性能が低いのであれば,同一仕様のPCによるパフォーマンステストなしにシステムをWin95+VB5などに変更してはならない.ライセンスの問題を解決できるのであれば,Win3.1+VB3+VBXで開発を継続するべきである.

● 16bitからの自動コンバートは幻想

 VB2Jで作成したプログラムをVB5用にコンバートする機能は標準でサポートされており,その方法はいたって簡単です.VB5を起動し【既存のファイルを開く】ダイアログからコンバートするVB2のプロジェクトファイル(.mak)を開き,後は【すべてのファイルを変換する】ボタンを押して【DAOライブラリの追加の有無】の確認で“追加しない”を選べば,VB5形式のプロジェクトに自動にコンバートされるとともに,一部のVBXについては上位互換のOCXに自動で置き換えられます(注3・4).あとはプロジェクトの保存時にプロジェクトファイルの拡張子をVB5の標準である“.vbp”に変更すれば,作業はすべて完了(注5).
 試しにVB2Jに附属している電卓プログラム(calc.mak)をコンバートしてみましょう.何の問題もありません.しかし,いつもこんな簡単にコンバートできる保証はありません.むしろ自動コンバートできるような業務用カスタムアプリケーションは皆無といってよいかもしれません.このことは,マイクロソフト株式会社のホームーページのサポート技術で,「【VB5】以前のバージョンからの移植時の注意」として次のように書かれています.

「16bit版からの移植時の注意事項」
(1) VBXカスタムコントロールは使用できない.ただし下記(2)のVBXおよびVB2Jに標準添付されたGRID.VBXについては自動コンバート時に該当するVBXの上位互換のOCXに置き換えることができる.
(2) Microsoft Visual Control Packに付属していたVBX(THREED.VBXなど)を使用している場合には,VB5のCD-ROMから別途インストールする必要がある(注6)
(3) 16bitのDLLやWin16APIの利用はできない
(4) 文字コードにはUnicodeが採用されており,旧来のANSIコードとは異なる
(5) フォームモジュールはテキスト形式でされていなければコンバートできない

 あなたのカスタムアプリケーションは自動コンバートできそうでしょうか?おそらく躊躇せずに手を挙げられる読者は少ないことでしょう.実際にVB2Jで開発された業務用アプリケーションでこれらの「注意事項」をクリアできるようなアプリケーションはほとんどないといえます.試しに市販されているVB2Jで開発されたパッケージアプリケーション(図1)を自動コンバートしてみましょう.(注7)
 すると今度は[カスタムコントロールのアップグレード]ダイアログが表示され,サードパーティ製のカスタムコントロールについては「アップグレードすることができない」とのメッセージが出力され,先ほどのコンバートと同じようには行きません.仮に警告メッセージを無視して自動コンバートを強行すれば,そのプログラムが正常に動作しないことはもちろん,設計した画面さえも崩れてしまうのです(図2).
 このアプリケーションはそのコードにとりたてて高度な技術を使っているわけではなく,むしろ一般的なレベルのプログラムといえます.つまり,業務用カスタムアプリケーションをVB5に移植するためには自動コンバートだけでは足りないのです.

図1:一般的な業務用アプリケーションの例
図2:自動コンバートの失敗例




「一般的な16bitカスタムアプリケーションの現状」

(1) VBXカスタムコントロールを使用している:VB2Jの魅力のひとつは豊富なVBXを使用することによる開発効率のUPや貧弱なVB2Jの機能を手軽に拡張できることにあった.
(2) Microsoft Visual Basic Control Pack に付属していたVBX(THREED.VBXなど)のほとんどは現在は“廃止”されている(表1)
(3) .iniファイルへの読み書きをはじめ,多くはWin16APIを使用しており,また自社開発などの16bitのDLLを使用しているプロジェクトは少なくない
(4) 日本のカスタムアプリケーションでは日本語を扱う文字列方の変数を多用しているので,内部の文字コードをが変更されたことの影響は大きい



注3:VB2Jのフォームモジュールがバイナリ形式で保存されているとコンバートできません.事前にテキスト形式で保存しなおしてからコンバートしてください
注4:VB2JではまだDAOはサポートされていませんでした.しかしコンバート対象がVB3やVB4-16で作成したプロジェクトであるときには適切な選択をしてください
注5:VB2Jで作成したプロジェクトのすべてのファイルは,事前に必ずバックアップを取っておくことをお勧めします.一度VB5でコンパバートしたプログラムはVB2Jで開くことはできませんし,VB5には「VB2J形式で保存するなどという便利な機能はありません
注6:これら追加インストールされるのはOCXはVB5での動作保証がないばかりか,VB5で開発したアプリケーションとともに再配布することは許されていない
注7:「カットマネージャVer1.1(開発元:株式会社ジェイ・ビー・クラフト06-339-1545)」なお,現在はVB4-16により開発されたVer1.5が販売されている



● コンバート作業にまつわるエトセトラ

 16bit版のカスタムアプリケーションのVB5へのコンバートが自動コンバートのみでは足りず,追加コンバート作業が必要なことは先に述べたとおりです.これはVBに限ったことではありません.他の開発言語においても,その言語仕様がバージョンアップにより変更されれば,なんらかの追加コンバート作業が必要なものです.ただ,16bit版VBから32bit版VBへのコンバートにおいては“その注意事項”が“あまりに多く”そして“広範囲”ですから,結果としてそのための追加コンバート作業も多くなってしまうのです.
 「コンバート作業だから」というだけで安易に引かれたスケジュールが誤りであることは,作業を始めてみればすぐに明らかになります.筆者の周りでも,当初のスケジュール内でコンバート作業を完了できたプロジェクトはわずかでした.また,結局VB5で新規開発したときと同じ時間を要してしまうケースも珍しくはなく,実際にコンバートを断念し「新規開発(参考プログラムあり)」とVB5での新規開発に切り替えたケースも少なくありませんでした.
 では,何がコンバート作業を難しくしているのでしょうか?
 トラブルの事例(表2)を見てみれば,コンバートに必要な作業項目はそう多くはありません.


コントロール名 VB2J VB4-16 VB4-32 VB5
アニメーションボタン ANIBUTON.VBX ANIBTN16.OCX ANIBTN32.OCX (廃止)
アップダウン他       COMCT232.OCX
プログレスバー他     COMCLT32.OCX COMCLT32.OCX
コモンダイアログ CMDIALOG.VBX COMDLG16.OCX COMDLG32.OCX COMDLG32.OCX
クリスタルレポート   CRYSTL16.OCX CRYSTL32.OCX CRYSTL32.OCX
DBグリッド   DBGRID16.OCX DBGRID32.OCX DBGRID32.OCX
DBリスト   DBLIST16.OCX DBLIST32.OCX DBLIST32.OCX
ゲージ GAUGE.VBX GAUGE16.OCX GAUGE32.OCX (廃止)
グラフ GRAPH.VBX GRAPH16.OCX GRAPH32.OCX (廃止)
グリッド GRID.VBX GRID16.OCX GRID32.OCX (廃止)
キーステート    KEYSTA16.OCX KEYSTA32.OCX (廃止)
マルチメディアMCI MCI.VBX MCI16.OCX MCI32.OCX MCI32.OCX
MCIWndX       MCIWNDX.OCX
チャート       MSCHART.OCX
コミュニケーション   MSCOMM16.OCX MSCOMM32.OCX MSCOMM32.OCX
フレシキブルグリッド       MSFLXGRD.OCX
MSインターネットトランスファ       MSINET.OCX
MAPIメッセージ MSMAPI.VBX MSMAPI16.OCX MSMAPI32.OCX MSMAPI32.OCX
マスクエディット   MSMASK16.OCX MSMASK32.OCX MSMASK32.OCX
リモートデータ     MSRDC32.OCX MSRDC20.OCX
Winsock       MSWINSCK.OCX
アウトライン   MSOUTL16.OCX MSOUTL32.OCX (廃止)
OLEクライアント OLECLIEN.VBX (内部に) (内部に) (内部に)
ペン PENCTRL.VBX (廃止) (廃止) (廃止)
ピクチャークリップ PICCLIP.VBX PICCLP16.OCX PICCLP32.OCX PICCLP32.OCX
リッチテキスト     RICHTX32.OCX RICHTX32.OCX
システム情報       SYSINFO.OCX
スピンボタン SPIN.VBX SPIN16.OCX SPIN32.OCX (廃止)
タブストリップ   TABCTL16.OCX TABCTL32.OCX TABCTL32.OCX
3D THREED.VBX THREED16.OCX THREED32.OCX (廃止)



表2:移行にまつわるトラブル事例
VBXから上位互換のOCXへの変更
VBXが上位互換OCXに自動置き換えされない(その1)
原因 自動置き換えを行なうためには,そのVBXとおきかえるOCXの情報がvb.iniに未登録
対策 vb.iniの[VBX Conversions32]セクションのエントリにその情報を追加する
VBXが上位互換OCXに自動置き換えされない(その2)
原因 事前にOCXがレジストリに登録されていない
対策 OCXをレジストリに登録してから,再度自動置き換えを実行する
VBXが上位互換OCXに自動置き換えされない(その3)
原因 該当するVBXとOCXに互換性がない
対策 サードパーティ製のVBXの場合はその販売元に互換性の有無を確認する
Microsoft Control Packに付属するVBXの上位互換OCXは再配布できない
原因 VBのインストールフォルダにあるRedist.txtに記載がなく再配布はできない
対策 他の再配布可能なカスタムコントロールを使用するようにプログラムを変更する
VB4-32によるプログラムを同梱することにより再配布する
16bitDLLとWin16APIから32bitDLLとWin32API
作成したアプリケーションがWin32sで動作しない
原因 VB5は16bitOS環境(Win3.1)では動作しない
対策 32bitOS(Win95/WinNT4.0/WinNT3.51)を使用する
16bitDLLを呼び出すことができない
原因 16bitDLLを呼ぶことはできない
対策 32bitDLLを呼ぶように変更する
VB4-16等で16bitなOLEサーバーを作成し,それを使用する
Win32APIに変更すると正常動作しない
原因 APIの仕様が変わっているものもある
対策 他のWin32APIを使用する
システムモーダルウィンドウにならない
原因 Win32ではシステムモーダルウィンドウは使用しない
対策 プログラム仕様を変更する
16bitDLLを呼び出すことができない
原因 16bitDLLを呼ぶことはできない
対策 32bitDLLを呼ぶように変更する
VB4-16等で16bitなOLEサーバーを作成し,それを使用する
32bitDLLを呼ぶことができない
原因 Win32ではDLLプロシージャー名の大文字と小文字が区別される
対策 Win32SDKを参照し,正しく記述する
32bitDLLを呼ぶことができない(その2)
原因 DLLの参照順が変更されている
対策 DLLのパスを正しく指定する
データベースとVBをむすぶミドルウェア
SQL*NET V1.1で接続できない
原因 16bit用のSQL*NET V1.1では接続できない
対策 SQL*NET V2以降を使用する.なお,16bitとの混合環境の場合にはそれぞれのクライアントライセンスが必要
Oracle Grueが使用できない
原因 16bit版は使用できない
対策 Oracle Objects for OLE(oo4o)を使用する
ANSIコードからUnicodeへの変更
文字列操作が正常にできない
原因 VB5では内部的にUnicodeを使用するため
対策 Unicodeの使用を前提とした文字列操作に変更する
固定長文字列変数や固定長文字列変数を含むユーザー定義型変数がおかしい
原因 固定長文字列変数のレングス指定がバイト数から文字数に変更されたため
対策 文字数で定義する
バイナリデータの内容がおかしい
原因 Unicodeの採用により,バイナリデータは文字列変数では扱えない
対策 バイト型を使用する
テキストボックスのMaxLengthによる入力制限が正しく動かない
原因 MaxLengthには文字数を指定するように変更された
対策 文字数を指定する
言語仕様の変更
Psetメソッドの動きのX,Yの指定が逆になる(VB4からの移行時)
原因 VB4のバグ(VB5で修正されたため,逆になっているように見える)
対策 正しくX,Yの順で指定する
テキストボックスのMaxLengthを越えてからKeyPressイベントが発生しない
原因 仕様
対策 KeyDown/KeyUpイベントを使用する
日付に関する処理が正しく動かなくなった
原因 日付型が追加されたため,バリアント型で日付を扱っていると期待している値が得られない場合がある
対策 バリアント型を使わず,日付型または文字列型を使用する
Formのアンロード時に,そのフォームをコンテナとするオブジェクトのTerminateイベントより先に
FormのTerminateイベントが発生する場合がある
原因 おそらくバグ
対策 Form_Unloadイベントで,Set フォーム = Nothing を記述しておく
Win32の参照順:
EXEを含むフォルダ→カレントフォルダ→32bitシステムフォルダ(WinNTのみ)→システムフォルダ→Windowsフォルダ→環境変数PATHに指定されたフォルダ
Win16の参照順:
カレントディレクトリ→Windowsディレクトリ→システムディレクトリ→EXEを含むディレクトリ→環境変数PATHに指定されたフォルダ


「コンバートに必要な作業項目」

・VBXから上位互換のOCXへの変更
・16bitDLLやWin16APIのコール部分の32bitDLLやWin32APIへの変更
・データベースとVBを結ぶミドルウェアの置き換えによる変更
・VB内部での文字コードがANSIコードからUnicodeに変更されたことによる影響箇所の変更
・言語仕様の変更にともなう変更

 筆者はコンバート作業のスケジュールを誤らせる原因の多くは,次の2つの誤解によるものが多いと考えています.

「陥りやすい誤解」

・「VBXと同名のOCXだから互換性があり,簡単にOCXへの変更ができるであろう」という誤解
・「ANSIコードからUnicodeへの変更に伴なう作業はそう多くはない」という誤解


 VBXと同名のOCXでも互換性がないものは少なくありません.後述するvb.iniを利用した自動置き換えの機能を利用するためには,そのカスタムコントロール内のオブジェクトモデルとプロパティが同一でなければいけません.互換性がなければ,そのコントロールに対する操作のコードを変更することはもちろん,自動置き換えが使えず,フォーム上に手作業でコントロールを貼り直す作業が必要となり,互換性のあるコントロールに比べ多くの手間を要することは明らかです.もっとも,VBに依存しメソッドを持てない独自仕様のVBXと,OLEをベースに公開されたメソッドを持つオープンな仕様のOCXはまったくの“別物”なのですから,互換性がある方が不思議といえるのかもしれません.
 そして,もうひとつのUnicodeの問題ですが,これこそが,コンバート作業を泥沼にはめる大きな原因といえます.日本語のカスタムアプリケーションではそのほとんどが漢字を使いますから,このUnicodeの問題は深刻です.文字列の定義部はもちろん,ユーザー定義体やテキストボックスのMaxLength,さらには文字列操作時にも影響が出る可能性があります.しかし,プログラム中のどの文字列操作で問題が発生するかは,そのコードすべてをチェックしなければわかりません.さらに「原則的にVB内部はUnicode,外部はANSIコードとし,DLL呼び出し時やファイルへの読み書き時には強制的にコード変換される」という仕様が,事態をさらに混乱させています.
 先の“VBXとOCXの問題”や“16bitDLLやWin16APIの問題”などは,後で紹介するようないくつかのツールを使うことにより作業時間を大幅に軽減することもできるのですが,このUnicodeの問題だけは効果的な方法もみあたりません.本当に頭の痛い問題です.
 そうです,これらのことを考慮せずに,「コンバートだから新規作成の30%の時間でプログラムが書けるね」などと,根拠のない思い込みで引かれたスケジュールなど実現できるはずもないのです.
 また,直接VBとは関係がありませんが,大きなプロジェクトでのコンバート作業では,そのプロジェクト管理の能力も高いレベルで要求されます.大規模な修正を実施するためには,そのバージョンの不整合,修正手順のばらつき,などなど,プロジェクト全体をより深い暗闇に突き落とす要因はいくつもあります.
 なんだか暗い記事になってしまいました.こんな状況ではとても“お気楽コンバート”などはできそうにもありません.しかし,それでは面白くありませんから次の項では,少し明く“お気楽コンバート”へのアプローチ法について書くことにしましょう.

 


● ツールを使って“お気楽コンバート


 筆者はコンバート作業があまり好きではありません.なぜなら,ただでさえ単調で興味の薄い作業でありながら,その繰り返しは集中力の低下を招き,さらに面倒な事態を引き起こすことがしばしばあるからです.となれば,単調な作業はコンピュータにやらせるに限ります.VB5の自動コンバート機能や上位互換OCXへの自動置き換え機能とまではいかなくても,ちょっとしたツールはその移行作業を楽にするだけでなくプログラムの品質をもあげてくれます.まずは,VB5のCD-ROMの中を覗いてみましょう.
 なお,これらのツールの利用は個人の責任にて行なってください.これらのツールを使用したことにより生じた損害の一切について筆者および編集部は責任を負いません.


● VBXから上位互換OCXへの自動置き換え


 VB5自身が行なってくれるこの機能は,なかなか便利です.どうせならマイクロソフトのVBXだけでなく,サードパーティのVBXからの置き換えにも使いたいと思うのが人情です.ではこの機能はどのようにして実現されているのでしょうか? Windowsフォルダの中にあるvb.iniなるファイルを開いてみれば,その仕組みは一目瞭然です.そのファイルの[VBX Conversions32]セクションのエントリに,VBX名と対応するOCXのクラスID,バージョン,所在が記述されているのです(リスト1).

リスト1:vb.iniの定義内容
[VBX Conversions32]
crystal.vbx={00025600-0000-0000-C000-000000000046}#1.0#0;C:\WINNT\System32\crystl32.ocx
msmapi.vbx={20C62CAE-15DA-101B-B9A8-444553540000}#1.1#0;C:\WINNT\System32\msmapi32.ocx
mci.vbx={C1A8AF28-1257-101B-8FB0-0020AF039CA3}#1.0#0;C:\WINNT\System32\mci32.ocx
mscomm.vbx={648A5603-2C6E-101B-82B6-000000000014}#1.0#0;C:\WINNT\System32\mscomm32.ocx
msmasked.vbx={C932BA88-4374-101B-A56C-00AA003668DC}#1.0#0;C:\WINNT\System32\msmask32.ocx
picclip.vbx={27395F88-0C0C-101B-A3C9-08002B2F49FB}#1.0#0;C:\WINNT\System32\picclp32.ocx
cmdialog.vbx={F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.0#0;C:\WINNT\System32\comdlg32.ocx
msoutlin.vbx={BE4F3AC8-AEC9-101A-947B-00DD010F7B46}#1.0#0;C:\WINNT\System32\msoutl32.ocx
anibuton.vbx={F72CC888-5ADC-101B-A56C-00AA003668DC}#1.0#0;C:\WINNT\System32\anibtn32.ocx
graph.vbx={0842D103-1E19-101B-9AAF-1A1626551E7C}#1.0#0;C:\WINNT\System32\graph32.ocx
gauge.vbx={7A080CC8-26E2-101B-AEBD-04021C009402}#1.0#0;C:\WINNT\System32\gauge32.ocx
keystat.vbx={B9D22273-0C24-101B-AEBD-04021C009402}#1.0#0;C:\WINNT\System32\keysta32.ocx
spin.vbx={B16553C3-06DB-101B-85B2-0000C009BE81}#1.0#0;C:\WINNT\System32\spin32.ocx
threed.vbx={0BA686C6-F7D3-101A-993E-0000C0EF6F5E}#1.0#0;C:\WINNT\System32\threed32.ocx

 もちろん,ここにエントリを追加すれば,サードパーティのVBXもマイクロソフトのVBXと同様に自動置き換えができるようになります(注8).OCXのクラスIDやバージョンを調べるのは簡単です,VB5プロジェクトを新規に作成し,該当するOCXを[プロジェクト]-[コンポーネント]から追加した後にそのプロジェクトを保存してください.後は,その保存したプロジェクトファイルをメモ帳などのエディタで覗いてみれば,必要な情報はすべてそこにあります.


注8:そのVBXとOCXに互換性がなければ,自動置き換え後のフォームモジュールのロードでエラーになる場合がある. また,逆に「互換性がない」といわれているコントロールでも正常に置き換えできるケースもありうる

● 使用している16bitDLLおよびWin16APIコール箇所の洗い出し


 VB5では16bitDLLやWin16APIをコールすることはできません.これらは32bitDLLやWin32APIへの書き換えが必要になります.それらのDeclare文を探すことはそれほど問題もないのですが,コードの中から修正対象を見つける作業は厄介なものです.こんなときに便利なアップグレードウィザードが,VB5のCD-ROMの中に同梱されています.

“Tools\Unsupprt\Migrwiz\Cswiz.exe”

 このツールは,その名のとおり“サポート対象外”なのですが,なかなかよくできています.16bitDLL呼び出し行の洗い出しはもちろん,コンバート作業前に必要となる問題点レポートの出力や,修正すべきコードの自動生成など,使いやすいツールに仕上がっています.


図3:VB5に付属するアップグレードウィザード






 ご覧の通りPDQCommなどでおなじみのアメリカの会社の製品です.いかにも「急遽VB5に対応した」といわんばかりのタイトルはさて置き,このツールの実力は先に延べたとおりです.ただし日本語版VB5での動作は前提としていないでしょうから,日本語のファイル名やオブジェクト名を付けていると正常に動作しない可能性もありますが(筆者の環境では正常に動作しているようです),この会社のホームページにはこのプログラムの改訂版とそのソースコードがともに公開されていますので,いずれにせよ問題はないでしょう.

Crescent Division of Progress Software
http://www.progress.com/crescent


● 互換性がないOCXの貼り付けとプロパティの設定を自動で


 VB5が提供するOCXの自動置き換え機能は,互換性のあるOCXについてのみ利用できます.もちろん,互換性がないカスタムコントロールを置き換えてもうまく動く保証はありませんので,VB5の自動置き換え機能自体に問題があるわけではありません.しかし,ソースコードの変更は高機能なエディタなどで一括変更を行なえるなど,比較的短時間で作業を終えることができるのにくらべ,フォーム上にカスタムコントロールを貼り直して必要なプロパティを設定してゆく作業はなかなか大変な作業です.なんとかこの“貼り付け”の作業だけでも楽にこなす方法はないでしょうか?
 試しに互換性のないOCXを先のvb.iniに指定してみると,自動置き換えができるOCXもあります.場合によってはそのOCXの置き換え時や,カスタムコントロールが貼られているフォームを開く際にエラーが発生したり,いくつかの情報が失われることもありますが,いったん保存し直せば特に問題もないようです.エラーの原因はその.logを見ればわかるとおり,VBXにはあったプロパティがOCXでなくなっている場合に発生しています.また,このような場合にはアイコンイメージなどの.frxファイルにバイナリ形式で保持されていた情報も失われてしまうようです.
 フォームに貼り付けられたらしめたものです.後は失われたプロパティ情報や,非互換の部分のコードを修正すれば置き換え作業は完了となります.また,無理矢理貼り付けことが少し不安でもありますが,作業効率のUPには有効な手段のひとつといえます.


● さらに互換性のないOCXを無理やり貼り付ける


 まったく別のOCXと置き換えようとしたり,また同名のOCXであるにもかかわらずそのカスタムコントロール内のオブジェクト構造に変更が加えられている場合には,前項の自動置き換えの最初の段階ですらエラーになり,そのフォームモジュール自体がプロジェクトから除外される場合があります.これはOCX内のカスタムコントロールのクラス名が変更されている場合に発生するようです.
 このケースはどのように対処すれば,“お気楽コンバート”が実現できるのでしょうか?
 方法はあります.フォームに貼り付けたカスタムコントロールの内容は一部のバイナリ情報を除き,プロジェクトファイルとフォームモジュールにテキスト形式で記述されていますから,それらの記述内容を直接編集することにより,フォームへのカスタムコントロールの貼り付けや,VBXからの一部のプロパティの引き継ぎが可能になります.
 では,実際にファイルの中身を覗いてみましょう(プロジェクトファイルとフォームモジュールをメモ帳で開ければその中身を見ることができます:図4).

図4:プロジェクトファイル・フォームモジュールの直接編集

 VB2Jのプロジェクトファイルやフォームモジュールの内容はとても単純ですが,VB5の方は少し複雑で,とても直接編集するなどということは困難なように思えてきます.しかし,よい方法があります.VB4-16とVB4-32でも同じ構造のプロジェクトファイルとフォームモジュールを作ってみましょう(VB2Jで作成したものをVB4-16でコンバートすれば簡単です).それぞれのファイルの内容を並べてみてみると,どこを直せばよいのかは自ずと解ってくると思います.
 後はその規則性にしたがい,エディタなどで一括変換すればでき上がりというわけです.
 もちろん,これはあくまで“カスタムコントロールの貼り付け”を一括で行なうためのツールですから,コードの中身は別途修正する必要があることはいうまでもありません.
 今回は紙面の都合もあり,各ツールや筆者が作成したツールについて詳細な説明をすることはできませんでしたが,またいずれ本誌またはPC Developer's Networkにてご紹介させて頂くことにします.どうぞお楽しみに.


●最後に


 これからも開発言語のバージョンアップがある限り,過去の資産のコンバート作業は避けては通れません.今回の記事では触れませんでしたが,コンバートをより“お気楽に実現する”には,必要なドキュメントに事前に目を通すことも必須といえます.VB5の場合ならば,マニュアルのWhat Newの項はもちろん,readme.hlpやvb5dll.txt,そしてマイクロソフトのホームページやMSDNにより公開されているFAQやKnowleage Base,PC Developer's Networkなどの団体のFAQやNews Groupのログに目を通しておくことも必須といえるかもしれません.やはり「敵を知り己を知れば百戦危うからず」なのです.
 また,丁寧につくられたプログラムは意外と簡単にコンバートできるものです.たとえば,変数の型定義はもちろん,その型変換を明示的に行なっているプログラムとVBのバリアント型や自動型変換機能を使っているプログラムとでは,そのコンバートのしやすさは大きく違います.さすがに変数の宣言を省略するプログラマはいないでしょうが,正しいコーディング,推奨されているコードィングを心がけ,実践していくことが,次回のコンバートの助けになることはいうまでもありません. なにごとも基本が大切なのです.



コンバートの前に


本文のVB2JからVB5へのコンバートの問題を読まれて,コンバート作業に不安を覚えた方もいらっしゃるかもしれません.確かに筆者も今回のVB2JからVB5へのコンバートは「労多く実りの少ない」コンバートであると思います.できることならば,VB5の優れた新機能を使うためにも,コンバートより“作り直し”を選ぶ方が正しい選択といえます.しかし,すでに多くのVB2Jプログラムという資産を抱えている方には「では,作り直しで…」とはゆかないでしょう.是非はともかく「短期間で,とりあえず動かす」ことが前提となる場合も多いでしょうし,運がよければ(上位互換のOCXやDLLがあれば)意外と簡単にコンバートできる場合もあります.
しかし,VB5へのコンバート作業を見くびってはいけません. 変更箇所は多大で複雑です.必ずコンバート作業のチェックリストをつくり,漏れのなく確実なコンバート作業をしてください.以下にサンプルを上げておきます.ご武運を!


コンバート作業のチェックリスト


Part1:まずはバックアップ

0.VB2Jプログラムをクリーニングしておきましょう
・VB5がVB2Jに比べてかなり複雑であるため,コンバートする前にクリーニングしておく
・コンバートする元のプログラムについているゴミは先にとっておく(後述).

1.【必須】VB2Jプログラムをバックアップします
・コンバートするプロジェクトのすべてのファイル(*.MAK,*.FRM,*.BAS,*.FRX)は必ずバックアップ(コピーして保存)する
・コンバートに失敗した場合に備えることはもちろん,成功した場合にも必要
・コンバート済みプロジェクトはVB2Jで開けなくなる

2.【必須】使用していないカスタムコントロール(*.VBX)をすべて外します
・必要のないカスタムコントロールは,コンバート上は単なるゴミ.すべて外しておく
・プロジェクトウィンドウに表示されているVBXファイルを選択し,[ファイル]-[ファイルの解放]とすればカスタムコントロールを外せる
・必要なVBXファイルを間違って解放しようとすればエラーとなるので,安心して,片っ端から外そう

3.変数宣言を必須にして,変数の型を明確にしましょう
・フォームモジュールやコードモジュール(VB4-16では標準モジュール)のgeneral declarationsの先頭に
  Option Explicit
・を追加すれば,変数宣言が必須になる
・プロジェクトを実行し「変数が定義されていません」エラーが発生したプロシージャにローカル変数を定義する
・整数型(Integer),長整数型(Long),単精度浮動小数点型(Single),倍精度浮動小数点型(Double),通貨型(Currency),文字列型(String)から正しい型を定義する
・もし,わからない場合はバリアント型(Variant)にしておこう
・また,あまりに未定義の変数が多い場合には,涙をのんで変数宣言をあきらめよう(深追いは失敗の元)

4.【必須】フォームモジュールはテキスト形式で保存しましょう
・バイナリ形式で保存されたフォームモジュールはコンバートできない
・[ファイル]-[名前を付けてファイルの保存]で表示されるダイアログボックスの「テキスト形式で保存」にチェックして保存

5.【推奨】プロジェクトで使用するファイルはできるだけひとつのディレクトリにまとめましょう
・階層化されたディレクトリにファイルが別れていると,コンバート機能や調査ツールが正常に動作しない場合がある
・[ファイル]-[名前を付けてファイルの保存]で同じディレクトリ内に保存
・なお,ディレクトリ名には日本語(漢字やカナ)は使わないように.コンバート機能や調査ツールが正常に動作しない場合がある

【中級】プロジェクトやファイルの数が多い場合にはファイルマネージャで必要ファイル(*.MAK,*.FRM,*.BAS,*.FRX,など)を同じディレクトリに集めた後に,プロジェクトファイルを直接編集することもできる

6.【必須】コンバート前に正常動作することを確認しておきましょう
・きちんと動かないプログラムをコンバートすることはトラブルの元
・開発中のプログラムであれば,VB5の新機能を学習した上でVB5で新規開発するべきである

7.【注意】巨大なプロシージャは分割しましょう
・大きすぎるプロシージャやモジュールは,コンバートできない場合がある
・ただし,分割にはリスクを伴なうため,コンバートができない場合にのみ分割する方がよい

Part2:VBの情報を集める

8.VB2JやVB5(VB4-32)のバグ情報を集めておきましょう
・VB2Jでのバグ回避ロジックが,VB5であだになる場合がある(VB2Jのバグが修正されたために,逆にプログラムの動作がおかしくなる場合など).
・マイクロソフト株式会社のホームページ(http://www.microsoft.com/japan/)のサポート情報やFAQ,PC Developer's Network(http://pcdn.int21.co.jp/pcdn/)のFAQの一覧をチェックしておこう

9.VB5の新機能の情報を集めておきましょう
・VB5のBooksOnlineのWhat's New,VB5のCD-ROMよりReadme.hlp,やVB5DLL.TXTなど

10.【推奨】本文にて紹介したアップグレードウィザード(事前調査ツール)の最新版のソースコードを入手ししよう
・Crescent Division of Progress Software(http://www.progress.com/crescent

Part3:VBXからOCXへの互換性を調査する

11.【必須】コンバート対象のプロジェクトすべてで使用しているVBXを洗い出しましょう
・プロジェクトファイルをメモ帳などのエディタで開き確認
・対象プロジェクトが多い場合には,秀丸エディタなどに付属するgrep(文字列検索機能)を使用し,「検索文字列:VBX,対象ファイル:*.mak」として抽出した情報をExcelなどでソートすればお手軽

12.【必須】11.で洗い出したVBXの上位互換OCXの有無を調査しましょう
・マイクロソフト製品については,本文のとおり
・他のサードパーティ製のVBXはその販売元に確認する

13.【必須】12.で得たOCXをインストールし,クラスIDなどの情報を入手しましょう(互換性のないOCXも調査しておきましょう.運がよければ使えるかもしれません)
・インストール後にVB5の新規プロジェクトを作成し,すべてのコントロールをフォームに貼りつける
・上記プロジェクトを保存し,そのプロジェクトファイル(*.vbp)の内容をメモ帳などで開いておく

14.【必須】11〜13.で得た情報を元にvb.iniを編集しましょう
・[VBX Conversions32]セクションにエントリを追加(詳細は本文を参照してください)

15.【必須】互換性(失われる情報)を確認しましょう
・VB2Jの新規プロジェクトを作成し,11.で得たすべてのカスタムコントロールを張り付けて保存
・メモリ不足になる場合には複数のプロジェクトに分割して貼り付ける
・上記プロジェクトを保存し,各ファイルの内容をバックアップしておく
・VB5で開く(コンバートの実行).
・コンバート中のエラーの内容や,ログファイル(*.log),コンバート後の内容をチェックし,コンバートできないカスタムコントロールや失われる情報を確認しておく
・コンバート後の各ファイルの内容を比較し,失われる情報を確認
・特にFRXファイル(カスタムコントロールのバイナリ情報を保存するファイル)の情報は失われる場合が多いので注意
・コンバートできないカスタムコントロールや失われる情報については手作業で設定することに

Part4:16bitDLL,Win16APIから32bitDLL,Win32APIへの変更内容を調査する

16.【推奨】10.で取得したアップグレードウィザードを実行し,レポートを作りましょう
・変更対象となる16bitDLLをコール,Win16APIコールの有無を確認
・プロシージャが大きくなければ,コメントの追加や自動コンバート機能を利用するのもよい

17.【必須】16bitDLLを代替する32bitDLLを調査しましょう
・パラメータ定義を含め,変更内容を明確に
・代替する32bitDLLがなければ,そのDLLを使う16bitOLEサーバーをVB4-16等で作成(詳細は割愛)することになるため,コンバートの中止も含め対策を検討すべき

18.【必須】Win16APIと同機能のWin32APIを調査しましょう
・Win32SDK(Visual C++やMSDNに付属する32bit版 Windows APIのリファレンス)により,変更内容を明確に
・パラメータの型や文字列の引き渡しなどに注意

Part5:VB5へのコンバート

19.【必須】コンバート直前のファイルの内容をバックアップしましょう
・コンバート処理の再実行をしやすくするため

20.【必須】VB5でVB2Jのプロジェクトファイルを開きましょう(コンバート実行です)
・エラーログ(*.log)の内容を確認しよう

21.【必須】失われた情報を復旧しましょう
・15.の調査結果を元に,失われた情報を復旧
・コンバートできずピクチャーボックスになってしまったカスタムコントロールは手作業で貼り直す
・復旧作業はVB2JとVB5を同時に起動し両プロジェクトを比較しながら作業すると便利

22.【必須】16bitDLL,Win16APIを32bitDLL,Win32APIに変更しましょう
・16〜18.で調査した内容にしたがい,該当部分を修正

Part6:言語仕様の変更に伴なう変更

23.【必須】Unicode対応(その1)を行ないましょう
・固定長文字列型の妥当性を確認(“As String”をキーワードに19.のファイルをgrep)
・特にユーザー定義体には注意
・文字列操作の妥当性を確認(下記のステートメントをキーワードに19.のファイルをgrep)
  Asc,Chr,InStrB,LeftB,LenB,MidB,RightB
・ファイルの入出力部分を確認(下記のステートメントをキーワードに19.のファイルをgrep)
 Input,Output

24.【必須】Unicode対応(その2)を行ないましょう
・MaxLengthの指定をバイト数から文字数に変更(下記のステートメントをキーワードに19.のファイルをgrep)
  MaxLength

25.【必須】予約語の拡張にともなう文法エラーなどを修正しましょう
・実行し,文法エラー箇所を修正
・[ツール]-[オプション]-[全般]の「順次コンパイル」のチェックは外しておきます.

26.【必須】動作確認し,その他の不具合を修正します
・(本文の移行に伴なうトラブル例や,上記8〜10.を参照してください)

お疲れ様でした.


VB Magazine ライブラリ | Visual Basic WorkGroup
int21 ホームページ | PCDN ホームページ


Copyright (c) 1998 int21 Corporation All Rights Reserved.
For questions or comments, please send mail to: pcdn@int21.co.jp