Tips & Tricks

2024年4月24日更新
今回はプログラミングをする際のヒントやコツに関してです。
標準外の便利な機能や知っていると重宝する技などを紹介します。
全てプロデル用の内容ですが他言語からの流用も含まれます。

プロデルを使い始めた頃は正直なところ戸惑いました。
それは英語的な表記のプログラミングに慣れていたからでした。
その為に逆に取っつき難く感じました。
暫くして「プロデルは大変だけと難しくはない」と感じました。
「大変」と感じるのは関連情報が少ないからです。
そして完成したソースを眺めたら「難しくはない」と感じました。

その後は開発環境をプロデルに変えて今日に至っています。
そこでプロデル初心者から初級者を対象に何かの役に立てばと、
その間に培って来たノウハウを公開します。
[ 01 モーダルとモードレス ]
デスクトップ プログラムを作るのであればウィンドウが有るのが普通です。
その形態は一つではなくプロデルにも数種類が用意されています。
その中に「ダイアログ」という種類が有ります。
主にユーザに何かを選択させる為に使います。
ダイアログはユーザが何かを決定するのを待って次の処理に移ります。
この様な形態を「モーダルウィンドウ」と言います。

多くの場合はこの様な仕様で何も問題有りませんが、
時にはダイアログを表示しつつ裏で何かの処理を行いたい事も有ります。
その様な形態を「モードレスウィンドウ」と言います。
今回はプロデルでこれを実現する方法を紹介します。

例えばメインとダイアログの二つのウィンドウを用意して、
メインウィンドウだけを表示させます。
ダイアログウィンドウの方はメインのボタン操作から表示させます。
そのボタンのイベントには普通なら下記のような内容が書かれます。
ボタンがクリックされた時の手順
  情報音を鳴らす
  ダイアログを表示する
 終わり

これは普通のモーダルなウィンドウなので、
ダイアログが閉じられるまで次の動作に移れません。

もしもダイアログをモードレスで表示させたいなら、
下記のようにする事で可能です。
ボタンがクリックされた時の手順
  スレッド1というスレッドを作る
  スレッド1で『
   情報音を鳴らす
   選択ダイアログを表示する
  』を実行する
  何かの処理
 終わり

[ 02 「チェックされた」の意味が誤解されやすい ]
チェックボックスのイベントに「チェックされた」が有ります。
表現の紛らわしさも有り誤解される事が有ります。
私も最初はそうでした。

チェックボックスの「チェックされた」というイベントは、
「チェックが付けられた」とか「チェックが書き込まれた」の意味ではなく、
単に「チェックされた」という事でチェックが外された時も発生します。
因みに「チェックが外れた」というイベントは有りません。

チェックボックスのチェックの状態は「状態」プロパティで判断します。
コントロールに備わっているメソッドとプロパティを理解して使わないと、
思わぬところで嵌ってしまう事になります。
[ 03 トグルという動作 ]
電気のスイッチを例にするとシーソースイッチの場合、
ボタンを倒してどちらかに傾ける事でスイッチを切り替えます。
見た目でもスイッチの状態が分かる一般的な方式です。

押し込む動作のプッシュスイッチは同じ動作でON/OFFを切り替えます。
見た目ではスイッチの状態が分かり難い事が多いので、
パイロットランプを併用したりします。
この様なスイッチの動作の事を「トグル動作」と言います。

今回はプロデルでトグル動作をさせる方法を紹介します。
チェックボックスは「チェックされた」と「チェックが外れた」の、
二つの状態を切り替えるのでこれも一種のトグル動作です。

ここで問題です。
チェックボックスにチェックを入れたり外したりする場合、
貴方ならどのようなプログラムを書きますか?
そのチェックボックスのチェックや状態を取得して、
条件判断文で処理を分岐させますか?

勿論、それはそれで不正解では有りませんがもっと良い方法が有ります。
こういう時には否定文を使うと便利です。

チェックボックス1のチェックをチェックボックス1のチェックでないに変える

これだけでチェックボックスのチェックを切り替える事ができます。
[ 04 すんなりとは行かないアクティブ化 ]
処理の途中で自分のウィンドウをアクティブにしたい時が有ります。
アクティブ化の方法は幾つか在るとは思いますが、
私が思いつくのはウィンドウハンドルを利用する方法と、
プロセスを利用する方法の二通りです。
今回は後者の方法です。

簡単なサンプル プログラムを用意しました。
ウィンドウだけで何も配置していないプログラムです。
このプログラムは開いた時にメモ帳を起動します。
その後、タイマーを使って自分とメモ帳のウィンドウを交互に切り替えます。
只それだけの簡単なものですがこれを使って説明します。

サンプル プログラムは こちら からダウンロードできます。

先ずはサンプル プログラムの「アクティブ化対処前」を実行してください。
ウィンドウが切り替わらず意図した動作がされない筈です。
次にサンプル プログラムの「アクティブ化対処後」を実行してみてください。
今度は意図した通りにウィンドウが切り替わったと思います。

この違いはたった一行の処理の追加です。
具体的な相違はソースをご覧ください。
この現象は他の言語でも経験が有るので対処できましたが、
私の力量では説明をする事はできません。
[ 05 動的に生成する ]
コントロールを予め配置して置くのではなく、
プログラムの実行時に行う事を「動的に生成する」と言います。
扱う数にも依りますがプログラミングの効率が上がります。
便利な反面で若干の制約が有ります。

個別に名前やイベントを設定できないので工夫が必要です。
配列を併用すると簡潔に書く事が可能です。
今回はボタンコントロールを動的に生成したメニューを用意しました。
言葉で説明しても分かり辛いのでソースをご覧ください。

サンプル プログラムは こちら からダウンロードできます。

