明日をおもしろくするサイトです。お勧めの商品、お店、スポット、書籍、プログラミングの情報が満載です。入門講座(第3回)本講座のトップページでは、C言語仕様が自由である事の功罪と、特定の個人/組織でしか通用しないローカルなルールでソフトウェア設計を束縛する事の功罪について述べました。以上の事を踏まえ、第3回では、オブジェクト指向設計の世界で常識とされている幾つかの習慣をC言語によるソフトウェア設計に取り入れる事を提案します。今回提案する習慣は、以下の5つです。変数と関数の有効範囲(スコープ)を局所化する。グローバル関数の呼び出しを「ソフトウェア部品名_アクション名(引数...)」で表現する。ソフトウェアの構造を階層化する。上位アプリケーションをパソコン上で動かす。変数と関数の有効範囲(スコープ)を局所化する第1回では「特定の役割り」を担う複数の「部品」によってソフトウェア全体を構成する事の重要性について述べ、その部品が備えるべき特性として、他の「部品」からは見えない/見る必要の無い、隠された「変数」や「関数」を有するという特性を挙げました。これは、オブジェクト指向設計において、当たり前のように適用されている習慣です。この習慣を適用するための第一歩は、「グローバル変数」を極力、使わない事です。重要なデータは、何れかのソフトウェア部品内でstatic宣言して外部から隠ぺいし、データを所有するソフトウェア部品によって許可された方法、すなわちグローバル関数呼び出しによってのみ、更新または参照できるようにするのです。これにより、データ構造も隠ぺいできます。「0から始まるユニークな番号」と、「16ビット長のデータ」を「対」で沢山、保持するソフトウェア部品があったとします。この場合、データは以下のような構造体配列で管理できます。lv_XxxDataTable[DF_XX_DATA_NUM];がしかし、このデータを参照する側のソフトウェア部品では、このようなデータ構造の詳細は知る必要が無く、参照用の関数として用意された、以下のようなグローバル関数を呼べば良いだけです。*pData);第1引数の番号に相当するデータが存在しない場合はfalseを返し、存在する場合は、第2引数のポインタが指す先にデータを格納し、trueを返せば良いのです。すれば、今後、何かの事情でデータ構造を変更する必要が生じた場合でも、データを参照する外部のソフトウェア部品のソースコードは変更しなくて済みます。デバッグの目的でデータ参照のログを取りたい...という場合は、前記のグローバル関数の中でログを出力するだけで済みます。外部のソフトウェア部品のグローバル関数を「スタブ」と呼ばれるテスト用の関数に差し替える事で、単体テストがし易くなります。このように設計する事に対して、関数呼び出しが1段増え、実行時間やコードサイズが増える事を嫌がる人がいますが、本講座のトップページで述べたとおり、昨今のマイクロプロセッサの高速化/フラッシュメモリの大容量化/低価格化を考えれば、許容されるレベルと思います。関数についても、グローバル関数を減らす事を心掛け、外部から呼ぶ事のできないstaticな関数を中心に処理します。グローバル関数の呼び出しを「ソフトウェア部品名_アクション名()」で表現するオブジェクト指向設計では、本記事で提案する「ソフトウェア部品」は「オブジェクト(インスタンスと呼ばれる場合もあります)」に相当します。クラスは、オブジェクトの「型」を意味します。そのオブジェクト指向設計では、オブジェクトが所有する関数の内、外部のオブジェクトから呼び出せる関数は「publicなメンバ関数」と呼ばれ、その関数呼び出しは「オブジェクト名.関数名()」で表現します。オブジェクト指向設計では、publicなメンバ関数呼び出しは、そのオブジェクトに対して「メッセージ」を送る行為と見なせます(「メッセージパッシング」といいます)。データベースの役割りを担うオブジェクト「dataBase」に対して「データを読みたい」というメッセージを送るには、「dataBase.Read()」という関数呼び出しを実行するのです。このようにオブジェクト指向設計では、ソフトウェア部品間で何らかのメッセージやデータ(メンバ関数の引数で渡す)をやり取りする場合、必ず「dataBase.Read()」のようにソフトウェア部品名(すなわちオブジェクト名)」メッセージ内容(すなわちpublicメンバ関数名)を「ペア」で表現する事がプログラミング言語仕様で義務付けられています。これに対して、C言語ではグローバル関数の呼び出しに際して、そのようなルールは存在しません。従って、本記事で提案する「幾つかのソフトウェア部品で全体を構成する」ような設計を行い、その部品間でやり取りする際、どの部品に対するアクションなのか、Cの言語仕様としては、表現する手段が無いのです。すれば良いでしょうか?本記事では、グローバル関数名に特別な「命名規則」を設ける事で、この問題に対処する事を提案します。具体的には、「グローバル関数名のプリフィックス(接頭語)としてソフトウェア部品名を書く」事を提案します。1つのソフトウェア部品は「部品名.c」と「部品名.h」の2つのソースファイルに記述する事を提案します。ヘッダには、そのソフトウェア部品のグローバル関数呼び出しに必要な「プロトタイプ宣言」と「型宣言」「マクロ宣言」等を記述します。データベースの役割りを担うソフトウェア部品をCのソースファイルで「DataBase.c」「DataBase.h」として記述したとします。この場合、ソフトウェア部品名は「DataBase」になりますので、そのグローバル関数名は、たとえば「DataBase_Read()」とします。この命名規則だけでは、static関数名と区別できないので、グローバル関数は、大文字で始め、static関数は小文字で始める。static関数には、プリフィックス(接頭語)として「l_」を付ける。static関数名には、アンダースコア「_」は使わない。等、static関数にも「命名規則」を設ける必要があります。以上のようなルールは、特定の個人や組織でしか通用しないルールなのですが、その根本は、オブジェクト指向設計のルールに基づいており、効果的なルールとして機能すると思います。初期化関数を持つオブジェクト指向設計では、オブジェクトを動作させる際、予め「生成」というステップを踏む必要があるのですが、その際、「コンストラクタ」と呼ばれる、自身を初期化するための専用のメンバ関数が呼ばます。C言語によるソフトウェア設計でも、この習慣を取り入れる事を提案します。具体的には、「ソフトウェア部品名_Init()」という初期化関数を準備し、起動後にSchedulerから1度だけ呼び出すようにするのです。ソフトウェアの構造を階層化するC言語において、変数/関数の有効範囲(スコープ)として利用できる範囲は、以下の3種類しかありません。従って、これらを有効活用してソフトウェアを設計する事になるのですが、理想的な有効範囲は、それぞれ1ソースファイルは、千行以内1関数は、数十行くらい1ブロックは、数行くらいだと思いますので、大規模なソフトウェア開発では、千行くらいのソースファイルを大量に書く事になります。変数や関数に局所性を持たせたのと同じ理由で、ソフトウェア部品についても、全ての部品と関係を持つソフトウェア部品は少なくし、一部のソフトウェア部品間でのみ関係を持つように、局所化/グループ化する事をお勧めします。その際、同一グループのソースファイル群は、サブフォルダに分けて管理する事をお勧めします。そのソフトウェア部品の局所化/グループ化に際しては、1階層の広い平面内で局所化/グループ化するだけで無く、多層化し、階層化された空間内で局所化/グループ化する事も重要です。この階層化ですが、オブジェクト指向設計では、オブジェクト間で「継承(is-a)」や「包含(has-a)」という関係を持たせ、階層化する事が一般的ですが、C言語では、クラスが無いため、そのような設計を行う事は難しいです。(関数ポインタをメンバに持つ構造体を使えば、同じような設計ができなくは無いですが、本記事で提案したい方法ではありません)。「オブジェクト指向設計では、階層化する事が一般的なのだ」という事を念頭に置いて、C言語によるソフトウェア部品の設計に際しても、階層化を意識する事は重要と考えます。どのようにソフトウェア部品を階層化すれば良いでしょうか?その1つのアイデアは、「詳細な仕事」を担うソフトウェア部品と、その機能を活用して「より抽象的な仕事」を担うソフトウェア部品を設ける事で、階層化する案があります。Layerというソフトウェア部品について説明しましたが、これらは階層化された関係を持つと言えます。上位アプリケーションをパソコン上で動かす上位アプリケーションをパソコン上で動かす事は、オブジェクト指向設計とは直接、関係しないのですが、オブジェクト指向で設計されたソフトウェアの多くは、WindowsやLinuxが稼働するパソコン上で実行されるため、ここで説明させて頂きます。これまで述べてきたような習慣に基づいてソフトウェアを設計した場合、階層化された設計の上位に位置するアプリケーション部は、実際のハードウェア上だけで無く、パソコン上で動かす事も容易です。この記事では、上位に位置するソフトウェア部品をWindowsやLinux上のソフトウェアとして開発される事、もしくは実際のハードウェア上でデバッグされる前に、上位に位置するソフトウェア部品だけをパソコン上で実行される事(デバッグされる事)をお勧めします。この設計方法は、一部の書籍では「デュアルターゲット」として紹介されています。パソコン上のソフトウェアとして組み込みソフトウェアの一部を開発した場合、以下のようなメリットが得られます。ハードウェアを入手するまでに上位アプリケーション部の単体テストが実施できる昨今の組み込みシステムの開発では、ソフトウェアとハードウェアは同時並行開発される事が多いです。ソフトウェア設計者にハードウェアが手渡される際、デバッグやテストを終えた信頼性の高いハードウェアが手渡される事は稀で、ソフトウェアのデバッグの際に、併せてハードウェアの動作検証を求められる事は少なくありません。いうケースでは、いきなり上位アプリケーションまで含めた全ソフトウェアをハードウェア上で動かすと、不正動作の原因が解らず、混乱を招く事が多いです。これに対して、上位アプリケーション部は、別途、パソコン上で開発/デバッグ/単体テストまで進めておき、入手したハードウェア上では、本記事で「擬似パソコン化」として提案した一部のソフトウェア部品と、その上位に位置づけられる「試験用ソフト」だけを動作させ、別々に開発を進めた場合、前記のような混乱は、最小限に抑えられます。C++を利用)、未初期化のauto変数を参照したり、不正なメモリをアクセスした場合は例外が発生し、ブレークする事が多いため、この種の不具合は、初期段階で改修できる可能性が高いです。これに対して、前記のような不具合を含むソフトウェアを実機上で実行した場合、不正アクセスの直後でブレークさせる事は難しく、別の異常現象として現れますので、デバッグに時間を要する事になります。組み込みソフトウェア技術者「以外」の技術者に協力を仰げるこれまで述べてきたような習慣に基づく上位アプリケーション部の開発は、組み込み用途で無い、一般的なソフトウェア開発と大きな違いはありません。よって、技術者を確保する際、組み込みソフトウェア技術者だけで無く、C言語特有の言語仕様(ポインタ等)を勉強してもらう前提で、C#/Java等の経験者に協力を仰ぐ事も可能になります。ダウンロードが不要パソコン上でソフトウェアを直接(ネイティブとして)実行する場合、ダウンロードという手順は不要で、ビルドが終われば、即、実行可能です。これに対して、組み込みソフトウェアを実機上で実行するには、ダウンロードという手順が必要となります。このダウンロードですが、累計時間で見れば、それ程、負荷の高い作業では無いですが、別の作業が実施できる程の時間では無く、思考が途絶える「待ち時間」になってしまう事が多いです。故に、ビルド時間も短く、ダウンロードが不要なソフトウェア開発は、設計者にとって生産性が格段に向上したような感覚をもたらします。続く第4回では、これまで述べた習慣に基づき、実際に「電気ポット」のソフトウェアを設計します。入門講座(第2回)第2回では、Schedulerについて説明します。Schedulerは、第1回の「擬人化」「擬似パソコン化」の説明の中で、最後に登場したソフトウェア部品です。Schedulerは、ソフトウェア部品が有するグローバル関数の内、並列実行の対象となる関数群のスケジューリング(実行順序制御)を担います。グローバル関数が呼ばれるタイミング各ソフトウェア部品は、それぞれ幾つかのグローバル関数を有しますが、それらのグローバル関数が呼ばれるタイミングは、以下の3種類に分類できます。他のソフトウェア部品から直接呼ばれる。機能を提供するグローバル関数は、その機能が必要になったタイミングでそれを必要とする他のソフトウェア部品から直接、呼ばれます。Generatorのコールバック関数として呼ばれる。Generatorから呼ばれます。並列処理関数として呼ばれる。他のソフトウェア部品と並列に実行しなければならない関数は、Schedulerと呼ばれるソフトウェア部品から呼ぶようにします。この記事では、並列処理関数の設計手法である「ステートマシン」について説明した後、上記3のSchedulerによるスケジューリングについて説明します。本記事では、リアルタイムOSなしでスケジューリングを行う事を想定しています。組み込みシステムでは、前記1~2のいずれの場合でも、1つの関数でCPU実行権を長時間、占有する事は許されません。いう関数を作ってしまうと、並列動作させるべき他の処理が実行できないからです。1回あたりの関数呼び出しで許容されるCPU占有時間(すなわち実行時間)は、開発するシステムの要件に依存します。故に、一概に「XXmsec以内」とは言えませんが、たとえばイベント発生待ちや、大量の計算/検索のために、実行時間の長い繰り返し処理を1回の関数呼び出しで処理する事は避けた方が良いと思います。この記事では、並列処理関数の設計手法として「ステートマシン」を紹介します。ステートマシンとはステートマシンは、組み込みソフトウェアでは一般的な設計手法です。オブジェクト指向設計のデザインパターンでは「ステートパターン」に相当します。関数が呼ばれた際、毎回、同じ処理を実行するのでは無く、現在の「状態」に応じて異なる処理を実行するように設計します。ある処理を行う過程で、イベント発生を待たなければならないとします。while文でイベント発生を待ってしまうと、目的のイベントが発生するまで、CPU実行権を占有してしまいます。この問題を回避するため、たとえば「前処理」「イベント発生待ち」「メイン処理」の3つのグローバル関数に分割し、Schedulerに呼び分けてもらう案も考えられますが、この方法では、ソフトウェア部品の内部仕様を外部にさらす事になり、更にグローバル関数の数も増えるため、望ましくありません。いうケースでは、ステートマシンの設計手法を利用します。イベント待ちが必要ならば「初期状態」「イベント待ち状態」の2つの状態を持つようにします。この「状態」を保持する変数は、enum型のstatic変数として定義します。*/関数の実装では、swtich~case文で、現在の状態に応じて、異なる処理を実行するようにします。Generatorによってコールバック関数で通知してもらうようにしておき、その情報は、static変数に保存しておきます。イベント発生チェック()では、コールバック関数で通知され、static変数に保存された直近のイベント情報をチェックするようにします。このように設計すれば、このソフトウェア部品と外部のソフトウェア部品間のインタフェースは、イベント通知のコールバック関数と、並列処理関数の2つに集約でき、更にこのソフトウェア部品がどういう状態を持つかは外部から隠ぺいできます。Schedulerによるスケジューリング前記のとおり、並列処理関数をステートマシンで設計した後、Schedulerと呼ばれるソフトウェア部品から、各並列処理関数を呼び出します。その際の最も単純なスケジューリングの方法は、ラウンドロビンと呼ばれる方法です。ラウンドロビンでは、並列処理に相当するグローバル関数を単純に順番に、繰り返し呼び出します。以下のような感じです。{並列処理_その1();並列処理_その2();並列処理_その3();並列処理_その4();}}上記関数は、関数mainから呼ばれる無限ループの関数です。これが最も単純なスケジューリングの方法です。この方法に対して更に、イベントAが発生した場合は「並列処理_その1()」と「並列処理_その2()」は休止させて、代わりに「並列処理_その5()」を実行し、その処理が終わり次第、元の状態に戻すというようなスケジューリングを追加する事も可能です。この場合、Scheduler内のスケジューリング関数Scheduler_main自体をステートマシン化し、以下のように設計します。*/並列処理_その4();}}上記の実装例では、イベントAの発生後、緊急処理の「並列処理_その5()」が開始されるまでの待ち時間は、最大で「並列処理_その1()」~「並列処理_その4()」の最大時間の「合計」になります。この待ち時間が長すぎる場合は、関数Scheduler_mainの状態管理を詳細化する事で、「並列処理_その1()」~「並列処理_その4()」の中の「最大時間」まで短縮できます。以上のように、ステートマシンとSchedulerの設計手法を利用する事で、リアルタイムOSなしでも、ソフトウェア部品の独立性を維持しつつ、リアルタイム性を確保した設計が可能になります。第2回はここまでです。「特定の役割り」を担う「部品」によってソフトウェア全体を構成する。オブジェクト指向プログラミングの習慣を取り入れる。うち、後者の「オブジェクト指向プログラミングの習慣を取り入れる」について説明します。「特定の役割り」を担う「部品」によってソフトウェア全体を構成する。オブジェクト指向プログラミングの習慣を取り入れる。うち、1について解説します。このページでは、以下の内容について説明しています。Generator「特定の役割り」を担う「ソフトウェア部品」とは?「特定の役割り」を担う「ソフトウェア部品」とは、たとえば以下のような「特性」を備えたC言語の「モジュール」、すなわちコンパイル/リンク単位です。他の「部品」は担わない、その部品ならではの「役割り」を担う。他の「部品」からは見えない/見る必要の無い、隠された「変数」や「関数」を有する。「部品」間は「グローバル関数呼び出し」によって情報交換(すなわち入出力)を行う。グローバル変数は、基本、NGとしたいですが、グローバル変数を使わない代わりに、Getter/Setterと呼ばれる種のグローバル関数を乱用する事もNGとしたいです。システムを分析し、要件を満たす最適な部品と、その組み合わせを見つけ出した結果、グローバル変数の代わりに、少ないGetter/Setter関数を用意すれば済む...を目指します。オブジェクト指向設計の用語を使って説明しますと、唯一のインスタンスしか生成できない(Singletonな)クラスを使ってソフトウェアを設計するイメージです。我々の目の前に複雑で難解な仕事があった場合に、複数のメンバで協力し、各メンバはそれぞれ単純で解り易い仕事を担い、メンバ全員で協力して協調的に仕事する時のような発想で、役割りを決めます。「Watcher(見張り人)」「Generator(生成人)」「Converter(変換人)」「Viewer(表示人)」「Manager(管理人)」のような役割りを設けます。Watcher(見張り人)は、何かを監視し、その結果を周りに伝える役割りを担います。Generator(生成人)は、何かを生成し、その結果を周りに提供する役割りを担います。Converter(変換人)は、何かから別の何かを生成し、その結果を周りに提供する役割りを担います。Viewer(表示人)は、何かを表示する役割りを担います。Manager(管理人)は、全体をまとめる役割りを担います。いうような役割りを設け、モジュール名として「xxxWatcher.c/.h」というよう名前を付ければ、仕様書を読まなくても「このモジュールはxxxの監視を担うモジュールだな」と、大よその推測ができます。擬似パソコン化Webアプリやゲームソフトは、予め決められた環境下で動作します。パソコン上のWebブラウザや、Androidスマホ上などです。これらの環境下でソフトウェアを開発する場合は、GUIボタン表示、そのボタンがクリックされた際のイベント発生等、殆どのソフトウェアが同様に必要とするようなソフトウェア部品は予め準備されており、プログラマは、それらを最初から利用できます。組み込みソフトウェアにおいては、そのような標準的な動作環境は存在せず、システム固有の入出力装置を備えたハードウェア上で動作させる必要があります。OS(オペレーティングシステム)も、プロジェクトの要件によって、使用できる場合と、使用できない場合があります。このように、標準の動作環境が無い組み込みソフトウェアですが、そのソフトウェア開発において「まず動作環境から作成する」というようなステップが取られる事は稀です。アプリケーション処理から、直接、低レベルの入出力のためのレジスタを制御してしまう...というような事が行われがちです。このようなソフトウェアを開発してしまうと、その後、ソースコードを別のマイコン上で動作するように移植せねばならない...というような流用開発の時は、アプリケーション中に点在する入出力処理を書き換えないといけなくなります。「擬似パソコン化」では、アプリケーションソフトが動作する「動作環境」を「特定の役割り」と位置づけ、部品化します。「擬似パソコン」は、たとえば以下のような部品(モジュール)で構成します。Driver(以下Driverと記す)は、入出力ポート、シリアルI/O、A/D変換器等、マイコンの周辺ハードウェア(Peripheralといいます)を制御する役割を担います。(以下Halと記す)は、Driver内のグローバル関数を呼び出し、上位アプリケーションに対してアプリケーション固有の入出力機能を提供します。等、マイコン周辺のハードウェアに強く依存した機能を提供するのに対して、Halは周辺ハードウェアの更に先に接続されたハードウェアを制御する事に着目している点が違います。温度センサを扱うシステムの場合、上位アプリケーションは、Halとして準備された関数Hal_GetTemprature()を呼ぶ事になります。ch)のようなDriver関数を呼ぶ事になります。このような役割分担にする事で、上位アプリケーションは、温度センサをA/D変換器で制御するのか、シリアルI/Oで制御するのか、意識する必要が無くなり、Halに委ねる事ができます。Generatorは、ハードウェアの状態変化を検出し、該当するコールバック関数を呼び出す役割を担います。パソコンやスマホでは、マウスやタッチパッドを操作した際、該当するコールバック関数が呼ばれます。マスクがクリックされた際は、関数OnClickが呼ばれる...という感じです。これと同じ要領で、組み込みシステムの周辺ハードウェアの状態変化をコールバック関数を呼び出す方法で上位アプリケーションに通知します。Generatorは、たとえば「スタートボタンは1秒間、長押しされた際に検出される」というようなアプリケーション固有の要件があった場合、その要件に従って状態変化を検出します。Generatorに任せ、それ以外の仕事に専念できるようになります。Generatorは、ハードウェアに依存した処理を行いますので、Halと同じく、Driver関数を直接呼び出してもかまいません。Generator側に用意し、他のソフトウェア部品から登録関数を呼ぶ際、呼び出して欲しいstatic関数のポインタを引数として渡す方法が考えられます。Generatorは、ポインタ間接でstatic関数を呼び出す事になります。Generatorの仕様書に「xxxイベント検出時は、zzzモジュール内のグローバル関数yyyを呼び出す事」というような仕様を記載しておき、そのとおりに実装する方法も考えられます。この2つの方法のいずれの場合でも、関数名の命名において、その関数は何のイベントが発生した際に呼ばれるコールバック関数であるか、第三者に解るよう配慮しておく事をお勧めします。callback_StartButton()のような感じです。第1回はここまでです。「特定の役割り」を担う「ソフトウェア部品」を選定するために、「擬人化」と「擬似パソコン化」の2つの観点で役割分担を検討してみました。次回は、組み込みシステムにおいて極めて重要な「Scheduler」について説明します。福山雅治さんについて書きたいと思います。対極にある、「新鮮」かつ「発展途上」のイメージなのです。FMから全国ネットで放送されているFMラジオ番組「福のラジオ」の熱心なファンで、毎週土曜の14時から欠かさず拝聴しているのですが、色んな意味でこの番組は凄い番組だと思います。何が凄いかと申しますと、福山さんの話術です。「しゃべりの師匠は(オールナイトニッポンの笑福亭)鶴光師匠」と公言されているだけの事はあると思います。番組の構成作家であられる今浪祐介(いまなみゆうすけ)さんとの掛け合いトークは、「ガキ使」でダウンタウンさんが展開される即興漫才のような「話芸」の域に達していると思います。流れとしては、毎度、今浪さんの不用意な発言に対して、福山さんが絶妙なつっこみを入れられる展開です。今浪さんも受け役としていい味を出されています。パワハラ感の漂う福山さんの鋭いつっこみに耐え忍ぶ今浪さんを愛おしく感じる時があります。次に凄いのは、番組の構成です。番組中の多くの時間は、福山さん作品(音楽/ドラマ/映画等)のプロモーションに使われているのです。この種の構成は、一歩間違えると、福山さんの積極的なファンで無い方々がラジオを点けられた際に拒否反応を示されるリスクがあると思うのですが、「福山さん作品のプロモーション活動」という「舞台」を通して、福山さんと今浪さんの絶妙なトークが展開されますので、福山さんのファンで無い方々も充分に楽しめます。結果、トークを楽しみに毎週拝聴する中で、気付いたときには福山さん作品のファンになってしまっている...という事が起こり得ます。私自身がそうだったのです。メールを紹介するコーナーが設けられていますが、これらのコーナーでは、土曜のお昼のFMラジオ番組とは思えない、超爆笑な、しかもエロい内容が展開されます。そのエロい内容を男前の福山さんが、顔を見せずにサラッと言い切られるので、いやらしく感じません。同番組の中では、福山さんの人間性が垣間見えるトークも展開されます。消費者目線を忘れない福山さん印象に残っているのは、福山さんがスタッフの皆さんと昼食を摂られる時のエピソードです。印税その他で多額の資産をお持ちのはずの福山さんですが、数種のランチメニューの中から、高いメニューを注文される事は無く、手頃な価格のメニューを選択されるそうです。この点について、今浪さんが「なぜですか?」と問われた際、福山さんは「ランチメニューは、殆どの場合、安いメニューの方がコストパフォーマンスとして高いメニューより優れているから」との事でした。要は、折角、高いお金を払って高いメニューを注文しても、それに見合う満足感が得られないとガッカリしてしまうので、それが嫌なのだそうです。巨額の富を得ながら、我々消費者と同じ金銭感覚を維持されている事に驚きましたし、また業種は違えど同じ「表現者」と言える「料理人」に対して妥協されない姿勢は素晴らしいと思いました。幼少の事、ご実家は裕福で無かった事も度々公言されています。今浪さんが「子供の頃、ハンバーグを食べる事も無かったんですよね」と問われると、福山さんは「そこまで貧乏じゃ無かったよ!」と憤慨され、今浪さんが恐縮される場面もありました。ご自分を「美しい」と感じている福山さん(?)旅先のエピソードとして、福山さんはホテルへのチェックイン後、即シャワーを浴びられる事を今浪さんが紹介されていました。それと同じ気持ちなんだ。してから食事を楽しみたいだけなんだ」と主張されていました。いう、どうでもいい事にも向きになられる福山さんは、微笑ましいです。レジェンドへのリスペクトを忘れない福山さん番組では、泉谷しげるさん、Charさん、鮎川誠さん等、音楽界のレジェンドへのリスペクトの気持ちを度々述べられます。その謙虚さ、更なる上を目指される貪欲さは、素晴らしいと思います。その中のエピソードとして、山下達郎さんがご自身のFMラジオ番組「サタデーソングブック」で福山さんのカバーアルバム「魂リク」から「元気をだして」をオンエアされたときのエピソードが印象に残っています。仕事の移動中、車内での出来事だったらしいのですが、オンエアされてる事に気付いた福山さんは、スタッフさんに車を脇に停車するよう要求され、達郎さんのトーク/批評に真剣に耳を傾けられ、オンエアされた事にいたく感動されていました。「あの山下達郎さんが『すごい』ってオンエアして下さったんだよ!」と、子供のように感激されていた事を覚えています。いつまでも新鮮さを失わない理由の1つが垣間見えた場面でした。BL(ボーイズラブ)疑惑の福山さん(?)昔、同番組には「主婦『雅子』」のコーナーがありました。福山さんが主婦「雅子」に扮して、視聴者からのメールに主婦目線でコメントされるコーナーで、「おねえ言葉」で話されていました。いう疑惑がありました。その後、ご結婚され、一子も授けられたとの事で、この疑惑は払拭された...と思いきや、再び同番組にて、香川照之さん、斎藤工さんとのBL(ボーイズラブ)疑惑が浮上しています。いつも興味深い話題を提供してくれる番組です。福山雅治さんの魅力をご紹介しました。いつまでも発展途上、チャレンジャー、未完成である故に、最強の表現者であられる福山雅治さんを今後も応援します。Editor」を使って、演習問題の解答例を実行する手順について説明します。このページでは、以下の内容について説明しています。Editorは、以下の目的で使用します。プログラミング言語VBAで書いたソースプログラムをExcelに入力するため。本講座の第1回~第3回を読まれた方は、演習問題を解く際、紙と鉛筆を使ってソースプログラムを書かれたと思いますが、その状態では作成したプログラムは実行できません。Editorの画面から作成したソースプログラムを入力する事で、コンピューターおよびExcelに対して、実行して欲しいプログラム(すなわち作業指示書)の詳細を伝える事ができます。プログラムの記述誤りをチェックするため。Editorにソースプログラムを入力すると、単純な記述誤りを発見してくれます。入力したソースプログラムを機械語のプログラムに翻訳しながら実行するため。実行中のプログラムを途中で止めるため。途中で止めたプログラムを続きから1行ずつ実行するため。変数に記憶している値を確認するため。上記の内、4~6は、作成したプログラムが期待どおりに動作せず、プログラムの誤りを見つけたいときに行う作業です。これらの作業のことを「デバッグ」といいます。Editorを使用するには、予めExcel側で必要な初期設定を行う必要があります。その手順を以下に示します。2010」を使用するケースを想定しています。「開発」タブを追加する。Excelの上部のタブの並びから、左端の「ファイル」タブを選択し(下図の1)、表示された画面から左端の下の「オプション」ボタン(下図の2)をクリックします。すると、新たなダイアログが表示されます。初期状態では、左端の一番上の「基本設定」が選択されていますので、左端の列の途中「リボンのユーザー設定」(下図の3)を選択して、下図の画面を表示させて下さい。その画面の右端の表示をスクロールさせて「開発」のチェックボックスを表示させて下さい(下図の4)。このチェックボックスが選択されていない場合は、選択して、OKボタンをクリックして下さい。結果、Excelの初期画面のタブに「開発」タブが表示されます(下図の5)ので、これをクリックして下さい。上図のような画面に変わります。Basic」(下図の6)をクリックして下さい。Editorが起動できます。)を「同時」に押す方法でも起動できます。Editorの画面が開いたら、「表示」⇒「ツールバー」メニューの「標準」と「デバッグ」を選択しておいて下さい。前節までの設定を行えば、VBAでプログラミングを始める事ができますが、追加で以下を設定される事をお勧めします。Editorを使ってプログラムを入力し始めると、不完全なプログラムだとして、再三、ダイアログでエラーメッセージが表示されます。入力途中なのでプログラムが不完全である事は自分で解っているので、毎度、OKボタンでダイアログをクローズしないといけないのは面倒です。Editorの設定を変更する事で抑止できます。抑止した場合は、ダイアログは表示されなくなり、プログラムの入力画面上で、誤った行が赤字で表示されるようになります。変数の宣言が無い場合にエラーを表示させる本講座では、変数を使用するときは事前に「Dim」文で宣言する事を推奨しています。Excelではインストール直後は、変数の宣言なしに、いきなり変数を使って良い設定になっています。これは、プログラミングに慣れた人にとっては便利な機能ですが、プログラミング入門者にとっては、変数名を誤って入力してしまった場合にエラーが表示されないので、間違い探しに時間を要する危険性があります。Explicit」と宣言すれば良いです。これにより、作成するプログラムで宣言なしで変数を使用した場合、エラーが表示されるようになります。Editorで事前に設定しておけば、自動的にこの行が宣言されます。結果、下図が表示されますので、上部のタブから右端の「編集」を選択し、「自動構文チェック」のチェックボックスを外し、「変数の宣言を強制する」のチェックボックスをチェックして下さい。ソースプログラム入力先の「関数」と「ボタン」の作成VBAでソースプログラムを入力し、実行する方法には、幾つかの方法がありますが、本講座ではExcelのシート上に専用のボタンを追加し、そのボタンが押されたときに入力したソースプログラムを実行する方法を紹介します。Excelで新規に空のファイルを開いて、シート”Sheet1”を表示した状態で「開発」タブ(下図の8)を選択します。「挿入」(下図の9)をクリックします。すると下図のような「フォームコントロール」とその下に「ActiveXコントロール」が表示されますので、「ActiveXコントロール」の中の上段の右端の「コマンドボタン(ActiveXコントロール)」(下図の10)をクリックして下さい。カーソルが矢印から「+」に変わりますので、ドラッグして、適当な大きさのボタンを作成して下さい。結果、リボンの「デザインモード」が選択された状態になります。上図の状態で、作成したボタンをダブルクリックして下さい。Editorが起動し、以下の画面が表示されます。ここまで作業した時点で、新規作成したファイルを「名前を付けて保存」で保存して下さい。Editorでは無くExcelの画面に戻って、「ファイル」タブ⇒「名前を付けて保存」ボタンをクリックし、開いたダイアログで「ファイルの種類」として「Excelマクロ有効ブック(*.xlsm)」を選択して、適当なファイル名で保存して下さい。以上の操作により、プログラムを実行するためのボタンと、そのボタンが押された際に実行される「関数」を作成したことになります。Editorの画面に戻り、紙に書いて作成したソースプログラムを下記の空行の部分に入力して下さい。第3回の演習問題の解答例を入力すると、以下のようになります。この画面は、左画面のシート名表示から「Sheet1(Sheet1)」が選択されている場合に表示されます。万一、別のファイルが選択され、上記の部分が表示されなくなった場合は、左画面から「Sheet1(Sheet1)」をダブルクリックして、表示し直して下さい。入力したプログラムを実行する方法には、以下の2つの方法があります。Editorの画面を使って、少しずつ実行する方法。Editorの画面は使わずに、Excelの画面から一気に実行する方法。前者は「プログラム作成途中」の実行方法で、プログラムに間違いが無いか動作確認しながら少しずつ実行する方法です。後者は「プログラム完成後」の実行方法です。プログラムを少しずつ実行する目的について(=デバッグ)入力したソースプログラムに間違いがあった場合、プログラムは期待通りに動作しません。この場合、入力したソースプログラムを読み直し、自分で間違っている箇所を探し出す必要があります。ソースプログラムを読み直しただけでは、どこが間違っているのか解らない事が多々あります。この場合は、プログラムを1行ずつ実行して、変数に記憶した値の変化や、Excelのシート/セルの変化を確認しながら、ソースプログラムの間違った箇所を特定する必要があります。Editorを使ってプログラムを少しずつ実行させ、その時の動作を確認することでプログラムの間違った箇所を見つける作業のことを「デバッグ」と呼びます。プログラムを一気に実行する方法Excel画面に戻り、「開発」タブを選択して「デザインモード」をクリックして、デザインモードが選択されていない状態に戻してください。「デザインモード」が選択されていない状態では、「デザインモード」のボタンの色がオレンジ色から白に戻ります。「デザインモード」のボタンが選択されていない状態になったら、シート上のボタン「CommandButton1」をクリックして下さい。結果、入力したプログラムが実行されます。プログラムを途中で止める方法プログラムの実行に先立って、途中で止めたい行を選びます。Editorの下記画面でプログラムの左端の部分(下図の11)をクリックすると、選択した行の色が変わります。この状態で「ブレークポイント」が設定された状態になります。その後、Excelの画面に戻って「CommandButton1」ボタンをクリックすると、プログラムが実行され、事前に選択した行で止まります。プログラムの実行中、今止めたい...と思った場合は、「中断」ボタン(下図の12)をクリックします。オーバー(Shift+F8)」ボタンのいずれかをクリックします(下図の13)。結果、1行だけ実行され、次に実行する行を表す黄色のラインが移動します。オーバー(Shift+F8)」)。今のところ、この2つのボタンの何れをクリックしても、同じ動きとなり、1行分、プログラムを実行した後に止まります。この2つのボタンは、ご自分で関数を作成された場合で、かつその関数呼び出しを実行する場合に限り、動作が異なります。「ステップイン」は、呼び出した関数の中に入ってから止まります。「ステップオーバー」は、呼び出した関数から戻るまで1回で実行します。変数が記憶している値を確認する方法プログラムが止まっている状態で、マウスカーソルを変数名の上に移動させると、「変数=値」という表示がポップアップで表示されます(下図の14)。他には「表示」⇒「ウォッチウィンドウ」メニューを選択してウォッチウィンドウを表示した後(画面の右下に表示されます)、「デバッグ」⇒「ウォッチ式の追加」メニューを選択し、表示されたダイアログの「式」の欄に確認したい式(変数名やオブジェクト変数名を含む)を入力する方法があります。結果、停止する度に入力した式の値が確認できます。下図は、式として「row」を入力した例です。プログラムを最初から実行し直す方法リセットボタン(上図の15)をクリックした後、再度、Excelのシートからプログラムを実行する「CommandButton1」ボタンをクリックします。デバッグの注意点Do~Loop等の繰り返しを含むプログラムをデバッグする場合は、繰り返しの先頭か最後に必ず「DoEvents」文を挿入して下さい。作成したプログラムに誤りがあり、無限ループに陥る事は多々あります。この場合、繰り返しの中に「DoEvents」文を挿入しておかないと、中断ボタンやリセットボタンでプログラムを止める事ができなくなります。この事を考えると、Do~Loopを書く場合は、予めループ内の最後にDoEventsを書く習慣を付けられるのが良いと思います。プログラムを再実行する場合は、開発ツールのリセットボタンをクリックしてからExcel画面のプログラム実行開始ボタンをクリックして下さい。VBAプログラミングVBAによるプログラミング超入門講座(第3回)このページでは、以下の内容について説明しています。文字列について関数についてオブジェクトについてブック、シート、セルを表すオブジェクトについてオブジェクトの「参照」について「値」の記憶と「参照」の記憶の違いについて演習問題(その2)文字列についてプログラムで「言葉」の情報を扱うときは、データ型として「整数型」で無く、「文字列型」を使用します。文字列型の場合も、整数型のように定数と変数が使えます。ように複数の文字を並べてダブルクォーテーション(")で囲んで表します。String」として宣言し、以後、整数型の変数のように扱います。文字列を扱うプログラム例を以下に示します。If文で文字列の比較を2回行い、その結果を整数型の変数cmp1とcmp2にそれぞれ1(等しい)と0(異なる)で記憶し、最後に文字列型変数の代入を実行しています。このプログラムを実行した後、変数str1、str2、cmp1、cmp2にどんな値が記憶されるか、考えながら読んでいきましょう。いう文字列を記憶させています。その後、If文で変数str1とstr2が等しいか比較しています。1」は実行されません。続いて、変数str1と文字列定数”abc”を比較しています。続いて、変数str2で記憶していた文字列を変数str1に上書きしています。このプログラムの実行後、整数型の変数cmp1には0、cmp2には1が記憶され、文字列型の変数str1、str2には共に”efg”が記憶されます。文字列型の最大文字数はString型の変数には、何万文字も記憶できます。文字列型の最小文字数はString型の最小文字数はゼロです。文字数ゼロの文字列は””として表現します。Excelでは、空のセルを探すとき、空の文字列””を使用しますので、ここで文字数ゼロの文字列の使い方を覚えておいてください。“abc”」と書けば、変数str1には文字a,b,cに対応する何らかの「数」が記憶されるはずです。記憶した文字数もどこかに数で記憶されるはずです。いう細かい処理はVBAが勝手に処理してくれますので、我々は意識しなくて済みます。変数str1には任意の文字列が記憶でき、後でその情報が取り出せ、比較できれば充分...と割り切って、この疑問は先送りにしましょう。関数についてプログラミング言語の翻訳ソフトには、役立つプログラム集が付属しており、我々が作るプログラムから利用できます。その個々のプログラムは「関数」と呼ばれます。VBAで利用できる関数には、たとえば画面にメッセージを表示する関数(MsgBox)、文字列を大文字に変換する関数(UCase)、文字列の中から別の文字列を検索する関数(InStr)等があります。利用するときは、コンピューターに対して「次の作業指示は、xxxxという名前の関数の指示に従ってくれ。その作業が終わったら再び私が書いた作業指示書のここに戻ってきて、次の行以降の作業指示に従ってくれ」というように、一時的に別の作業指示書で作業を指示する事になります。関数は、「入力」を受け取り「処理」した結果を「出力」するような小さなプログラムです。我々のプログラムから関数を利用する場合は、以下のように書きます。Then上記の例は、VBAが用意してくれている「文字列を大文字に変換する関数」である「UCase」を利用した例です。関数UCaseは、カッコ()の中に書いた文字列を受け取って、大文字に変換した結果を返します。関数が返した情報は、’=’を使って変数に記憶させるか、記憶する必要が無い場合、たとえばIf文の中で比較するだけで良い場合は、記憶させずにその場で参照するだけにします。「UCase(str1)」や「UCase(“efg”)」の記述は、これまで式の中に変数や定数を書いてきた書き方に似ています。この記述は、カッコ内に書いた文字列が大文字に変換された文字列を指す事になりますが、コンピューターの動きとしては、一旦、ここに書かれているプログラムから離れて、別のところに書かれている関数UCaseのプログラムを実行し、その後、再びここのプログラムに戻ってくる...という動きになります。その際、関数UCaseを実行した結果として大文字に変換した文字列を持って帰ってくる事になります。関数は「探して」使おうVBAがサポートする関数の数は、膨大な数に及びますので、全部覚える事は難しいと思います。最初は「何がしたいか?」という我々の要求をはっきりさせてから、インターネットやVBAの入門書の目次/索引で検索する事をお勧めします。変換」というキーワードで検索して見つけました。関数の仕様、たとえばその関数はどういう仕事をするための関数かカッコの中にどんな情報を幾つ書けば良いか渡す情報のデータ型は何型か?(整数型か文字列型か他の型か)関数が返す情報はどんな情報か、またその型は何型かなどの仕様は、関数によって異なりますので、これらについてもインターネットや書籍で調べてください。オブジェクトについてここでは引き続き、プログラミング言語の翻訳ソフトに付属している役立つプログラム集について話をします。前項では「関数」の話をしましたが、プログラミング言語はその他にも「オブジェクト」と呼ばれる仕組みを使って、役立つプログラムを提供してくれます。オブジェクトとはオブジェクトは、複数の変数と、それに係る関数が一体化したものです。オブジェクトの特徴オブジェクトの特徴を以下に示します。(変数のように)情報が記憶できます。オブジェクトは、自身に係る情報を記憶するための変数を「所有」します。(関数のように)処理や仕事が実行できます。(変数のように)名前を持ちます。VBAが提供するオブジェクト「Range」を例に挙げて、オブジェクトの特徴について更に説明していきます。RangeはExcelの「セル」を扱うオブジェクトです。セルの特徴を記憶する変数としてValue(値)、Row(行番号)、Column(列番号)、Width(セルの幅)、Height(セルの高さ)などの変数を所有しています。これらの変数に整数や文字列等を記憶させるときは、通常の変数と同じく‘=’演算子を使います。左辺にはオブジェクト名と変数名をカンマ(.)で繋げた名前を記述し、右辺には整数、文字列等を記述します。以下に、オブジェクトRangeを使ったソースプログラム例を示します。オブジェクト型名」と書きます。上記ではRange型のオブジェクト変数abcを宣言しています。Workbooks(“成績表.xlsx”).Worksheets(“Sheet1”).Cells(3,1)」は、宣言したオブジェクト変数abcを使って、現在開いている”成績表.xlsx”のシート”Sheet1”の「3行目の1列目」のセルを扱うための記述です。この記述については後程、説明しますので、ここでは以後、オブジェクト変数abcを使って、”成績表.xlsx”のシート”Sheet1”の「3行目の1列目」のセルが扱えるようになる...とだけ理解しておいてください。12345」は、セルの値を保持する変数Valueに整数を記憶させる記述です。記憶した情報は後で取り出せます。abc.Value」と書けます。ここで重要な事は、整数型の変数なら単に情報を記憶するだけですが、オブジェクトの場合は記憶すると同時に、記憶した情報に関連する何らかの処理も併せて実行できる事です。Range型オブジェクトが所有する変数Valueに値を記憶させた場合は、セルの中身が記憶した値に変わり、Excelの表に反映されます。Excelの画面でもその変化が確認できます。5」は、フォントの情報を持つ変数Fontに色情報を記憶させています。ここで注目して頂きたいのは、変数Fontもオブジェクト変数であり、フォントの色情報を保持する変数ColorIndexを持っているという点です。この場合は前記のように、オブジェクト変数名をピリオド(.)で区切って並べて書きます。5」を実行した後は、「3行目の1列目」のセルのフォントは青に変わります。VBAでは、そのときに既に開いているExcelのファイル(Excelではファイルの事をブックと呼びます)や、その中のシート、更にその中のセルに相当するオブジェクトは、プログラム開始の時点で既に存在しています。これらのオブジェクトの間には「所有」の関係があり、ブックはシートを所有し、シートはセルを所有しています。成績表.xlsx”のシート”Sheet1”の中に存在する「3行目の1列目」のセルに整数1234を入れる場合は、以下のように書きます。1234上記のオブジェクト変数「Workbooks」、「Worksheets」、「Cells」は、それぞれブック、シート、セルの情報を扱うオブジェクトですが、いずれも複数のオブジェクトから成るオブジェクトです。したがって複数のオブジェクトの中から所望のオブジェクトを特定するために、カッコを付けてブック名、シート名、行列番号を指定する必要があります。上記の例では、カッコの中は全て文字列および整数の「定数」で指定しましたが、変数で指定する事も可能です。1234プログラムの中でこれらの変数の値を書き換えれば、同じ式で異なるファイル、シート、セルが扱えるようになります。オブジェクトの「参照」について前項では、Excelのセルを扱う際、以下のような長い文を書きました。1234しかしセルを操作する度に、毎度このような長い文を書くのは大変です。よってVBAや他のプログラミング言語では、オブジェクト変数を使って別のオブジェクトを「参照」できるようになっています。「オブジェクトRangeを使ったプログラム例」で説明した下記プログラムは、Range型のオブジェクト変数を使って別のセルを参照している例です。Workbooks("成績表.xlsx").Worksheets("Sheet1").Cells(3,1)以下では、シートを扱うWorksheet型オブジェクトを使って、ブック”成績表.xlsx”の中のシート”Sheet1′′を参照するプログラム例を紹介します。オブジェクト変数名」という文を使って、ブック”成績表.xlsx”の中のシート”Sheet1′′の「参照」を記憶させています。以後、このオブジェクト変数tableを使えば、ブック名”成績表.xlsx”とシート名”Sheet1′′は書かずに、同じシートが参照できるようになります。「値」の記憶と「参照」の記憶の違いについて前項で説明したオブジェクト変数の「参照」を記憶する...という意味について、もう少し説明します。演算子を使って「変数名=別の変数名」と書いた場合は、右辺の変数が記憶していた「値」がコピーされるだけでした。この事を改めてプログラム例で見てみましょう。i1」という文を使って、変数i1が記憶していた値を変数i2に記憶させています。20」という文で書き換えていますが、この記述は変数i2が記憶している値には影響しません。i2」を実行した場合、10が表示されます。オブジェクト変数名」と書いた場合は、先程の動きとは違ってきます。Workbooks(“成績表.xlsx”).Worksheets(“Sheet1”)」の文によって、オブジェクト変数t1に対して、「ブック”成績表.xlsx”の中のシート”Sheet1′′」の「参照」が記憶されます。これは右辺の記憶していた「値」がコピーされるのでは無く、右辺の存在自体が記憶される...という意味になります。よって以後、左辺のオブジェクト変数と右辺のオブジェクト変数は、同じ実体「ブック”成績表.xlsx”の中のシート”Sheet1′′」を指すようになります。演習問題(その2)では、オブジェクトを使った演習問題をやってみましょう。Excelで作成した以下のような”成績表.xlsx”が既に開かれているとします。この既に開かれている”成績表.xlsx”のシート”Sheet1”を操作して、60点以上の生徒の「名前」と「点数」を青色に変えるプログラムを作成してください。ヒントセルのフォントの色を青色に変える方法は「フォント色を表す変数」のソースプログラム例を参考にしてください。シート”Sheet1′′の2列(B列)目に着目して、2行目から最後の行まで、60点以上かどうか繰り返し確認してください。表の終わりは、セルが空かどうかで判定してください。“”で表す)になります。超入門VBAによるプログラミング超入門講座(第2回)このページでは、以下の内容について説明しています。3回、繰り返す」という超簡単なプログラム例を再び見て行きましょう。Integer」は『今から「i」という名前の「変数」を使います。その「型」は「整数型」です』...という事を「宣言」する文です。「Dim」と「As」の部分は、VBAでは「こう書いて下さい!」と厳密に決められている部分です。「語源は何だろう?」とか考えずに、この通りに書いてください。「i」の部分は変数名です。ここで、使用する変数の名前を宣言します。変数名には、好きな名前を使う事ができます。変数の名前に使用できる文字の種類は、プログラミング言語によって異なりますが、先頭に「英字」、2文字目以降に「英字」か「数字」を使っておけば、殆どのプログラミング言語で変数として認識されるはずです。「Integer」は「整数」という意味です。ここで変数の「型」を宣言します。変数の「型」とは、記憶する情報の「種類」の事です。「Integer(=整数)」と宣言する事で、以後、この変数iを使って整数が記憶できます。3,...などの事です。間の「いずれかの整数値」が記憶できます。変数の「型」には他にも幾つか種類がありますが、この講座では最初は整数型だけを使って行きます。「=」は、変数に値を記憶させるときに使う記号(演算子と言います)です。小学校で習った算数では「=」はたとえば「1+2=3」と書いて、左の式と右の式は「等しい」事を表しますが、プログラミング言語では「=」は、「左の変数に右の式を記憶させる」事を表します。算数に慣れ親しんだ我々にとっては解り辛いですが、そういうルールなのだと、ここで覚えておきましょう。(上書きする)事ができます。Do~Loop次の「Do」と、その7行先にある「Loop」はペアになっています。「Do」文と「Loop」文を書くと、間で挟んだ文を繰り返し実行してもらえます。Do(処理1)Loopたとえば、上記のように書けば、(処理1)を実行した後、再びDo文に戻って(処理1)を実行し、これを無限に繰り返してもらえます。Do」を実行してもらえれば、そこで繰り返しのループから抜けて、Loop文の次の行から実行してもらえます。Then」は「もし変数iが3より大きいなら」という意味です。Ifで囲んだ文を実行します。Do」文は変数iが4になったときに実行されます。後には以下のような「条件式」を記述します。左辺が右辺以下(等しいか、より小さい)のときここでまた’=’が出てきました。3と等しいなら」という意味に変わります。同じ’=’という演算子でも、書く場所によって意味が変わるのです。ややこしいですが、VBAで決まっているルールですので、ここで覚えておきましょう。左辺や右辺には、式を記述します。式には、変数、定数(決まった数のことです)、演算子が記述できます。演算子については、後で説明します。1」という2つの文が書かれています。曖昧に記述していますが、実際にはここで実行して欲しい計算式を記述する事になります。繰り返し実行して欲しい処理をここに記述するのです。1」は、現在のループ回数を記憶するための文です。iに1を足した値が再度、iに記憶されます。演算子についてここで「式」に使用する演算子について説明します。整数型の変数iとjがあり、jに13が記憶されていたとします。3」は、変数jを3で割った結果(商)を記憶するときの指示です。結果は整数型で、余りは切り捨てられます。この例では変数iに商の4が記憶されます。3」は、変数jを3で割った余り(剰余)を記憶するときの指示です。結果は1になり、iには1が記憶されます。使えますが、割り切れない場合は商が偶数になるよう、小数点以下の切り上げ、または切り捨てが発生してしまいます。プログラム例の動き以上の説明を踏まえ、このプログラムがどういう動きをするか、もう一度、見て行きましょう。Loop12:コンピューターはまず1行目を実行します。