[ 06 Zip書庫を解凍する ]
今回はプロデルからZip書庫を解凍する方法です。
勿論、専用のDLLを使えば簡単にできる事なのですが、
セキュリティ等の問題で外部からソフトを持ち込めない状況も有ります。

実を言うとプロデルからもネット型を使えば簡単にできてしまいます。
しかし、そのネット型自体が初心者には難し過ぎます。
今回紹介するのはそれよりずっと分かり易いVBScriptを応用した方法です。

プロデルには他言語を取り込んで実行する機能が豊富に用意されています。
VBScriptの場合はCOM型を使用して実行します。
初心者にはCOM型も難しいと思うかも知れませんが、
VBScriptの原型を残しているのでネット型より遥かに易しいです。

先ずは解凍からです。
以前は結構使われていた「CopyHere()」というメソッドを使います。
数年前に非推奨扱いになりましたが現在も使えます。

ZIPファイルを解凍する時の手順
  ShellApplicationからインスタンスを作ってShellAppとする
  objZip=ShellApp:NameSpace(「[対象ファイル]」)
  objSource=objZip:Items()
  objDest=ShellApp:NameSpace(「[テンポラリフォルダ]Work\」)
  objDest:CopyHere(objSource)
 終わり


次回は同じCOM型を使用して圧縮操作を行います。
[ 07 Zip書庫を作成する ]
前回の解凍に続いて今回はファイルを圧縮してZip書庫を作成します。
VBScriptの経験が有るとバイナリファイルを扱えないと思うかも知れませんが、
VBScriptでもADODBを使えばそれが可能です。
しかし、今回はプロデルと融合させて使用するのでそれも必要ありません。

先ずはプロデルでバイナリファイルを作成してそれを容れ物とします。
次にZip書庫のヘッダ情報をバイナリ配列で用意して、
先程用意した容れ物へ順次書き込んで行きます。
最後に圧縮対象のファイルを書き込みます。
ここでも解凍時と同様に「CopyHere()」メソッドを使います。

ファイルをZIP圧縮する時の手順
  FileSystemObjectからインスタンスを作ってObjFSOとする
  ベース名=ObjFSO:GetBaseName([圧縮対象])
  生成先は、「[テンポラリフォルダ]Work\[ベース名].zip」
  作成場所は、[ファイルパス]のフォルダだけ
  NewZipというバイナリデータを作る
  内容配列は、{80,75,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
  内容配列を要素にそれぞれ繰り返す
   NewZipに要素をバイトとして書き込む
  繰り返し終わり
  NewZipを「[生成先]」へ、保存する
  NewZipを、閉じる
  ShellApplicationからインスタンスを作ってShellAppとする
  objZIP=ShellApp:NameSpace(「[生成先]」)
  objZIP:CopyHere(「[圧縮対象]」)
  番号を1から増やしながら10まで繰り返す
   圧縮ファイルというファイル情報(「[生成先]」)を作る
   圧縮容量は、圧縮ファイルのサイズ
   もし圧縮容量が22なら
    0.5秒待つ
    繰り返しを続ける
   そうでないなら
    繰り返しを抜ける
   もし終わり
  繰り返し終わり
 終わり


「CopyHere()」メソッドの下にある繰り返し文は、
「CopyHere()」メソッドの完了を待ち合わせています。
[ 08 二重起動を防止する ]
プログラムを作成していると多重に起動すると不都合な事が有ります。
そういう場合には二重起動防止処理を入れる事で簡単に解決します。
それを素のプロデルで行う方法を考えましたので紹介します。
下記コードをプログラムの冒頭へ書き加える事で実現します。
例外監視
  プロセス一覧は、「二重起動防止」のプロセス一覧
  起動数は、プロセス一覧の個数
 発生した場合
  起動数は、0
 監視終わり
 もし(起動数>1)なら
  番号は、1
  指定は、2
  プロセス一覧をプロセスにそれぞれ繰り返す
   もし(番号が指定)ならプロセスを終了する
   番号を増やす
  繰り返し終わり
 もし終わり


二行目の「二重起動防止」の所にはプログラムのベース名を書きます。
九行目の数字は「1」または「2」を指定します。
「1」を指定すると既に起動しているプログラムが終了し、
「2」を指定すると今起動しようとしたプログラムが終了します。
[ 09 時にはボキャブラリが問われます ]
自分が作りたいものを作るにはプログラミングのスキルは重要です。
勿論、正統派のプログラミング テクニックは高いに越した事は有りませんが、
此処で扱っている「コツ」なども役に立ちます。
しかし、時には自分の語学力の低さが妨げになる事も有ります。

デスクトップ プログラムを作成する時には殆ど遭遇しませんが、
プラグインを開発する時等は要注意です。
デスクトップ プログラムと違ってプラグインは特定の機能を纏める事が多く、
その内部の手順が多くなる程に手順名が似通ってしまいがちです。

詳しい方では無いので間違えているかも知れませんが、
プロデルは手順を動詞と助詞だけで判別しています。
他に書かれている名詞や変数などは判別に影響を与えないようです。
つまり一見全く違って見える手順名であっても、
使われている動詞と助詞が同じなら同じものという判定です。

当然、同じ手順名が幾つも書かれていたらエラーになります。
しかし、そのエラーはデザイナ上で実行している時には発現しません。
実行ファイルにしてから始めて気付く事になります。
これを防ぐには同じ動詞と助詞の組み合わせを作らない事です。

只、助詞を適当に変えてしまと日本語的に可笑しな表現になる事が多く、
有効な解決策として同じような意味合いの動詞を使い分ける事になります。
日本語プログラミング言語のプロデルで日本語のボキャブラリを問われます。
冗談のような話ですが実際に何回も経験しています。